mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-10 01:02:56 +03:00
Fix the OP_OpenEphemeral opcode in the bytecode engine so that if it is called
a second or subsequent time, it merely clears the existing table rather than creating a new one. Proposed fix for ticket [d0866b26f83e9c55e30de0821f5d]. FossilOrigin-Name: 4678cb1044f0b4dc813e48f3bd0f85240a66e2ecf8763280d66726cc031c93a7
This commit is contained in:
20
src/vdbe.c
20
src/vdbe.c
@@ -3628,6 +3628,9 @@ case OP_OpenDup: {
|
||||
** the main database is read-only. The ephemeral
|
||||
** table is deleted automatically when the cursor is closed.
|
||||
**
|
||||
** If the cursor P1 is already opened on an ephermal table, the table
|
||||
** is cleared (all content is erased).
|
||||
**
|
||||
** P2 is the number of columns in the ephemeral table.
|
||||
** The cursor points to a BTree table if P4==0 and to a BTree index
|
||||
** if P4 is not 0. If P4 is not NULL, it points to a KeyInfo structure
|
||||
@@ -3659,6 +3662,14 @@ case OP_OpenEphemeral: {
|
||||
SQLITE_OPEN_TRANSIENT_DB;
|
||||
assert( pOp->p1>=0 );
|
||||
assert( pOp->p2>=0 );
|
||||
pCx = p->apCsr[pOp->p1];
|
||||
if( pCx ){
|
||||
/* If the ephermeral table is already open, erase all existing content
|
||||
** so that the table is empty again, rather than creating a new table. */
|
||||
rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0);
|
||||
if( rc ) goto abort_due_to_error;
|
||||
break;
|
||||
}
|
||||
pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE);
|
||||
if( pCx==0 ) goto no_mem;
|
||||
pCx->nullRow = 1;
|
||||
@@ -3675,18 +3686,19 @@ case OP_OpenEphemeral: {
|
||||
** automatically created table with root-page 1 (an BLOB_INTKEY table).
|
||||
*/
|
||||
if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){
|
||||
int pgno;
|
||||
assert( pOp->p4type==P4_KEYINFO );
|
||||
rc = sqlite3BtreeCreateTable(pCx->pBtx, &pgno, BTREE_BLOBKEY | pOp->p5);
|
||||
rc = sqlite3BtreeCreateTable(pCx->pBtx, (int*)&pCx->pgnoRoot,
|
||||
BTREE_BLOBKEY | pOp->p5);
|
||||
if( rc==SQLITE_OK ){
|
||||
assert( pgno==MASTER_ROOT+1 );
|
||||
assert( pCx->pgnoRoot==MASTER_ROOT+1 );
|
||||
assert( pKeyInfo->db==db );
|
||||
assert( pKeyInfo->enc==ENC(db) );
|
||||
rc = sqlite3BtreeCursor(pCx->pBtx, pgno, BTREE_WRCSR,
|
||||
rc = sqlite3BtreeCursor(pCx->pBtx, pCx->pgnoRoot, BTREE_WRCSR,
|
||||
pKeyInfo, pCx->uc.pCursor);
|
||||
}
|
||||
pCx->isTable = 0;
|
||||
}else{
|
||||
pCx->pgnoRoot = MASTER_ROOT;
|
||||
rc = sqlite3BtreeCursor(pCx->pBtx, MASTER_ROOT, BTREE_WRCSR,
|
||||
0, pCx->uc.pCursor);
|
||||
pCx->isTable = 1;
|
||||
|
Reference in New Issue
Block a user