1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-05 15:55:57 +03:00

Test that virtual table methods xBestIndex, xOpen, xFilter, xNext, xColumn, xRowid, xUpdate, xSync and xBegin can all return error messages using the sqlite3_vtab.zErrMsg variable. (CVS 5519)

FossilOrigin-Name: 007359b770f225877880b11f4c5d97bb548e38ca
This commit is contained in:
danielk1977
2008-08-01 17:37:40 +00:00
parent 6480aad473
commit 3e3a84d32a
9 changed files with 200 additions and 53 deletions

View File

@@ -13,7 +13,7 @@
** is not included in the SQLite library. It is used for automated
** testing of the SQLite library.
**
** $Id: test8.c,v 1.69 2008/07/28 19:34:54 drh Exp $
** $Id: test8.c,v 1.70 2008/08/01 17:37:41 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
@@ -44,6 +44,22 @@ typedef struct echo_cursor echo_cursor;
** use the named table as a backing store will fail.
*/
/*
** Errors can be provoked within the following echo virtual table methods:
**
** xBestIndex xOpen xFilter xNext
** xColumn xRowid xUpdate xSync
** xBegin
**
** This is done by setting the global tcl variable:
**
** echo_module_fail($method,$tbl)
**
** where $method is set to the name of the virtual table method to fail
** (i.e. "xBestIndex") and $tbl is the name of the table being echoed (not
** the name of the virtual table, the name of the underlying real table).
*/
/*
** An echo virtual-table object.
**
@@ -76,6 +92,18 @@ struct echo_cursor {
sqlite3_stmt *pStmt;
};
static int simulateVtabError(echo_vtab *p, const char *zMethod){
const char *zErr;
char zVarname[128];
zVarname[127] = '\0';
snprintf(zVarname, 127, "echo_module_fail(%s,%s)", zMethod, p->zTableName);
zErr = Tcl_GetVar(p->interp, zVarname, TCL_GLOBAL_ONLY);
if( zErr ){
p->base.zErrMsg = sqlite3_mprintf("echo-vtab-error: %s", zErr);
}
return (zErr!=0);
}
/*
** Convert an SQL-style quoted string into a normal string by removing
** the quote characters. The conversion is done in-place. If the
@@ -524,6 +552,9 @@ static int echoDestroy(sqlite3_vtab *pVtab){
*/
static int echoOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
echo_cursor *pCur;
if( simulateVtabError((echo_vtab *)pVTab, "xOpen") ){
return SQLITE_ERROR;
}
pCur = sqlite3MallocZero(sizeof(echo_cursor));
*ppCursor = (sqlite3_vtab_cursor *)pCur;
return (pCur ? SQLITE_OK : SQLITE_NOMEM);
@@ -557,6 +588,10 @@ static int echoNext(sqlite3_vtab_cursor *cur){
int rc = SQLITE_OK;
echo_cursor *pCur = (echo_cursor *)cur;
if( simulateVtabError((echo_vtab *)(cur->pVtab), "xNext") ){
return SQLITE_ERROR;
}
if( pCur->pStmt ){
rc = sqlite3_step(pCur->pStmt);
if( rc==SQLITE_ROW ){
@@ -576,6 +611,11 @@ static int echoNext(sqlite3_vtab_cursor *cur){
static int echoColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
int iCol = i + 1;
sqlite3_stmt *pStmt = ((echo_cursor *)cur)->pStmt;
if( simulateVtabError((echo_vtab *)(cur->pVtab), "xColumn") ){
return SQLITE_ERROR;
}
if( !pStmt ){
sqlite3_result_null(ctx);
}else{
@@ -590,6 +630,11 @@ static int echoColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
*/
static int echoRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
sqlite3_stmt *pStmt = ((echo_cursor *)cur)->pStmt;
if( simulateVtabError((echo_vtab *)(cur->pVtab), "xRowid") ){
return SQLITE_ERROR;
}
*pRowid = sqlite3_column_int64(pStmt, 0);
return SQLITE_OK;
}
@@ -627,6 +672,10 @@ static int echoFilter(
echo_vtab *pVtab = (echo_vtab *)pVtabCursor->pVtab;
sqlite3 *db = pVtab->db;
if( simulateVtabError(pVtab, "xFilter") ){
return SQLITE_ERROR;
}
/* Check that idxNum matches idxStr */
assert( idxNum==hashString(idxStr) );
@@ -734,12 +783,15 @@ static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
int rc = SQLITE_OK;
int useCost = 0;
double cost;
int isIgnoreUsable = 0;
if( Tcl_GetVar(interp, "echo_module_ignore_usable", TCL_GLOBAL_ONLY) ){
isIgnoreUsable = 1;
}
if( simulateVtabError(pVtab, "xBestIndex") ){
return SQLITE_ERROR;
}
/* Determine the number of rows in the table and store this value in local
** variable nRow. The 'estimated-cost' of the scan will be the number of
** rows in the table for a linear scan, or the log (base 2) of the
@@ -892,6 +944,10 @@ int echoUpdate(
** making any changes to a virtual table */
assert( pVtab->inTransaction );
if( simulateVtabError(pVtab, "xUpdate") ){
return SQLITE_ERROR;
}
/* If apData[0] is an integer and nData>1 then do an UPDATE */
if( nData>1 && sqlite3_value_type(apData[0])==SQLITE_INTEGER ){
char *zSep = " SET";
@@ -1019,6 +1075,10 @@ static int echoBegin(sqlite3_vtab *tab){
** a transaction */
assert( !pVtab->inTransaction );
if( simulateVtabError(pVtab, "xBegin") ){
return SQLITE_ERROR;
}
rc = echoTransactionCall(tab, "xBegin");
if( rc==SQLITE_OK ){
@@ -1046,6 +1106,10 @@ static int echoSync(sqlite3_vtab *tab){
** transaction */
assert( pVtab->inTransaction );
if( simulateVtabError(pVtab, "xSync") ){
return SQLITE_ERROR;
}
rc = echoTransactionCall(tab, "xSync");
if( rc==SQLITE_OK ){
@@ -1068,6 +1132,10 @@ static int echoCommit(sqlite3_vtab *tab){
** a transaction */
assert( pVtab->inTransaction );
if( simulateVtabError(pVtab, "xCommit") ){
return SQLITE_ERROR;
}
sqlite3BeginBenignMalloc();
rc = echoTransactionCall(tab, "xCommit");
sqlite3EndBenignMalloc();