Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Change the collation sequence interface to allow collation sequences that use UTF-16 in non-native byte order to be registered. (CVS 1559) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
b8aaa3a29e0ddef357ab1b3b0b9f87ed |
User & Date: | danielk1977 2004-06-10 02:16:02.000 |
Context
2004-06-10
| ||
04:32 | When in PAGER_RESERVED state, don't write to the main file when rolling back a statement transaction. (CVS 1560) (check-in: adb2bd6143 user: danielk1977 tags: trunk) | |
02:16 | Change the collation sequence interface to allow collation sequences that use UTF-16 in non-native byte order to be registered. (CVS 1559) (check-in: b8aaa3a29e user: danielk1977 tags: trunk) | |
01:30 | Add the vdbe_listing and sql_trace pragmas used for debugging. (CVS 1558) (check-in: 28c3cc0880 user: drh tags: trunk) | |
Changes
Changes to src/build.c.
︙ | ︙ | |||
19 20 21 22 23 24 25 | ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** ** $Id: build.c,v 1.214 2004/06/10 02:16:02 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** This routine is called when a new SQL statement is beginning to ** be parsed. Check to see if the schema for the database needs |
︙ | ︙ | |||
851 852 853 854 855 856 857 | if( pIdx->aiColumn[0]==i ) pIdx->keyInfo.aColl[0] = pColl; } } /* ** 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 | | > > | < | | < | | | | > | | > > > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | < > | 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 | if( pIdx->aiColumn[0]==i ) pIdx->keyInfo.aColl[0] = pColl; } } /* ** 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. Otherwise return NULL. ** ** 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. ** ** 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. */ 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( 3*sizeof(*pColl) + nName + 1 ); if( 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){ 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, zName, nName, 0); } pParse->nErr++; } return pColl; } /* ** Scan the column type name zType (length nType) and return the |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** ** $Id: main.c,v 1.213 2004/06/10 02:16:02 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> /* ** A pointer to this structure is used to communicate information |
︙ | ︙ | |||
253 254 255 256 257 258 259 260 261 262 263 264 265 266 | ** For an attached db, it is an error if the encoding is not the same ** as sqlite3.enc. */ if( meta[4] ){ /* text encoding */ if( iDb==0 ){ /* If opening the main database, set db->enc. */ db->enc = (u8)meta[4]; }else{ /* If opening an attached database, the encoding much match db->enc */ if( meta[4]!=db->enc ){ sqlite3BtreeCloseCursor(curMain); sqlite3SetString(pzErrMsg, "attached databases must use the same" " text encoding as main database", (char*)0); return SQLITE_ERROR; | > | 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 | ** For an attached db, it is an error if the encoding is not the same ** as sqlite3.enc. */ if( meta[4] ){ /* text encoding */ 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 ){ sqlite3BtreeCloseCursor(curMain); sqlite3SetString(pzErrMsg, "attached databases must use the same" " text encoding as main database", (char*)0); return SQLITE_ERROR; |
︙ | ︙ | |||
484 485 486 487 488 489 490 491 492 493 494 495 496 497 | for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){ FuncDef *pFunc, *pNext; for(pFunc = (FuncDef*)sqliteHashData(i); pFunc; pFunc=pNext){ pNext = pFunc->pNext; sqliteFree(pFunc); } } sqlite3HashClear(&db->aFunc); sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */ sqliteFree(db); } /* ** Rollback all database files. | > > > > > > | 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 | for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){ FuncDef *pFunc, *pNext; for(pFunc = (FuncDef*)sqliteHashData(i); pFunc; pFunc=pNext){ pNext = pFunc->pNext; 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); } /* ** Rollback all database files. |
︙ | ︙ | |||
1054 1055 1056 1057 1058 1059 1060 | sqlite3HashInit(&db->aDb[i].aFKey, SQLITE_HASH_STRING, 1); } /* Add the default collation sequence BINARY. BINARY works for both UTF-8 ** 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. */ | | | > | | | 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 | sqlite3HashInit(&db->aDb[i].aFKey, SQLITE_HASH_STRING, 1); } /* Add the default collation sequence BINARY. BINARY works for both UTF-8 ** 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", 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 ); db->magic = SQLITE_MAGIC_CLOSED; goto opendb_out; } /* Also add a UTF-8 case-insensitive collation sequence. */ sqlite3_create_collation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc); /* Open the backend database driver */ if( zFilename[0]==':' && strcmp(zFilename,":memory:")==0 ){ db->temp_store = 2; db->nMaster = 0; /* Disable atomic multi-file commit for :memory: */ }else{ db->nMaster = -1; /* Size of master journal filename initially unknown */ |
︙ | ︙ | |||
1168 1169 1170 1171 1172 1173 1174 | sqlite3VdbeMakeReady((Vdbe*)pStmt, -1, 0); return rc; } int sqlite3_create_collation( sqlite3* db, const char *zName, | | > > > > > > > | < < < | | | | 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 | sqlite3VdbeMakeReady((Vdbe*)pStmt, -1, 0); return rc; } int sqlite3_create_collation( sqlite3* db, const char *zName, int enc, void* pCtx, int(*xCompare)(void*,int,const void*,int,const void*) ){ CollSeq *pColl; int rc = SQLITE_OK; 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{ pColl->xCmp = xCompare; pColl->pUser = pCtx; } sqlite3Error(db, rc, 0); return rc; } int sqlite3_create_collation16( sqlite3* db, const char *zName, 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, enc, pCtx, xCompare); sqliteFree(zName8); return rc; } |
Changes to src/pager.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** | | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** ** @(#) $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" #include "pager.h" #include <assert.h> #include <string.h> /* ** Macros for troubleshooting. Normally turned off */ #if 0 static Pager *mainPager = 0; #define SET_PAGER(X) if( mainPager==0 ) mainPager = (X) #define CLR_PAGER(X) if( mainPager==(X) ) mainPager = 0 #define TRACE1(X) if( pPager==mainPager ) sqlite3DebugPrintf(X) #define TRACE2(X,Y) if( pPager==mainPager ) sqlite3DebugPrintf(X,Y) #define TRACE3(X,Y,Z) if( pPager==mainPager ) sqlite3DebugPrintf(X,Y,Z) #else |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the SQLite library ** presents to client programs. ** | | | 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 header file defines the interface that the SQLite library ** presents to client programs. ** ** @(#) $Id: sqlite.h.in,v 1.96 2004/06/10 02:16:02 danielk1977 Exp $ */ #ifndef _SQLITE_H_ #define _SQLITE_H_ #include <stdarg.h> /* Needed for the definition of va_list */ /* ** Make sure we can call this stuff from C++. |
︙ | ︙ | |||
958 959 960 961 962 963 964 965 966 967 968 | void sqlite3_result_error16(sqlite3_context*, const void*, int); void sqlite3_result_int(sqlite3_context*, int); void sqlite3_result_int64(sqlite3_context*, long long int); void sqlite3_result_null(sqlite3_context*); 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*); int sqlite3_create_collation( sqlite3*, const char *zName, | > > > > | | | 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 | void sqlite3_result_error16(sqlite3_context*, const void*, int); void sqlite3_result_int(sqlite3_context*, int); void sqlite3_result_int64(sqlite3_context*, long long int); void sqlite3_result_null(sqlite3_context*); 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 enc, void*, int(*xCompare)(void*,int,const void*,int,const void*) ); int sqlite3_create_collation16( sqlite3*, const char *zName, int enc, void*, int(*xCompare)(void*,int,const void*,int,const void*) ); #ifdef __cplusplus } /* End of the 'extern "C"' block */ #endif #endif |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.279 2004/06/10 02:16:02 danielk1977 Exp $ */ #include "config.h" #include "sqlite3.h" #include "hash.h" #include "parse.h" #include <stdio.h> #include <stdlib.h> |
︙ | ︙ | |||
508 509 510 511 512 513 514 515 | ** ** If both CollSeq.xCmp and CollSeq.xCmp16 are NULL, it means that the ** collating sequence is undefined. Indices built on an undefined ** collating sequence may not be read or written. */ struct CollSeq { char *zName; /* Name of the collating sequence, UTF-8 encoded */ void *pUser; /* First argument to xCmp() */ | > < < | 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 | ** ** If both CollSeq.xCmp and CollSeq.xCmp16 are NULL, it means that the ** collating sequence is undefined. Indices built on an undefined ** collating sequence may not be read or written. */ 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() */ int (*xCmp)(void*,int, const void*, int, const void*); }; /* ** A sort order can be either ASC or DESC. */ #define SQLITE_SO_ASC 0 /* Sort in ascending order */ #define SQLITE_SO_DESC 1 /* Sort in ascending order */ |
︙ | ︙ | |||
1390 1391 1392 1393 1394 1395 1396 | int sqlite3utfTranslate(const void *, int , u8 , void **, int *, u8); u8 sqlite3UtfReadBom(const void *zData, int nData); void *sqlite3HexToBlob(const char *z); 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 **); | | | 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 | int sqlite3utfTranslate(const void *, int , u8 , void **, int *, u8); u8 sqlite3UtfReadBom(const void *zData, int nData); void *sqlite3HexToBlob(const char *z); 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 *,u8 enc, const char *,int,int); CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName); CollSeq *sqlite3ExprCollSeq(Expr *pExpr); |
Changes to src/tclsqlite.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** A TCL Interface to SQLite ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** A TCL Interface to SQLite ** ** $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 */ #include "sqliteInt.h" #include "tcl.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
913 914 915 916 917 918 919 | zScript = Tcl_GetStringFromObj(objv[3], &nScript); pCollate = (SqlCollate*)Tcl_Alloc( sizeof(*pCollate) + nScript + 1 ); if( pCollate==0 ) return TCL_ERROR; pCollate->interp = interp; pCollate->pNext = pDb->pCollate; pCollate->zScript = (char*)&pCollate[1]; strcpy(pCollate->zScript, zScript); | | > | 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 | zScript = Tcl_GetStringFromObj(objv[3], &nScript); pCollate = (SqlCollate*)Tcl_Alloc( sizeof(*pCollate) + nScript + 1 ); if( pCollate==0 ) return TCL_ERROR; pCollate->interp = interp; pCollate->pNext = pDb->pCollate; pCollate->zScript = (char*)&pCollate[1]; strcpy(pCollate->zScript, zScript); if( sqlite3_create_collation(pDb->db, zName, SQLITE_UTF8, pCollate, tclSqlCollate) ){ return TCL_ERROR; } break; } } /* End of the SWITCH statement */ return rc; |
︙ | ︙ |
Changes to src/vdbemem.c.
︙ | ︙ | |||
434 435 436 437 438 439 440 | /* FIX ME: This may fail if the collation sequence is deleted after ** this vdbe program is compiled. We cannot just use BINARY in this ** case as this may lead to a segfault caused by traversing an index ** table incorrectly. We need to return an error to the user in this ** case. */ | | | > > > > | | | | | | | | > > > | | | | | | | > > > | 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 | /* FIX ME: This may fail if the collation sequence is deleted after ** this vdbe program is compiled. We cannot just use BINARY in this ** case as this may lead to a segfault caused by traversing an index ** table incorrectly. We need to return an error to the user in this ** case. */ assert( !pColl || pColl->xCmp ); if( pColl ){ if( pMem1->enc==pColl->enc ){ return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z); }else{ 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 ** to the blob case and use memcmp(). */ } |
︙ | ︙ |