diff options
author | drh <drh@noemail.net> | 2018-12-31 16:36:42 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2018-12-31 16:36:42 +0000 |
commit | 4afdfa195b0ae5fe3b8638c722c937792d3cfd0c (patch) | |
tree | 10a99fe9b774a31410da9ad96939cb7958acde0d /src | |
parent | d1d158bf5abbab97ee65462c7ee391693ce7ffd7 (diff) | |
download | sqlite-4afdfa195b0ae5fe3b8638c722c937792d3cfd0c.tar.gz sqlite-4afdfa195b0ae5fe3b8638c722c937792d3cfd0c.zip |
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
Diffstat (limited to 'src')
-rw-r--r-- | src/vdbe.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/src/vdbe.c b/src/vdbe.c index 26382bcd4..1f4d569ae 100644 --- a/src/vdbe.c +++ b/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; |