Allow functions to be created when there are outstanding VMs.
(Ticket #926) Fix problems with sqlite3_errcode(). Add tests for sqlite3_errcode(). (CVS 1989) FossilOrigin-Name: d0f1dc5898382258b283308c2cce55a8bc378ee4
This commit is contained in:
parent
44f87bdc56
commit
c60d04464f
28
manifest
28
manifest
@ -1,5 +1,5 @@
|
||||
C Comment\schanges\sin\sbtree.c.\s\sNo\schanges\sto\scode.\s(CVS\s1988)
|
||||
D 2004-09-27T13:19:52
|
||||
C Allow\sfunctions\sto\sbe\screated\swhen\sthere\sare\soutstanding\sVMs.\n(Ticket\s#926)\s\sFix\sproblems\swith\ssqlite3_errcode().\s\sAdd\stests\sfor\nsqlite3_errcode().\s(CVS\s1989)
|
||||
D 2004-09-30T13:43:13
|
||||
F Makefile.in abdeb5bd9d017822691884935c320037c33f6ee6
|
||||
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
|
||||
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
||||
@ -27,7 +27,7 @@ F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2
|
||||
F sqlite3.def dbaeb20c153e1d366e8f421b55a573f5dfc00863
|
||||
F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a
|
||||
F src/attach.c e49d09dad9f5f9fb10b4b0c1be5a70ae4c45e689
|
||||
F src/auth.c 65408baa7e6621520882478dfa1e6b8c1d6c1850
|
||||
F src/auth.c 3b81f2a42f48a62c2c9c9b0eda31a157c681edea
|
||||
F src/btree.c 014d3c9d31136050f3b3294c0c5dc0c7615557bf
|
||||
F src/btree.h 94dfec0a1722d33359b23e7e310f2b64ffedf029
|
||||
F src/build.c 86318bdcd291919d4f87700385fdb73146436531
|
||||
@ -39,7 +39,7 @@ F src/hash.c a97721a55440b7bea31ffe471bb2f6b4123cddd5
|
||||
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
|
||||
F src/insert.c 2c10c001f62cde92e9517ec7516b6584519754d1
|
||||
F src/legacy.c d58ea507bce885298a2c8c3cbb0f4bff5d47830b
|
||||
F src/main.c b86dacaaa09eb614dec7051a8a006434a7bcaa06
|
||||
F src/main.c 2a1b9623fde3fe5e22fe726cdae4e10f33671caa
|
||||
F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
|
||||
F src/os.h d1780e0db95cad01f213d48da22ab490eb4fd345
|
||||
F src/os_common.h cd7eb025fdab7dc91e0e97bf6310f1648205857f
|
||||
@ -61,9 +61,9 @@ F src/select.c 96b1489111abe9b584be2f2cce26ad6f2d425b4e
|
||||
F src/shell.c 0856973c2b94e22664bc43f398ba3fc22d5e080c
|
||||
F src/sqlite.h.in e29a526593b806f148017ed8bada760ada84cf2f
|
||||
F src/sqliteInt.h 1259d965d61209d35e5fb3704ab5167a8a123a72
|
||||
F src/table.c 549f324e3239d3c3658e333e5e422bdcab81b9a0
|
||||
F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9
|
||||
F src/tclsqlite.c 0302e3f42f015d132d1291f3388c06e86c24a008
|
||||
F src/test1.c 1305825c29575ee55a1c8b98a191669fd78b6287
|
||||
F src/test1.c 3d78e5d827bf5d037f697c233c5934d45af46cb5
|
||||
F src/test2.c 0f3e0ad7b675a6f3323211ab4ea95490855654c3
|
||||
F src/test3.c 5b5b0f3d11b097399c1054fff73d8f3711092301
|
||||
F src/test4.c 7c6b9fc33dd1f3f93c7f1ee6e5e6d016afa6c1df
|
||||
@ -72,20 +72,20 @@ F src/tokenize.c d4619367d9ba17c6bd4e018fb7e91015ae8562aa
|
||||
F src/trigger.c d1f770ee37a80391dd6d0948ee821b0272f99ae7
|
||||
F src/update.c 7157084216c4b02a23cdb23eb6d246aa9034fa4d
|
||||
F src/utf.c f4f83acd73389090e32d6589d307fc55d794c7ed
|
||||
F src/util.c 39a6718b221b5c575e09bb9069ec7c7fb539d5a5
|
||||
F src/util.c f4ab796b9def353feed2191d7ce8e39a0f5059cd
|
||||
F src/vacuum.c 257de36230cb988842f66eb08dc6c0250b8e05f3
|
||||
F src/vdbe.c 0542852785220807feb02b9dee1150ac2e592c8d
|
||||
F src/vdbe.h 067ca8d6750ba4f69a50284765e5883dee860181
|
||||
F src/vdbeInt.h 6017100adff362b8dfa37a69e3f1431f084bfa5b
|
||||
F src/vdbeapi.c 81ab9e84c55f5762f552904e6e5d309269b02017
|
||||
F src/vdbeaux.c 598af6c20124a205306475cd9dcee04317d0c622
|
||||
F src/vdbeaux.c a43a2989eeb3a478b31dba2fc28578bbb2d6366e
|
||||
F src/vdbemem.c ef9ac7d32acfe4bce5c5b408b1294c8d9e0cdb56
|
||||
F src/where.c 04d3ee039d8e66c520e3b6bd5103dc3b8c3eb76b
|
||||
F test/all.test 929bfa932b55e75c96fe2203f7650ba451c1862c
|
||||
F test/attach.test feb2ce54e78688df4c84553416d5aec3b2a0112e
|
||||
F test/attach2.test 32ca2c1a5a347a7404219a11f9f84739a63d2582
|
||||
F test/attach3.test 6d060986ff004ebb89e1876a331d96c6bb62269e
|
||||
F test/auth.test 300024c28fd0aac163a135b94504dffe82f06952
|
||||
F test/auth.test 1cc252d9e7b3bdc1314199cbf3a0d3c5ed026c21
|
||||
F test/bigfile.test 62722ac4b420dfbcdceb137b8634e2cf2865fe27
|
||||
F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747
|
||||
F test/bind.test a8682ba41433b93bb36a4213a43f282ca9aec5a9
|
||||
@ -144,7 +144,7 @@ F test/misc1.test 1a20ea722dff15155e93948dc4ac3e8d80fec386
|
||||
F test/misc2.test 703734f5817215ca54e364833b3bf5ff36fcc21e
|
||||
F test/misc3.test 57c373aed45acdf45f8f78ea914ef8855841e6b7
|
||||
F test/misc4.test 9f8ab4896dd627f5f9ba893a7b57c9f0a95dfd64
|
||||
F test/misuse.test 2a64ce711419f2fd12806ed95af930fd4e7bb8f3
|
||||
F test/misuse.test fcd9e7cec6ecccc34822584aec6b4e31f13629e1
|
||||
F test/notnull.test 7a08117a71e74b0321aaa937dbeb41a09d6eb1d0
|
||||
F test/null.test 642428b6a5408cc5b954b49e1b6e5025e4458b2b
|
||||
F test/pager.test 394455707a079804e8a4e431d12edce831a065f0
|
||||
@ -216,7 +216,7 @@ F www/arch2b.fig d22a2c9642d584b89d4088b1e51e2bb0f7c04bed
|
||||
F www/audit.tcl 90e09d580f79c7efec0c7d6f447b7ec5c2dce5c0
|
||||
F www/c_interface.tcl 83b39203e1ded4c2dab97f42edf31279a308efcb
|
||||
F www/capi3.tcl 5c1cb163f4d2a54e2d0e22dcc399dd71245c8b89
|
||||
F www/capi3ref.tcl 893977e2b1c8ae47a441335bc124cdc6d5fdbe95
|
||||
F www/capi3ref.tcl 3d34b40270f126a98d09c3613ab31f609c47c79b
|
||||
F www/changes.tcl 16a490bbe5520705861abf36387a5e6b8c18456a
|
||||
F www/common.tcl f786e6be86fb2627ceb30e770e9efa83b9c67a3a
|
||||
F www/conflict.tcl fb8a2ba83746c7fdfd9e52fa7f6aaf5c422b8246
|
||||
@ -247,7 +247,7 @@ F www/tclsqlite.tcl 560ecd6a916b320e59f2917317398f3d59b7cc25
|
||||
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
|
||||
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
|
||||
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
|
||||
P cb3e12372d96f5a24f5a5d79645c705775bc63ff
|
||||
R 94470b4120ee288eca8b9b72b996ebdd
|
||||
P b15abf984fa06ae968d92fa9533dab20dcebd323
|
||||
R 8f6137a115115a381df787e036d26411
|
||||
U drh
|
||||
Z b8354c1b1ec396f3dd5711b713f744d9
|
||||
Z 0f9579e4a88ed7070472b7f1aab3addc
|
||||
|
@ -1 +1 @@
|
||||
b15abf984fa06ae968d92fa9533dab20dcebd323
|
||||
d0f1dc5898382258b283308c2cce55a8bc378ee4
|
@ -14,7 +14,7 @@
|
||||
** systems that do not need this facility may omit it by recompiling
|
||||
** the library with -DSQLITE_OMIT_AUTHORIZATION=1
|
||||
**
|
||||
** $Id: auth.c,v 1.18 2004/09/09 13:55:50 drh Exp $
|
||||
** $Id: auth.c,v 1.19 2004/09/30 13:43:13 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -87,7 +87,7 @@ static void sqliteAuthBadReturnCode(Parse *pParse, int rc){
|
||||
sqlite3ErrorMsg(pParse, "illegal return value (%d) from the "
|
||||
"authorization function - should be SQLITE_OK, SQLITE_IGNORE, "
|
||||
"or SQLITE_DENY", rc);
|
||||
pParse->rc = SQLITE_MISUSE;
|
||||
pParse->rc = SQLITE_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
|
128
src/main.c
128
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.261 2004/09/25 14:39:18 drh Exp $
|
||||
** $Id: main.c,v 1.262 2004/09/30 13:43:13 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
@ -445,11 +445,7 @@ int sqlite3_close(sqlite3 *db){
|
||||
if( !db ){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
if( db->magic!=SQLITE_MAGIC_CLOSED &&
|
||||
db->magic!=SQLITE_MAGIC_OPEN &&
|
||||
db->magic!=SQLITE_MAGIC_BUSY
|
||||
){
|
||||
if( sqlite3SafetyCheck(db) ){
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
|
||||
@ -530,6 +526,8 @@ void sqlite3RollbackAll(sqlite3 *db){
|
||||
const char *sqlite3ErrStr(int rc){
|
||||
const char *z;
|
||||
switch( rc ){
|
||||
case SQLITE_ROW:
|
||||
case SQLITE_DONE:
|
||||
case SQLITE_OK: z = "not an error"; break;
|
||||
case SQLITE_ERROR: z = "SQL logic error or missing database"; break;
|
||||
case SQLITE_INTERNAL: z = "internal SQLite implementation flaw"; break;
|
||||
@ -613,6 +611,9 @@ int sqlite3_busy_handler(
|
||||
int (*xBusy)(void*,int),
|
||||
void *pArg
|
||||
){
|
||||
if( sqlite3SafetyCheck(db) ){
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
db->busyHandler.xFunc = xBusy;
|
||||
db->busyHandler.pArg = pArg;
|
||||
return SQLITE_OK;
|
||||
@ -630,14 +631,16 @@ void sqlite3_progress_handler(
|
||||
int (*xProgress)(void*),
|
||||
void *pArg
|
||||
){
|
||||
if( nOps>0 ){
|
||||
db->xProgress = xProgress;
|
||||
db->nProgressOps = nOps;
|
||||
db->pProgressArg = pArg;
|
||||
}else{
|
||||
db->xProgress = 0;
|
||||
db->nProgressOps = 0;
|
||||
db->pProgressArg = 0;
|
||||
if( !sqlite3SafetyCheck(db) ){
|
||||
if( nOps>0 ){
|
||||
db->xProgress = xProgress;
|
||||
db->nProgressOps = nOps;
|
||||
db->pProgressArg = pArg;
|
||||
}else{
|
||||
db->xProgress = 0;
|
||||
db->nProgressOps = 0;
|
||||
db->pProgressArg = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -660,7 +663,9 @@ int sqlite3_busy_timeout(sqlite3 *db, int ms){
|
||||
** Cause any pending operation to stop at its earliest opportunity.
|
||||
*/
|
||||
void sqlite3_interrupt(sqlite3 *db){
|
||||
db->flags |= SQLITE_Interrupt;
|
||||
if( !sqlite3SafetyCheck(db) ){
|
||||
db->flags |= SQLITE_Interrupt;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -689,7 +694,10 @@ int sqlite3_create_function(
|
||||
FuncDef *p;
|
||||
int nName;
|
||||
|
||||
if( (db==0 || zFunctionName==0 || sqlite3SafetyCheck(db)) ||
|
||||
if( sqlite3SafetyCheck(db) ){
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
if( zFunctionName==0 ||
|
||||
(xFunc && (xFinal || xStep)) ||
|
||||
(!xFunc && (xFinal && !xStep)) ||
|
||||
(!xFunc && (!xFinal && xStep)) ||
|
||||
@ -738,8 +746,12 @@ int sqlite3_create_function16(
|
||||
){
|
||||
int rc;
|
||||
char const *zFunc8;
|
||||
sqlite3_value *pTmp;
|
||||
|
||||
sqlite3_value *pTmp = sqlite3GetTransientValue(db);
|
||||
if( sqlite3SafetyCheck(db) ){
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
pTmp = sqlite3GetTransientValue(db);
|
||||
sqlite3ValueSetStr(pTmp, -1, zFunctionName, SQLITE_UTF16NATIVE,SQLITE_STATIC);
|
||||
zFunc8 = sqlite3ValueText(pTmp, SQLITE_UTF8);
|
||||
|
||||
@ -854,22 +866,18 @@ int sqlite3BtreeFactory(
|
||||
** error.
|
||||
*/
|
||||
const char *sqlite3_errmsg(sqlite3 *db){
|
||||
if( !db || !db->pErr ){
|
||||
/* If db is NULL, then assume that a malloc() failed during an
|
||||
** sqlite3_open() call.
|
||||
*/
|
||||
const char *z;
|
||||
if( sqlite3_malloc_failed ){
|
||||
return sqlite3ErrStr(SQLITE_NOMEM);
|
||||
}
|
||||
if( db->magic!=SQLITE_MAGIC_OPEN &&
|
||||
db->magic!=SQLITE_MAGIC_BUSY &&
|
||||
db->magic!=SQLITE_MAGIC_CLOSED
|
||||
){
|
||||
if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){
|
||||
return sqlite3ErrStr(SQLITE_MISUSE);
|
||||
}
|
||||
if( !sqlite3_value_text(db->pErr) ){
|
||||
return sqlite3ErrStr(db->errCode);
|
||||
z = sqlite3_value_text(db->pErr);
|
||||
if( z==0 ){
|
||||
z = sqlite3ErrStr(db->errCode);
|
||||
}
|
||||
return sqlite3_value_text(db->pErr);
|
||||
return z;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -896,31 +904,32 @@ const void *sqlite3_errmsg16(sqlite3 *db){
|
||||
0, 's', 0, 'e', 0, 'q', 0, 'u', 0, 'e', 0, 'n', 0, 'c', 0, 'e', 0, 0, 0
|
||||
};
|
||||
|
||||
if( db && db->pErr ){
|
||||
if( db->magic!=SQLITE_MAGIC_OPEN &&
|
||||
db->magic!=SQLITE_MAGIC_BUSY &&
|
||||
db->magic!=SQLITE_MAGIC_CLOSED
|
||||
){
|
||||
return (void *)(&misuseBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
|
||||
}
|
||||
if( !sqlite3_value_text16(db->pErr) ){
|
||||
sqlite3ValueSetStr(db->pErr, -1, sqlite3ErrStr(db->errCode),
|
||||
SQLITE_UTF8, SQLITE_STATIC);
|
||||
}
|
||||
if( sqlite3_value_text16(db->pErr) ){
|
||||
return sqlite3_value_text16(db->pErr);
|
||||
}
|
||||
}
|
||||
|
||||
/* If db is NULL, then assume that a malloc() failed during an
|
||||
** sqlite3_open() call. We have a static version of the string
|
||||
** "out of memory" encoded using UTF-16 just for this purpose.
|
||||
*/
|
||||
return (void *)(&outOfMemBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
|
||||
const void *z;
|
||||
if( sqlite3_malloc_failed ){
|
||||
return (void *)(&outOfMemBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
|
||||
}
|
||||
if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){
|
||||
return (void *)(&misuseBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
|
||||
}
|
||||
z = sqlite3_value_text16(db->pErr);
|
||||
if( z==0 ){
|
||||
sqlite3ValueSetStr(db->pErr, -1, sqlite3ErrStr(db->errCode),
|
||||
SQLITE_UTF8, SQLITE_STATIC);
|
||||
z = sqlite3_value_text16(db->pErr);
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the most recent error code generated by an SQLite routine.
|
||||
*/
|
||||
int sqlite3_errcode(sqlite3 *db){
|
||||
if( !db ) return SQLITE_NOMEM;
|
||||
if( sqlite3_malloc_failed ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
if( sqlite3SafetyCheck(db) ){
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
return db->errCode;
|
||||
}
|
||||
|
||||
@ -1043,6 +1052,9 @@ int sqlite3_prepare16(
|
||||
int rc;
|
||||
sqlite3_value *pTmp;
|
||||
|
||||
if( sqlite3SafetyCheck(db) ){
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
pTmp = sqlite3GetTransientValue(db);
|
||||
sqlite3ValueSetStr(pTmp, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC);
|
||||
zSql8 = sqlite3ValueText(pTmp, SQLITE_UTF8);
|
||||
@ -1245,6 +1257,10 @@ int sqlite3_create_collation(
|
||||
CollSeq *pColl;
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
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.
|
||||
@ -1283,7 +1299,11 @@ int sqlite3_create_collation16(
|
||||
int(*xCompare)(void*,int,const void*,int,const void*)
|
||||
){
|
||||
char const *zName8;
|
||||
sqlite3_value *pTmp = sqlite3GetTransientValue(db);
|
||||
sqlite3_value *pTmp;
|
||||
if( sqlite3SafetyCheck(db) ){
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
pTmp = sqlite3GetTransientValue(db);
|
||||
sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF16NATIVE, SQLITE_STATIC);
|
||||
zName8 = sqlite3ValueText(pTmp, SQLITE_UTF8);
|
||||
return sqlite3_create_collation(db, zName8, enc, pCtx, xCompare);
|
||||
@ -1298,6 +1318,9 @@ int sqlite3_collation_needed(
|
||||
void *pCollNeededArg,
|
||||
void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*)
|
||||
){
|
||||
if( sqlite3SafetyCheck(db) ){
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
db->xCollNeeded = xCollNeeded;
|
||||
db->xCollNeeded16 = 0;
|
||||
db->pCollNeededArg = pCollNeededArg;
|
||||
@ -1313,6 +1336,9 @@ int sqlite3_collation_needed16(
|
||||
void *pCollNeededArg,
|
||||
void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*)
|
||||
){
|
||||
if( sqlite3SafetyCheck(db) ){
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
db->xCollNeeded = 0;
|
||||
db->xCollNeeded16 = xCollNeeded16;
|
||||
db->pCollNeededArg = pCollNeededArg;
|
||||
|
@ -154,6 +154,7 @@ int sqlite3_get_table(
|
||||
}
|
||||
sqliteFree(res.zErrMsg);
|
||||
}
|
||||
db->errCode = res.rc;
|
||||
return res.rc;
|
||||
}
|
||||
sqliteFree(res.zErrMsg);
|
||||
|
110
src/test1.c
110
src/test1.c
@ -13,7 +13,7 @@
|
||||
** is not included in the SQLite library. It is used for automated
|
||||
** testing of the SQLite library.
|
||||
**
|
||||
** $Id: test1.c,v 1.103 2004/09/08 20:13:05 drh Exp $
|
||||
** $Id: test1.c,v 1.104 2004/09/30 13:43:13 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "tcl.h"
|
||||
@ -52,12 +52,35 @@ static const char * errorName(int rc){
|
||||
case SQLITE_RANGE: zName = "SQLITE_RANGE"; break;
|
||||
case SQLITE_ROW: zName = "SQLITE_ROW"; break;
|
||||
case SQLITE_DONE: zName = "SQLITE_DONE"; break;
|
||||
case SQLITE_NOTADB: zName = "SQLITE_NOTADB"; break;
|
||||
case SQLITE_NOTADB: zName = "SQLITE_NOTADB"; break;
|
||||
default: zName = "SQLITE_Unknown"; break;
|
||||
}
|
||||
return zName;
|
||||
}
|
||||
|
||||
/*
|
||||
** Convert an sqlite3_stmt* into an sqlite3*. This depends on the
|
||||
** fact that the sqlite3* is the first field in the Vdbe structure.
|
||||
*/
|
||||
#define StmtToDb(X) (*(sqlite3**)(X))
|
||||
|
||||
/*
|
||||
** Check a return value to make sure it agrees with the results
|
||||
** from sqlite3_errcode.
|
||||
*/
|
||||
int sqlite3TestErrCode(Tcl_Interp *interp, sqlite3 *db, int rc){
|
||||
if( rc!=SQLITE_MISUSE && rc!=SQLITE_OK && sqlite3_errcode(db)!=rc ){
|
||||
char zBuf[200];
|
||||
int r2 = sqlite3_errcode(db);
|
||||
sprintf(zBuf, "error code %s (%d) does not match sqlite3_errcode %s (%d)",
|
||||
errorName(rc), rc, errorName(r2), r2);
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_AppendResult(interp, zBuf, 0);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Decode a pointer to an sqlite3 object.
|
||||
*/
|
||||
@ -160,6 +183,7 @@ static int test_exec_printf(
|
||||
Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr);
|
||||
Tcl_DStringFree(&str);
|
||||
if( zErr ) free(zErr);
|
||||
if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@ -234,6 +258,7 @@ static int test_get_table_printf(
|
||||
}
|
||||
sqlite3_free_table(aResult);
|
||||
if( zErr ) free(zErr);
|
||||
if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@ -451,6 +476,7 @@ static int test_create_function(
|
||||
int argc, /* Number of arguments */
|
||||
char **argv /* Text of each argument */
|
||||
){
|
||||
int rc;
|
||||
sqlite3 *db;
|
||||
sqlite3_value *pVal;
|
||||
extern void Md5_Register(sqlite3*);
|
||||
@ -461,16 +487,20 @@ static int test_create_function(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
|
||||
sqlite3_create_function(db, "x_coalesce", -1, SQLITE_ANY, 0,
|
||||
ifnullFunc, 0, 0);
|
||||
rc = sqlite3_create_function(db, "x_coalesce", -1, SQLITE_ANY, 0,
|
||||
ifnullFunc, 0, 0);
|
||||
|
||||
/* Use the sqlite3_create_function16() API here. Mainly for fun, but also
|
||||
** because it is not tested anywhere else. */
|
||||
pVal = sqlite3ValueNew();
|
||||
sqlite3ValueSetStr(pVal, -1, "x_sqlite_exec", SQLITE_UTF8, SQLITE_STATIC);
|
||||
sqlite3_create_function16(db, sqlite3ValueText(pVal, SQLITE_UTF16NATIVE),
|
||||
1, SQLITE_UTF16, db, sqlite3ExecFunc, 0, 0);
|
||||
sqlite3ValueFree(pVal);
|
||||
if( rc==SQLITE_OK ){
|
||||
pVal = sqlite3ValueNew();
|
||||
sqlite3ValueSetStr(pVal, -1, "x_sqlite_exec", SQLITE_UTF8, SQLITE_STATIC);
|
||||
rc = sqlite3_create_function16(db,
|
||||
sqlite3ValueText(pVal, SQLITE_UTF16NATIVE),
|
||||
1, SQLITE_UTF16, db, sqlite3ExecFunc, 0, 0);
|
||||
sqlite3ValueFree(pVal);
|
||||
}
|
||||
if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@ -512,16 +542,20 @@ static int test_create_aggregate(
|
||||
char **argv /* Text of each argument */
|
||||
){
|
||||
sqlite3 *db;
|
||||
int rc;
|
||||
if( argc!=2 ){
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||
" FILENAME\"", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
|
||||
sqlite3_create_function(db, "x_count", 0, SQLITE_UTF8, 0, 0,
|
||||
countStep,countFinalize);
|
||||
sqlite3_create_function(db, "x_count", 1, SQLITE_UTF8, 0, 0,
|
||||
rc = sqlite3_create_function(db, "x_count", 0, SQLITE_UTF8, 0, 0,
|
||||
countStep,countFinalize);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_create_function(db, "x_count", 1, SQLITE_UTF8, 0, 0,
|
||||
countStep,countFinalize);
|
||||
}
|
||||
if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@ -831,6 +865,7 @@ static int test_register_func(
|
||||
Tcl_AppendResult(interp, sqlite3ErrStr(rc), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@ -847,6 +882,7 @@ static int test_finalize(
|
||||
){
|
||||
sqlite3_stmt *pStmt;
|
||||
int rc;
|
||||
sqlite3 *db;
|
||||
|
||||
if( objc!=2 ){
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"",
|
||||
@ -856,8 +892,10 @@ static int test_finalize(
|
||||
|
||||
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
|
||||
|
||||
db = StmtToDb(pStmt);
|
||||
rc = sqlite3_finalize(pStmt);
|
||||
Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
|
||||
if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@ -884,6 +922,7 @@ static int test_reset(
|
||||
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
|
||||
|
||||
rc = sqlite3_reset(pStmt);
|
||||
if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
|
||||
if( rc ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@ -956,6 +995,7 @@ static int test_bind(
|
||||
"\"null\" or \"static\" or \"normal\"", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
|
||||
if( rc ){
|
||||
char zBuf[50];
|
||||
sprintf(zBuf, "(%d) ", rc);
|
||||
@ -1045,25 +1085,28 @@ static int test_collate(
|
||||
sqlite3 *db;
|
||||
int val;
|
||||
sqlite3_value *pVal;
|
||||
int rc;
|
||||
|
||||
if( objc!=5 ) goto bad_args;
|
||||
pTestCollateInterp = interp;
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
|
||||
|
||||
if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR;
|
||||
sqlite3_create_collation(db, "test_collate", SQLITE_UTF8,
|
||||
(void *)SQLITE_UTF8, val?test_collate_func:0);
|
||||
if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR;
|
||||
sqlite3_create_collation(db, "test_collate", SQLITE_UTF16LE,
|
||||
(void *)SQLITE_UTF16LE, val?test_collate_func:0);
|
||||
if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR;
|
||||
rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF8,
|
||||
(void *)SQLITE_UTF8, val?test_collate_func:0);
|
||||
if( rc==SQLITE_OK ){
|
||||
if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR;
|
||||
rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF16LE,
|
||||
(void *)SQLITE_UTF16LE, val?test_collate_func:0);
|
||||
if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR;
|
||||
|
||||
pVal = sqlite3ValueNew();
|
||||
sqlite3ValueSetStr(pVal, -1, "test_collate", SQLITE_UTF8, SQLITE_STATIC);
|
||||
sqlite3_create_collation16(db, sqlite3ValueText(pVal, SQLITE_UTF16NATIVE),
|
||||
SQLITE_UTF16BE, (void *)SQLITE_UTF16BE, val?test_collate_func:0);
|
||||
sqlite3ValueFree(pVal);
|
||||
|
||||
pVal = sqlite3ValueNew();
|
||||
sqlite3ValueSetStr(pVal, -1, "test_collate", SQLITE_UTF8, SQLITE_STATIC);
|
||||
sqlite3_create_collation16(db, sqlite3ValueText(pVal, SQLITE_UTF16NATIVE),
|
||||
SQLITE_UTF16BE, (void *)SQLITE_UTF16BE, val?test_collate_func:0);
|
||||
sqlite3ValueFree(pVal);
|
||||
}
|
||||
if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
|
||||
return TCL_OK;
|
||||
|
||||
bad_args:
|
||||
@ -1093,10 +1136,12 @@ static int test_collate_needed(
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
sqlite3 *db;
|
||||
int rc;
|
||||
|
||||
if( objc!=2 ) goto bad_args;
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
|
||||
sqlite3_collation_needed16(db, 0, test_collate_needed_cb);
|
||||
rc = sqlite3_collation_needed16(db, 0, test_collate_needed_cb);
|
||||
if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
|
||||
return TCL_OK;
|
||||
|
||||
bad_args:
|
||||
@ -1335,6 +1380,7 @@ static int test_bind_int(
|
||||
if( Tcl_GetIntFromObj(interp, objv[3], &value) ) return TCL_ERROR;
|
||||
|
||||
rc = sqlite3_bind_int(pStmt, idx, value);
|
||||
if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
|
||||
if( rc!=SQLITE_OK ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@ -1372,6 +1418,7 @@ static int test_bind_int64(
|
||||
if( Tcl_GetWideIntFromObj(interp, objv[3], &value) ) return TCL_ERROR;
|
||||
|
||||
rc = sqlite3_bind_int64(pStmt, idx, value);
|
||||
if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
|
||||
if( rc!=SQLITE_OK ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@ -1409,6 +1456,7 @@ static int test_bind_double(
|
||||
if( Tcl_GetDoubleFromObj(interp, objv[3], &value) ) return TCL_ERROR;
|
||||
|
||||
rc = sqlite3_bind_double(pStmt, idx, value);
|
||||
if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
|
||||
if( rc!=SQLITE_OK ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@ -1443,6 +1491,7 @@ static int test_bind_null(
|
||||
if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
|
||||
|
||||
rc = sqlite3_bind_null(pStmt, idx);
|
||||
if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
|
||||
if( rc!=SQLITE_OK ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@ -1482,6 +1531,7 @@ static int test_bind_text(
|
||||
if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR;
|
||||
|
||||
rc = sqlite3_bind_text(pStmt, idx, value, bytes, SQLITE_TRANSIENT);
|
||||
if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
|
||||
if( rc!=SQLITE_OK ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@ -1521,6 +1571,7 @@ static int test_bind_text16(
|
||||
if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR;
|
||||
|
||||
rc = sqlite3_bind_text16(pStmt, idx, (void *)value, bytes, SQLITE_TRANSIENT);
|
||||
if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
|
||||
if( rc!=SQLITE_OK ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@ -1559,6 +1610,7 @@ static int test_bind_blob(
|
||||
if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR;
|
||||
|
||||
rc = sqlite3_bind_blob(pStmt, idx, value, bytes, SQLITE_TRANSIENT);
|
||||
if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
|
||||
if( rc!=SQLITE_OK ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@ -1757,6 +1809,7 @@ static int test_prepare(
|
||||
if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;
|
||||
|
||||
rc = sqlite3_prepare(db, zSql, bytes, &pStmt, &zTail);
|
||||
if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
|
||||
if( zTail ){
|
||||
if( bytes>=0 ){
|
||||
bytes = bytes - (zTail-zSql);
|
||||
@ -1796,7 +1849,8 @@ static int test_prepare16(
|
||||
const void *zTail = 0;
|
||||
Tcl_Obj *pTail = 0;
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
char zBuf[50];
|
||||
char zBuf[50];
|
||||
int rc;
|
||||
int bytes; /* The integer specified as arg 3 */
|
||||
int objlen; /* The byte-array length of arg 2 */
|
||||
|
||||
@ -1809,7 +1863,9 @@ static int test_prepare16(
|
||||
zSql = Tcl_GetByteArrayFromObj(objv[2], &objlen);
|
||||
if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;
|
||||
|
||||
if( SQLITE_OK!=sqlite3_prepare16(db, zSql, bytes, &pStmt, &zTail) ){
|
||||
rc = sqlite3_prepare16(db, zSql, bytes, &pStmt, &zTail);
|
||||
if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
|
||||
if( rc ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
|
26
src/util.c
26
src/util.c
@ -14,7 +14,7 @@
|
||||
** This file contains functions for allocating memory, comparing
|
||||
** strings, and stuff like that.
|
||||
**
|
||||
** $Id: util.c,v 1.118 2004/09/25 14:39:19 drh Exp $
|
||||
** $Id: util.c,v 1.119 2004/09/30 13:43:13 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <stdarg.h>
|
||||
@ -746,19 +746,21 @@ int sqlite3SafetyOff(sqlite3 *db){
|
||||
}
|
||||
|
||||
/*
|
||||
** Check to make sure we are not currently executing an sqlite3_exec().
|
||||
** If we are currently in an sqlite3_exec(), return true and set
|
||||
** sqlite.magic to SQLITE_MAGIC_ERROR. This will cause a complete
|
||||
** shutdown of the database.
|
||||
**
|
||||
** This routine is used to try to detect when API routines are called
|
||||
** at the wrong time or in the wrong sequence.
|
||||
** Check to make sure we have a valid db pointer. This test is not
|
||||
** foolproof but it does provide some measure of protection against
|
||||
** misuse of the interface such as passing in db pointers that are
|
||||
** NULL or which have been previously closed. If this routine returns
|
||||
** TRUE it means that the db pointer is invalid and should not be
|
||||
** dereferenced for any reason. The calling function should invoke
|
||||
** SQLITE_MISUSE immediately.
|
||||
*/
|
||||
int sqlite3SafetyCheck(sqlite3 *db){
|
||||
if( db->pVdbe!=0 ){
|
||||
db->magic = SQLITE_MAGIC_ERROR;
|
||||
return 1;
|
||||
}
|
||||
int magic;
|
||||
if( db==0 ) return 1;
|
||||
magic = db->magic;
|
||||
if( magic!=SQLITE_MAGIC_CLOSED &&
|
||||
magic!=SQLITE_MAGIC_OPEN &&
|
||||
magic!=SQLITE_MAGIC_BUSY ) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1274,7 +1274,7 @@ int sqlite3VdbeHalt(Vdbe *p){
|
||||
*/
|
||||
int sqlite3VdbeReset(Vdbe *p){
|
||||
if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){
|
||||
sqlite3Error(p->db, SQLITE_MISUSE, 0 ,0);
|
||||
sqlite3Error(p->db, SQLITE_MISUSE, 0);
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
|
||||
@ -1288,7 +1288,7 @@ int sqlite3VdbeReset(Vdbe *p){
|
||||
** main database structure.
|
||||
*/
|
||||
if( p->zErrMsg ){
|
||||
sqlite3Error(p->db, p->rc, "%s", p->zErrMsg, 0);
|
||||
sqlite3Error(p->db, p->rc, "%s", p->zErrMsg);
|
||||
sqliteFree(p->zErrMsg);
|
||||
p->zErrMsg = 0;
|
||||
}else if( p->rc ){
|
||||
|
@ -12,7 +12,7 @@
|
||||
# focus of this script is testing the ATTACH and DETACH commands
|
||||
# and related functionality.
|
||||
#
|
||||
# $Id: auth.test,v 1.18 2004/09/09 13:55:51 drh Exp $
|
||||
# $Id: auth.test,v 1.19 2004/09/30 13:43:14 drh Exp $
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
@ -1732,7 +1732,7 @@ do_test auth-2.9.1 {
|
||||
} {1 {illegal return value (999) from the authorization function - should be SQLITE_OK, SQLITE_IGNORE, or SQLITE_DENY}}
|
||||
do_test auth-2.9.2 {
|
||||
db errorcode
|
||||
} {21}
|
||||
} {1}
|
||||
do_test auth-2.10 {
|
||||
proc auth {code arg1 arg2 arg3 arg4} {
|
||||
if {$code=="SQLITE_SELECT"} {
|
||||
|
@ -13,7 +13,7 @@
|
||||
# This file implements tests for the SQLITE_MISUSE detection logic.
|
||||
# This test file leaks memory and file descriptors.
|
||||
#
|
||||
# $Id: misuse.test,v 1.6 2004/06/26 09:50:12 danielk1977 Exp $
|
||||
# $Id: misuse.test,v 1.7 2004/09/30 13:43:14 drh Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@ -94,6 +94,9 @@ do_test misuse-2.1 {
|
||||
do_test misuse-2.2 {
|
||||
catchsql2 {SELECT * FROM t1}
|
||||
} {0 {a b 1 2}}
|
||||
|
||||
# We used to disallow creating new function from within an exec().
|
||||
# But now this is acceptable.
|
||||
do_test misuse-2.3 {
|
||||
set v [catch {
|
||||
db eval {SELECT * FROM t1} {} {
|
||||
@ -101,15 +104,15 @@ do_test misuse-2.3 {
|
||||
}
|
||||
} msg]
|
||||
lappend v $msg
|
||||
} {1 {library routine called out of sequence}}
|
||||
} {0 {}}
|
||||
do_test misuse-2.4 {
|
||||
catchsql2 {SELECT * FROM t1}
|
||||
} {1 {library routine called out of sequence}}
|
||||
} {0 {a b 1 2}}
|
||||
do_test misuse-2.5 {
|
||||
catchsql {
|
||||
SELECT * FROM t1
|
||||
}
|
||||
} {1 {library routine called out of sequence}}
|
||||
} {0 {1 2}}
|
||||
|
||||
# Attempt to register a new SQL aggregate while an sqlite_exec() is active.
|
||||
#
|
||||
@ -123,6 +126,9 @@ do_test misuse-3.1 {
|
||||
do_test misuse-3.2 {
|
||||
catchsql2 {SELECT * FROM t1}
|
||||
} {0 {a b 1 2}}
|
||||
|
||||
# We used to disallow creating new function from within an exec().
|
||||
# But now this is acceptable.
|
||||
do_test misuse-3.3 {
|
||||
set v [catch {
|
||||
db eval {SELECT * FROM t1} {} {
|
||||
@ -130,15 +136,15 @@ do_test misuse-3.3 {
|
||||
}
|
||||
} msg]
|
||||
lappend v $msg
|
||||
} {1 {library routine called out of sequence}}
|
||||
} {0 {}}
|
||||
do_test misuse-3.4 {
|
||||
catchsql2 {SELECT * FROM t1}
|
||||
} {1 {library routine called out of sequence}}
|
||||
} {0 {a b 1 2}}
|
||||
do_test misuse-3.5 {
|
||||
catchsql {
|
||||
SELECT * FROM t1
|
||||
}
|
||||
} {1 {library routine called out of sequence}}
|
||||
} {0 {1 2}}
|
||||
|
||||
# Attempt to close the database from an sqlite_exec callback.
|
||||
#
|
||||
|
@ -1,4 +1,4 @@
|
||||
set rcsid {$Id: capi3ref.tcl,v 1.12 2004/09/15 13:38:11 drh Exp $}
|
||||
set rcsid {$Id: capi3ref.tcl,v 1.13 2004/09/30 13:43:14 drh Exp $}
|
||||
source common.tcl
|
||||
header {C/C++ Interface For SQLite Version 3}
|
||||
puts {
|
||||
@ -540,15 +540,17 @@ int sqlite3_data_count(sqlite3_stmt *pStmt);
|
||||
api {} {
|
||||
int sqlite3_errcode(sqlite3 *db);
|
||||
} {
|
||||
Return the error code for the most recent sqlite3_* API call associated
|
||||
with sqlite3 handle 'db'. SQLITE_OK is returned if the most recent
|
||||
API call was successful.
|
||||
Return the error code for the most recent failed sqlite3_* API call associated
|
||||
with sqlite3 handle 'db'. If a prior API call failed but the most recent
|
||||
API call succeeded, the return value from this routine is undefined.
|
||||
|
||||
Calls to many sqlite3_* functions set the error code and string returned
|
||||
by sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16()
|
||||
(overwriting the previous values). Note that calls to sqlite3_errcode(),
|
||||
sqlite3_errmsg() and sqlite3_errmsg16() themselves do not affect the
|
||||
results of future invocations.
|
||||
results of future invocations. Calls to API routines that do not return
|
||||
an error code (examples: sqlite3_data_count() or sqlite3_mprintf()) do
|
||||
not change the error code returned by this routine.
|
||||
|
||||
Assuming no other intervening sqlite3_* API calls are made, the error
|
||||
code returned by this function is associated with the same error as
|
||||
|
Loading…
x
Reference in New Issue
Block a user