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

📄 vdbe.c

📁 最新的sqlite3.6.2源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* If 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: Permutation * * * P4 ***** Set the permuation used by the OP_Compare operator to be the array** of integers in P4.**** The permutation is only valid until the next OP_Permutation, OP_Compare,** OP_Halt, or OP_ResultRow.  Typically the OP_Permutation should occur** immediately prior to the OP_Compare.*/case OP_Permutation: {  assert( pOp->p4type==P4_INTARRAY );  assert( pOp->p4.ai );  aPermute = pOp->p4.ai;  break;}/* Opcode: Compare P1 P2 P3 P4 ***** Compare to vectors of registers in reg(P1)..reg(P1+P3-1) (all this** one "A") and in reg(P2)..reg(P2+P3-1) ("B").  Save the result of** the comparison for use by the next OP_Jump instruct.**** P4 is a KeyInfo structure that defines collating sequences and sort** orders for the comparison.  The permutation applies to registers** only.  The KeyInfo elements are used sequentially.**** The comparison is a sort comparison, so NULLs compare equal,** NULLs are less than numbers, numbers are less than strings,** and strings are less than blobs.*/case OP_Compare: {  int n = pOp->p3;  int i, p1, p2;  const KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;  assert( n>0 );  assert( pKeyInfo!=0 );  p1 = pOp->p1;  assert( p1>0 && p1+n-1<p->nMem );  p2 = pOp->p2;  assert( p2>0 && p2+n-1<p->nMem );  for(i=0; i<n; i++){    int idx = aPermute ? aPermute[i] : i;    CollSeq *pColl;    /* Collating sequence to use on this term */    int bRev;          /* True for DESCENDING sort order */    REGISTER_TRACE(p1+idx, &p->aMem[p1+idx]);    REGISTER_TRACE(p2+idx, &p->aMem[p2+idx]);    assert( i<pKeyInfo->nField );    pColl = pKeyInfo->aColl[i];    bRev = pKeyInfo->aSortOrder[i];    iCompare = sqlite3MemCompare(&p->aMem[p1+idx], &p->aMem[p2+idx], pColl);    if( iCompare ){      if( bRev ) iCompare = -iCompare;      break;    }  }  aPermute = 0;  break;}/* Opcode: Jump P1 P2 P3 * ***** Jump to the instruction at address P1, P2, or P3 depending on whether** in the most recent OP_Compare instruction the P1 vector was less than** equal to, or greater than the P2 vector, respectively.*/case OP_Jump: {             /* jump */  if( iCompare<0 ){    pc = pOp->p1 - 1;  }else if( iCompare==0 ){    pc = pOp->p2 - 1;  }else{    pc = pOp->p3 - 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 extern

⌨️ 快捷键说明

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