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

Handle recovery of virtual tables by recovering each shadow table individually, then writing the CREATE VIRTUAL TABLE statement directly into the sqlite_schema table.

FossilOrigin-Name: 5f2d5ccd56c06c3468377126acfd4be39b79b05bb6fb09b674b2e185df143aa3
This commit is contained in:
dan
2022-09-09 16:25:19 +00:00
parent 46d4398440
commit 7920162093
6 changed files with 54 additions and 18 deletions

View File

@ -672,9 +672,17 @@ static int recoverWriteSchema1(sqlite3_recover *p){
sqlite3_stmt *pTblname = 0;
pSelect = recoverPrepare(p, p->dbOut,
"SELECT rootpage, sql, type='table' FROM recovery.schema "
" WHERE type='table' OR (type='index' AND sql LIKE '%unique%') "
" ORDER BY type!='table', name!='sqlite_sequence'"
"WITH dbschema(rootpage, name, sql, tbl, isVirtual, isUnique) AS ("
" SELECT rootpage, name, sql, "
" type='table', "
" sql LIKE 'create virtual%',"
" (type='index' AND sql LIKE '%unique%')"
" FROM recovery.schema"
")"
"SELECT rootpage, tbl, isVirtual, name, sql"
" FROM dbschema "
" WHERE tbl OR isUnique"
" ORDER BY tbl DESC, name=='sqlite_sequence' DESC"
);
pTblname = recoverPrepare(p, p->dbOut,
@ -685,13 +693,23 @@ static int recoverWriteSchema1(sqlite3_recover *p){
if( pSelect ){
while( sqlite3_step(pSelect)==SQLITE_ROW ){
i64 iRoot = sqlite3_column_int64(pSelect, 0);
const char *zSql = (const char*)sqlite3_column_text(pSelect, 1);
int bTable = sqlite3_column_int(pSelect, 2);
int bTable = sqlite3_column_int(pSelect, 1);
int bVirtual = sqlite3_column_int(pSelect, 2);
const char *zName = (const char*)sqlite3_column_text(pSelect, 3);
const char *zSql = (const char*)sqlite3_column_text(pSelect, 4);
char *zFree = 0;
int rc = SQLITE_OK;
int rc = sqlite3_exec(p->dbOut, zSql, 0, 0, 0);
if( bVirtual ){
zSql = (const char*)(zFree = recoverMPrintf(p,
"INSERT INTO sqlite_schema VALUES('table', %Q, %Q, 0, %Q)",
zName, zName, zSql
));
}
rc = sqlite3_exec(p->dbOut, zSql, 0, 0, 0);
if( rc==SQLITE_OK ){
recoverSqlCallback(p, zSql);
if( bTable ){
if( bTable && !bVirtual ){
if( SQLITE_ROW==sqlite3_step(pTblname) ){
const char *zName = sqlite3_column_text(pTblname, 0);
recoverAddTable(p, zName, iRoot);
@ -701,6 +719,7 @@ static int recoverWriteSchema1(sqlite3_recover *p){
}else if( rc!=SQLITE_ERROR ){
recoverDbError(p, p->dbOut);
}
sqlite3_free(zFree);
}
}
recoverFinalize(p, pSelect);
@ -1130,7 +1149,8 @@ static int recoverWriteData(sqlite3_recover *p){
if( apVal==0 ) return p->errCode;
pTbls = recoverPrepare(p, p->dbOut,
"SELECT rootpage FROM recovery.schema WHERE type='table'"
"SELECT rootpage FROM recovery.schema "
" WHERE type='table' AND (sql NOT LIKE 'create virtual%')"
" ORDER BY (tbl_name='sqlite_sequence') ASC"
);