aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2018-12-31 16:36:42 +0000
committerdrh <drh@noemail.net>2018-12-31 16:36:42 +0000
commit4afdfa195b0ae5fe3b8638c722c937792d3cfd0c (patch)
tree10a99fe9b774a31410da9ad96939cb7958acde0d /src
parentd1d158bf5abbab97ee65462c7ee391693ce7ffd7 (diff)
downloadsqlite-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.c20
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;