Add further tests for the intck module.

FossilOrigin-Name: c253e276b29de28a18270d01b60d95157ce3fc4b37e246d991f9119d26e718d7
This commit is contained in:
dan 2024-02-24 16:26:15 +00:00
parent ee299cc7d4
commit 9c59c87448
6 changed files with 211 additions and 63 deletions

View File

@ -200,9 +200,132 @@ reset_db
do_execsql_test 5.0 {
CREATE TABLE t1(a, b);
CREATE INDEX i1 ON t1(a COLLATE NOCASE);
INSERT INTO t1 VALUES(1, 1);
INSERT INTO t1 VALUES(2, 2);
}
#puts [intck_sql db i1]
do_test 5.1 {
set ic [sqlite3_intck db nosuchdb]
$ic step
} {SQLITE_ERROR}
do_test 5.2 {
$ic close
set ic [sqlite3_intck db {}]
while {[$ic step]=="SQLITE_OK"} {}
set res [$ic error]
$ic close
set res
} {SQLITE_OK {}}
do_test 5.3 { test_do_intck db "main" } {}
do_test 5.4 {
set ret {}
set ic [sqlite3_intck db main]
db eval [$ic test_sql t1] {
if {$error_message!=""} { lappend ret $error_message }
}
$ic close
set ret
} {}
do_test 5.5 {
set ret {}
set ic [sqlite3_intck db main]
db eval [$ic test_sql {}] {
if {$error_message!=""} { lappend ret $error_message }
}
$ic close
set ret
} {}
db cache flush
do_test 5.6 {
set ret {}
set ic [sqlite3_intck db main]
$ic step
db eval [$ic test_sql {}] {
if {$error_message!=""} { lappend ret $error_message }
}
$ic close
set ret
} {}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 6.0 {
CREATE TABLE t1(x, y, PRIMARY KEY(x)) WITHOUT ROWID;
CREATE INDEX i1 ON t1(y, x);
INSERT INTO t1 VALUES(X'0000', X'1111');
}
do_intck_test 6.1 {}
do_execsql_test 6.2.1 {
PRAGMA writable_schema = 1;
UPDATE sqlite_schema SET sql = 'CREATE INDEX i1' WHERE name='i1';
} {}
do_intck_test 6.2.2 {}
do_execsql_test 6.3.1 {
UPDATE sqlite_schema SET sql = 'CREATE INDEX i1(y' WHERE name='i1';
} {}
do_intck_test 6.3.2 {}
do_execsql_test 6.4.1 {
UPDATE sqlite_schema
SET sql = 'CREATE INDEX i1(y) hello world'
WHERE name='i1';
} {}
do_intck_test 6.4.2 {}
do_execsql_test 6.5.1 {
UPDATE sqlite_schema
SET sql = 'CREATE INDEX i1(y, x) WHERE 1 '
WHERE name='i1';
} {}
do_intck_test 6.5.2 {}
do_execsql_test 6.6.1 {
UPDATE sqlite_schema
SET sql = 'CREATE INDEX i1( , ) WHERE 1 '
WHERE name='i1';
} {}
do_test 6.7.2 {
set ic [sqlite3_intck db main]
$ic step
} {SQLITE_ERROR}
do_test 6.5.3 {
$ic error
} {SQLITE_ERROR {near "AS": syntax error}}
$ic close
do_execsql_test 6.6.1 {
UPDATE sqlite_schema
SET sql = 'CREATE INDEX i1([y'
WHERE name='i1';
} {}
do_intck_test 6.6.2 {}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 7.0 {
CREATE TABLE x1("1", "22", "3333", four);
CREATE INDEX i1 ON x1( "1" , "22", NULL);
INSERT INTO x1 VALUES(1, 22, 3333, NULL);
INSERT INTO x1 VALUES(1, 22, 3333, NULL);
}
do_execsql_test 7.1 " CREATE INDEX i2 ON x1( \"1\"\r\n\t ) "
do_execsql_test 7.2 { CREATE INDEX i3 ON x1( "22" || 'abc''def' || `1` ) }
do_execsql_test 7.3 { CREATE INDEX i4 ON x1( [22] + [1] ) }
do_execsql_test 7.4 { CREATE INDEX i5 ON x1( four||'hello' ) }
do_intck_test 7.5 {}
finish_test

48
ext/intck/intckbusy.test Normal file
View File

@ -0,0 +1,48 @@
# 2024 February 24
#
# 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.
#
#***********************************************************************
#
source [file join [file dirname [info script]] intck_common.tcl]
set testprefix intckbusy
do_execsql_test 1.0 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
INSERT INTO t1 VALUES(1, 2, 3);
INSERT INTO t1 VALUES(2, 'two', 'three');
INSERT INTO t1 VALUES(3, NULL, NULL);
CREATE INDEX i1 ON t1(b, c);
}
sqlite3 db2 test.db
do_execsql_test -db db2 1.1 {
BEGIN EXCLUSIVE;
INSERT INTO t1 VALUES(4, 5, 6);
}
do_test 1.2 {
set ic [sqlite3_intck db main]
$ic step
} {SQLITE_BUSY}
do_test 1.3 {
$ic unlock
} {SQLITE_BUSY}
do_test 1.4 {
$ic error
} {SQLITE_BUSY {database is locked}}
do_test 1.4 {
$ic close
} {}
finish_test

View File

@ -60,12 +60,9 @@ struct sqlite3_intck {
** and error code currently held by the database handle in p->rc and p->zErr.
*/
static void intckSaveErrmsg(sqlite3_intck *p){
const char *zDberr = sqlite3_errmsg(p->db);
p->rc = sqlite3_errcode(p->db);
if( zDberr ){
sqlite3_free(p->zErr);
p->zErr = sqlite3_mprintf("%s", zDberr);
}
sqlite3_free(p->zErr);
p->zErr = sqlite3_mprintf("%s", sqlite3_errmsg(p->db));
}
/*
@ -125,6 +122,15 @@ static void intckFinalize(sqlite3_intck *p, sqlite3_stmt *pStmt){
}
}
/*
** If there is already an error in handle p, return it. Otherwise, call
** sqlite3_step() on the statement handle and return that value.
*/
static int intckStep(sqlite3_intck *p, sqlite3_stmt *pStmt){
if( p->rc ) return p->rc;
return sqlite3_step(pStmt);
}
/*
** Execute SQL statement zSql. There is no way to obtain any results
** returned by the statement. This function uses the sqlite3_intck error
@ -133,42 +139,10 @@ static void intckFinalize(sqlite3_intck *p, sqlite3_stmt *pStmt){
static void intckExec(sqlite3_intck *p, const char *zSql){
sqlite3_stmt *pStmt = 0;
pStmt = intckPrepare(p, zSql);
while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) );
intckStep(p, pStmt);
intckFinalize(p, pStmt);
}
/*
** Wrapper around sqlite3_malloc64() that uses the sqlite3_intck error
** code convention.
*/
static void *intckMalloc(sqlite3_intck *p, sqlite3_int64 nByte){
void *pRet = 0;
assert( nByte>0 );
if( p->rc==SQLITE_OK ){
pRet = sqlite3_malloc64(nByte);
if( pRet==0 ){
p->rc = SQLITE_NOMEM;
}
}
return pRet;
}
/*
** Like strdup(), but uses the sqlite3_intck error code convention. Any
** returned buffer should eventually be freed using sqlite3_free().
*/
static char *intckStrdup(sqlite3_intck *p, const char *zIn){
char *zOut = 0;
if( zIn ){
int nIn = strlen(zIn);
zOut = (char*)intckMalloc(p, nIn+1);
if( zOut ){
memcpy(zOut, zIn, nIn+1);
}
}
return zOut;
}
/*
** A wrapper around sqlite3_mprintf() that uses the sqlite3_intck error
** code convention.
@ -280,7 +254,7 @@ static void intckSaveKey(sqlite3_intck *p){
sqlite3_bind_value(pStmt, ii+1, sqlite3_column_value(p->pCheck, ii+1));
}
if( SQLITE_ROW==sqlite3_step(pStmt) ){
p->zKey = intckStrdup(p, (const char*)sqlite3_column_text(pStmt, 0));
p->zKey = intckMprintf(p,"%s",(const char*)sqlite3_column_text(pStmt, 0));
}
intckFinalize(p, pStmt);
}
@ -318,7 +292,7 @@ static void intckFindObject(sqlite3_intck *p){
if( p->rc==SQLITE_OK ){
sqlite3_bind_text(pStmt, 1, zPrev, -1, SQLITE_TRANSIENT);
if( sqlite3_step(pStmt)==SQLITE_ROW ){
p->zObj = intckStrdup(p, (const char*)sqlite3_column_text(pStmt, 0));
p->zObj = intckMprintf(p,"%s",(const char*)sqlite3_column_text(pStmt, 0));
}
}
intckFinalize(p, pStmt);
@ -347,7 +321,7 @@ static int intckGetToken(const char *z){
while( 1 ){
if( z[iRet]==c ){
iRet++;
if( z[iRet+1]!=c ) break;
if( z[iRet]!=c ) break;
}
iRet++;
}
@ -496,7 +470,7 @@ static int intckGetAutoIndex(sqlite3_intck *p){
int bRet = 0;
sqlite3_stmt *pStmt = 0;
pStmt = intckPrepare(p, "PRAGMA automatic_index");
if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
if( SQLITE_ROW==intckStep(p, pStmt) ){
bRet = sqlite3_column_int(pStmt, 0);
}
intckFinalize(p, pStmt);
@ -789,7 +763,7 @@ static char *intckCheckObjectSql(
}
while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
zRet = intckStrdup(p, (const char*)sqlite3_column_text(pStmt, 0));
zRet = intckMprintf(p, "%s", (const char*)sqlite3_column_text(pStmt, 0));
if( pnKeyVal ){
*pnKeyVal = sqlite3_column_int(pStmt, 1);
}
@ -839,15 +813,15 @@ int sqlite3_intck_open(
*/
void sqlite3_intck_close(sqlite3_intck *p){
if( p ){
if( p->db ){
sqlite3_create_function(
p->db, "parse_create_index", 1, SQLITE_UTF8, 0, 0, 0, 0
);
}
sqlite3_finalize(p->pCheck);
sqlite3_create_function(
p->db, "parse_create_index", 1, SQLITE_UTF8, 0, 0, 0, 0
);
sqlite3_free(p->zObj);
sqlite3_free(p->zKey);
sqlite3_free(p->zTestSql);
sqlite3_free(p->zErr);
sqlite3_free(p->zMessage);
sqlite3_free(p);
}
}
@ -881,7 +855,7 @@ int sqlite3_intck_step(sqlite3_intck *p){
}
}else if( p->rc==SQLITE_CORRUPT ){
p->rc = SQLITE_OK;
p->zMessage = intckStrdup(p,
p->zMessage = intckMprintf(p, "%s",
"corruption found while reading database schema"
);
p->bCorruptSchema = 1;
@ -937,7 +911,7 @@ int sqlite3_intck_error(sqlite3_intck *p, const char **pzErr){
** on the database.
*/
int sqlite3_intck_unlock(sqlite3_intck *p){
if( p->pCheck && p->rc==SQLITE_OK ){
if( p->rc==SQLITE_OK && p->pCheck ){
assert( p->zKey==0 && p->nKeyVal>0 );
intckSaveKey(p);
intckFinalize(p, p->pCheck);

View File

@ -92,12 +92,12 @@ static int testIntckCmd(
case 3: assert( 0==strcmp("error", aCmd[iIdx].zName) ); {
const char *zErr = 0;
int rc = sqlite3_intck_error(p->intck, &zErr);
int rc = sqlite3_intck_error(p->intck, 0);
Tcl_Obj *pRes = Tcl_NewObj();
Tcl_ListObjAppendElement(
interp, pRes, Tcl_NewStringObj(sqlite3ErrName(rc), -1)
);
sqlite3_intck_error(p->intck, &zErr);
Tcl_ListObjAppendElement(
interp, pRes, Tcl_NewStringObj(zErr ? zErr : 0, -1)
);
@ -160,6 +160,7 @@ static int test_sqlite3_intck(
return TCL_ERROR;
}
zDb = Tcl_GetString(objv[2]);
if( zDb[0]=='\0' ) zDb = 0;
rc = sqlite3_intck_open(db, zDb, &p->intck);
if( rc!=SQLITE_OK ){
@ -169,7 +170,7 @@ static int test_sqlite3_intck(
}
do {
sprintf(zName, "intck%d", iName);
sprintf(zName, "intck%d", iName++);
}while( Tcl_GetCommandInfo(interp, zName, &info)!=0 );
Tcl_CreateObjCommand(interp, zName, testIntckCmd, (void*)p, testIntckFree);
Tcl_SetObjResult(interp, Tcl_NewStringObj(zName, -1));
@ -226,6 +227,7 @@ static int test_do_intck(
}
Tcl_DecrRefCount(pRet);
sqlite3_intck_close(pCk);
sqlite3_intck_close(0);
return rc ? TCL_ERROR : TCL_OK;
}

View File

@ -1,5 +1,5 @@
C Add\stests\sfor\sthe\snew\scode\son\sthis\sbranch.
D 2024-02-23T20:51:06.837
C Add\sfurther\stests\sfor\sthe\sintck\smodule.
D 2024-02-24T16:26:15.674
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@ -248,14 +248,15 @@ F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c
F ext/icu/README.txt 7ab7ced8ae78e3a645b57e78570ff589d4c672b71370f5aa9e1cd7024f400fc9
F ext/icu/icu.c c074519b46baa484bb5396c7e01e051034da8884bad1a1cb7f09bbe6be3f0282
F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a32075a8
F ext/intck/intck1.test e73c4f87b54176291b9a01b52dbc9dd88f42f3ec8aea48c8e0bd7f87a1440a40
F ext/intck/intck1.test 866f0937911bf3a10491af6ce319b75bcd587c39dc8decf2444746b946aa4f3e
F ext/intck/intck2.test 97daaf43b8a3c870ba7c2fd421dc1887053f5b30188896fa64677ce8174c206f
F ext/intck/intck_common.tcl 9e51458126576783f11051ac0fd25bea3f6b17f570a55884223737f3200b214b
F ext/intck/intckbusy.test 0732fe3efbb9e0a53ffdcc240073f6ff2777ea82c3e08812b16494f650763fe1
F ext/intck/intckcorrupt.test 3211ef68ac53e83951b6c8f6a8d2396506d123fe5898f97f848a25837744ec56
F ext/intck/intckfault.test ba0213c9c8dce08d519d5251268a3bab076a184b4d07acdea23b65e89c9ae03c
F ext/intck/sqlite3intck.c 642f57a4604580513547df9d8489cdb49b8f5f3af1981c7ffb87bc37e5ce1439
F ext/intck/sqlite3intck.c 52381a627637504a49e93400814b36e99afa0b972a9a24ef1732b8268bb27fa8
F ext/intck/sqlite3intck.h 2b40c38e7063ab822c974c0bd4aed97dabb579ccfe2e180a4639bb3bbef0f1c9
F ext/intck/test_intck.c dec07fc82e2626a1450e58be474e351643627b04ee08ce8fae6495a533b87e85
F ext/intck/test_intck.c d63f1707432802f5db125ee40b794923af77d4686869bd8d3a7eb43332344267
F ext/jni/GNUmakefile 59eb05f2a363bdfac8d15d66bed624bfe1ff289229184f3861b95f98a19cf4b2
F ext/jni/README.md d899789a9082a07b99bf30b1bbb6204ae57c060efcaa634536fa669323918f42
F ext/jni/jar-dist.make 030aaa4ae71dd86e4ec5e7c1e6cd86f9dfa47c4592c070d2e35157e42498e1fa
@ -2170,8 +2171,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P cfd051836b72f7d4e38cc9614f6ae5c003de4ce377359fd391adf06fe1ddf6b9
R aa9167c841a6524a2987fc0088c3a9be
P 351d46b2373f08bc8033d0902d9f67cd6c8bcc16c0d9f787e4fb279c0a76da87
R 38b420c887519ac9a48b5a886e5c9758
U dan
Z 2a1b98d11090580141aae0cbd3e3021e
Z 449a9c9353165606d5987b5f74af35a1
# Remove this line to create a well-formed Fossil manifest.

View File

@ -1 +1 @@
351d46b2373f08bc8033d0902d9f67cd6c8bcc16c0d9f787e4fb279c0a76da87
c253e276b29de28a18270d01b60d95157ce3fc4b37e246d991f9119d26e718d7