From: danielk1977 Date: Wed, 25 May 2005 10:45:10 +0000 (+0000) Subject: Rearrange code so that SSE can invoke the collation factory. (CVS 2482) X-Git-Tag: version-3.2.2~28 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4dade03788d1ff4a7b3ddc14533ac84fda599331;p=thirdparty%2Fsqlite.git Rearrange code so that SSE can invoke the collation factory. (CVS 2482) FossilOrigin-Name: ea061d2ed3b25908fcfcb88e35ba612e5832a217 --- diff --git a/manifest b/manifest index ba6c1dc2aa..689aaf220d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Split\smain.c\sinto\stwo\sfiles\sto\smake\sbuilding\swithout\sthe\sparser\seasier.\s(CVS\s2481) -D 2005-05-25T04:11:56 +C Rearrange\scode\sso\sthat\sSSE\scan\sinvoke\sthe\scollation\sfactory.\s(CVS\s2482) +D 2005-05-25T10:45:10 F Makefile.in 8129e7f261d405db783676f9ca31e0841768c652 F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -32,8 +32,8 @@ F src/attach.c 3615dbe960cbee4aa5ea300b8a213dad36527b0f F src/auth.c 18c5a0befe20f3a58a41e3ddd78f372faeeefe1f F src/btree.c d2e09ebf755bfd665727133361b22c6a915b12d7 F src/btree.h 41a71ce027db9ddee72cb43df2316bbe3a1d92af -F src/build.c b7a5d09791cff54dbe9d8ace89217fcbc6cd475d -F src/callback.c c80e399ec3ef01d9a667f87c79331648a4debb13 +F src/build.c 8c6201bcac8e4cecd7a9fb7f608698994471c17f +F src/callback.c 0910b611e0c158f107ee3ff86f8a371654971e2b F src/date.c 2134ef4388256e8247405178df8a61bd60dc180a F src/delete.c 75b53db21aa1879d3655bbbc208007db31d58a63 F src/experimental.c 50c1e3b34f752f4ac10c36f287db095c2b61766d @@ -63,7 +63,7 @@ F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3 F src/select.c 43cc2a76e3e00dabc59da82d0dcdef23cdba43a3 F src/shell.c 25b3217d7c64e6497225439d261a253a23efff26 F src/sqlite.h.in 3675e3ada207e09b9d52a0463561325df4ac26b5 -F src/sqliteInt.h 9eb8fa1c04da427a0a840b0a0359a8b763484c58 +F src/sqliteInt.h 0de60fafa8d9a15b03b4ed2cfbc2372a5b259295 F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9 F src/tclsqlite.c af0f002d9d6ab4f7f32b9bee5b57665946e76ad9 F src/test1.c 4ad7ffe5a74fd99d4f73f6fd28ba27f403b3adba @@ -281,7 +281,7 @@ F www/tclsqlite.tcl 425be741b8ae664f55cb1ef2371aab0a75109cf9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b F www/whentouse.tcl 528299b8316726dbcc5548e9aa0648c8b1bd055b -P 3e64f1ab417f371e9875915303b898c5b45f0807 -R f1df240b45731b7db4ecb585924f1d63 +P d50915fafbde6859a5c2c3fc5cc9b99553b54e21 +R 787444208f2d5447ef2c5b202731c1af U danielk1977 -Z 9396e64a640a1eaa13d2b45263343304 +Z 8246f07000cee68270a634faa3b8b200 diff --git a/manifest.uuid b/manifest.uuid index 084c77d1cd..e2f1cccb9d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d50915fafbde6859a5c2c3fc5cc9b99553b54e21 \ No newline at end of file +ea061d2ed3b25908fcfcb88e35ba612e5832a217 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 3e7ea9ae5b..964e0e03e5 100644 --- a/src/build.c +++ b/src/build.c @@ -22,7 +22,7 @@ ** COMMIT ** ROLLBACK ** -** $Id: build.c,v 1.322 2005/05/24 20:19:58 drh Exp $ +** $Id: build.c,v 1.323 2005/05/25 10:45:10 danielk1977 Exp $ */ #include "sqliteInt.h" #include @@ -1077,84 +1077,6 @@ void sqlite3AddCollateType(Parse *pParse, const char *zType, int nType){ } } -/* -** Invoke the 'collation needed' callback to request a collation sequence -** in the database text encoding of name zName, length nName. -** If the collation sequence -*/ -static void callCollNeeded(sqlite3 *db, const char *zName, int nName){ - assert( !db->xCollNeeded || !db->xCollNeeded16 ); - if( nName<0 ) nName = strlen(zName); - if( db->xCollNeeded ){ - char *zExternal = sqliteStrNDup(zName, nName); - if( !zExternal ) return; - db->xCollNeeded(db->pCollNeededArg, db, (int)db->enc, zExternal); - sqliteFree(zExternal); - } -#ifndef SQLITE_OMIT_UTF16 - if( db->xCollNeeded16 ){ - char const *zExternal; - sqlite3_value *pTmp = sqlite3GetTransientValue(db); - sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC); - zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE); - if( !zExternal ) return; - db->xCollNeeded16(db->pCollNeededArg, db, (int)db->enc, zExternal); - } -#endif -} - -/* -** This routine is called if the collation factory fails to deliver a -** collation function in the best encoding but there may be other versions -** of this collation function (for other text encodings) available. Use one -** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if -** possible. -*/ -static int synthCollSeq(Parse *pParse, CollSeq *pColl){ - CollSeq *pColl2; - char *z = pColl->zName; - int n = strlen(z); - sqlite3 *db = pParse->db; - int i; - static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 }; - for(i=0; i<3; i++){ - pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, n, 0); - if( pColl2->xCmp!=0 ){ - memcpy(pColl, pColl2, sizeof(CollSeq)); - return SQLITE_OK; - } - } - if( pParse->nErr==0 ){ - sqlite3ErrorMsg(pParse, "no such collation sequence: %.*s", n, z); - } - pParse->nErr++; - return SQLITE_ERROR; -} - -/* -** This routine is called on a collation sequence before it is used to -** check that it is defined. An undefined collation sequence exists when -** a database is loaded that contains references to collation sequences -** that have not been defined by sqlite3_create_collation() etc. -** -** If required, this routine calls the 'collation needed' callback to -** request a definition of the collating sequence. If this doesn't work, -** an equivalent collating sequence that uses a text encoding different -** from the main database is substituted, if one is available. -*/ -int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){ - if( pColl && !pColl->xCmp ){ - /* No collation sequence of this type for this encoding is registered. - ** Call the collation factory to see if it can supply us with one. - */ - callCollNeeded(pParse->db, pColl->zName, strlen(pColl->zName)); - if( !pColl->xCmp && synthCollSeq(pParse, pColl) ){ - return SQLITE_ERROR; - } - } - return SQLITE_OK; -} - /* ** Call sqlite3CheckCollSeq() for all collating sequences in an index, ** in order to verify that all the necessary collating sequences are @@ -1187,33 +1109,22 @@ int sqlite3CheckIndexCollSeq(Parse *pParse, Index *pIdx){ ** pParse. */ CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName){ - u8 enc = pParse->db->enc; - u8 initbusy = pParse->db->init.busy; - CollSeq *pColl = sqlite3FindCollSeq(pParse->db, enc, zName, nName, initbusy); - if( nName<0 ) nName = strlen(zName); - if( !initbusy && (!pColl || !pColl->xCmp) ){ - /* No collation sequence of this type for this encoding is registered. - ** Call the collation factory to see if it can supply us with one. - */ - callCollNeeded(pParse->db, zName, nName); - pColl = sqlite3FindCollSeq(pParse->db, enc, zName, nName, 0); - if( pColl && !pColl->xCmp ){ - /* There may be a version of the collation sequence that requires - ** translation between encodings. Search for it with synthCollSeq(). - */ - if( synthCollSeq(pParse, pColl) ){ - return 0; - } - } - } + sqlite3 *db = pParse->db; + u8 enc = db->enc; + u8 initbusy = db->init.busy; - /* If nothing has been found, write the error message into pParse */ + CollSeq *pColl = sqlite3FindCollSeq(db, enc, zName, nName, initbusy); if( !initbusy && (!pColl || !pColl->xCmp) ){ - if( pParse->nErr==0 ){ + pColl = sqlite3GetCollSeq(db, pColl, zName, nName); + if( !pColl ){ + if( nName<0 ){ + nName = strlen(zName); + } sqlite3ErrorMsg(pParse, "no such collation sequence: %.*s", nName, zName); + pColl = 0; } - pColl = 0; } + return pColl; } diff --git a/src/callback.c b/src/callback.c index 81edfb9c8b..1abf826684 100644 --- a/src/callback.c +++ b/src/callback.c @@ -13,11 +13,127 @@ ** This file contains functions used to access the internal hash tables ** of user defined functions and collation sequences. ** -** $Id: callback.c,v 1.1 2005/05/24 12:01:02 danielk1977 Exp $ +** $Id: callback.c,v 1.2 2005/05/25 10:45:10 danielk1977 Exp $ */ #include "sqliteInt.h" +/* +** Invoke the 'collation needed' callback to request a collation sequence +** in the database text encoding of name zName, length nName. +** If the collation sequence +*/ +static void callCollNeeded(sqlite3 *db, const char *zName, int nName){ + assert( !db->xCollNeeded || !db->xCollNeeded16 ); + if( nName<0 ) nName = strlen(zName); + if( db->xCollNeeded ){ + char *zExternal = sqliteStrNDup(zName, nName); + if( !zExternal ) return; + db->xCollNeeded(db->pCollNeededArg, db, (int)db->enc, zExternal); + sqliteFree(zExternal); + } +#ifndef SQLITE_OMIT_UTF16 + if( db->xCollNeeded16 ){ + char const *zExternal; + sqlite3_value *pTmp = sqlite3GetTransientValue(db); + sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC); + zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE); + if( !zExternal ) return; + db->xCollNeeded16(db->pCollNeededArg, db, (int)db->enc, zExternal); + } +#endif +} + +/* +** This routine is called if the collation factory fails to deliver a +** collation function in the best encoding but there may be other versions +** of this collation function (for other text encodings) available. Use one +** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if +** possible. +*/ +static int synthCollSeq(sqlite3 *db, CollSeq *pColl){ + CollSeq *pColl2; + char *z = pColl->zName; + int n = strlen(z); + int i; + static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 }; + for(i=0; i<3; i++){ + pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, n, 0); + if( pColl2->xCmp!=0 ){ + memcpy(pColl, pColl2, sizeof(CollSeq)); + return SQLITE_OK; + } + } + return SQLITE_ERROR; +} + +/* +** This function is responsible for invoking the collation factory callback +** or substituting a collation sequence of a different encoding when the +** requested collation sequence is not available in the database native +** encoding. +** +** If it is not NULL, then pColl must point to the database native encoding +** collation sequence with name zName, length nName. +** +** The return value is either the collation sequence to be used in database +** db for collation type name zName, length nName, or NULL, if no collation +** sequence can be found. +*/ +CollSeq *sqlite3GetCollSeq( + sqlite3* db, + CollSeq *pColl, + const char *zName, + int nName +){ + CollSeq *p; + + p = pColl; + if( !p ){ + p = sqlite3FindCollSeq(db, db->enc, zName, nName, 0); + } + if( !p || !p->xCmp ){ + /* No collation sequence of this type for this encoding is registered. + ** Call the collation factory to see if it can supply us with one. + */ + callCollNeeded(db, zName, nName); + p = sqlite3FindCollSeq(db, db->enc, zName, nName, 0); + } + if( p && !p->xCmp && synthCollSeq(db, p) ){ + p = 0; + } + assert( !p || p->xCmp ); + return p; +} + +/* +** This routine is called on a collation sequence before it is used to +** check that it is defined. An undefined collation sequence exists when +** a database is loaded that contains references to collation sequences +** that have not been defined by sqlite3_create_collation() etc. +** +** If required, this routine calls the 'collation needed' callback to +** request a definition of the collating sequence. If this doesn't work, +** an equivalent collating sequence that uses a text encoding different +** from the main database is substituted, if one is available. +*/ +int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){ + if( pColl ){ + const char *zName = pColl->zName; + CollSeq *p = sqlite3GetCollSeq(pParse->db, pColl, zName, -1); + if( !p ){ + if( pParse->nErr==0 ){ + sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); + } + pParse->nErr++; + return SQLITE_ERROR; + } + } + return SQLITE_OK; +} + + + /* ** Locate and return an entry from the db.aCollSeq hash table. If the entry ** specified by zName and nName is not found and parameter 'create' is diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 384a65691f..21904557e6 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.383 2005/05/24 20:19:59 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.384 2005/05/25 10:45:10 danielk1977 Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -1561,6 +1561,7 @@ void sqlite3ColumnDefault(Vdbe *, Table *, int); void sqlite3AlterFinishAddColumn(Parse *, Token *); void sqlite3AlterBeginAddColumn(Parse *, SrcList *); const char *sqlite3TestErrorName(int); +CollSeq *sqlite3GetCollSeq(sqlite3*, CollSeq *, const char *, int); #ifdef SQLITE_SSE #include "sseInt.h"