📄 vdbe.c
字号:
sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC); if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem; if( SQLITE_OK!=sqlite3VdbeMemDynamicify(pOut) ) goto no_mem; pOut->flags &= ~(MEM_Dyn); pOut->flags |= MEM_Static; if( pOp->p4type==P4_DYNAMIC ){ sqlite3_free(pOp->p4.z); } pOp->p4type = P4_DYNAMIC; pOp->p4.z = pOut->z; pOp->p1 = pOut->n; if( pOp->p1>SQLITE_MAX_LENGTH ){ goto too_big; } UPDATE_MAX_BLOBSIZE(pOut); break; }#endif if( pOp->p1>SQLITE_MAX_LENGTH ){ goto too_big; } /* Fall through to the next case, OP_String */} /* Opcode: String P1 P2 * P4 ***** The string value P4 of length P1 (bytes) is stored in register P2.*/case OP_String: { /* out2-prerelease */ assert( pOp->p4.z!=0 ); pOut->flags = MEM_Str|MEM_Static|MEM_Term; pOut->z = pOp->p4.z; pOut->n = pOp->p1; pOut->enc = encoding; UPDATE_MAX_BLOBSIZE(pOut); break;}/* Opcode: Null * P2 * * ***** Write a NULL into register P2.*/case OP_Null: { /* out2-prerelease */ break;}#ifndef SQLITE_OMIT_BLOB_LITERAL/* Opcode: Blob P1 P2 * P4**** P4 points to a blob of data P1 bytes long. Store this** blob in register P2. This instruction is not coded directly** by the compiler. Instead, the compiler layer specifies** an OP_HexBlob opcode, with the hex string representation of** the blob as P4. This opcode is transformed to an OP_Blob** the first time it is executed.*/case OP_Blob: { /* out2-prerelease */ assert( pOp->p1 <= SQLITE_MAX_LENGTH ); sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0); pOut->enc = encoding; UPDATE_MAX_BLOBSIZE(pOut); break;}#endif /* SQLITE_OMIT_BLOB_LITERAL *//* Opcode: Variable P1 P2 * * ***** The value of variable P1 is written into register P2. A variable is** an unknown in the original SQL string as handed to sqlite3_compile().** Any occurance of the '?' character in the original SQL is considered** a variable. Variables in the SQL string are number from left to** right beginning with 1. The values of variables are set using the** sqlite3_bind() API.*/case OP_Variable: { /* out2-prerelease */ int j = pOp->p1 - 1; Mem *pVar; assert( j>=0 && j<p->nVar ); pVar = &p->aVar[j]; if( sqlite3VdbeMemTooBig(pVar) ){ goto too_big; } sqlite3VdbeMemShallowCopy(pOut, &p->aVar[j], MEM_Static); UPDATE_MAX_BLOBSIZE(pOut); break;}/* Opcode: Move P1 P2 * * ***** Move the value in register P1 over into register P2. Register P1** is left holding a NULL. It is an error for P1 and P2 to be the** same register.*//* Opcode: Copy P1 P2 * * ***** Make a copy of register P1 into register P2.**** This instruction makes a deep copy of the value. A duplicate** is made of any string or blob constant. See also OP_SCopy.*//* Opcode: SCopy P1 P2 * * ***** Make a shallow copy of register P1 into register P2.**** This instruction makes a shallow copy of the value. If the value** is a string or blob, then the copy is only a pointer to the** original and hence if the original changes so will the copy.** Worse, if the original is deallocated, the copy becomes invalid.** Thus the program must guarantee that the original will not change** during the lifetime of the copy. Use OP_Copy to make a complete** copy.*/case OP_Move:case OP_Copy:case OP_SCopy: { assert( pOp->p1>0 ); assert( pOp->p1<=p->nMem ); pIn1 = &p->aMem[pOp->p1]; REGISTER_TRACE(pOp->p1, pIn1); assert( pOp->p2>0 ); assert( pOp->p2<=p->nMem ); pOut = &p->aMem[pOp->p2]; assert( pOut!=pIn1 ); if( pOp->opcode==OP_Move ){ sqlite3VdbeMemMove(pOut, pIn1); }else{ sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); if( pOp->opcode==OP_Copy ){ Deephemeralize(pOut); } } REGISTER_TRACE(pOp->p2, pOut); break;}/* Opcode: ResultRow P1 P2 * * ***** The registers P1 throught P1+P2-1 contain a single row of** results. This opcode causes the sqlite3_step() call to terminate** with an SQLITE_ROW return code and it sets up the sqlite3_stmt** structure to provide access to the top P1 values as the result** row.*/case OP_ResultRow: { Mem *pMem; int i; assert( p->nResColumn==pOp->p2 ); assert( pOp->p1>0 ); assert( pOp->p1+pOp->p2<=p->nMem ); /* Invalidate all ephemeral cursor row caches */ p->cacheCtr = (p->cacheCtr + 2)|1; /* Make sure the results of the current row are \000 terminated ** and have an assigned type. The results are deephemeralized as ** as side effect. */ pMem = p->pResultSet = &p->aMem[pOp->p1]; for(i=0; i<pOp->p2; i++){ sqlite3VdbeMemNulTerminate(&pMem[i]); storeTypeInfo(&pMem[i], encoding); } /* Return SQLITE_ROW */ p->nCallback++; p->pc = pc + 1; rc = SQLITE_ROW; goto vdbe_return;}/* Opcode: Concat P1 P2 P3 * ***** Add the text in register P1 onto the end of the text in** register P2 and store the result in register P3.** If either the P1 or P2 text are NULL then store NULL in P3.*/case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */ char *zNew; i64 nByte; if( (pIn1->flags | pIn2->flags) & MEM_Null ){ Release(pOut); pOut->flags = MEM_Null; break; } ExpandBlob(pIn1); Stringify(pIn1, encoding); ExpandBlob(pIn2); Stringify(pIn2, encoding); nByte = pIn1->n + pIn2->n; if( nByte>SQLITE_MAX_LENGTH ){ goto too_big; } zNew = sqlite3DbMallocRaw(db, nByte+2); if( zNew==0 ){ goto no_mem; } memcpy(zNew, pIn2->z, pIn2->n); memcpy(&zNew[pIn2->n], pIn1->z, pIn1->n); zNew[nByte] = 0; zNew[nByte+1] = 0; Release(pOut); pOut->n = nByte; pOut->flags = MEM_Str|MEM_Dyn|MEM_Term; pOut->xDel = 0; pOut->enc = encoding; pOut->z = zNew; UPDATE_MAX_BLOBSIZE(pOut); break;}/* Opcode: Add P1 P2 P3 * ***** Add the value in register P1 to the value in register P2** and store the result in regiser P3.** If either input is NULL, the result is NULL.*//* Opcode: Multiply P1 P2 P3 * ******* Multiply the value in regiser P1 by the value in regiser P2** and store the result in register P3.** If either input is NULL, the result is NULL.*//* Opcode: Subtract P1 P2 P3 * ***** Subtract the value in register P1 from the value in register P2** and store the result in register P3.** If either input is NULL, the result is NULL.*//* Opcode: Divide P1 P2 P3 * ***** Divide the value in register P1 by the value in register P2** and store the result in register P3. If the value in register P2** is zero, then the result is NULL.** If either input is NULL, the result is NULL.*//* Opcode: Remainder P1 P2 P3 * ***** Compute the remainder after integer division of the value in** register P1 by the value in register P2 and store the result in P3. ** If the value in register P2 is zero the result is NULL.** If either operand is NULL, the result is NULL.*/case OP_Add: /* same as TK_PLUS, in1, in2, out3 */case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ int flags; flags = pIn1->flags | pIn2->flags; if( (flags & MEM_Null)!=0 ) goto arithmetic_result_is_null; if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){ i64 a, b; a = pIn1->u.i; b = pIn2->u.i; switch( pOp->opcode ){ case OP_Add: b += a; break; case OP_Subtract: b -= a; break; case OP_Multiply: b *= a; break; case OP_Divide: { if( a==0 ) goto arithmetic_result_is_null; /* Dividing the largest possible negative 64-bit integer (1<<63) by ** -1 returns an integer to large to store in a 64-bit data-type. On ** some architectures, the value overflows to (1<<63). On others, ** a SIGFPE is issued. The following statement normalizes this ** behaviour so that all architectures behave as if integer ** overflow occured. */ if( a==-1 && b==(((i64)1)<<63) ) a = 1; b /= a; break; } default: { if( a==0 ) goto arithmetic_result_is_null; if( a==-1 ) a = 1; b %= a; break; } } Release(pOut); pOut->u.i = b; pOut->flags = MEM_Int; }else{ double a, b; a = sqlite3VdbeRealValue(pIn1); b = sqlite3VdbeRealValue(pIn2); switch( pOp->opcode ){ case OP_Add: b += a; break; case OP_Subtract: b -= a; break; case OP_Multiply: b *= a; break; case OP_Divide: { if( a==0.0 ) goto arithmetic_result_is_null; b /= a; break; } default: { i64 ia = (i64)a; i64 ib = (i64)b; if( ia==0 ) goto arithmetic_result_is_null; if( ia==-1 ) ia = 1; b = ib % ia; break; } } if( sqlite3_isnan(b) ){ goto arithmetic_result_is_null; } Release(pOut); pOut->r = b; pOut->flags = MEM_Real; if( (flags & MEM_Real)==0 ){ sqlite3VdbeIntegerAffinity(pOut); } } break;arithmetic_result_is_null: sqlite3VdbeMemSetNull(pOut); break;}/* Opcode: CollSeq * * P4**** P4 is a pointer to a CollSeq struct. If the next call to a user function** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will** be returned. This is used by the built-in min(), max() and nullif()** functions.**** The interface used by the implementation of the aforementioned functions** to retrieve the collation sequence set by this opcode is not available** publicly, only to user functions defined in func.c.*/case OP_CollSeq: { assert( pOp->p4type==P4_COLLSEQ ); break;}/* Opcode: Function P1 P2 P3 P4 P5**** Invoke a user function (P4 is a pointer to a Function structure that** defines the function) with P5 arguments taken from register P2 and** successors. The result of the function is stored in register P3.**** 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: AggStep and AggFinal*/case OP_Function: { int i; Mem *pArg; sqlite3_context ctx; sqlite3_value **apVal; int n = pOp->p5; apVal = p->apArg; assert( apVal || n==0 ); assert( n==0 || (pOp->p2>0 && pOp->p2+n<=p->nMem) ); pArg = &p->aMem[pOp->p2]; for(i=0; i<n; i++, pArg++){ apVal[i] = pArg; storeTypeInfo(pArg, encoding); REGISTER_TRACE(pOp->p2, pArg); } assert( pOp->p4type==P4_FUNCDEF || pOp->p4type==P4_VDBEFUNC ); if( pOp->p4type==P4_FUNCDEF ){ ctx.pFunc = pOp->p4.pFunc; ctx.pVdbeFunc = 0; }else{ ctx.pVdbeFunc = (VdbeFunc*)pOp->p4.pVdbeFunc; ctx.pFunc = ctx.pVdbeFunc->pFunc; } ctx.s.flags = MEM_Null; ctx.s.z = 0; ctx.s.xDel = 0; ctx.s.db = db; ctx.isError = 0; if( ctx.pFunc->needCollSeq ){ assert( pOp>p->aOp ); assert( pOp[-1].p4type==P4_COLLSEQ ); assert( pOp[-1].opcode==OP_CollSeq ); ctx.pColl = pOp[-1].p4.pColl; } if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; (*ctx.pFunc->xFunc)(&ctx, n, apVal); if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; if( db->mallocFailed ){ /* Even though a malloc() has failed, the implementation of the ** user function may have called an sqlite3_result_XXX() function ** to return a value. The following call releases any resources ** associated with such a value. ** ** Note: Maybe MemRelease() should be called if sqlite3SafetyOn() ** fails also (the if(...) statement above). But if people are ** misusing sqlite, they have bigger problems than a leaked value. */ sqlite3VdbeMemRelease(&ctx.s); goto no_mem; } /* If any auxilary data functions have been called by this user function,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -