aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ctime.c3
-rw-r--r--src/dbstat.c55
-rw-r--r--src/main.c3
-rw-r--r--src/malloc.c14
-rw-r--r--src/resolve.c1
-rw-r--r--src/shell.c3
-rw-r--r--src/sqliteInt.h4
-rw-r--r--src/tclsqlite.c47
-rw-r--r--src/test1.c36
9 files changed, 89 insertions, 77 deletions
diff --git a/src/ctime.c b/src/ctime.c
index 4f98ffef6..9503214f5 100644
--- a/src/ctime.c
+++ b/src/ctime.c
@@ -75,6 +75,9 @@ static const char * const azCompileOpt[] = {
#if SQLITE_ENABLE_COLUMN_METADATA
"ENABLE_COLUMN_METADATA",
#endif
+#if SQLITE_ENABLE_DBSTAT_VTAB
+ "ENABLE_DBSTAT_VTAB",
+#endif
#if SQLITE_ENABLE_EXPENSIVE_ASSERT
"ENABLE_EXPENSIVE_ASSERT",
#endif
diff --git a/src/dbstat.c b/src/dbstat.c
index fb5a52b79..e0ab0cea6 100644
--- a/src/dbstat.c
+++ b/src/dbstat.c
@@ -122,6 +122,7 @@ struct StatCursor {
struct StatTable {
sqlite3_vtab base;
sqlite3 *db;
+ int iDb; /* Index of database to analyze */
};
#ifndef get2byte
@@ -140,7 +141,17 @@ static int statConnect(
){
StatTable *pTab = 0;
int rc = SQLITE_OK;
+ int iDb;
+ if( argc>=4 ){
+ iDb = sqlite3FindDbName(db, argv[3]);
+ if( iDb<0 ){
+ *pzErr = sqlite3_mprintf("no such database: %s", argv[3]);
+ return SQLITE_ERROR;
+ }
+ }else{
+ iDb = 0;
+ }
rc = sqlite3_declare_vtab(db, VTAB_SCHEMA);
if( rc==SQLITE_OK ){
pTab = (StatTable *)sqlite3_malloc64(sizeof(StatTable));
@@ -151,6 +162,7 @@ static int statConnect(
if( rc==SQLITE_OK ){
memset(pTab, 0, sizeof(StatTable));
pTab->db = db;
+ pTab->iDb = iDb;
}
*ppVtab = (sqlite3_vtab*)pTab;
@@ -205,16 +217,22 @@ static int statOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
if( pCsr==0 ){
rc = SQLITE_NOMEM;
}else{
+ char *zSql;
memset(pCsr, 0, sizeof(StatCursor));
pCsr->base.pVtab = pVTab;
- rc = sqlite3_prepare_v2(pTab->db,
+ zSql = sqlite3_mprintf(
"SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type"
" UNION ALL "
- "SELECT name, rootpage, type FROM sqlite_master WHERE rootpage!=0"
- " ORDER BY name", -1,
- &pCsr->pStmt, 0
- );
+ "SELECT name, rootpage, type"
+ " FROM \"%w\".sqlite_master WHERE rootpage!=0"
+ " ORDER BY name", pTab->db->aDb[pTab->iDb].zName);
+ if( zSql==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0);
+ sqlite3_free(zSql);
+ }
if( rc!=SQLITE_OK ){
sqlite3_free(pCsr);
pCsr = 0;
@@ -380,7 +398,7 @@ static int statDecodePage(Btree *pBt, StatPage *p){
*/
static void statSizeAndOffset(StatCursor *pCsr){
StatTable *pTab = (StatTable *)((sqlite3_vtab_cursor *)pCsr)->pVtab;
- Btree *pBt = pTab->db->aDb[0].pBt;
+ Btree *pBt = pTab->db->aDb[pTab->iDb].pBt;
Pager *pPager = sqlite3BtreePager(pBt);
sqlite3_file *fd;
sqlite3_int64 x[2];
@@ -394,7 +412,7 @@ static void statSizeAndOffset(StatCursor *pCsr){
*/
fd = sqlite3PagerFile(pPager);
x[0] = pCsr->iPageno;
- if( sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){
+ if( fd->pMethods!=0 && sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){
pCsr->iOffset = x[0];
pCsr->szPage = (int)x[1];
}
@@ -406,9 +424,10 @@ static void statSizeAndOffset(StatCursor *pCsr){
static int statNext(sqlite3_vtab_cursor *pCursor){
int rc;
int nPayload;
+ char *z;
StatCursor *pCsr = (StatCursor *)pCursor;
StatTable *pTab = (StatTable *)pCursor->pVtab;
- Btree *pBt = pTab->db->aDb[0].pBt;
+ Btree *pBt = pTab->db->aDb[pTab->iDb].pBt;
Pager *pPager = sqlite3BtreePager(pBt);
sqlite3_free(pCsr->zPath);
@@ -428,8 +447,9 @@ statNextRestart:
rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg);
pCsr->aPage[0].iPgno = iRoot;
pCsr->aPage[0].iCell = 0;
- pCsr->aPage[0].zPath = sqlite3_mprintf("/");
+ pCsr->aPage[0].zPath = z = sqlite3_mprintf("/");
pCsr->iPage = 0;
+ if( z==0 ) rc = SQLITE_NOMEM;
}else{
pCsr->isEof = 1;
return sqlite3_reset(pCsr->pStmt);
@@ -452,7 +472,7 @@ statNextRestart:
pCsr->zPagetype = "overflow";
pCsr->nCell = 0;
pCsr->nMxPayload = 0;
- pCsr->zPath = sqlite3_mprintf(
+ pCsr->zPath = z = sqlite3_mprintf(
"%s%.3x+%.6x", p->zPath, p->iCell, pCell->iOvfl
);
if( pCell->iOvfl<pCell->nOvfl-1 ){
@@ -464,7 +484,7 @@ statNextRestart:
}
pCell->iOvfl++;
statSizeAndOffset(pCsr);
- return SQLITE_OK;
+ return z==0 ? SQLITE_NOMEM : SQLITE_OK;
}
if( p->iRightChildPg ) break;
p->iCell++;
@@ -486,8 +506,9 @@ statNextRestart:
}
rc = sqlite3PagerGet(pPager, p[1].iPgno, &p[1].pPg);
p[1].iCell = 0;
- p[1].zPath = sqlite3_mprintf("%s%.3x/", p->zPath, p->iCell);
+ p[1].zPath = z = sqlite3_mprintf("%s%.3x/", p->zPath, p->iCell);
p->iCell++;
+ if( z==0 ) rc = SQLITE_NOMEM;
}
@@ -520,7 +541,8 @@ statNextRestart:
pCsr->nCell = p->nCell;
pCsr->nUnused = p->nUnused;
pCsr->nMxPayload = p->nMxPayload;
- pCsr->zPath = sqlite3_mprintf("%s", p->zPath);
+ pCsr->zPath = z = sqlite3_mprintf("%s", p->zPath);
+ if( z==0 ) rc = SQLITE_NOMEM;
nPayload = 0;
for(i=0; i<p->nCell; i++){
nPayload += p->aCell[i].nLocal;
@@ -556,7 +578,7 @@ static int statColumn(
StatCursor *pCsr = (StatCursor *)pCursor;
switch( i ){
case 0: /* name */
- sqlite3_result_text(ctx, pCsr->zName, -1, SQLITE_STATIC);
+ sqlite3_result_text(ctx, pCsr->zName, -1, SQLITE_TRANSIENT);
break;
case 1: /* path */
sqlite3_result_text(ctx, pCsr->zPath, -1, SQLITE_TRANSIENT);
@@ -582,7 +604,8 @@ static int statColumn(
case 8: /* pgoffset */
sqlite3_result_int64(ctx, pCsr->iOffset);
break;
- case 9: /* pgsize */
+ default: /* pgsize */
+ assert( i==9 );
sqlite3_result_int(ctx, pCsr->szPage);
break;
}
@@ -598,7 +621,7 @@ static int statRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
/*
** Invoke this routine to register the "dbstat" virtual table module
*/
-int sqlite3_dbstat_register(sqlite3 *db){
+int sqlite3DbstatRegister(sqlite3 *db){
static sqlite3_module dbstat_module = {
0, /* iVersion */
statConnect, /* xCreate */
diff --git a/src/main.c b/src/main.c
index cc819c3fa..83d0b9913 100644
--- a/src/main.c
+++ b/src/main.c
@@ -2878,8 +2878,7 @@ static int openDatabase(
#ifdef SQLITE_ENABLE_DBSTAT_VTAB
if( !db->mallocFailed && rc==SQLITE_OK){
- int sqlite3_dbstat_register(sqlite3*);
- rc = sqlite3_dbstat_register(db);
+ rc = sqlite3DbstatRegister(db);
}
#endif
diff --git a/src/malloc.c b/src/malloc.c
index f06e27d84..70b834579 100644
--- a/src/malloc.c
+++ b/src/malloc.c
@@ -226,10 +226,8 @@ void sqlite3MallocEnd(void){
** Return the amount of memory currently checked out.
*/
sqlite3_int64 sqlite3_memory_used(void){
- int n, mx;
- sqlite3_int64 res;
- sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, 0);
- res = (sqlite3_int64)n; /* Work around bug in Borland C. Ticket #3216 */
+ sqlite3_int64 res, mx;
+ sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &res, &mx, 0);
return res;
}
@@ -239,11 +237,9 @@ sqlite3_int64 sqlite3_memory_used(void){
** or since the most recent reset.
*/
sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
- int n, mx;
- sqlite3_int64 res;
- sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, resetFlag);
- res = (sqlite3_int64)mx; /* Work around bug in Borland C. Ticket #3216 */
- return res;
+ sqlite3_int64 res, mx;
+ sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &res, &mx, resetFlag);
+ return mx;
}
/*
diff --git a/src/resolve.c b/src/resolve.c
index b75db42ef..23636eace 100644
--- a/src/resolve.c
+++ b/src/resolve.c
@@ -99,7 +99,6 @@ static void resolveAlias(
assert( iCol>=0 && iCol<pEList->nExpr );
pOrig = pEList->a[iCol].pExpr;
assert( pOrig!=0 );
- assert( (pOrig->flags & EP_Resolved)!=0 || zType[0]==0 );
db = pParse->db;
pDup = sqlite3ExprDup(db, pOrig, 0);
if( pDup==0 ) return;
diff --git a/src/shell.c b/src/shell.c
index 542381a8c..7db8dbda0 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -3258,7 +3258,8 @@ static int do_meta_command(char *zLine, ShellState *p){
goto meta_command_exit;
}
if( nArg==3 ){
- sqlite3_limit(p->db, aLimit[iLimit].limitCode, integerValue(azArg[2]));
+ sqlite3_limit(p->db, aLimit[iLimit].limitCode,
+ (int)integerValue(azArg[2]));
}
printf("%20s %d\n", aLimit[iLimit].zLimitName,
sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 7b9542a96..d809245a6 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -3867,4 +3867,8 @@ int sqlite3ThreadCreate(SQLiteThread**,void*(*)(void*),void*);
int sqlite3ThreadJoin(SQLiteThread*, void**);
#endif
+#if defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)
+int sqlite3DbstatRegister(sqlite3*);
+#endif
+
#endif /* _SQLITEINT_H_ */
diff --git a/src/tclsqlite.c b/src/tclsqlite.c
index 3e9c98664..b44f5b8fa 100644
--- a/src/tclsqlite.c
+++ b/src/tclsqlite.c
@@ -3706,43 +3706,6 @@ static int db_last_stmt_ptr(
}
#endif /* SQLITE_TEST */
-#if defined(SQLITE_TEST) || defined(SQLITE_ENABLE_DBSTAT_VTAB)
-/*
-** tclcmd: register_dbstat_vtab DB
-**
-** Cause the dbstat virtual table to be available on the connection DB
-*/
-static int sqlite3RegisterDbstatCmd(
- void *clientData,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
-){
-#ifdef SQLITE_OMIT_VIRTUALTABLE
- Tcl_AppendResult(interp, "dbstat not available because of "
- "SQLITE_OMIT_VIRTUALTABLE", (void*)0);
- return TCL_ERROR;
-#else
- struct SqliteDb { sqlite3 *db; };
- char *zDb;
- Tcl_CmdInfo cmdInfo;
-
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "DB");
- return TCL_ERROR;
- }
-
- zDb = Tcl_GetString(objv[1]);
- if( Tcl_GetCommandInfo(interp, zDb, &cmdInfo) ){
- int sqlite3_dbstat_register(sqlite3*);
- sqlite3* db = ((struct SqliteDb*)cmdInfo.objClientData)->db;
- sqlite3_dbstat_register(db);
- }
- return TCL_OK;
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-}
-#endif /* defined(SQLITE_TEST) || defined(SQLITE_ENABLE_DBSTAT_VTAB) */
-
/*
** Configure the interpreter passed as the first argument to have access
** to the commands and linked variables that make up:
@@ -3761,16 +3724,6 @@ static void init_all(Tcl_Interp *interp){
Md5_Init(interp);
#endif
- /* Install the [register_dbstat_vtab] command to access the implementation
- ** of virtual table dbstat (source file test_stat.c). This command is
- ** required for testfixture and sqlite3_analyzer, but not by the production
- ** Tcl extension. */
-#if defined(SQLITE_TEST) || defined(SQLITE_ENABLE_DBSTAT_VTAB)
- Tcl_CreateObjCommand(
- interp, "register_dbstat_vtab", sqlite3RegisterDbstatCmd, 0, 0
- );
-#endif
-
#ifdef SQLITE_TEST
{
extern int Sqliteconfig_Init(Tcl_Interp*);
diff --git a/src/test1.c b/src/test1.c
index a87fcd859..732ad9e04 100644
--- a/src/test1.c
+++ b/src/test1.c
@@ -6680,7 +6680,40 @@ static int test_bad_behavior(
}
return TCL_OK;
}
-
+
+/*
+** tclcmd: register_dbstat_vtab DB
+**
+** Cause the dbstat virtual table to be available on the connection DB
+*/
+static int test_register_dbstat_vtab(
+ void *clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *CONST objv[]
+){
+#ifdef SQLITE_OMIT_VIRTUALTABLE
+ Tcl_AppendResult(interp, "dbstat not available because of "
+ "SQLITE_OMIT_VIRTUALTABLE", (void*)0);
+ return TCL_ERROR;
+#else
+ struct SqliteDb { sqlite3 *db; };
+ char *zDb;
+ Tcl_CmdInfo cmdInfo;
+
+ if( objc!=2 ){
+ Tcl_WrongNumArgs(interp, 1, objv, "DB");
+ return TCL_ERROR;
+ }
+
+ zDb = Tcl_GetString(objv[1]);
+ if( Tcl_GetCommandInfo(interp, zDb, &cmdInfo) ){
+ sqlite3* db = ((struct SqliteDb*)cmdInfo.objClientData)->db;
+ sqlite3DbstatRegister(db);
+ }
+ return TCL_OK;
+#endif /* SQLITE_OMIT_VIRTUALTABLE */
+}
/*
** Register commands with the TCL interpreter.
@@ -6752,6 +6785,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
void *clientData;
} aObjCmd[] = {
{ "bad_behavior", test_bad_behavior, (void*)&iZero },
+ { "register_dbstat_vtab", test_register_dbstat_vtab },
{ "sqlite3_connection_pointer", get_sqlite_pointer, 0 },
{ "sqlite3_bind_int", test_bind_int, 0 },
{ "sqlite3_bind_zeroblob", test_bind_zeroblob, 0 },