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

📄 vdbe.c

📁 最新的sqlite3.6.2源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*** 2001 September 15**** The author disclaims copyright to this source code.  In place of** a legal notice, here is a blessing:****    May you do good and not evil.**    May you find forgiveness for yourself and forgive others.**    May you share freely, never taking more than you give.***************************************************************************** The code in this file implements execution method of the ** Virtual Database Engine (VDBE).  A separate file ("vdbeaux.c")** handles housekeeping details such as creating and deleting** VDBE instances.  This file is solely interested in executing** the VDBE program.**** In the external interface, an "sqlite3_stmt*" is an opaque pointer** to a VDBE.**** The SQL parser generates a program which is then executed by** the VDBE to do the work of the SQL statement.  VDBE programs are ** similar in form to assembly language.  The program consists of** a linear sequence of operations.  Each operation has an opcode ** and 5 operands.  Operands P1, P2, and P3 are integers.  Operand P4 ** is a null-terminated string.  Operand P5 is an unsigned character.** Few opcodes use all 5 operands.**** Computation results are stored on a set of registers numbered beginning** with 1 and going up to Vdbe.nMem.  Each register can store** either an integer, a null-terminated string, a floating point** number, or the SQL "NULL" value.  An implicit conversion from one** type to the other occurs as necessary.** ** Most of the code in this file is taken up by the sqlite3VdbeExec()** function which does the work of interpreting a VDBE program.** But other routines are also provided to help in building up** a program instruction by instruction.**** Various scripts scan this source file in order to generate HTML** documentation, headers files, or other derived files.  The formatting** of the code in this file is, therefore, important.  See other comments** in this file for details.  If in doubt, do not deviate from existing** commenting and indentation practices when changing or adding code.**** $Id: vdbe.c,v 1.777 2008/08/21 19:28:30 drh Exp $*/#include "sqliteInt.h"#include <ctype.h>#include "vdbeInt.h"/*** The following global variable is incremented every time a cursor** moves, either by the OP_MoveXX, OP_Next, or OP_Prev opcodes.  The test** procedures use this information to make sure that indices are** working correctly.  This variable has no function other than to** help verify the correct operation of the library.*/#ifdef SQLITE_TESTint sqlite3_search_count = 0;#endif/*** When this global variable is positive, it gets decremented once before** each instruction in the VDBE.  When reaches zero, the u1.isInterrupted** field of the sqlite3 structure is set in order to simulate and interrupt.**** This facility is used for testing purposes only.  It does not function** in an ordinary build.*/#ifdef SQLITE_TESTint sqlite3_interrupt_count = 0;#endif/*** The next global variable is incremented each type the OP_Sort opcode** is executed.  The test procedures use this information to make sure that** sorting is occurring or not occurring at appropriate times.   This variable** has no function other than to help verify the correct operation of the** library.*/#ifdef SQLITE_TESTint sqlite3_sort_count = 0;#endif/*** The next global variable records the size of the largest MEM_Blob** or MEM_Str that has been used by a VDBE opcode.  The test procedures** use this information to make sure that the zero-blob functionality** is working correctly.   This variable has no function other than to** help verify the correct operation of the library.*/#ifdef SQLITE_TESTint sqlite3_max_blobsize = 0;static void updateMaxBlobsize(Mem *p){  if( (p->flags & (MEM_Str|MEM_Blob))!=0 && p->n>sqlite3_max_blobsize ){    sqlite3_max_blobsize = p->n;  }}#endif/*** Test a register to see if it exceeds the current maximum blob size.** If it does, record the new maximum blob size.*/#if defined(SQLITE_TEST) && !defined(SQLITE_OMIT_BUILTIN_TEST)# define UPDATE_MAX_BLOBSIZE(P)  updateMaxBlobsize(P)#else# define UPDATE_MAX_BLOBSIZE(P)#endif/*** Release the memory associated with a register.  This** leaves the Mem.flags field in an inconsistent state.*/#define Release(P) if((P)->flags&MEM_Dyn){ sqlite3VdbeMemRelease(P); }/*** Convert the given register into a string if it isn't one** already. Return non-zero if a malloc() fails.*/#define Stringify(P, enc) \   if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc)) \     { goto no_mem; }/*** An ephemeral string value (signified by the MEM_Ephem flag) contains** a pointer to a dynamically allocated string where some other entity** is responsible for deallocating that string.  Because the register** does not control the string, it might be deleted without the register** knowing it.**** This routine converts an ephemeral string into a dynamically allocated** string that the register itself controls.  In other words, it** converts an MEM_Ephem string into an MEM_Dyn string.*/#define Deephemeralize(P) \   if( ((P)->flags&MEM_Ephem)!=0 \       && sqlite3VdbeMemMakeWriteable(P) ){ goto no_mem;}/*** Call sqlite3VdbeMemExpandBlob() on the supplied value (type Mem*)** P if required.*/#define ExpandBlob(P) (((P)->flags&MEM_Zero)?sqlite3VdbeMemExpandBlob(P):0)/*** Argument pMem points at a register that will be passed to a** user-defined function or returned to the user as the result of a query.** The second argument, 'db_enc' is the text encoding used by the vdbe for** register variables.  This routine sets the pMem->enc and pMem->type** variables used by the sqlite3_value_*() routines.*/#define storeTypeInfo(A,B) _storeTypeInfo(A)static void _storeTypeInfo(Mem *pMem){  int flags = pMem->flags;  if( flags & MEM_Null ){    pMem->type = SQLITE_NULL;  }  else if( flags & MEM_Int ){    pMem->type = SQLITE_INTEGER;  }  else if( flags & MEM_Real ){    pMem->type = SQLITE_FLOAT;  }  else if( flags & MEM_Str ){    pMem->type = SQLITE_TEXT;  }else{    pMem->type = SQLITE_BLOB;  }}/*** Properties of opcodes.  The OPFLG_INITIALIZER macro is** created by mkopcodeh.awk during compilation.  Data is obtained** from the comments following the "case OP_xxxx:" statements in** this file.  */static unsigned char opcodeProperty[] = OPFLG_INITIALIZER;/*** Return true if an opcode has any of the OPFLG_xxx properties** specified by mask.*/int sqlite3VdbeOpcodeHasProperty(int opcode, int mask){  assert( opcode>0 && opcode<sizeof(opcodeProperty) );  return (opcodeProperty[opcode]&mask)!=0;}/*** Allocate cursor number iCur.  Return a pointer to it.  Return NULL** if we run out of memory.*/static Cursor *allocateCursor(  Vdbe *p,   int iCur,   Op *pOp,  int iDb,   int isBtreeCursor){  /* Find the memory cell that will be used to store the blob of memory  ** required for this Cursor structure. It is convenient to use a   ** vdbe memory cell to manage the memory allocation required for a  ** Cursor structure for the following reasons:  **  **   * Sometimes cursor numbers are used for a couple of different  **     purposes in a vdbe program. The different uses might require  **     different sized allocations. Memory cells provide growable  **     allocations.  **  **   * When using ENABLE_MEMORY_MANAGEMENT, memory cell buffers can  **     be freed lazily via the sqlite3_release_memory() API. This  **     minimizes the number of malloc calls made by the system.  **  ** Memory cells for cursors are allocated at the top of the address  ** space. Memory cell (p->nMem) corresponds to cursor 0. Space for  ** cursor 1 is managed by memory cell (p->nMem-1), etc.  */  Mem *pMem = &p->aMem[p->nMem-iCur];  int nByte;  Cursor *pCx = 0;  /* If the opcode of pOp is OP_SetNumColumns, then pOp->p2 contains  ** the number of fields in the records contained in the table or  ** index being opened. Use this to reserve space for the   ** Cursor.aType[] array.  */  int nField = 0;  if( pOp->opcode==OP_SetNumColumns || pOp->opcode==OP_OpenEphemeral ){    nField = pOp->p2;  }  nByte =       sizeof(Cursor) +       (isBtreeCursor?sqlite3BtreeCursorSize():0) +       2*nField*sizeof(u32);  assert( iCur<p->nCursor );  if( p->apCsr[iCur] ){    sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);    p->apCsr[iCur] = 0;  }  if( SQLITE_OK==sqlite3VdbeMemGrow(pMem, nByte, 0) ){    p->apCsr[iCur] = pCx = (Cursor *)pMem->z;    memset(pMem->z, 0, nByte);    pCx->iDb = iDb;    pCx->nField = nField;    if( nField ){      pCx->aType = (u32 *)&pMem->z[sizeof(Cursor)];    }    if( isBtreeCursor ){      pCx->pCursor = (BtCursor *)&pMem->z[sizeof(Cursor)+2*nField*sizeof(u32)];    }  }  return pCx;}/*** Try to convert a value into a numeric representation if we can** do so without loss of information.  In other words, if the string** looks like a number, convert it into a number.  If it does not** look like a number, leave it alone.*/static void applyNumericAffinity(Mem *pRec){  if( (pRec->flags & (MEM_Real|MEM_Int))==0 ){    int realnum;    sqlite3VdbeMemNulTerminate(pRec);    if( (pRec->flags&MEM_Str)         && sqlite3IsNumber(pRec->z, &realnum, pRec->enc) ){      i64 value;      sqlite3VdbeChangeEncoding(pRec, SQLITE_UTF8);      if( !realnum && sqlite3Atoi64(pRec->z, &value) ){        pRec->u.i = value;        MemSetTypeFlag(pRec, MEM_Int);      }else{        sqlite3VdbeMemRealify(pRec);      }    }  }}/*** Processing is determine by the affinity parameter:**** SQLITE_AFF_INTEGER:** SQLITE_AFF_REAL:** SQLITE_AFF_NUMERIC:**    Try to convert pRec to an integer representation or a **    floating-point representation if an integer representation**    is not possible.  Note that the integer representation is**    always preferred, even if the affinity is REAL, because**    an integer representation is more space efficient on disk.**** SQLITE_AFF_TEXT:**    Convert pRec to a text representation.**** SQLITE_AFF_NONE:**    No-op.  pRec is unchanged.*/static void applyAffinity(  Mem *pRec,          /* The value to apply affinity to */  char affinity,      /* The affinity to be applied */  u8 enc              /* Use this text encoding */){  if( affinity==SQLITE_AFF_TEXT ){    /* Only attempt the conversion to TEXT if there is an integer or real    ** representation (blob and NULL do not get converted) but no string    ** representation.    */    if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){      sqlite3VdbeMemStringify(pRec, enc);    }    pRec->flags &= ~(MEM_Real|MEM_Int);  }else if( affinity!=SQLITE_AFF_NONE ){    assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL             || affinity==SQLITE_AFF_NUMERIC );    applyNumericAffinity(pRec);    if( pRec->flags & MEM_Real ){      sqlite3VdbeIntegerAffinity(pRec);    }  }}/*** Try to convert the type of a function argument or a result column** into a numeric representation.  Use either INTEGER or REAL whichever** is appropriate.  But only do the conversion if it is possible without** loss of information and return the revised type of the argument.**** This is an EXPERIMENTAL api and is subject to change or removal.*/int sqlite3_value_numeric_type(sqlite3_value *pVal){  Mem *pMem = (Mem*)pVal;  applyNumericAffinity(pMem);  storeTypeInfo(pMem, 0);  return pMem->type;}/*** Exported version of applyAffinity(). This one works on sqlite3_value*, ** not the internal Mem* type.*/void sqlite3ValueApplyAffinity(  sqlite3_value *pVal,   u8 affinity,   u8 enc){  applyAffinity((Mem *)pVal, affinity, enc);}#ifdef SQLITE_DEBUG/*** Write a nice string representation of the contents of cell pMem** into buffer zBuf, length nBuf.*/void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){  char *zCsr = zBuf;  int f = pMem->flags;  static const char *const encnames[] = {"(X)", "(8)", "(16LE)", "(16BE)"};  if( f&MEM_Blob ){    int i;    char c;    if( f & MEM_Dyn ){      c = 'z';      assert( (f & (MEM_Static|MEM_Ephem))==0 );    }else if( f & MEM_Static ){      c = 't';      assert( (f & (MEM_Dyn|MEM_Ephem))==0 );    }else if( f & MEM_Ephem ){      c = 'e';      assert( (f & (MEM_Static|MEM_Dyn))==0 );    }else{      c = 's';    }    sqlite3_snprintf(100, zCsr, "%c", c);    zCsr += strlen(zCsr);    sqlite3_snprintf(100, zCsr, "%d[", pMem->n);    zCsr += strlen(zCsr);    for(i=0; i<16 && i<pMem->n; i++){      sqlite3_snprintf(100, zCsr, "%02X", ((int)pMem->z[i] & 0xFF));      zCsr += strlen(zCsr);    }    for(i=0; i<16 && i<pMem->n; i++){      char z = pMem->z[i];      if( z<32 || z>126 ) *zCsr++ = '.';      else *zCsr++ = z;    }    sqlite3_snprintf(100, zCsr, "]%s", encnames[pMem->enc]);    zCsr += strlen(zCsr);    if( f & MEM_Zero ){      sqlite3_snprintf(100, zCsr,"+%lldz",pMem->u.i);      zCsr += strlen(zCsr);    }    *zCsr = '\0';  }else if( f & MEM_Str ){    int j, k;    zBuf[0] = ' ';    if( f & MEM_Dyn ){      zBuf[1] = 'z';      assert( (f & (MEM_Static|MEM_Ephem))==0 );    }else if( f & MEM_Static ){      zBuf[1] = 't';      assert( (f & (MEM_Dyn|MEM_Ephem))==0 );    }else if( f & MEM_Ephem ){      zBuf[1] = 'e';      assert( (f & (MEM_Static|MEM_Dyn))==0 );    }else{      zBuf[1] = 's';    }    k = 2;    sqlite3_snprintf(100, &zBuf[k], "%d", pMem->n);    k += strlen(&zBuf[k]);    zBuf[k++] = '[';    for(j=0; j<15 && j<pMem->n; j++){      u8 c = pMem->z[j];      if( c>=0x20 && c<0x7f ){        zBuf[k++] = c;

⌨️ 快捷键说明

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