mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Work toward making the schema parsing logic simplier and more compact.
FossilOrigin-Name: c52ca2c0662bb30ab34574f933429512655b19ff
This commit is contained in:
119
src/btree.c
119
src/btree.c
@@ -8541,6 +8541,14 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){
|
||||
return SQLITE_LOCKED_SHAREDCACHE;
|
||||
}
|
||||
|
||||
/*
|
||||
** It is illegal to drop the sqlite_master table on page 1. But again,
|
||||
** this error is caught long before reaching this point.
|
||||
*/
|
||||
if( NEVER(iTable<2) ){
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
|
||||
rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0);
|
||||
if( rc ) return rc;
|
||||
rc = sqlite3BtreeClearTable(p, iTable, 0);
|
||||
@@ -8551,76 +8559,67 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){
|
||||
|
||||
*piMoved = 0;
|
||||
|
||||
if( iTable>1 ){
|
||||
#ifdef SQLITE_OMIT_AUTOVACUUM
|
||||
freePage(pPage, &rc);
|
||||
releasePage(pPage);
|
||||
freePage(pPage, &rc);
|
||||
releasePage(pPage);
|
||||
#else
|
||||
if( pBt->autoVacuum ){
|
||||
Pgno maxRootPgno;
|
||||
sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &maxRootPgno);
|
||||
if( pBt->autoVacuum ){
|
||||
Pgno maxRootPgno;
|
||||
sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &maxRootPgno);
|
||||
|
||||
if( iTable==maxRootPgno ){
|
||||
/* If the table being dropped is the table with the largest root-page
|
||||
** number in the database, put the root page on the free list.
|
||||
*/
|
||||
freePage(pPage, &rc);
|
||||
releasePage(pPage);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
}else{
|
||||
/* The table being dropped does not have the largest root-page
|
||||
** number in the database. So move the page that does into the
|
||||
** gap left by the deleted root-page.
|
||||
*/
|
||||
MemPage *pMove;
|
||||
releasePage(pPage);
|
||||
rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable, 0);
|
||||
releasePage(pMove);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
pMove = 0;
|
||||
rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
|
||||
freePage(pMove, &rc);
|
||||
releasePage(pMove);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
*piMoved = maxRootPgno;
|
||||
}
|
||||
|
||||
/* Set the new 'max-root-page' value in the database header. This
|
||||
** is the old value less one, less one more if that happens to
|
||||
** be a root-page number, less one again if that is the
|
||||
** PENDING_BYTE_PAGE.
|
||||
if( iTable==maxRootPgno ){
|
||||
/* If the table being dropped is the table with the largest root-page
|
||||
** number in the database, put the root page on the free list.
|
||||
*/
|
||||
maxRootPgno--;
|
||||
while( maxRootPgno==PENDING_BYTE_PAGE(pBt)
|
||||
|| PTRMAP_ISPAGE(pBt, maxRootPgno) ){
|
||||
maxRootPgno--;
|
||||
}
|
||||
assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) );
|
||||
|
||||
rc = sqlite3BtreeUpdateMeta(p, 4, maxRootPgno);
|
||||
}else{
|
||||
freePage(pPage, &rc);
|
||||
releasePage(pPage);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
}else{
|
||||
/* The table being dropped does not have the largest root-page
|
||||
** number in the database. So move the page that does into the
|
||||
** gap left by the deleted root-page.
|
||||
*/
|
||||
MemPage *pMove;
|
||||
releasePage(pPage);
|
||||
rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable, 0);
|
||||
releasePage(pMove);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
pMove = 0;
|
||||
rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
|
||||
freePage(pMove, &rc);
|
||||
releasePage(pMove);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
*piMoved = maxRootPgno;
|
||||
}
|
||||
#endif
|
||||
}else{
|
||||
/* If sqlite3BtreeDropTable was called on page 1.
|
||||
** This really never should happen except in a corrupt
|
||||
** database.
|
||||
|
||||
/* Set the new 'max-root-page' value in the database header. This
|
||||
** is the old value less one, less one more if that happens to
|
||||
** be a root-page number, less one again if that is the
|
||||
** PENDING_BYTE_PAGE.
|
||||
*/
|
||||
zeroPage(pPage, PTF_INTKEY|PTF_LEAF );
|
||||
maxRootPgno--;
|
||||
while( maxRootPgno==PENDING_BYTE_PAGE(pBt)
|
||||
|| PTRMAP_ISPAGE(pBt, maxRootPgno) ){
|
||||
maxRootPgno--;
|
||||
}
|
||||
assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) );
|
||||
|
||||
rc = sqlite3BtreeUpdateMeta(p, 4, maxRootPgno);
|
||||
}else{
|
||||
freePage(pPage, &rc);
|
||||
releasePage(pPage);
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){
|
||||
|
Reference in New Issue
Block a user