📄 vdbe.c
字号:
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 + -