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

📄 vdbe.c

📁 SQLite 2.8.6 源代码,用来在Linux/Unix/Windows上编译安装.它是一个小型的数据库,但是非常好用,速度也快,一般的数据库查询之类的操作据统计比MySQL,PostgreSQL
💻 C
📖 第 1 页 / 共 5 页
字号:
  sqliteFree(pAgg->apFunc);  pAgg->apFunc = 0;  pAgg->pCurrent = 0;  pAgg->pSearch = 0;  pAgg->nMem = 0;}/*** Insert a new aggregate element and make it the element that** has focus.**** Return 0 on success and 1 if memory is exhausted.*/static int AggInsert(Agg *p, char *zKey, int nKey){  AggElem *pElem, *pOld;  int i;  pElem = sqliteMalloc( sizeof(AggElem) + nKey +                        (p->nMem-1)*sizeof(pElem->aMem[0]) );  if( pElem==0 ) return 1;  pElem->zKey = (char*)&pElem->aMem[p->nMem];  memcpy(pElem->zKey, zKey, nKey);  pElem->nKey = nKey;  pOld = sqliteHashInsert(&p->hash, pElem->zKey, pElem->nKey, pElem);  if( pOld!=0 ){    assert( pOld==pElem );  /* Malloc failed on insert */    sqliteFree(pOld);    return 0;  }  for(i=0; i<p->nMem; i++){    pElem->aMem[i].s.flags = STK_Null;  }  p->pCurrent = pElem;  return 0;}/*** Get the AggElem currently in focus*/#define AggInFocus(P)   ((P).pCurrent ? (P).pCurrent : _AggInFocus(&(P)))static AggElem *_AggInFocus(Agg *p){  HashElem *pElem = sqliteHashFirst(&p->hash);  if( pElem==0 ){    AggInsert(p,"",1);    pElem = sqliteHashFirst(&p->hash);  }  return pElem ? sqliteHashData(pElem) : 0;}/*** Convert the given stack entity into a string if it isn't one** already.*/#define Stringify(P,I) if((aStack[I].flags & STK_Str)==0){hardStringify(P,I);}static int hardStringify(Vdbe *p, int i){  Stack *pStack = &p->aStack[i];  int fg = pStack->flags;  if( fg & STK_Real ){    sprintf(pStack->z,"%.15g",pStack->r);  }else if( fg & STK_Int ){    sprintf(pStack->z,"%d",pStack->i);  }else{    pStack->z[0] = 0;  }  p->zStack[i] = pStack->z;  pStack->n = strlen(pStack->z)+1;  pStack->flags = STK_Str;  return 0;}/*** Convert the given stack entity into a string that has been obtained** from sqliteMalloc().  This is different from Stringify() above in that** Stringify() will use the NBFS bytes of static string space if the string** will fit but this routine always mallocs for space.** Return non-zero if we run out of memory.*/#define Dynamicify(P,I) ((aStack[I].flags & STK_Dyn)==0 ? hardDynamicify(P,I):0)static int hardDynamicify(Vdbe *p, int i){  Stack *pStack = &p->aStack[i];  int fg = pStack->flags;  char *z;  if( (fg & STK_Str)==0 ){    hardStringify(p, i);  }  assert( (fg & STK_Dyn)==0 );  z = sqliteMallocRaw( pStack->n );  if( z==0 ) return 1;  memcpy(z, p->zStack[i], pStack->n);  p->zStack[i] = z;  pStack->flags |= STK_Dyn;  return 0;}/*** An ephemeral string value (signified by the STK_Ephem flag) contains** a pointer to a dynamically allocated string where some other entity** is responsible for deallocating that string.  Because the stack entry** does not control the string, it might be deleted without the stack** entry knowing it.**** This routine converts an ephemeral string into a dynamically allocated** string that the stack entry itself controls.  In other words, it** converts an STK_Ephem string into an STK_Dyn string.*/#define Deephemeralize(P,I) \   if( ((P)->aStack[I].flags&STK_Ephem)!=0 && hardDeephem(P,I) ){ goto no_mem;}static int hardDeephem(Vdbe *p, int i){  Stack *pStack = &p->aStack[i];  char **pzStack = &p->zStack[i];  char *z;  assert( (pStack->flags & STK_Ephem)!=0 );  z = sqliteMallocRaw( pStack->n );  if( z==0 ) return 1;  memcpy(z, *pzStack, pStack->n);  *pzStack = z;  pStack->flags &= ~STK_Ephem;  pStack->flags |= STK_Dyn;  return 0;}/*** Release the memory associated with the given stack level*/#define Release(P,I)  if((P)->aStack[I].flags&STK_Dyn){ hardRelease(P,I); }static void hardRelease(Vdbe *p, int i){  sqliteFree(p->zStack[i]);  p->zStack[i] = 0;  p->aStack[i].flags &= ~(STK_Str|STK_Dyn|STK_Static|STK_Ephem);}/*** Return TRUE if zNum is a 32-bit signed integer and write** the value of the integer into *pNum.  If zNum is not an integer** or is an integer that is too large to be expressed with just 32** bits, then return false.**** Under Linux (RedHat 7.2) this routine is much faster than atoi()** for converting strings into integers.*/static int toInt(const char *zNum, int *pNum){  int v = 0;  int neg;  int i, c;  if( *zNum=='-' ){    neg = 1;    zNum++;  }else if( *zNum=='+' ){    neg = 0;    zNum++;  }else{    neg = 0;  }  for(i=0; (c=zNum[i])>='0' && c<='9'; i++){    v = v*10 + c - '0';  }  *pNum = neg ? -v : v;  return c==0 && i>0 && (i<10 || (i==10 && memcmp(zNum,"2147483647",10)<=0));}/*** Convert the given stack entity into a integer if it isn't one** already.**** Any prior string or real representation is invalidated.  ** NULLs are converted into 0.*/#define Integerify(P,I) \    if(((P)->aStack[(I)].flags&STK_Int)==0){ hardIntegerify(P,I); }static void hardIntegerify(Vdbe *p, int i){  if( p->aStack[i].flags & STK_Real ){    p->aStack[i].i = (int)p->aStack[i].r;    Release(p, i);  }else if( p->aStack[i].flags & STK_Str ){    toInt(p->zStack[i], &p->aStack[i].i);    Release(p, i);  }else{    p->aStack[i].i = 0;  }  p->aStack[i].flags = STK_Int;}/*** Get a valid Real representation for the given stack element.**** Any prior string or integer representation is retained.** NULLs are converted into 0.0.*/#define Realify(P,I) \    if(((P)->aStack[(I)].flags&STK_Real)==0){ hardRealify(P,I); }static void hardRealify(Vdbe *p, int i){  if( p->aStack[i].flags & STK_Str ){    p->aStack[i].r = atof(p->zStack[i]);  }else if( p->aStack[i].flags & STK_Int ){    p->aStack[i].r = p->aStack[i].i;  }else{    p->aStack[i].r = 0.0;  }  p->aStack[i].flags |= STK_Real;}/*** Pop the stack N times.  Free any memory associated with the** popped stack elements.*/static void PopStack(Vdbe *p, int N){  assert( N>=0 );  if( p->zStack==0 ) return;  assert( p->aStack || sqlite_malloc_failed );  if( p->aStack==0 ) return;  while( N-- > 0 ){    if( p->aStack[p->tos].flags & STK_Dyn ){      sqliteFree(p->zStack[p->tos]);    }    p->aStack[p->tos].flags = 0;    p->zStack[p->tos] = 0;    p->tos--;  }}/*** Here is a macro to handle the common case of popping the stack** once.  This macro only works from within the sqliteVdbeExec()** function.*/#define POPSTACK \  assert(p->tos>=0); \  if( aStack[p->tos].flags & STK_Dyn ) sqliteFree(zStack[p->tos]); \  p->tos--;/*** Delete a keylist*/static void KeylistFree(Keylist *p){  while( p ){    Keylist *pNext = p->pNext;    sqliteFree(p);    p = pNext;  }}/*** Close a cursor and release all the resources that cursor happens** to hold.*/static void cleanupCursor(Cursor *pCx){  if( pCx->pCursor ){    sqliteBtreeCloseCursor(pCx->pCursor);  }  if( pCx->pBt ){    sqliteBtreeClose(pCx->pBt);  }  sqliteFree(pCx->pData);  memset(pCx, 0, sizeof(Cursor));}/*** Close all cursors*/static void closeAllCursors(Vdbe *p){  int i;  for(i=0; i<p->nCursor; i++){    cleanupCursor(&p->aCsr[i]);  }  sqliteFree(p->aCsr);  p->aCsr = 0;  p->nCursor = 0;}/*** Remove any elements that remain on the sorter for the VDBE given.*/static void SorterReset(Vdbe *p){  while( p->pSort ){    Sorter *pSorter = p->pSort;    p->pSort = pSorter->pNext;    sqliteFree(pSorter->zKey);    sqliteFree(pSorter->pData);    sqliteFree(pSorter);  }}/*** Clean up the VM after execution.**** This routine will automatically close any cursors, lists, and/or** sorters that were left open.*/static void Cleanup(Vdbe *p){  int i;  PopStack(p, p->tos+1);  closeAllCursors(p);  if( p->aMem ){    for(i=0; i<p->nMem; i++){      if( p->aMem[i].s.flags & STK_Dyn ){        sqliteFree(p->aMem[i].z);      }    }  }  sqliteFree(p->aMem);  p->aMem = 0;  p->nMem = 0;  if( p->pList ){    KeylistFree(p->pList);    p->pList = 0;  }  SorterReset(p);  if( p->pFile ){    if( p->pFile!=stdin ) fclose(p->pFile);    p->pFile = 0;  }  if( p->azField ){    sqliteFree(p->azField);    p->azField = 0;  }  p->nField = 0;  if( p->zLine ){    sqliteFree(p->zLine);    p->zLine = 0;  }  p->nLineAlloc = 0;  AggReset(&p->agg);  if( p->aSet ){    for(i=0; i<p->nSet; i++){      sqliteHashClear(&p->aSet[i].hash);    }  }  sqliteFree(p->aSet);  p->aSet = 0;  p->nSet = 0;  if( p->keylistStack ){    int ii;    for(ii = 0; ii < p->keylistStackDepth; ii++){      KeylistFree(p->keylistStack[ii]);    }    sqliteFree(p->keylistStack);    p->keylistStackDepth = 0;    p->keylistStack = 0;  }  sqliteFree(p->zErrMsg);  p->zErrMsg = 0;  p->magic = VDBE_MAGIC_DEAD;}/*** Delete an entire VDBE.*/void sqliteVdbeDelete(Vdbe *p){  int i;  if( p==0 ) return;  Cleanup(p);  if( p->pPrev ){    p->pPrev->pNext = p->pNext;  }else{    assert( p->db->pVdbe==p );    p->db->pVdbe = p->pNext;  }  if( p->pNext ){    p->pNext->pPrev = p->pPrev;  }  p->pPrev = p->pNext = 0;  if( p->nOpAlloc==0 ){    p->aOp = 0;    p->nOp = 0;  }  for(i=0; i<p->nOp; i++){    if( p->aOp[i].p3type==P3_DYNAMIC ){      sqliteFree(p->aOp[i].p3);    }  }  sqliteFree(p->aOp);  sqliteFree(p->aLabel);  sqliteFree(p->aStack);  sqliteFree(p);}/*** Give a listing of the program in the virtual machine.**** The interface is the same as sqliteVdbeExec().  But instead of** running the code, it invokes the callback once for each instruction.** This feature is used to implement "EXPLAIN".*/int sqliteVdbeList(  Vdbe *p                   /* The VDBE */){  sqlite *db = p->db;  int i;  static char *azColumnNames[] = {     "addr", "opcode", "p1",  "p2",  "p3",      "int",  "text",   "int", "int", "text",     0  };  assert( p->popStack==0 );  assert( p->explain );  p->azColName = azColumnNames;  p->azResColumn = p->zStack;  for(i=0; i<5; i++) p->zStack[i] = p->aStack[i].z;  p->rc = SQLITE_OK;  for(i=p->pc; p->rc==SQLITE_OK && i<p->nOp; i++){    if( db->flags & SQLITE_Interrupt ){      db->flags &= ~SQLITE_Interrupt;      if( db->magic!=SQLITE_MAGIC_BUSY ){        p->rc = SQLITE_MISUSE;      }else{        p->rc = SQLITE_INTERRUPT;      }      sqliteSetString(&p->zErrMsg, sqlite_error_string(p->rc), 0);      break;    }    sprintf(p->zStack[0],"%d",i);    sprintf(p->zStack[2],"%d", p->aOp[i].p1);    sprintf(p->zStack[3],"%d", p->aOp[i].p2);    if( p->aOp[i].p3type==P3_POINTER ){      sprintf(p->aStack[4].z, "ptr(%#x)", (int)p->aOp[i].p3);      p->zStack[4] = p->aStack[4].z;    }else{      p->zStack[4] = p->aOp[i].p3;    }    p->zStack[1] = sqliteOpcodeNames[p->aOp[i].opcode];    if( p->xCallback==0 ){      p->pc = i+1;      p->azResColumn = p->zStack;      p->nResColumn = 5;      return SQLITE_ROW;    }    if( sqliteSafetyOff(db) ){      p->rc = SQLITE_MISUSE;      break;    }    if( p->xCallback(p->pCbArg, 5, p->zStack, p->azColName) ){      p->rc = SQLITE_ABORT;    }    if( sqliteSafetyOn(db) ){

⌨️ 快捷键说明

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