mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Modify the OP_RowData opcode so that when P3!=0 it is allowed to hold an
ephemeral copy of the content. This avoids unnecessary memcpy() operations in the xfer-optimization and VACUUM. FossilOrigin-Name: 6e106acd74da3baa5c308a76443d2f0a7c904e5e
This commit is contained in:
27
src/vdbe.c
27
src/vdbe.c
@@ -4632,7 +4632,7 @@ case OP_SorterData: {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: RowData P1 P2 * * *
|
||||
/* Opcode: RowData P1 P2 P3 * *
|
||||
** Synopsis: r[P2]=data
|
||||
**
|
||||
** Write into register P2 the complete row content for the row at
|
||||
@@ -4646,14 +4646,26 @@ case OP_SorterData: {
|
||||
**
|
||||
** If the P1 cursor must be pointing to a valid row (not a NULL row)
|
||||
** of a real table, not a pseudo-table.
|
||||
**
|
||||
** If P3!=0 then this opcode is allowed to make an ephermeral pointer
|
||||
** into the database page. That means that the content of the output
|
||||
** register will be invalidated as soon as the cursor moves - including
|
||||
** moves caused by other cursors that "save" the the current cursors
|
||||
** position in order that they can write to the same table. If P3==0
|
||||
** then a copy of the data is made into memory. P3!=0 is faster, but
|
||||
** P3==0 is safer.
|
||||
**
|
||||
** If P3!=0 then the content of the P2 register is unsuitable for use
|
||||
** in OP_Result and any OP_Result will invalidate the P2 register content.
|
||||
** The P2 register content is invalided by opcodes like OP_Function or
|
||||
** by any use of another cursor pointing to the same table.
|
||||
*/
|
||||
case OP_RowData: {
|
||||
VdbeCursor *pC;
|
||||
BtCursor *pCrsr;
|
||||
u32 n;
|
||||
|
||||
pOut = &aMem[pOp->p2];
|
||||
memAboutToChange(p, pOut);
|
||||
pOut = out2Prerelease(p, pOp);
|
||||
|
||||
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
||||
pC = p->apCsr[pOp->p1];
|
||||
@@ -4684,14 +4696,9 @@ case OP_RowData: {
|
||||
goto too_big;
|
||||
}
|
||||
testcase( n==0 );
|
||||
if( sqlite3VdbeMemClearAndResize(pOut, MAX(n,32)) ){
|
||||
goto no_mem;
|
||||
}
|
||||
pOut->n = n;
|
||||
MemSetTypeFlag(pOut, MEM_Blob);
|
||||
rc = sqlite3BtreePayload(pCrsr, 0, n, pOut->z);
|
||||
rc = sqlite3VdbeMemFromBtree(pCrsr, 0, n, pOut);
|
||||
if( rc ) goto abort_due_to_error;
|
||||
pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */
|
||||
if( !pOp->p3 ) Deephemeralize(pOut);
|
||||
UPDATE_MAX_BLOBSIZE(pOut);
|
||||
REGISTER_TRACE(pOp->p2, pOut);
|
||||
break;
|
||||
|
Reference in New Issue
Block a user