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

📄 vdbe.c

📁 SQLite 2.8.6 源代码,用来在Linux/Unix/Windows上编译安装.它是一个小型的数据库,但是非常好用,速度也快,一般的数据库查询之类的操作据统计比MySQL,PostgreSQL
💻 C
📖 第 1 页 / 共 5 页
字号:
      p->rc = SQLITE_MISUSE;    }  }  return p->rc==SQLITE_OK ? SQLITE_DONE : SQLITE_ERROR;}/*** The parameters are pointers to the head of two sorted lists** of Sorter structures.  Merge these two lists together and return** a single sorted list.  This routine forms the core of the merge-sort** algorithm.**** In the case of a tie, left sorts in front of right.*/static Sorter *Merge(Sorter *pLeft, Sorter *pRight){  Sorter sHead;  Sorter *pTail;  pTail = &sHead;  pTail->pNext = 0;  while( pLeft && pRight ){    int c = sqliteSortCompare(pLeft->zKey, pRight->zKey);    if( c<=0 ){      pTail->pNext = pLeft;      pLeft = pLeft->pNext;    }else{      pTail->pNext = pRight;      pRight = pRight->pNext;    }    pTail = pTail->pNext;  }  if( pLeft ){    pTail->pNext = pLeft;  }else if( pRight ){    pTail->pNext = pRight;  }  return sHead.pNext;}/*** Convert an integer in between the native integer format and** the bigEndian format used as the record number for tables.**** The bigEndian format (most significant byte first) is used for** record numbers so that records will sort into the correct order** even though memcmp() is used to compare the keys.  On machines** whose native integer format is little endian (ex: i486) the** order of bytes is reversed.  On native big-endian machines** (ex: Alpha, Sparc, Motorola) the byte order is the same.**** This function is its own inverse.  In other words****         X == byteSwap(byteSwap(X))*/static int byteSwap(int x){  union {     char zBuf[sizeof(int)];     int i;  } ux;  ux.zBuf[3] = x&0xff;  ux.zBuf[2] = (x>>8)&0xff;  ux.zBuf[1] = (x>>16)&0xff;  ux.zBuf[0] = (x>>24)&0xff;  return ux.i;}/*** When converting from the native format to the key format and back** again, in addition to changing the byte order we invert the high-order** bit of the most significant byte.  This causes negative numbers to** sort before positive numbers in the memcmp() function.*/#define keyToInt(X)   (byteSwap(X) ^ 0x80000000)#define intToKey(X)   (byteSwap((X) ^ 0x80000000))/*** Code contained within the VERIFY() macro is not needed for correct** execution.  It is there only to catch errors.  So when we compile** with NDEBUG=1, the VERIFY() code is omitted.*/#ifdef NDEBUG# define VERIFY(X)#else# define VERIFY(X) X#endif/*** The following routine works like a replacement for the standard** library routine fgets().  The difference is in how end-of-line (EOL)** is handled.  Standard fgets() uses LF for EOL under unix, CRLF** under windows, and CR under mac.  This routine accepts any of these** character sequences as an EOL mark.  The EOL mark is replaced by** a single LF character in zBuf.*/static char *vdbe_fgets(char *zBuf, int nBuf, FILE *in){  int i, c;  for(i=0; i<nBuf-1 && (c=getc(in))!=EOF; i++){    zBuf[i] = c;    if( c=='\r' || c=='\n' ){      if( c=='\r' ){        zBuf[i] = '\n';        c = getc(in);        if( c!=EOF && c!='\n' ) ungetc(c, in);      }      i++;      break;    }  }  zBuf[i]  = 0;  return i>0 ? zBuf : 0;}#if !defined(NDEBUG) || defined(VDBE_PROFILE)/*** Print a single opcode.  This routine is used for debugging only.*/static void vdbePrintOp(FILE *pOut, int pc, Op *pOp){  char *zP3;  char zPtr[40];  if( pOp->p3type==P3_POINTER ){    sprintf(zPtr, "ptr(%#x)", (int)pOp->p3);    zP3 = zPtr;  }else{    zP3 = pOp->p3;  }  if( pOut==0 ) pOut = stdout;  fprintf(pOut,"%4d %-12s %4d %4d %s\n",      pc, sqliteOpcodeNames[pOp->opcode], pOp->p1, pOp->p2, zP3 ? zP3 : "");  fflush(pOut);}#endif/*** Make sure there is space in the Vdbe structure to hold at least** mxCursor cursors.  If there is not currently enough space, then** allocate more.**** If a memory allocation error occurs, return 1.  Return 0 if** everything works.*/static int expandCursorArraySize(Vdbe *p, int mxCursor){  if( mxCursor>=p->nCursor ){    Cursor *aCsr = sqliteRealloc( p->aCsr, (mxCursor+1)*sizeof(Cursor) );    if( aCsr==0 ) return 1;    p->aCsr = aCsr;    memset(&p->aCsr[p->nCursor], 0, sizeof(Cursor)*(mxCursor+1-p->nCursor));    p->nCursor = mxCursor+1;  }  return 0;}#ifdef VDBE_PROFILE/*** The following routine only works on pentium-class processors.** It uses the RDTSC opcode to read cycle count value out of the** processor and returns that value.  This can be used for high-res** profiling.*/__inline__ unsigned long long int hwtime(void){  unsigned long long int x;  __asm__("rdtsc\n\t"          "mov %%edx, %%ecx\n\t"          :"=A" (x));  return x;}#endif/*** The CHECK_FOR_INTERRUPT macro defined here looks to see if the** sqlite_interrupt() routine has been called.  If it has been, then** processing of the VDBE program is interrupted.**** This macro added to every instruction that does a jump in order to** implement a loop.  This test used to be on every single instruction,** but that meant we more testing that we needed.  By only testing the** flag on jump instructions, we get a (small) speed improvement.*/#define CHECK_FOR_INTERRUPT \   if( db->flags & SQLITE_Interrupt ) goto abort_due_to_interrupt;/*** Prepare a virtual machine for execution.  This involves things such** as allocating stack space and initializing the program counter.** After the VDBE has be prepped, it can be executed by one or more** calls to sqliteVdbeExec().  **** The behavior of sqliteVdbeExec() is influenced by the parameters to** this routine.  If xCallback is NULL, then sqliteVdbeExec() will return** with SQLITE_ROW whenever there is a row of the result set ready** to be delivered.  p->azResColumn will point to the row and ** p->nResColumn gives the number of columns in the row.  If xCallback** is not NULL, then the xCallback() routine is invoked to process each** row in the result set.*/void sqliteVdbeMakeReady(  Vdbe *p,                       /* The VDBE */  sqlite_callback xCallback,     /* Result callback */  void *pCallbackArg,            /* 1st argument to xCallback() */  int isExplain                  /* True if the EXPLAIN keywords is present */){  int n;  assert( p!=0 );  assert( p->aStack==0 );  assert( p->magic==VDBE_MAGIC_INIT );  /* Add a HALT instruction to the very end of the program.  */  sqliteVdbeAddOp(p, OP_Halt, 0, 0);  /* No instruction ever pushes more than a single element onto the  ** stack.  And the stack never grows on successive executions of the  ** same loop.  So the total number of instructions is an upper bound  ** on the maximum stack depth required.  **  ** Allocation all the stack space we will ever need.  */  n = isExplain ? 10 : p->nOp;  p->aStack = sqliteMalloc( n*(sizeof(p->aStack[0]) + 2*sizeof(char*)) );  p->zStack = (char**)&p->aStack[n];  p->azColName = (char**)&p->zStack[n];  sqliteHashInit(&p->agg.hash, SQLITE_HASH_BINARY, 0);  p->agg.pSearch = 0;#ifdef MEMORY_DEBUG  if( sqliteOsFileExists("vdbe_trace") ){    p->trace = stdout;  }#endif  p->tos = -1;  p->pc = 0;  p->rc = SQLITE_OK;  p->uniqueCnt = 0;  p->returnDepth = 0;  p->errorAction = OE_Abort;  p->undoTransOnError = 0;  p->xCallback = xCallback;  p->pCbArg = pCallbackArg;  p->popStack =  0;  p->explain = isExplain;  p->magic = VDBE_MAGIC_RUN;#ifdef VDBE_PROFILE  for(i=0; i<p->nOp; i++){    p->aOp[i].cnt = 0;    p->aOp[i].cycles = 0;  }#endif}/*** Execute as much of a VDBE program as we can then return.**** sqliteVdbeMakeReady() must be called before this routine in order to** close the program with a final OP_Halt and to set up the callbacks** and the error message pointer.**** Whenever a row or result data is available, this routine will either** invoke the result callback (if there is one) or return with** SQLITE_ROW.**** If an attempt is made to open a locked database, then this routine** will either invoke the busy callback (if there is one) or it will** return SQLITE_BUSY.**** If an error occurs, an error message is written to memory obtained** from sqliteMalloc() and p->zErrMsg is made to point to that memory.** The error code is stored in p->rc and this routine returns SQLITE_ERROR.**** If the callback ever returns non-zero, then the program exits** immediately.  There will be no error message but the p->rc field is** set to SQLITE_ABORT and this routine will return SQLITE_ERROR.**** A memory allocation error causes p->rc to be set to SQLITE_NOMEM and this** routine to return SQLITE_ERROR.**** Other fatal errors return SQLITE_ERROR.**** After this routine has finished, sqliteVdbeFinalize() should be** used to clean up the mess that was left behind.*/int sqliteVdbeExec(  Vdbe *p                    /* The VDBE */){  int pc;                    /* The program counter */  Op *pOp;                   /* Current operation */  int rc = SQLITE_OK;        /* Value to return */  sqlite *db = p->db;        /* The database */  char **zStack = p->zStack; /* Text stack */  Stack *aStack = p->aStack; /* Additional stack information */  char zBuf[100];            /* Space to sprintf() an integer */#ifdef VDBE_PROFILE  unsigned long long start;  /* CPU clock count at start of opcode */  int origPc;                /* Program counter at start of opcode */#endif  if( p->magic!=VDBE_MAGIC_RUN ) return SQLITE_MISUSE;  assert( db->magic==SQLITE_MAGIC_BUSY );  assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );  p->rc = SQLITE_OK;  assert( p->explain==0 );  if( sqlite_malloc_failed ) goto no_mem;  if( p->popStack ){    PopStack(p, p->popStack);    p->popStack = 0;  }  for(pc=p->pc; rc==SQLITE_OK; pc++){    assert( pc>=0 && pc<p->nOp );#ifdef VDBE_PROFILE    origPc = pc;    start = hwtime();#endif    pOp = &p->aOp[pc];    /* Only allow tracing if NDEBUG is not defined.    */#ifndef NDEBUG    if( p->trace ){      vdbePrintOp(p->trace, pc, pOp);    }#endif    switch( pOp->opcode ){/******************************************************************************* What follows is a massive switch statement where each case implements a** separate instruction in the virtual machine.  If we follow the usual** indentation conventions, each case should be indented by 6 spaces.  But** that is a lot of wasted space on the left margin.  So the code within** the switch statement will break with convention and be flush-left. Another** big comment (similar to this one) will mark the point in the code where** we transition back to normal indentation.**** The formatting of each case is important.  The makefile for SQLite** generates two C files "opcodes.h" and "opcodes.c" by scanning this** file looking for lines that begin with "case OP_".  The opcodes.h files** will be filled with #defines that give unique integer values to each** opcode and the opcodes.c file is filled with an array of strings where** each string is the symbolic name for the corresponding opcode.**** Documentation about VDBE opcodes is generated by scanning this file** for lines of that contain "Opcode:".  That line and all subsequent** comment lines are used in the generation of the opcode.html documentation** file.**** SUMMARY:****     Formatting is important to scripts that scan this file.**     Do not deviate from the formatting style currently in use.*******************************************************************************//* Opcode:  Goto * P2 ***** An unconditional jump to address P2.** The next instruction executed will be ** the one at index P2 from the beginning of** the program.*/case OP_Goto: {  CHECK_FOR_INTERRUPT;  pc = pOp->p2 - 1;  break;}/* Opcode:  Gosub * P2 ***** Push the current address plus 1 onto the return address stack** and then jump to address P2.**** The return address stack is of limited depth.  If too many** OP_Gosub operations occur without intervening OP_Returns, then** the return address stack will fill up and processing will abort** with a fatal error.*/case OP_Gosub: {  if( p->returnDepth>=sizeof(p->returnStack)/sizeof(p->returnStack[0]) ){    sqliteSetString(&p->zErrMsg, "return address stack overflow", 0);    p->rc = SQLITE_INTERNAL;    return SQLITE_ERROR;  }  p->returnStack[p->returnDepth++] = pc+1;  pc = pOp->p2 - 1;  break;}/* Opcode:  Return * * ***** Jump immediately to the next instruction after the last unreturned** OP_Gosub.  If an OP_Return has occurred for all OP_Gosubs, then** processing aborts with a fatal error.*/case OP_Return: {  if( p->returnDepth<=0 ){    sqliteSetString(&p->zErrMsg, "return address stack underflow", 0);    p->rc = SQLITE_INTERNAL;    return SQLITE_ERROR;  }  p->returnDepth--;  pc = p->returnStack[p->returnDepth] - 1;  break;}/* Opcode:  Halt P1 P2 ***** Exit immediately.  All open cursors, Lists, Sorts, etc are closed** automatically.**** P1 is the result code returned by sqlite_exec().  For a normal** halt, this should be SQLITE_OK (0).  For errors, it can be some** other value.  If P1!=0 then P2 will determine whether or not to** rollback the current transaction.  Do not rollback if P2==OE_Fail.** Do the rollback if P2==OE_Rollback.  If P2==OE_Abort, then back** out all changes that have occurred during this execution of the** VDBE, but do not rollback the transaction. **** There is an implied "Halt 0 0 0" instruction inserted at the very end of** every program.  So a jump past the last instruction of the program** is the same as executing Halt.*/case OP_Halt: {  p->magic = VDBE_MAGIC_HALT;  if( pOp->p1!=SQLITE_OK ){    p->rc = pOp->p1;    p->errorAction = pOp->p2;    if( pOp->p3 ){      sqliteSetString(&p->zErrMsg, pOp->p3, 0);    }    return SQLITE_ERROR;  }else{    p->rc = SQLITE_OK;    return SQLITE_DONE;  }}

⌨️ 快捷键说明

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