mirror of
https://github.com/sqlite/sqlite.git
synced 2025-12-24 14:17:58 +03:00
Changes to allow the code in sqlite3expert.c to be tested directly (via the
API in sqlite3expert.h) instead of by invoking the sqlite3_expert application. Fix memory leaks and other problems. FossilOrigin-Name: 5dd9831721b70a89a26728adcd49c7f6103ef8266891a79c2db34d913702709e
This commit is contained in:
@@ -11,6 +11,8 @@
|
||||
*************************************************************************
|
||||
*/
|
||||
|
||||
#if !defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHEREINFO_HOOK)
|
||||
|
||||
#include "sqlite3expert.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
@@ -20,7 +22,6 @@ typedef sqlite3_int64 i64;
|
||||
typedef sqlite3_uint64 u64;
|
||||
|
||||
typedef struct IdxConstraint IdxConstraint;
|
||||
typedef struct IdxContext IdxContext;
|
||||
typedef struct IdxScan IdxScan;
|
||||
typedef struct IdxStatement IdxStatement;
|
||||
typedef struct IdxWhere IdxWhere;
|
||||
@@ -89,19 +90,6 @@ struct IdxTable {
|
||||
IdxColumn *aCol;
|
||||
};
|
||||
|
||||
/*
|
||||
** Context object passed to idxWhereInfo() and other functions.
|
||||
*/
|
||||
struct IdxContext {
|
||||
char **pzErrmsg;
|
||||
IdxWhere *pCurrent; /* Current where clause */
|
||||
int rc; /* Error code (if error has occurred) */
|
||||
IdxScan *pScan; /* List of scan objects */
|
||||
sqlite3 *dbm; /* In-memory db for this analysis */
|
||||
sqlite3 *db; /* User database under analysis */
|
||||
sqlite3_stmt *pInsertMask; /* To write to aux.depmask */
|
||||
};
|
||||
|
||||
struct IdxStatement {
|
||||
int iId; /* Statement number */
|
||||
char *zSql; /* SQL statement */
|
||||
@@ -301,7 +289,7 @@ static IdxConstraint *idxNewConstraint(int *pRc, const char *zColl){
|
||||
** sqlite3_whereinfo_hook() callback.
|
||||
*/
|
||||
static void idxWhereInfo(
|
||||
void *pCtx, /* Pointer to IdxContext structure */
|
||||
void *pCtx, /* Pointer to sqlite3expert structure */
|
||||
int eOp,
|
||||
const char *zVal,
|
||||
int iVal,
|
||||
@@ -794,12 +782,31 @@ static int idxCreateCandidates(sqlite3expert *p, char **pzErr){
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void idxConstraintFree(IdxConstraint *pConstraint){
|
||||
IdxConstraint *pNext;
|
||||
IdxConstraint *p;
|
||||
|
||||
for(p=pConstraint; p; p=pNext){
|
||||
pNext = p->pNext;
|
||||
sqlite3_free(p);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Free all elements of the linked list starting from pScan up until pLast
|
||||
** (pLast is not freed).
|
||||
*/
|
||||
static void idxScanFree(IdxScan *pScan, IdxScan *pLast){
|
||||
/* TODO! */
|
||||
IdxScan *p;
|
||||
IdxScan *pNext;
|
||||
for(p=pScan; p!=pLast; p=pNext){
|
||||
pNext = p->pNextScan;
|
||||
idxConstraintFree(p->pOrder);
|
||||
idxConstraintFree(p->where.pEq);
|
||||
idxConstraintFree(p->where.pRange);
|
||||
sqlite3_free(p->pTable);
|
||||
sqlite3_free(p);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -807,7 +814,14 @@ static void idxScanFree(IdxScan *pScan, IdxScan *pLast){
|
||||
** until pLast (pLast is not freed).
|
||||
*/
|
||||
static void idxStatementFree(IdxStatement *pStatement, IdxStatement *pLast){
|
||||
/* TODO! */
|
||||
IdxStatement *p;
|
||||
IdxStatement *pNext;
|
||||
for(p=pStatement; p!=pLast; p=pNext){
|
||||
pNext = p->pNext;
|
||||
sqlite3_free(p->zEQP);
|
||||
sqlite3_free(p->zIdx);
|
||||
sqlite3_free(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -875,6 +889,7 @@ int idxFindIndexes(
|
||||
}
|
||||
|
||||
find_indexes_out:
|
||||
idxHashClear(&hIdx);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -974,7 +989,6 @@ int sqlite3_expert_analyze(sqlite3expert *p, char **pzErr){
|
||||
rc = idxGetTableInfo(p->dbm, pIter, pzErr);
|
||||
}
|
||||
|
||||
|
||||
/* Create candidate indexes within the in-memory database file */
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = idxCreateCandidates(p, pzErr);
|
||||
@@ -992,12 +1006,19 @@ int sqlite3_expert_analyze(sqlite3expert *p, char **pzErr){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the total number of statements that have been added to this
|
||||
** sqlite3expert using sqlite3_expert_sql().
|
||||
*/
|
||||
int sqlite3_expert_count(sqlite3expert *p){
|
||||
int nRet = 0;
|
||||
if( p->pStatement ) nRet = p->pStatement->iId+1;
|
||||
return nRet;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return a component of the report.
|
||||
*/
|
||||
const char *sqlite3_expert_report(sqlite3expert *p, int iStmt, int eReport){
|
||||
const char *zRet = 0;
|
||||
IdxStatement *pStmt;
|
||||
@@ -1027,6 +1048,9 @@ void sqlite3_expert_destroy(sqlite3expert *p){
|
||||
sqlite3_close(p->dbm);
|
||||
idxScanFree(p->pScan, 0);
|
||||
idxStatementFree(p->pStatement, 0);
|
||||
idxHashClear(&p->hIdx);
|
||||
sqlite3_free(p);
|
||||
}
|
||||
|
||||
#endif /* !defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHEREINFO_HOOK) */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user