Change the collation sequence interface to allow collation sequences that
use UTF-16 in non-native byte order to be registered. (CVS 1559) FossilOrigin-Name: b8aaa3a29e0ddef357ab1b3b0b9f87ed390f2f36
This commit is contained in:
parent
35d4c2f4b8
commit
466be56bcf
26
manifest
26
manifest
@ -1,5 +1,5 @@
|
||||
C Add\sthe\svdbe_listing\sand\ssql_trace\spragmas\sused\sfor\sdebugging.\s(CVS\s1558)
|
||||
D 2004-06-10T01:30:59
|
||||
C Change\sthe\scollation\ssequence\sinterface\sto\sallow\scollation\ssequences\sthat\nuse\sUTF-16\sin\snon-native\sbyte\sorder\sto\sbe\sregistered.\s(CVS\s1559)
|
||||
D 2004-06-10T02:16:02
|
||||
F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
|
||||
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
|
||||
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
||||
@ -27,7 +27,7 @@ F src/attach.c 93b8ecec4a8d7b4e9f2479e2327d90c9d01765e8
|
||||
F src/auth.c 5c2f0bea4729c98c2be3b69d6b466fc51448fe79
|
||||
F src/btree.c 281af87aa117de024f5b6c2728a2339cba9ef584
|
||||
F src/btree.h 589427ac13bb544d298cd99726e2572a6fe4bdaa
|
||||
F src/build.c 9ee417777c8d1be293773482c28adbf5cd59981b
|
||||
F src/build.c 5d958f480d71f56981f262de6994a4d2ee6e5f75
|
||||
F src/date.c 8e6fa3173386fb29fdef012ee08a853c1e9908b2
|
||||
F src/delete.c b30f08250c9ed53a25a13c7c04599c1e8753992d
|
||||
F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37
|
||||
@ -37,7 +37,7 @@ F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f
|
||||
F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb
|
||||
F src/insert.c 4268d9e3959cc845ea243fb4ec7507269404dad9
|
||||
F src/legacy.c ad23746f15f67e34577621b1875f639c94839e1f
|
||||
F src/main.c 6f1c01a587f1037f47bd8926dfa3246c0d04d196
|
||||
F src/main.c cb41777e75f6b95a2af42f439c78e761a49cdffa
|
||||
F src/md5.c 4302e84ae516c616bb079c4e6d038c0addb33481
|
||||
F src/os.h 23c69c5084e71b5fe199ff1c4e35a4aded0f1380
|
||||
F src/os_common.h 6393ac67a3a7b4aea19ff17529980ecf77eb2348
|
||||
@ -47,7 +47,7 @@ F src/os_unix.c 1d6f3d1a87d4aa0e4490bcc47b3f0ff9b2e37e7a
|
||||
F src/os_unix.h 1cd6133cf66dea704b8646b70b2dfdcbdd9b3738
|
||||
F src/os_win.c 6b8f9fcc683bb888e07fc485372803baa68faadb
|
||||
F src/os_win.h 004eec47b1780fcaf07420ddc2072294b698d48c
|
||||
F src/pager.c 70a372bd83fcd79846a49f3d9266d2773442cc82
|
||||
F src/pager.c 88a7160c749435c03a4154996cd851196c0a87c2
|
||||
F src/pager.h ca8f293e1d623a7c628a1c5e0c6cf43d5bbb80bf
|
||||
F src/parse.y 097438674976355a10cf177bd97326c548820b86
|
||||
F src/pragma.c 6ab13748a415bf8e8f2dd79e5f713fbe72dfd3f4
|
||||
@ -55,10 +55,10 @@ F src/printf.c 63b15f1ea9fe3daa066bb7430fd20d4a2d717dc8
|
||||
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
|
||||
F src/select.c 1f8355e702f109f6771f82a9bfe7aac4c82cbaf2
|
||||
F src/shell.c ca519519dcbbc582f6d88f7d0e7583b857fd3469
|
||||
F src/sqlite.h.in 6ad05abc7fd72da74691e1eb45f0eff4117eba4e
|
||||
F src/sqliteInt.h 88bcc2967b7c62f9a74d866e504847bba01a27e7
|
||||
F src/sqlite.h.in 00ce6b80cf4dffa9bf7a028d80d1ffba708b175a
|
||||
F src/sqliteInt.h cd9db5ca4a2ba59cf1692fcbd1ea7318c50f0c4f
|
||||
F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2
|
||||
F src/tclsqlite.c f5c5116720baefb7de5d6acf18baedf1e42756cc
|
||||
F src/tclsqlite.c 6383ba7b620b276d49b40d48872502e0adb1b685
|
||||
F src/test1.c f78d6ac0675bc5db48dac9c5379c965bdadb9113
|
||||
F src/test2.c 05f810c90cf6262d5f352860e87d41a3f34207f9
|
||||
F src/test3.c beafd0ccf7b9ae784744be1b1e66ffe8f64c25da
|
||||
@ -75,7 +75,7 @@ F src/vdbe.h 46f74444a213129bc4b5ce40124dd8ed613b0cde
|
||||
F src/vdbeInt.h d41605853332bdbd600d7ecd60e1f54bbaea174e
|
||||
F src/vdbeapi.c 4ac95766b0515538037a7aec172ed26142f97cf9
|
||||
F src/vdbeaux.c 6f5b26a6b4d9c9f0f99a9f75dce9460e5a90542e
|
||||
F src/vdbemem.c 04502b81039f9a2b1c9a096e894eecf6d4877508
|
||||
F src/vdbemem.c 5b2fab8b5a830e5204413b808c4a2d8335189f21
|
||||
F src/where.c 32578882a245f8ac3303c5cea4664cd51fc73891
|
||||
F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
|
||||
F test/attach.test aed659e52635662bcd5069599aaca823533edf5a
|
||||
@ -218,7 +218,7 @@ F www/support.tcl 1801397edd271cc39a2aadd54e701184b5181248
|
||||
F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075
|
||||
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
|
||||
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
|
||||
P a60afd04c5296020e5e72c4d35063fd1e6f90e9e
|
||||
R ef21e9b582fc0857d2dbfc2cd3336d42
|
||||
U drh
|
||||
Z feb0030425bea46368b7928207633687
|
||||
P 28c3cc088018833f507535b8d227232776cff204
|
||||
R f9fbe975e7140b57b35e8b9f5b97fbe5
|
||||
U danielk1977
|
||||
Z 419742ffbc029c96384373534fdaa6dc
|
||||
|
@ -1 +1 @@
|
||||
28c3cc088018833f507535b8d227232776cff204
|
||||
b8aaa3a29e0ddef357ab1b3b0b9f87ed390f2f36
|
139
src/build.c
139
src/build.c
@ -23,7 +23,7 @@
|
||||
** ROLLBACK
|
||||
** PRAGMA
|
||||
**
|
||||
** $Id: build.c,v 1.213 2004/06/10 00:29:09 drh Exp $
|
||||
** $Id: build.c,v 1.214 2004/06/10 02:16:02 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@ -855,46 +855,147 @@ void sqlite3AddCollateType(Parse *pParse, const char *zType, int nType){
|
||||
/*
|
||||
** 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
|
||||
** true, then create a new entry.
|
||||
** true, then create a new entry. Otherwise return NULL.
|
||||
**
|
||||
** FIX ME: For now, return NULL if create is not true and the entry is not
|
||||
** found. But this needs to change to call the collation factory.
|
||||
** Each pointer stored in the sqlite3.aCollSeq hash table contains an
|
||||
** array of three CollSeq structures. The first is the collation sequence
|
||||
** prefferred for UTF-8, the second UTF-16le, and the third UTF-16be.
|
||||
**
|
||||
** FIX ME: If we have a UTF-8 version of the collation function, and a
|
||||
** UTF-16 version would be better, should the collation factory be called?
|
||||
** If so should a flag be set to say that we already requested such a
|
||||
** function and couldn't get one?
|
||||
** Stored immediately after the three collation sequences is a copy of
|
||||
** the collation sequence name. A pointer to this string is stored in
|
||||
** each collation sequence structure.
|
||||
*/
|
||||
CollSeq *sqlite3FindCollSeq(
|
||||
sqlite *db,
|
||||
const char *zName,
|
||||
static CollSeq * findCollSeqEntry(
|
||||
sqlite *db,
|
||||
const char *zName,
|
||||
int nName,
|
||||
int create
|
||||
){
|
||||
CollSeq *pColl;
|
||||
if( nName<0 ) nName = strlen(zName);
|
||||
pColl = sqlite3HashFind(&db->aCollSeq, zName, nName);
|
||||
|
||||
if( 0==pColl && create ){
|
||||
pColl = sqliteMalloc( sizeof(*pColl) + nName + 1 );
|
||||
pColl = sqliteMalloc( 3*sizeof(*pColl) + nName + 1 );
|
||||
if( pColl ){
|
||||
pColl->zName = (char*)&pColl[1];
|
||||
memcpy(pColl->zName, zName, nName+1);
|
||||
sqlite3HashInsert(&db->aCollSeq, pColl->zName, nName, pColl);
|
||||
pColl[0].zName = (char*)&pColl[3];
|
||||
pColl[0].enc = TEXT_Utf8;
|
||||
pColl[1].zName = (char*)&pColl[3];
|
||||
pColl[1].enc = TEXT_Utf16le;
|
||||
pColl[2].zName = (char*)&pColl[3];
|
||||
pColl[2].enc = TEXT_Utf16be;
|
||||
memcpy(pColl[0].zName, zName, nName+1);
|
||||
sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl);
|
||||
}
|
||||
}
|
||||
return pColl;
|
||||
}
|
||||
|
||||
/*
|
||||
** 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(
|
||||
sqlite *db,
|
||||
u8 enc,
|
||||
const char *zName,
|
||||
int nName,
|
||||
int create
|
||||
){
|
||||
CollSeq *pColl = findCollSeqEntry(db, zName, nName, create);
|
||||
if( pColl ) switch( enc ){
|
||||
case TEXT_Utf8:
|
||||
break;
|
||||
case TEXT_Utf16le:
|
||||
pColl = &pColl[2];
|
||||
break;
|
||||
case TEXT_Utf16be:
|
||||
pColl = &pColl[1];
|
||||
break;
|
||||
default:
|
||||
assert(!"Cannot happen");
|
||||
}
|
||||
return pColl;
|
||||
}
|
||||
|
||||
/*
|
||||
** This function returns the collation sequence for database native text
|
||||
** encoding identified by the string zName, length nName.
|
||||
**
|
||||
** If the requested collation sequence is not available, or not available
|
||||
** in the database native encoding, the collation factory is invoked to
|
||||
** 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){
|
||||
CollSeq *pColl = sqlite3FindCollSeq(pParse->db, zName, nName, 0);
|
||||
if( !pColl ){
|
||||
u8 enc = pParse->db->enc;
|
||||
CollSeq *pColl = sqlite3FindCollSeq(pParse->db, enc, zName, nName, 0);
|
||||
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.
|
||||
*/
|
||||
|
||||
/* FIX ME: Actually call collation factory, then call
|
||||
** sqlite3FindCollSeq() again. */
|
||||
pColl = sqlite3FindCollSeq(pParse->db, enc, zName, nName, 0);
|
||||
|
||||
if( pColl && !pColl->xCmp ){
|
||||
/* The collation factory failed to deliver a function but there are
|
||||
** other versions of this collation function (for other text
|
||||
** encodings) available. Use one of these instead. Avoid a
|
||||
** UTF-8 <-> UTF-16 conversion if possible.
|
||||
*/
|
||||
CollSeq *pColl2 = 0;
|
||||
switch( enc ){
|
||||
case TEXT_Utf16le:
|
||||
pColl2 = sqlite3FindCollSeq(pParse->db,TEXT_Utf16be,zName,nName,0);
|
||||
assert( pColl2 );
|
||||
if( pColl2->xCmp ) break;
|
||||
pColl2 = sqlite3FindCollSeq(pParse->db,TEXT_Utf8,zName,nName,0);
|
||||
assert( pColl2 );
|
||||
break;
|
||||
|
||||
case TEXT_Utf16be:
|
||||
pColl2 = sqlite3FindCollSeq(pParse->db,TEXT_Utf16le,zName,nName,0);
|
||||
assert( pColl2 );
|
||||
if( pColl2->xCmp ) break;
|
||||
pColl2 = sqlite3FindCollSeq(pParse->db,TEXT_Utf8,zName,nName,0);
|
||||
assert( pColl2 );
|
||||
break;
|
||||
|
||||
case TEXT_Utf8:
|
||||
pColl2 = sqlite3FindCollSeq(pParse->db,TEXT_Utf16be,zName,nName,0);
|
||||
assert( pColl2 );
|
||||
if( pColl2->xCmp ) break;
|
||||
pColl2 = sqlite3FindCollSeq(pParse->db,TEXT_Utf16le,zName,nName,0);
|
||||
assert( pColl2 );
|
||||
break;
|
||||
}
|
||||
|
||||
if( pColl2->xCmp ){
|
||||
memcpy(pColl, pColl2, sizeof(CollSeq));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If nothing has been found, write the error message into pParse */
|
||||
if( !pColl || !pColl->xCmp ){
|
||||
if( pParse->nErr==0 ){
|
||||
sqlite3SetNString(&pParse->zErrMsg,
|
||||
"no such collation sequence: ", -1,
|
||||
sqlite3SetNString(&pParse->zErrMsg, "no such collation sequence: ", -1,
|
||||
zName, nName, 0);
|
||||
}
|
||||
pParse->nErr++;
|
||||
}
|
||||
|
||||
return pColl;
|
||||
}
|
||||
|
||||
|
38
src/main.c
38
src/main.c
@ -14,7 +14,7 @@
|
||||
** other files are for internal use by SQLite and should not be
|
||||
** accessed by users of the library.
|
||||
**
|
||||
** $Id: main.c,v 1.212 2004/06/10 01:30:59 drh Exp $
|
||||
** $Id: main.c,v 1.213 2004/06/10 02:16:02 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
@ -257,6 +257,7 @@ static int sqlite3InitOne(sqlite *db, int iDb, char **pzErrMsg){
|
||||
if( iDb==0 ){
|
||||
/* If opening the main database, set db->enc. */
|
||||
db->enc = (u8)meta[4];
|
||||
db->pDfltColl = sqlite3FindCollSeq(db, db->enc, "BINARY", 6, 0);
|
||||
}else{
|
||||
/* If opening an attached database, the encoding much match db->enc */
|
||||
if( meta[4]!=db->enc ){
|
||||
@ -488,6 +489,12 @@ void sqlite3_close(sqlite *db){
|
||||
sqliteFree(pFunc);
|
||||
}
|
||||
}
|
||||
|
||||
for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){
|
||||
CollSeq *pColl = (CollSeq *)sqliteHashData(i);
|
||||
/* sqliteFree(pColl); */
|
||||
}
|
||||
|
||||
sqlite3HashClear(&db->aFunc);
|
||||
sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */
|
||||
sqliteFree(db);
|
||||
@ -1058,9 +1065,10 @@ static int openDatabase(
|
||||
** and UTF-16, so add a version for each to avoid any unnecessary
|
||||
** conversions. The only error that can occur here is a malloc() failure.
|
||||
*/
|
||||
sqlite3_create_collation(db, "BINARY", 0, 0, binaryCollatingFunc);
|
||||
sqlite3_create_collation(db, "BINARY", 1, 0, binaryCollatingFunc);
|
||||
db->pDfltColl = sqlite3FindCollSeq(db, "BINARY", 6, 0);
|
||||
sqlite3_create_collation(db, "BINARY", SQLITE_UTF8, 0,binaryCollatingFunc);
|
||||
sqlite3_create_collation(db, "BINARY", SQLITE_UTF16LE, 0,binaryCollatingFunc);
|
||||
sqlite3_create_collation(db, "BINARY", SQLITE_UTF16BE, 0,binaryCollatingFunc);
|
||||
db->pDfltColl = sqlite3FindCollSeq(db, db->enc, "BINARY", 6, 0);
|
||||
if( !db->pDfltColl ){
|
||||
rc = db->errCode;
|
||||
assert( rc!=SQLITE_OK );
|
||||
@ -1069,7 +1077,7 @@ static int openDatabase(
|
||||
}
|
||||
|
||||
/* Also add a UTF-8 case-insensitive collation sequence. */
|
||||
sqlite3_create_collation(db, "NOCASE", 0, 0, nocaseCollatingFunc);
|
||||
sqlite3_create_collation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc);
|
||||
|
||||
/* Open the backend database driver */
|
||||
if( zFilename[0]==':' && strcmp(zFilename,":memory:")==0 ){
|
||||
@ -1172,36 +1180,40 @@ int sqlite3_reset(sqlite3_stmt *pStmt){
|
||||
int sqlite3_create_collation(
|
||||
sqlite3* db,
|
||||
const char *zName,
|
||||
int pref16,
|
||||
int enc,
|
||||
void* pCtx,
|
||||
int(*xCompare)(void*,int,const void*,int,const void*)
|
||||
){
|
||||
CollSeq *pColl;
|
||||
int rc = SQLITE_OK;
|
||||
pColl = sqlite3FindCollSeq(db, zName, strlen(zName), 1);
|
||||
if( enc!=SQLITE_UTF8 && enc!=SQLITE_UTF16LE && enc!=SQLITE_UTF16BE ){
|
||||
sqlite3Error(db, SQLITE_ERROR,
|
||||
"Param 3 to sqlite3_create_collation() must be one of "
|
||||
"SQLITE_UTF8, SQLITE_UTF16LE or SQLITE_UTF16BE"
|
||||
);
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
pColl = sqlite3FindCollSeq(db, (u8)enc, zName, strlen(zName), 1);
|
||||
if( 0==pColl ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else if( pref16 ){
|
||||
pColl->xCmp16 = xCompare;
|
||||
pColl->pUser16 = pCtx;
|
||||
}else{
|
||||
pColl->xCmp = xCompare;
|
||||
pColl->pUser = pCtx;
|
||||
}
|
||||
sqlite3Error(db, rc, 0);
|
||||
return SQLITE_OK;
|
||||
return rc;
|
||||
}
|
||||
|
||||
int sqlite3_create_collation16(
|
||||
sqlite3* db,
|
||||
const char *zName,
|
||||
int pref16,
|
||||
int enc,
|
||||
void* pCtx,
|
||||
int(*xCompare)(void*,int,const void*,int,const void*)
|
||||
){
|
||||
int rc;
|
||||
char *zName8 = sqlite3utf16to8(zName, -1, SQLITE_BIGENDIAN);
|
||||
rc = sqlite3_create_collation(db, zName8, pref16, pCtx, xCompare);
|
||||
rc = sqlite3_create_collation(db, zName8, enc, pCtx, xCompare);
|
||||
sqliteFree(zName8);
|
||||
return rc;
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
** file simultaneously, or one process from reading the database while
|
||||
** another is writing.
|
||||
**
|
||||
** @(#) $Id: pager.c,v 1.119 2004/06/10 01:30:59 drh Exp $
|
||||
** @(#) $Id: pager.c,v 1.120 2004/06/10 02:16:02 danielk1977 Exp $
|
||||
*/
|
||||
#include "os.h" /* Must be first to enable large file support */
|
||||
#include "sqliteInt.h"
|
||||
@ -29,7 +29,7 @@
|
||||
/*
|
||||
** Macros for troubleshooting. Normally turned off
|
||||
*/
|
||||
#if 1
|
||||
#if 0
|
||||
static Pager *mainPager = 0;
|
||||
#define SET_PAGER(X) if( mainPager==0 ) mainPager = (X)
|
||||
#define CLR_PAGER(X) if( mainPager==(X) ) mainPager = 0
|
||||
|
@ -12,7 +12,7 @@
|
||||
** This header file defines the interface that the SQLite library
|
||||
** presents to client programs.
|
||||
**
|
||||
** @(#) $Id: sqlite.h.in,v 1.95 2004/06/09 09:55:18 danielk1977 Exp $
|
||||
** @(#) $Id: sqlite.h.in,v 1.96 2004/06/10 02:16:02 danielk1977 Exp $
|
||||
*/
|
||||
#ifndef _SQLITE_H_
|
||||
#define _SQLITE_H_
|
||||
@ -963,17 +963,21 @@ void sqlite3_result_text(sqlite3_context*, const char*, int n, int eCopy);
|
||||
void sqlite3_result_text16(sqlite3_context*, const void*, int n, int eCopy);
|
||||
void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
|
||||
|
||||
#define SQLITE_UTF8 1
|
||||
#define SQLITE_UTF16LE 2
|
||||
#define SQLITE_UTF16BE 3
|
||||
|
||||
int sqlite3_create_collation(
|
||||
sqlite3*,
|
||||
const char *zName,
|
||||
int pref16,
|
||||
int enc,
|
||||
void*,
|
||||
int(*xCompare)(void*,int,const void*,int,const void*)
|
||||
);
|
||||
int sqlite3_create_collation16(
|
||||
sqlite3*,
|
||||
const char *zName,
|
||||
int pref16,
|
||||
int enc,
|
||||
void*,
|
||||
int(*xCompare)(void*,int,const void*,int,const void*)
|
||||
);
|
||||
|
@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** Internal interface definitions for SQLite.
|
||||
**
|
||||
** @(#) $Id: sqliteInt.h,v 1.278 2004/06/10 01:30:59 drh Exp $
|
||||
** @(#) $Id: sqliteInt.h,v 1.279 2004/06/10 02:16:02 danielk1977 Exp $
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "sqlite3.h"
|
||||
@ -512,10 +512,9 @@ struct Column {
|
||||
*/
|
||||
struct CollSeq {
|
||||
char *zName; /* Name of the collating sequence, UTF-8 encoded */
|
||||
u8 enc; /* Text encoding handled by xCmp() */
|
||||
void *pUser; /* First argument to xCmp() */
|
||||
void *pUser16; /* First argument to xCmp16() */
|
||||
int (*xCmp)(void*,int, const void*, int, const void*);
|
||||
int (*xCmp16)(void*,int, const void*, int, const void*);
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1394,6 +1393,6 @@ int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
|
||||
const char *sqlite3ErrStr(int);
|
||||
int sqlite3ReadUniChar(const char *zStr, int *pOffset, u8 *pEnc, int fold);
|
||||
int sqlite3ReadSchema(sqlite *db, char **);
|
||||
CollSeq *sqlite3FindCollSeq(sqlite *,const char *,int,int);
|
||||
CollSeq *sqlite3FindCollSeq(sqlite *,u8 enc, const char *,int,int);
|
||||
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName);
|
||||
CollSeq *sqlite3ExprCollSeq(Expr *pExpr);
|
||||
|
@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** A TCL Interface to SQLite
|
||||
**
|
||||
** $Id: tclsqlite.c,v 1.81 2004/06/09 09:55:19 danielk1977 Exp $
|
||||
** $Id: tclsqlite.c,v 1.82 2004/06/10 02:16:02 danielk1977 Exp $
|
||||
*/
|
||||
#ifndef NO_TCL /* Omit this whole file if TCL is unavailable */
|
||||
|
||||
@ -917,7 +917,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
pCollate->pNext = pDb->pCollate;
|
||||
pCollate->zScript = (char*)&pCollate[1];
|
||||
strcpy(pCollate->zScript, zScript);
|
||||
if( sqlite3_create_collation(pDb->db, zName, 0, pCollate, tclSqlCollate) ){
|
||||
if( sqlite3_create_collation(pDb->db, zName, SQLITE_UTF8,
|
||||
pCollate, tclSqlCollate) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
break;
|
||||
|
@ -438,25 +438,35 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
|
||||
** table incorrectly. We need to return an error to the user in this
|
||||
** case.
|
||||
*/
|
||||
assert( !pColl || (pColl->xCmp || pColl->xCmp16) );
|
||||
assert( !pColl || pColl->xCmp );
|
||||
|
||||
if( pColl ){
|
||||
if( (pMem1->enc==TEXT_Utf8 && pColl->xCmp) || !pColl->xCmp16 ){
|
||||
return pColl->xCmp(
|
||||
pColl->pUser,
|
||||
sqlite3_value_bytes((sqlite3_value *)pMem1),
|
||||
sqlite3_value_text((sqlite3_value *)pMem1),
|
||||
sqlite3_value_bytes((sqlite3_value *)pMem2),
|
||||
sqlite3_value_text((sqlite3_value *)pMem2)
|
||||
);
|
||||
if( pMem1->enc==pColl->enc ){
|
||||
return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z);
|
||||
}else{
|
||||
return pColl->xCmp16(
|
||||
pColl->pUser,
|
||||
sqlite3_value_bytes16((sqlite3_value *)pMem1),
|
||||
sqlite3_value_text16((sqlite3_value *)pMem1),
|
||||
sqlite3_value_bytes16((sqlite3_value *)pMem2),
|
||||
sqlite3_value_text16((sqlite3_value *)pMem2)
|
||||
);
|
||||
switch( pColl->enc ){
|
||||
case SQLITE_UTF8:
|
||||
return pColl->xCmp(
|
||||
pColl->pUser,
|
||||
sqlite3_value_bytes((sqlite3_value *)pMem1),
|
||||
sqlite3_value_text((sqlite3_value *)pMem1),
|
||||
sqlite3_value_bytes((sqlite3_value *)pMem2),
|
||||
sqlite3_value_text((sqlite3_value *)pMem2)
|
||||
);
|
||||
case SQLITE_UTF16LE:
|
||||
case SQLITE_UTF16BE:
|
||||
/* FIX ME: Handle non-native UTF-16 properly instead of
|
||||
** assuming it is always native. */
|
||||
return pColl->xCmp(
|
||||
pColl->pUser,
|
||||
sqlite3_value_bytes16((sqlite3_value *)pMem1),
|
||||
sqlite3_value_text16((sqlite3_value *)pMem1),
|
||||
sqlite3_value_bytes16((sqlite3_value *)pMem2),
|
||||
sqlite3_value_text16((sqlite3_value *)pMem2)
|
||||
);
|
||||
default:
|
||||
assert(!"Cannot happen");
|
||||
}
|
||||
}
|
||||
}
|
||||
/* If a NULL pointer was passed as the collate function, fall through
|
||||
|
Loading…
x
Reference in New Issue
Block a user