mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-05 15:55:57 +03:00
Handle malloc() failures that occur inside create_collation() calls. (CVS 2966)
FossilOrigin-Name: 95c5903f368413019af83aa73263e0e9d1204b62
This commit is contained in:
16
manifest
16
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Arrange\sfor\sThreadData\sto\sbe\sautomatically\sdeallocated\seven\sif\sSQLITE_MEMDEBUG\sis\sdefined.\sFix\sfor\s#1623.\s(CVS\s2965)
|
C Handle\smalloc()\sfailures\sthat\soccur\sinside\screate_collation()\scalls.\s(CVS\s2966)
|
||||||
D 2006-01-17T16:10:14
|
D 2006-01-18T04:26:07
|
||||||
F Makefile.in ab3ffd8d469cef4477257169b82810030a6bb967
|
F Makefile.in ab3ffd8d469cef4477257169b82810030a6bb967
|
||||||
F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092
|
F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092
|
||||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||||
@@ -48,7 +48,7 @@ F src/hash.c 8747cf51d12de46512880dfcf1b68b4e24072863
|
|||||||
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
|
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
|
||||||
F src/insert.c a5595cf8d1d8ba087b676a63f1f7277ea44b5ac1
|
F src/insert.c a5595cf8d1d8ba087b676a63f1f7277ea44b5ac1
|
||||||
F src/legacy.c 9bf7ee1b63c99aac6669533986a5240b16101458
|
F src/legacy.c 9bf7ee1b63c99aac6669533986a5240b16101458
|
||||||
F src/main.c e934ce6ce3b7166ad98c2778160f865761196480
|
F src/main.c bab16cf13d9a6388c321f6bc4693d258aea80a2a
|
||||||
F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
|
F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
|
||||||
F src/os.c 1d1a61cdf150e9f9520a3bc787c8465148ea2e78
|
F src/os.c 1d1a61cdf150e9f9520a3bc787c8465148ea2e78
|
||||||
F src/os.h 9debc3d3ca4cdafde222a0ea74a4c8415aef4f22
|
F src/os.h 9debc3d3ca4cdafde222a0ea74a4c8415aef4f22
|
||||||
@@ -73,7 +73,7 @@ F src/sqlite.h.in 492580f7e3ff71eb43193eb7bb98e2d549889ce3
|
|||||||
F src/sqliteInt.h d7b20e0a9453db123809d0bcc46d6ae0e4cf6bca
|
F src/sqliteInt.h d7b20e0a9453db123809d0bcc46d6ae0e4cf6bca
|
||||||
F src/table.c 486dcfce532685b53b5a2b5da8bba0ded6fb2316
|
F src/table.c 486dcfce532685b53b5a2b5da8bba0ded6fb2316
|
||||||
F src/tclsqlite.c d650bea0248fc0a310ddc2cb94273a3a5021fddf
|
F src/tclsqlite.c d650bea0248fc0a310ddc2cb94273a3a5021fddf
|
||||||
F src/test1.c 4dccd51f786f24d8f947f1028d840ab35f46d4de
|
F src/test1.c deb48cd5ab369a2ffccb62b017d248188a3be201
|
||||||
F src/test2.c ca74a1d8aeb7d9606e8f6b762c5daf85c1a3f92b
|
F src/test2.c ca74a1d8aeb7d9606e8f6b762c5daf85c1a3f92b
|
||||||
F src/test3.c 9742aa146eb750cab81c1d5605286c3a0eb88054
|
F src/test3.c 9742aa146eb750cab81c1d5605286c3a0eb88054
|
||||||
F src/test4.c 6633cb7b4a7429e938804a34f688d118c8b7f8e1
|
F src/test4.c 6633cb7b4a7429e938804a34f688d118c8b7f8e1
|
||||||
@@ -186,7 +186,7 @@ F test/lock.test 9b7afcb24f53d24da502abb33daaad2cd6d44107
|
|||||||
F test/lock2.test d83ba79d3c4fffdb5b926c7d8ca7a36c34288a55
|
F test/lock2.test d83ba79d3c4fffdb5b926c7d8ca7a36c34288a55
|
||||||
F test/lock3.test 615111293cf32aa2ed16d01c6611737651c96fb9
|
F test/lock3.test 615111293cf32aa2ed16d01c6611737651c96fb9
|
||||||
F test/main.test b12f01d49a5c805a33fa6c0ef168691f63056e79
|
F test/main.test b12f01d49a5c805a33fa6c0ef168691f63056e79
|
||||||
F test/malloc.test 34c2c0ce7f45bc5fe2f7f3c0b911e505af66e27f
|
F test/malloc.test 095d23a3840549cfc4282f95d9dc531152473c05
|
||||||
F test/malloc2.test e6e321db96d6c94cb18bf82ad7215070c41e624e
|
F test/malloc2.test e6e321db96d6c94cb18bf82ad7215070c41e624e
|
||||||
F test/malloc3.test 265644c655497242f7c0a1bb5b36c8500a5fc27c
|
F test/malloc3.test 265644c655497242f7c0a1bb5b36c8500a5fc27c
|
||||||
F test/malloc4.test 2e29d155eb4b4808019ef47eeedfcbe9e09e0f05
|
F test/malloc4.test 2e29d155eb4b4808019ef47eeedfcbe9e09e0f05
|
||||||
@@ -341,7 +341,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
|
|||||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||||
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
|
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
|
||||||
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
||||||
P 62dd2427784721436737a6e8e11fc05e10f0c44d
|
P 9e2e40845d30cc150abe23ee318a721b4fe9613c
|
||||||
R 394c8b76a3f1fd5dd680d2c15b203185
|
R 07ad42513a6cd0f560889373df73f012
|
||||||
U danielk1977
|
U danielk1977
|
||||||
Z 4cce626803e4e936d7ee616c54ded64d
|
Z 7bf4533c1b6879283691c3482fcc8f38
|
||||||
|
@@ -1 +1 @@
|
|||||||
9e2e40845d30cc150abe23ee318a721b4fe9613c
|
95c5903f368413019af83aa73263e0e9d1204b62
|
131
src/main.c
131
src/main.c
@@ -14,7 +14,7 @@
|
|||||||
** other files are for internal use by SQLite and should not be
|
** other files are for internal use by SQLite and should not be
|
||||||
** accessed by users of the library.
|
** accessed by users of the library.
|
||||||
**
|
**
|
||||||
** $Id: main.c,v 1.324 2006/01/17 13:21:40 danielk1977 Exp $
|
** $Id: main.c,v 1.325 2006/01/18 04:26:07 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@@ -745,6 +745,60 @@ int sqlite3_errcode(sqlite3 *db){
|
|||||||
return db->errCode;
|
return db->errCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int createCollation(
|
||||||
|
sqlite3* db,
|
||||||
|
const char *zName,
|
||||||
|
int enc,
|
||||||
|
void* pCtx,
|
||||||
|
int(*xCompare)(void*,int,const void*,int,const void*)
|
||||||
|
){
|
||||||
|
CollSeq *pColl;
|
||||||
|
|
||||||
|
if( sqlite3SafetyCheck(db) ){
|
||||||
|
return SQLITE_MISUSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If SQLITE_UTF16 is specified as the encoding type, transform this
|
||||||
|
** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the
|
||||||
|
** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally.
|
||||||
|
*/
|
||||||
|
if( enc==SQLITE_UTF16 ){
|
||||||
|
enc = SQLITE_UTF16NATIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
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_UTF16, SQLITE_UTF16LE or SQLITE_UTF16BE"
|
||||||
|
);
|
||||||
|
return SQLITE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if this call is removing or replacing an existing collation
|
||||||
|
** sequence. If so, and there are active VMs, return busy. If there
|
||||||
|
** are no active VMs, invalidate any pre-compiled statements.
|
||||||
|
*/
|
||||||
|
pColl = sqlite3FindCollSeq(db, (u8)enc, zName, strlen(zName), 0);
|
||||||
|
if( pColl && pColl->xCmp ){
|
||||||
|
if( db->activeVdbeCnt ){
|
||||||
|
sqlite3Error(db, SQLITE_BUSY,
|
||||||
|
"Unable to delete/modify collation sequence due to active statements");
|
||||||
|
return SQLITE_BUSY;
|
||||||
|
}
|
||||||
|
sqlite3ExpirePreparedStatements(db);
|
||||||
|
}
|
||||||
|
|
||||||
|
pColl = sqlite3FindCollSeq(db, (u8)enc, zName, strlen(zName), 1);
|
||||||
|
if( pColl ){
|
||||||
|
pColl->xCmp = xCompare;
|
||||||
|
pColl->pUser = pCtx;
|
||||||
|
pColl->enc = enc;
|
||||||
|
}
|
||||||
|
sqlite3Error(db, SQLITE_OK, 0);
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This routine does the work of opening a database on behalf of
|
** This routine does the work of opening a database on behalf of
|
||||||
** sqlite3_open() and sqlite3_open16(). The database filename "zFilename"
|
** sqlite3_open() and sqlite3_open16(). The database filename "zFilename"
|
||||||
@@ -776,8 +830,8 @@ static int openDatabase(
|
|||||||
** and UTF-16, so add a version for each to avoid any unnecessary
|
** 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.
|
** conversions. The only error that can occur here is a malloc() failure.
|
||||||
*/
|
*/
|
||||||
if( sqlite3_create_collation(db, "BINARY", SQLITE_UTF8, 0,binCollFunc) ||
|
if( createCollation(db, "BINARY", SQLITE_UTF8, 0,binCollFunc) ||
|
||||||
sqlite3_create_collation(db, "BINARY", SQLITE_UTF16, 0,binCollFunc) ||
|
createCollation(db, "BINARY", SQLITE_UTF16, 0,binCollFunc) ||
|
||||||
(db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 6, 0))==0
|
(db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 6, 0))==0
|
||||||
){
|
){
|
||||||
/* sqlite3_create_collation() is an external API. So the mallocFailed flag
|
/* sqlite3_create_collation() is an external API. So the mallocFailed flag
|
||||||
@@ -789,7 +843,7 @@ static int openDatabase(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Also add a UTF-8 case-insensitive collation sequence. */
|
/* Also add a UTF-8 case-insensitive collation sequence. */
|
||||||
sqlite3_create_collation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc);
|
createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc);
|
||||||
|
|
||||||
/* Set flags on the built-in collating sequences */
|
/* Set flags on the built-in collating sequences */
|
||||||
db->pDfltColl->type = SQLITE_COLL_BINARY;
|
db->pDfltColl->type = SQLITE_COLL_BINARY;
|
||||||
@@ -935,52 +989,14 @@ int sqlite3_create_collation(
|
|||||||
void* pCtx,
|
void* pCtx,
|
||||||
int(*xCompare)(void*,int,const void*,int,const void*)
|
int(*xCompare)(void*,int,const void*,int,const void*)
|
||||||
){
|
){
|
||||||
CollSeq *pColl;
|
int rc;
|
||||||
int rc = SQLITE_OK;
|
assert( !sqlite3ThreadDataReadOnly()->mallocFailed );
|
||||||
|
rc = createCollation(db, zName, enc, pCtx, xCompare);
|
||||||
if( sqlite3SafetyCheck(db) ){
|
if( sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||||
return SQLITE_MISUSE;
|
sqlite3MallocClearFailed();
|
||||||
}
|
|
||||||
|
|
||||||
/* If SQLITE_UTF16 is specified as the encoding type, transform this
|
|
||||||
** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the
|
|
||||||
** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally.
|
|
||||||
*/
|
|
||||||
if( enc==SQLITE_UTF16 ){
|
|
||||||
enc = SQLITE_UTF16NATIVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
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_UTF16, SQLITE_UTF16LE or SQLITE_UTF16BE"
|
|
||||||
);
|
|
||||||
return SQLITE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if this call is removing or replacing an existing collation
|
|
||||||
** sequence. If so, and there are active VMs, return busy. If there
|
|
||||||
** are no active VMs, invalidate any pre-compiled statements.
|
|
||||||
*/
|
|
||||||
pColl = sqlite3FindCollSeq(db, (u8)enc, zName, strlen(zName), 0);
|
|
||||||
if( pColl && pColl->xCmp ){
|
|
||||||
if( db->activeVdbeCnt ){
|
|
||||||
sqlite3Error(db, SQLITE_BUSY,
|
|
||||||
"Unable to delete/modify collation sequence due to active statements");
|
|
||||||
return SQLITE_BUSY;
|
|
||||||
}
|
|
||||||
sqlite3ExpirePreparedStatements(db);
|
|
||||||
}
|
|
||||||
|
|
||||||
pColl = sqlite3FindCollSeq(db, (u8)enc, zName, strlen(zName), 1);
|
|
||||||
if( 0==pColl ){
|
|
||||||
rc = SQLITE_NOMEM;
|
rc = SQLITE_NOMEM;
|
||||||
}else{
|
sqlite3Error(db, rc, 0);
|
||||||
pColl->xCmp = xCompare;
|
|
||||||
pColl->pUser = pCtx;
|
|
||||||
pColl->enc = enc;
|
|
||||||
}
|
}
|
||||||
sqlite3Error(db, rc, 0);
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -995,14 +1011,19 @@ int sqlite3_create_collation16(
|
|||||||
void* pCtx,
|
void* pCtx,
|
||||||
int(*xCompare)(void*,int,const void*,int,const void*)
|
int(*xCompare)(void*,int,const void*,int,const void*)
|
||||||
){
|
){
|
||||||
char *zName8;
|
int rc = SQLITE_OK;
|
||||||
int rc;
|
char *zName8;
|
||||||
if( sqlite3SafetyCheck(db) ){
|
assert( !sqlite3ThreadDataReadOnly()->mallocFailed );
|
||||||
return SQLITE_MISUSE;
|
|
||||||
}
|
|
||||||
zName8 = sqlite3utf16to8(zName, -1);
|
zName8 = sqlite3utf16to8(zName, -1);
|
||||||
rc = sqlite3_create_collation(db, zName8, enc, pCtx, xCompare);
|
if( zName8 ){
|
||||||
sqliteFree(zName8);
|
rc = createCollation(db, zName8, enc, pCtx, xCompare);
|
||||||
|
sqliteFree(zName8);
|
||||||
|
}
|
||||||
|
if( sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||||
|
sqlite3MallocClearFailed();
|
||||||
|
rc = SQLITE_NOMEM;
|
||||||
|
sqlite3Error(db, rc, 0);
|
||||||
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
#endif /* SQLITE_OMIT_UTF16 */
|
#endif /* SQLITE_OMIT_UTF16 */
|
||||||
|
17
src/test1.c
17
src/test1.c
@@ -13,7 +13,7 @@
|
|||||||
** is not included in the SQLite library. It is used for automated
|
** is not included in the SQLite library. It is used for automated
|
||||||
** testing of the SQLite library.
|
** testing of the SQLite library.
|
||||||
**
|
**
|
||||||
** $Id: test1.c,v 1.193 2006/01/17 13:21:40 danielk1977 Exp $
|
** $Id: test1.c,v 1.194 2006/01/18 04:26:07 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "tcl.h"
|
#include "tcl.h"
|
||||||
@@ -1346,13 +1346,24 @@ static int test_collate(
|
|||||||
(void *)SQLITE_UTF16LE, val?test_collate_func:0);
|
(void *)SQLITE_UTF16LE, val?test_collate_func:0);
|
||||||
if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR;
|
if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR;
|
||||||
|
|
||||||
|
#ifdef SQLITE_MEMDEBUG
|
||||||
|
if( sqlite3_iMallocFail>0 ){
|
||||||
|
sqlite3_iMallocFail++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
pVal = sqlite3ValueNew();
|
pVal = sqlite3ValueNew();
|
||||||
sqlite3ValueSetStr(pVal, -1, "test_collate", SQLITE_UTF8, SQLITE_STATIC);
|
sqlite3ValueSetStr(pVal, -1, "test_collate", SQLITE_UTF8, SQLITE_STATIC);
|
||||||
sqlite3_create_collation16(db, sqlite3ValueText(pVal, SQLITE_UTF16NATIVE),
|
rc = sqlite3_create_collation16(db,
|
||||||
SQLITE_UTF16BE, (void *)SQLITE_UTF16BE, val?test_collate_func:0);
|
sqlite3ValueText(pVal, SQLITE_UTF16NATIVE), SQLITE_UTF16BE,
|
||||||
|
(void *)SQLITE_UTF16BE, val?test_collate_func:0);
|
||||||
sqlite3ValueFree(pVal);
|
sqlite3ValueFree(pVal);
|
||||||
}
|
}
|
||||||
if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
|
if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
|
||||||
|
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
|
|
||||||
bad_args:
|
bad_args:
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
# special feature is used to see what happens in the library if a malloc
|
# special feature is used to see what happens in the library if a malloc
|
||||||
# were to really fail due to an out-of-memory situation.
|
# were to really fail due to an out-of-memory situation.
|
||||||
#
|
#
|
||||||
# $Id: malloc.test,v 1.27 2006/01/17 13:21:40 danielk1977 Exp $
|
# $Id: malloc.test,v 1.28 2006/01/18 04:26:08 danielk1977 Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@@ -97,7 +97,11 @@ proc do_malloc_test {tn args} {
|
|||||||
if {$leftover>0} {
|
if {$leftover>0} {
|
||||||
if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"}
|
if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v Message=$msg"}
|
||||||
set ::go 0
|
set ::go 0
|
||||||
set v {1 1}
|
if {$v} {
|
||||||
|
puts "\nError message returned: $msg"
|
||||||
|
} else {
|
||||||
|
set v {1 1}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
set v2 [expr {$msg=="" || $msg=="out of memory"}]
|
set v2 [expr {$msg=="" || $msg=="out of memory"}]
|
||||||
if {!$v2} {puts "\nError message returned: $msg"}
|
if {!$v2} {puts "\nError message returned: $msg"}
|
||||||
@@ -363,25 +367,44 @@ ifcapable crashtest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if {$tcl_platform(platform)!="windows"} {
|
if {$tcl_platform(platform)!="windows"} {
|
||||||
do_malloc_test 14 -tclprep {
|
do_malloc_test 14 -tclprep {
|
||||||
catch {db close}
|
catch {db close}
|
||||||
sqlite3 db2 test2.db
|
sqlite3 db2 test2.db
|
||||||
db2 eval {
|
db2 eval {
|
||||||
PRAGMA synchronous = 0;
|
PRAGMA synchronous = 0;
|
||||||
CREATE TABLE t1(a, b);
|
CREATE TABLE t1(a, b);
|
||||||
INSERT INTO t1 VALUES(1, 2);
|
INSERT INTO t1 VALUES(1, 2);
|
||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO t1 VALUES(3, 4);
|
INSERT INTO t1 VALUES(3, 4);
|
||||||
|
}
|
||||||
|
copy_file test2.db test.db
|
||||||
|
copy_file test2.db-journal test.db-journal
|
||||||
|
db2 close
|
||||||
|
} -tclbody {
|
||||||
|
sqlite3 db test.db
|
||||||
|
db eval {
|
||||||
|
SELECT * FROM t1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
copy_file test2.db test.db
|
|
||||||
copy_file test2.db-journal test.db-journal
|
|
||||||
db2 close
|
|
||||||
} -tclbody {
|
|
||||||
sqlite3 db test.db
|
|
||||||
db eval {
|
|
||||||
SELECT * FROM t1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proc string_compare {a b} {
|
||||||
|
return [string compare $a $b]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Test for malloc() failures in sqlite3_create_collation() and
|
||||||
|
# sqlite3_create_collation16().
|
||||||
|
do_malloc_test 15 -tclbody {
|
||||||
|
db collate string_compare string_compare
|
||||||
|
if {[catch {add_test_collate $::DB 1 1 1} msg]} {
|
||||||
|
if {$msg=="SQLITE_NOMEM"} {set msg "out of memory"}
|
||||||
|
error $msg
|
||||||
|
}
|
||||||
|
execsql {
|
||||||
|
CREATE TABLE t1(a, b COLLATE string_compare);
|
||||||
|
INSERT INTO t1 VALUES(10, 'string');
|
||||||
|
INSERT INTO t1 VALUES(10, 'string2');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Ensure that no file descriptors were leaked.
|
# Ensure that no file descriptors were leaked.
|
||||||
|
Reference in New Issue
Block a user