⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vdbe.c

📁 SQLite is a software library that implements a self-contained, serverless, zero-configuration, trans
💻 C
📖 第 1 页 / 共 5 页
字号:
** register P1.  See the Lt opcode for additional information.*/case OP_Eq:               /* same as TK_EQ, jump, in1, in3 */case OP_Ne:               /* same as TK_NE, jump, in1, in3 */case OP_Lt:               /* same as TK_LT, jump, in1, in3 */case OP_Le:               /* same as TK_LE, jump, in1, in3 */case OP_Gt:               /* same as TK_GT, jump, in1, in3 */case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */  int flags;  int res;  char affinity;  Mem x1, x3;  flags = pIn1->flags|pIn3->flags;  if( flags&MEM_Null ){    if( (pOp->p5 & SQLITE_NULLEQUAL)!=0 ){      /*      ** When SQLITE_NULLEQUAL set and either operand is NULL      ** then both operands are converted to integers prior to being       ** passed down into the normal comparison logic below.        ** NULL operands are converted to zero and non-NULL operands      ** are converted to 1.  Thus, for example, with SQLITE_NULLEQUAL      ** set,  NULL==NULL is true whereas it would normally NULL.      ** Similarly,  NULL!=123 is true.      */      x1.flags = MEM_Int;      x1.u.i = (pIn1->flags & MEM_Null)==0;      pIn1 = &x1;      x3.flags = MEM_Int;      x3.u.i = (pIn3->flags & MEM_Null)==0;      pIn3 = &x3;    }else{      /* If the SQLITE_NULLEQUAL bit is clear and either operand is NULL then      ** the result is always NULL.  The jump is taken if the       ** SQLITE_JUMPIFNULL bit is set.      */      if( pOp->p5 & SQLITE_STOREP2 ){        pOut = &p->aMem[pOp->p2];        MemSetTypeFlag(pOut, MEM_Null);        REGISTER_TRACE(pOp->p2, pOut);      }else if( pOp->p5 & SQLITE_JUMPIFNULL ){        pc = pOp->p2-1;      }      break;    }  }  affinity = pOp->p5 & SQLITE_AFF_MASK;  if( affinity ){    applyAffinity(pIn1, affinity, encoding);    applyAffinity(pIn3, affinity, encoding);  }  assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 );  ExpandBlob(pIn1);  ExpandBlob(pIn3);  res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);  switch( pOp->opcode ){    case OP_Eq:    res = res==0;     break;    case OP_Ne:    res = res!=0;     break;    case OP_Lt:    res = res<0;      break;    case OP_Le:    res = res<=0;     break;    case OP_Gt:    res = res>0;      break;    default:       res = res>=0;     break;  }  if( pOp->p5 & SQLITE_STOREP2 ){    pOut = &p->aMem[pOp->p2];    MemSetTypeFlag(pOut, MEM_Int);    pOut->u.i = res;    REGISTER_TRACE(pOp->p2, pOut);  }else if( res ){    pc = pOp->p2-1;  }  break;}/* Opcode: And P1 P2 P3 * ***** Take the logical AND of the values in registers P1 and P2 and** write the result into register P3.**** If either P1 or P2 is 0 (false) then the result is 0 even if** the other input is NULL.  A NULL and true or two NULLs give** a NULL output.*//* Opcode: Or P1 P2 P3 * ***** Take the logical OR of the values in register P1 and P2 and** store the answer in register P3.**** If either P1 or P2 is nonzero (true) then the result is 1 (true)** even if the other input is NULL.  A NULL and false or two NULLs** give a NULL output.*/case OP_And:              /* same as TK_AND, in1, in2, out3 */case OP_Or: {             /* same as TK_OR, in1, in2, out3 */  int v1, v2;    /* 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */  if( pIn1->flags & MEM_Null ){    v1 = 2;  }else{    v1 = sqlite3VdbeIntValue(pIn1)!=0;  }  if( pIn2->flags & MEM_Null ){    v2 = 2;  }else{    v2 = sqlite3VdbeIntValue(pIn2)!=0;  }  if( pOp->opcode==OP_And ){    static const unsigned char and_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 };    v1 = and_logic[v1*3+v2];  }else{    static const unsigned char or_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 };    v1 = or_logic[v1*3+v2];  }  if( v1==2 ){    MemSetTypeFlag(pOut, MEM_Null);  }else{    pOut->u.i = v1;    MemSetTypeFlag(pOut, MEM_Int);  }  break;}/* Opcode: Not P1 * * * ***** Interpret the value in register P1 as a boolean value.  Replace it** with its complement.  If the value in register P1 is NULL its value** is unchanged.*/case OP_Not: {                /* same as TK_NOT, in1 */  if( pIn1->flags & MEM_Null ) break;  /* Do nothing to NULLs */  sqlite3VdbeMemIntegerify(pIn1);  pIn1->u.i = !pIn1->u.i;  assert( pIn1->flags&MEM_Int );  break;}/* Opcode: BitNot P1 * * * ***** Interpret the content of register P1 as an integer.  Replace it** with its ones-complement.  If the value is originally NULL, leave** it unchanged.*/case OP_BitNot: {             /* same as TK_BITNOT, in1 */  if( pIn1->flags & MEM_Null ) break;  /* Do nothing to NULLs */  sqlite3VdbeMemIntegerify(pIn1);  pIn1->u.i = ~pIn1->u.i;  assert( pIn1->flags&MEM_Int );  break;}/* Opcode: If P1 P2 P3 * ***** Jump to P2 if the value in register P1 is true.  The value is** is considered true if it is numeric and non-zero.  If the value** in P1 is NULL then take the jump if P3 is true.*//* Opcode: IfNot P1 P2 P3 * ***** Jump to P2 if the value in register P1 is False.  The value is** is considered true if it has a numeric value of zero.  If the value** in P1 is NULL then take the jump if P3 is true.*/case OP_If:                 /* jump, in1 */case OP_IfNot: {            /* jump, in1 */  int c;  if( pIn1->flags & MEM_Null ){    c = pOp->p3;  }else{#ifdef SQLITE_OMIT_FLOATING_POINT    c = sqlite3VdbeIntValue(pIn1);#else    c = sqlite3VdbeRealValue(pIn1)!=0.0;#endif    if( pOp->opcode==OP_IfNot ) c = !c;  }  if( c ){    pc = pOp->p2-1;  }  break;}/* Opcode: IsNull P1 P2 P3 * ***** Jump to P2 if the value in register P1 is NULL.  If P3 is greater** than zero, then check all values reg(P1), reg(P1+1), ** reg(P1+2), ..., reg(P1+P3-1).*/case OP_IsNull: {            /* same as TK_ISNULL, jump, in1 */  int n = pOp->p3;  assert( pOp->p3==0 || pOp->p1>0 );  do{    if( (pIn1->flags & MEM_Null)!=0 ){      pc = pOp->p2 - 1;      break;    }    pIn1++;  }while( --n > 0 );  break;}/* Opcode: NotNull P1 P2 * * ***** Jump to P2 if the value in register P1 is not NULL.  */case OP_NotNull: {            /* same as TK_NOTNULL, jump, in1 */  if( (pIn1->flags & MEM_Null)==0 ){    pc = pOp->p2 - 1;  }  break;}/* Opcode: SetNumColumns * P2 * * ***** This opcode sets the number of columns for the cursor opened by the** following instruction to P2.**** An OP_SetNumColumns is only useful if it occurs immediately before ** one of the following opcodes:****     OpenRead**     OpenWrite**     OpenPseudo**** If the OP_Column opcode is to be executed on a cursor, then** this opcode must be present immediately before the opcode that** opens the cursor.*/case OP_SetNumColumns: {  break;}/* Opcode: Column P1 P2 P3 P4 ***** Interpret the data that cursor P1 points to as a structure built using** the MakeRecord instruction.  (See the MakeRecord opcode for additional** information about the format of the data.)  Extract the P2-th column** from this record.  If there are less that (P2+1) ** values in the record, extract a NULL.**** The value extracted is stored in register P3.**** If the KeyAsData opcode has previously executed on this cursor, then the** field might be extracted from the key rather than the data.**** If the column contains fewer than P2 fields, then extract a NULL.  Or,** if the P4 argument is a P4_MEM use the value of the P4 argument as** the result.*/case OP_Column: {  u32 payloadSize;   /* Number of bytes in the record */  int p1 = pOp->p1;  /* P1 value of the opcode */  int p2 = pOp->p2;  /* column number to retrieve */  Cursor *pC = 0;    /* The VDBE cursor */  char *zRec;        /* Pointer to complete record-data */  BtCursor *pCrsr;   /* The BTree cursor */  u32 *aType;        /* aType[i] holds the numeric type of the i-th column */  u32 *aOffset;      /* aOffset[i] is offset to start of data for i-th column */  u32 nField;        /* number of fields in the record */  int len;           /* The length of the serialized data for the column */  int i;             /* Loop counter */  char *zData;       /* Part of the record being decoded */  Mem *pDest;        /* Where to write the extracted value */  Mem sMem;          /* For storing the record being decoded */  sMem.flags = 0;  sMem.db = 0;  sMem.zMalloc = 0;  assert( p1<p->nCursor );  assert( pOp->p3>0 && pOp->p3<=p->nMem );  pDest = &p->aMem[pOp->p3];  MemSetTypeFlag(pDest, MEM_Null);  /* This block sets the variable payloadSize to be the total number of  ** bytes in the record.  **  ** zRec is set to be the complete text of the record if it is available.  ** The complete record text is always available for pseudo-tables  ** If the record is stored in a cursor, the complete record text  ** might be available in the  pC->aRow cache.  Or it might not be.  ** If the data is unavailable,  zRec is set to NULL.  **  ** We also compute the number of columns in the record.  For cursors,  ** the number of columns is stored in the Cursor.nField element.  */  pC = p->apCsr[p1];  assert( pC!=0 );#ifndef SQLITE_OMIT_VIRTUALTABLE  assert( pC->pVtabCursor==0 );#endif  if( pC->pCursor!=0 ){    /* The record is stored in a B-Tree */    rc = sqlite3VdbeCursorMoveto(pC);    if( rc ) goto abort_due_to_error;    zRec = 0;    pCrsr = pC->pCursor;    if( pC->nullRow ){      payloadSize = 0;    }else if( pC->cacheStatus==p->cacheCtr ){      payloadSize = pC->payloadSize;      zRec = (char*)pC->aRow;    }else if( pC->isIndex ){      i64 payloadSize64;      sqlite3BtreeKeySize(pCrsr, &payloadSize64);      payloadSize = payloadSize64;    }else{      sqlite3BtreeDataSize(pCrsr, &payloadSize);    }    nField = pC->nField;  }else{    assert( pC->pseudoTable );    /* The record is the sole entry of a pseudo-table */    payloadSize = pC->nData;    zRec = pC->pData;    pC->cacheStatus = CACHE_STALE;    assert( payloadSize==0 || zRec!=0 );    nField = pC->nField;    pCrsr = 0;  }  /* If payloadSize is 0, then just store a NULL */  if( payloadSize==0 ){    assert( pDest->flags&MEM_Null );    goto op_column_out;  }  if( payloadSize>db->aLimit[SQLITE_LIMIT_LENGTH] ){    goto too_big;  }  assert( p2<nField );  /* Read and parse the table header.  Store the results of the parse  ** into the record header cache fields of the cursor.  */  aType = pC->aType;  if( pC->cacheStatus==p->cacheCtr ){    aOffset = pC->aOffset;  }else{    u8 *zIdx;        /* Index into header */    u8 *zEndHdr;     /* Pointer to first byte after the header */    u32 offset;      /* Offset into the data */    int szHdrSz;     /* Size of the header size field at start of record */    int avail;       /* Number of bytes of available data */    assert(aType);    pC->aOffset = aOffset = &aType[nField];    pC->payloadSize = payloadSize;    pC->cacheStatus = p->cacheCtr;    /* Figure out how many bytes are in the header */    if( zRec ){      zData = zRec;    }else{      if( pC->isIndex ){        zData = (char*)sqlite3BtreeKeyFetch(pCrsr, &avail);      }else{        zData = (char*)sqlite3BtreeDataFetch(pCrsr, &avail);      }      /* If KeyFetch()/DataFetch() managed to get the entire payload,      ** save the payload in the pC->aRow cache.  That will save us from      ** having to make additional calls to fetch the content portion of      ** the record.      */      if( avail>=payloadSize ){        zRec = zData;        pC->aRow = (u8*)zData;      }else{        pC->aRow = 0;      }    }    /* The following assert is true in all cases accept when    ** the database file has been corrupted externally.    **    assert( zRec!=0 || avail>=payloadSize || avail>=9 ); */    szHdrSz = GetVarint((u8*)zData, offset);    /* The KeyFetch() or DataFetch() above are fast and will get the entire    ** record header in most cases.  But they will fail to get the complete    ** record header if the record header does not fit on a single page    ** in the B-Tree.  When that happens, use sqlite3VdbeMemFromBtree() to    ** acquire the complete header text.    */    if( !zRec && avail<offset ){      sMem.flags = 0;      sMem.db = 0;      rc = sqlite3VdbeMemFromBtree(pCrsr, 0, offset, pC->isIndex, &sMem);      if( rc!=SQLITE_OK ){        goto op_column_out;      }      zData = sMem.z;    }    zEndHdr = (u8 *)&zData[offset];    zIdx = (u8 *)&zData[szHdrSz];    /* Scan the header and use it to fill in the aType[] and aOffset[]    ** arrays.  aType[i] will contain the type integer for the i-th    ** column and aOffset[i] will contain the offset from the beginning    ** of the record to the start of the data for the i-th column    */    for(i=0; i<nField; i++){      if( zIdx<zEndHdr ){        aOffset[i] = offset;        zIdx += GetVarint(zIdx, aType[i]);        offset += sqlite3VdbeSerialTypeLen(aType[i]);      }else{        /* If i is less that nField, then there are less fields in this        ** re

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -