1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-30 19:03:16 +03:00

Enhancements to the fuzzer invariant checker to turn optimizations on and

off.

FossilOrigin-Name: 67594481379824823105939fea2ce1fe280667f6db91735ac78b4b6164a78dab
This commit is contained in:
drh
2024-04-08 06:37:19 +00:00
parent 5b613ed41b
commit ac94cf3ece
4 changed files with 43 additions and 19 deletions

View File

@ -30,7 +30,13 @@
/* Forward references */
static char *fuzz_invariant_sql(sqlite3_stmt*, int);
static int sameValue(sqlite3_stmt*,int,sqlite3_stmt*,int,sqlite3_stmt*);
static void reportInvariantFailed(sqlite3_stmt*,sqlite3_stmt*,int);
static void reportInvariantFailed(
sqlite3_stmt *pOrig, /* The original query */
sqlite3_stmt *pTest, /* The alternative test query with a missing row */
int iRow, /* Row number in pOrig */
unsigned int dbOpt, /* Optimization flags on pOrig */
int noOpt /* True if opt flags inverted for pTest */
);
/*
** Do an invariant check on pStmt. iCnt determines which invariant check to
@ -68,7 +74,8 @@ int fuzz_invariant(
int iRow, /* Current row number */
int nRow, /* Number of output rows from pStmt */
int *pbCorrupt, /* IN/OUT: Flag indicating a corrupt database file */
int eVerbosity /* How much debugging output */
int eVerbosity, /* How much debugging output */
unsigned int dbOpt /* Default optimization flags */
){
char *zTest;
sqlite3_stmt *pTestStmt = 0;
@ -76,13 +83,20 @@ int fuzz_invariant(
int i;
int nCol;
int nParam;
int noOpt = (iCnt%3)==0;
if( *pbCorrupt ) return SQLITE_DONE;
nParam = sqlite3_bind_parameter_count(pStmt);
if( nParam>100 ) return SQLITE_DONE;
zTest = fuzz_invariant_sql(pStmt, iCnt);
if( zTest==0 ) return SQLITE_DONE;
if( noOpt ){
sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, db, ~dbOpt);
}
rc = sqlite3_prepare_v2(db, zTest, -1, &pTestStmt, 0);
if( noOpt ){
sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, db, dbOpt);
}
if( rc ){
if( eVerbosity ){
printf("invariant compile failed: %s\n%s\n",
@ -212,7 +226,7 @@ int fuzz_invariant(
}
sqlite3_finalize(pCk);
if( rc==SQLITE_DONE ){
reportInvariantFailed(pStmt, pTestStmt, iRow);
reportInvariantFailed(pStmt, pTestStmt, iRow, dbOpt, noOpt);
return SQLITE_INTERNAL;
}else if( eVerbosity>0 ){
printf("invariant-error ignored due to the use of virtual tables\n");
@ -488,13 +502,17 @@ static void printRow(sqlite3_stmt *pStmt, int iRow){
static void reportInvariantFailed(
sqlite3_stmt *pOrig, /* The original query */
sqlite3_stmt *pTest, /* The alternative test query with a missing row */
int iRow /* Row number in pOrig */
int iRow, /* Row number in pOrig */
unsigned int dbOpt, /* Optimization flags on pOrig */
int noOpt /* True if opt flags inverted for pTest */
){
int iTestRow = 0;
printf("Invariant check failed on row %d.\n", iRow);
printf("Original query --------------------------------------------------\n");
printf("Original query (opt-flags: 0x%08x) --------------------------\n",
dbOpt);
printf("%s\n", sqlite3_expanded_sql(pOrig));
printf("Alternative query -----------------------------------------------\n");
printf("Alternative query (opt-flags: 0x%08x) -----------------------\n",
noOpt ? ~dbOpt : dbOpt);
printf("%s\n", sqlite3_expanded_sql(pTest));
printf("Result row that is missing from the alternative -----------------\n");
printRow(pOrig, iRow);