1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

Simplify the bytecode generation for SQL function calls such that the

OP_Function or OP_PureFunc opcodes are coded directly, rather than using
the intermediate OP_Function0 or OP_PureFunc0 - opcodes that are now removed.

FossilOrigin-Name: 84e02d773d60cffe619104991d21d7f0c68616c0f6bb99686bf54f5306c756d0
This commit is contained in:
drh
2019-10-30 16:29:02 +00:00
parent 9ee94147f0
commit 920cf596e6
8 changed files with 121 additions and 95 deletions

View File

@@ -7442,29 +7442,14 @@ case OP_MaxPgcnt: { /* out2 */
}
#endif
/* Opcode: Function0 P1 P2 P3 P4 P5
** Synopsis: r[P3]=func(r[P2@P5])
**
** Invoke a user function (P4 is a pointer to a FuncDef object that
** defines the function) with P5 arguments taken from register P2 and
** successors. The result of the function is stored in register P3.
** Register P3 must not be one of the function inputs.
**
** P1 is a 32-bit bitmask indicating whether or not each argument to the
** function was determined to be constant at compile time. If the first
** argument was constant then bit 0 of P1 is set. This is used to determine
** whether meta data associated with a user function argument using the
** sqlite3_set_auxdata() API may be safely retained until the next
** invocation of this opcode.
**
** See also: Function, AggStep, AggFinal
*/
/* Opcode: Function P1 P2 P3 P4 P5
/* Opcode: Function P1 P2 P3 P4 *
** Synopsis: r[P3]=func(r[P2@P5])
**
** Invoke a user function (P4 is a pointer to an sqlite3_context object that
** contains a pointer to the function to be run) with P5 arguments taken
** from register P2 and successors. The result of the function is stored
** contains a pointer to the function to be run) with arguments taken
** from register P2 and successors. The number of arguments is in
** the sqlite3_context object that P4 points to.
** The result of the function is stored
** in register P3. Register P3 must not be one of the function inputs.
**
** P1 is a 32-bit bitmask indicating whether or not each argument to the
@@ -7474,40 +7459,35 @@ case OP_MaxPgcnt: { /* out2 */
** sqlite3_set_auxdata() API may be safely retained until the next
** invocation of this opcode.
**
** SQL functions are initially coded as OP_Function0 with P4 pointing
** to a FuncDef object. But on first evaluation, the P4 operand is
** automatically converted into an sqlite3_context object and the operation
** changed to this OP_Function opcode. In this way, the initialization of
** the sqlite3_context object occurs only once, rather than once for each
** evaluation of the function.
**
** See also: Function0, AggStep, AggFinal
** See also: AggStep, AggFinal, PureFunc
*/
/* Opcode: PureFunc P1 P2 P3 P4 *
** Synopsis: r[P3]=func(r[P2@P5])
**
** Invoke a user function (P4 is a pointer to an sqlite3_context object that
** contains a pointer to the function to be run) with arguments taken
** from register P2 and successors. The number of arguments is in
** the sqlite3_context object that P4 points to.
** The result of the function is stored
** in register P3. Register P3 must not be one of the function inputs.
**
** P1 is a 32-bit bitmask indicating whether or not each argument to the
** function was determined to be constant at compile time. If the first
** argument was constant then bit 0 of P1 is set. This is used to determine
** whether meta data associated with a user function argument using the
** sqlite3_set_auxdata() API may be safely retained until the next
** invocation of this opcode.
**
** This opcode works exactly like OP_Function. The only difference is in
** its name. This opcode is used in places where the function must be
** purely non-deterministic. Some built-in date/time functions can be
** either determinitic of non-deterministic, depending on their arguments.
** When those function are used in a non-deterministic way, they will check
** to see if they were called using OP_PureFunc instead of OP_Function, and
** if they were, they throw an error.
**
** See also: AggStep, AggFinal, Function
*/
case OP_PureFunc0: /* group */
case OP_Function0: { /* group */
int n;
sqlite3_context *pCtx;
assert( pOp->p4type==P4_FUNCDEF );
n = pOp->p5;
assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) );
assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*));
if( pCtx==0 ) goto no_mem;
pCtx->pOut = 0;
pCtx->pFunc = pOp->p4.pFunc;
pCtx->iOp = (int)(pOp - aOp);
pCtx->pVdbe = p;
pCtx->isError = 0;
pCtx->argc = n;
pOp->p4type = P4_FUNCCTX;
pOp->p4.pCtx = pCtx;
assert( OP_PureFunc == OP_PureFunc0+2 );
assert( OP_Function == OP_Function0+2 );
pOp->opcode += 2;
/* Fall through into OP_Function */
}
case OP_PureFunc: /* group */
case OP_Function: { /* group */
int i;
@@ -7522,9 +7502,11 @@ case OP_Function: { /* group */
** reinitializes the relavant parts of the sqlite3_context object */
pOut = &aMem[pOp->p3];
if( pCtx->pOut != pOut ){
pCtx->pVdbe = p;
pCtx->pOut = pOut;
for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i];
}
assert( pCtx->pVdbe==p );
memAboutToChange(p, pOut);
#ifdef SQLITE_DEBUG