📄 vdbe.c
字号:
}else{ rc = p->rc ? SQLITE_ERROR : SQLITE_DONE; } goto vdbe_return;}/* Opcode: Integer P1 P2 * * ***** The 32-bit integer value P1 is written into register P2.*/case OP_Integer: { /* out2-prerelease */ pOut->flags = MEM_Int; pOut->u.i = pOp->p1; break;}/* Opcode: Int64 * P2 * P4 ***** P4 is a pointer to a 64-bit integer value.** Write that value into register P2.*/case OP_Int64: { /* out2-prerelease */ assert( pOp->p4.pI64!=0 ); pOut->flags = MEM_Int; pOut->u.i = *pOp->p4.pI64; break;}/* Opcode: Real * P2 * P4 ***** P4 is a pointer to a 64-bit floating point value.** Write that value into register P2.*/case OP_Real: { /* same as TK_FLOAT, out2-prerelease */ pOut->flags = MEM_Real; assert( !sqlite3IsNaN(*pOp->p4.pReal) ); pOut->r = *pOp->p4.pReal; break;}/* Opcode: String8 * P2 * P4 ***** P4 points to a nul terminated UTF-8 string. This opcode is transformed ** into an OP_String before it is executed for the first time.*/case OP_String8: { /* same as TK_STRING, out2-prerelease */ assert( pOp->p4.z!=0 ); pOp->opcode = OP_String; pOp->p1 = strlen(pOp->p4.z);#ifndef SQLITE_OMIT_UTF16 if( encoding!=SQLITE_UTF8 ){ sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC); if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem; if( SQLITE_OK!=sqlite3VdbeMemMakeWriteable(pOut) ) goto no_mem; pOut->zMalloc = 0; pOut->flags |= MEM_Static; pOut->flags &= ~MEM_Dyn; if( pOp->p4type==P4_DYNAMIC ){ sqlite3DbFree(db, pOp->p4.z); } pOp->p4type = P4_DYNAMIC; pOp->p4.z = pOut->z; pOp->p1 = pOut->n; if( pOp->p1>db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } UPDATE_MAX_BLOBSIZE(pOut); break; }#endif if( pOp->p1>db->aLimit[SQLITE_LIMIT_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 occurrence 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 P3 * ***** Move the values in register P1..P1+P3-1 over into** registers P2..P2+P3-1. Registers P1..P1+P1-1 are** left holding a NULL. It is an error for register ranges** P1..P1+P3-1 and P2..P2+P3-1 to overlap.*/case OP_Move: { char *zMalloc; int n = pOp->p3; int p1 = pOp->p1; int p2 = pOp->p2; assert( n>0 ); assert( p1>0 ); assert( p1+n<p->nMem ); pIn1 = &p->aMem[p1]; assert( p2>0 ); assert( p2+n<p->nMem ); pOut = &p->aMem[p2]; assert( p1+n<=p2 || p2+n<=p1 ); while( n-- ){ zMalloc = pOut->zMalloc; pOut->zMalloc = 0; sqlite3VdbeMemMove(pOut, pIn1); pIn1->zMalloc = zMalloc; REGISTER_TRACE(p2++, pOut); pIn1++; pOut++; } break;}/* 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.*/case OP_Copy: { assert( pOp->p1>0 ); assert( pOp->p1<=p->nMem ); pIn1 = &p->aMem[pOp->p1]; assert( pOp->p2>0 ); assert( pOp->p2<=p->nMem ); pOut = &p->aMem[pOp->p2]; assert( pOut!=pIn1 ); sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); Deephemeralize(pOut); REGISTER_TRACE(pOp->p2, pOut); break;}/* 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_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 ); sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); REGISTER_TRACE(pOp->p2, pOut); break;}/* Opcode: ResultRow P1 P2 * * ***** The registers P1 through 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 de-ephemeralized 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); REGISTER_TRACE(pOp->p1+i, &pMem[i]); } if( db->mallocFailed ) goto no_mem; /* 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.**** P3 = P2 || P1**** It is illegal for P1 and P3 to be the same register. Sometimes,** if P3 is the same register as P2, the implementation is able** to avoid a memcpy().*/case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */ i64 nByte; assert( pIn1!=pOut ); if( (pIn1->flags | pIn2->flags) & MEM_Null ){ sqlite3VdbeMemSetNull(pOut); break; } ExpandBlob(pIn1); Stringify(pIn1, encoding); ExpandBlob(pIn2); Stringify(pIn2, encoding); nByte = pIn1->n + pIn2->n; if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } MemSetTypeFlag(pOut, MEM_Str); if( sqlite3VdbeMemGrow(pOut, nByte+2, pOut==pIn2) ){ goto no_mem; } if( pOut!=pIn2 ){ memcpy(pOut->z, pIn2->z, pIn2->n); } memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n); pOut->z[nByte] = 0; pOut->z[nByte+1] = 0; pOut->flags |= MEM_Term; pOut->n = nByte; pOut->enc = encoding; 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 register P3.** If either input is NULL, the result is NULL.*//* Opcode: Multiply P1 P2 P3 * ******* Multiply the value in register P1 by the value in register 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; applyNumericAffinity(pIn1); applyNumericAffinity(pIn2); 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 too 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 ** behavior so that all architectures behave as if integer ** overflow occurred. */ if( a==-1 && b==SMALLEST_INT64 ) a = 1; b /= a; break; } default: { if( a==0 ) goto arithmetic_result_is_null; if( a==-1 ) a = 1; b %= a; break; } } pOut->u.i = b; MemSetTypeFlag(pOut, 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( sqlite3IsNaN(b) ){ goto arithmetic_result_is_null; } pOut->r = b; MemSetTypeFlag(pOut, 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()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -