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

📄 vdbeaux.c

📁 嵌入式数据系统软件!
💻 C
📖 第 1 页 / 共 5 页
字号:
static void freeP3(int p3type, void *p3){  if( p3 ){    switch( p3type ){      case P3_REAL:      case P3_INT64:      case P3_MPRINTF:      case P3_DYNAMIC:      case P3_KEYINFO:      case P3_KEYINFO_HANDOFF: {        sqlite3_free(p3);        break;      }      case P3_VDBEFUNC: {        VdbeFunc *pVdbeFunc = (VdbeFunc *)p3;        freeEphemeralFunction(pVdbeFunc->pFunc);        sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);        sqlite3_free(pVdbeFunc);        break;      }      case P3_FUNCDEF: {        freeEphemeralFunction((FuncDef*)p3);        break;      }      case P3_MEM: {        sqlite3ValueFree((sqlite3_value*)p3);        break;      }    }  }}/*** Change N opcodes starting at addr to No-ops.*/void sqlite3VdbeChangeToNoop(Vdbe *p, int addr, int N){  if( p && p->aOp ){    VdbeOp *pOp = &p->aOp[addr];    while( N-- ){      freeP3(pOp->p3type, pOp->p3);      memset(pOp, 0, sizeof(pOp[0]));      pOp->opcode = OP_Noop;      pOp++;    }  }}/*** Change the value of the P3 operand for a specific instruction.** This routine is useful when a large program is loaded from a** static array using sqlite3VdbeAddOpList but we want to make a** few minor changes to the program.**** If n>=0 then the P3 operand is dynamic, meaning that a copy of** the string is made into memory obtained from sqlite3_malloc().** A value of n==0 means copy bytes of zP3 up to and including the** first null byte.  If n>0 then copy n+1 bytes of zP3.**** If n==P3_KEYINFO it means that zP3 is a pointer to a KeyInfo structure.** A copy is made of the KeyInfo structure into memory obtained from** sqlite3_malloc, to be freed when the Vdbe is finalized.** n==P3_KEYINFO_HANDOFF indicates that zP3 points to a KeyInfo structure** stored in memory that the caller has obtained from sqlite3_malloc. The ** caller should not free the allocation, it will be freed when the Vdbe is** finalized.** ** Other values of n (P3_STATIC, P3_COLLSEQ etc.) indicate that zP3 points** to a string or structure that is guaranteed to exist for the lifetime of** the Vdbe. In these cases we can just copy the pointer.**** If addr<0 then change P3 on the most recently inserted instruction.*/void sqlite3VdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){  Op *pOp;  assert( p==0 || p->magic==VDBE_MAGIC_INIT );  if( p==0 || p->aOp==0 || p->db->mallocFailed ){    if (n != P3_KEYINFO) {      freeP3(n, (void*)*(char**)&zP3);    }    return;  }  if( addr<0 || addr>=p->nOp ){    addr = p->nOp - 1;    if( addr<0 ) return;  }  pOp = &p->aOp[addr];  freeP3(pOp->p3type, pOp->p3);  pOp->p3 = 0;  if( zP3==0 ){    pOp->p3 = 0;    pOp->p3type = P3_NOTUSED;  }else if( n==P3_KEYINFO ){    KeyInfo *pKeyInfo;    int nField, nByte;    nField = ((KeyInfo*)zP3)->nField;    nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]) + nField;    pKeyInfo = sqlite3_malloc( nByte );    pOp->p3 = (char*)pKeyInfo;    if( pKeyInfo ){      unsigned char *aSortOrder;      memcpy(pKeyInfo, zP3, nByte);      aSortOrder = pKeyInfo->aSortOrder;      if( aSortOrder ){        pKeyInfo->aSortOrder = (unsigned char*)&pKeyInfo->aColl[nField];        memcpy(pKeyInfo->aSortOrder, aSortOrder, nField);      }      pOp->p3type = P3_KEYINFO;    }else{      p->db->mallocFailed = 1;      pOp->p3type = P3_NOTUSED;    }  }else if( n==P3_KEYINFO_HANDOFF ){    pOp->p3 = (char*)zP3;    pOp->p3type = P3_KEYINFO;  }else if( n<0 ){    pOp->p3 = (char*)zP3;    pOp->p3type = n;  }else{    if( n==0 ) n = strlen(zP3);    pOp->p3 = sqlite3DbStrNDup(p->db, zP3, n);    pOp->p3type = P3_DYNAMIC;  }}#ifndef NDEBUG/*** Replace the P3 field of the most recently coded instruction with** comment text.*/void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){  va_list ap;  assert( p->nOp>0 || p->aOp==0 );  assert( p->aOp==0 || p->aOp[p->nOp-1].p3==0 || p->db->mallocFailed );  va_start(ap, zFormat);  sqlite3VdbeChangeP3(p, -1, sqlite3VMPrintf(p->db, zFormat, ap), P3_DYNAMIC);  va_end(ap);}#endif/*** Return the opcode for a given address.*/VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){  assert( p->magic==VDBE_MAGIC_INIT );  assert( (addr>=0 && addr<p->nOp) || p->db->mallocFailed );  return ((addr>=0 && addr<p->nOp)?(&p->aOp[addr]):0);}#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \     || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)/*** Compute a string that describes the P3 parameter for an opcode.** Use zTemp for any required temporary buffer space.*/static char *displayP3(Op *pOp, char *zTemp, int nTemp){  char *zP3;  assert( nTemp>=20 );  switch( pOp->p3type ){    case P3_KEYINFO: {      int i, j;      KeyInfo *pKeyInfo = (KeyInfo*)pOp->p3;      sqlite3_snprintf(nTemp, zTemp, "keyinfo(%d", pKeyInfo->nField);      i = strlen(zTemp);      for(j=0; j<pKeyInfo->nField; j++){        CollSeq *pColl = pKeyInfo->aColl[j];        if( pColl ){          int n = strlen(pColl->zName);          if( i+n>nTemp-6 ){            memcpy(&zTemp[i],",...",4);            break;          }          zTemp[i++] = ',';          if( pKeyInfo->aSortOrder && pKeyInfo->aSortOrder[j] ){            zTemp[i++] = '-';          }          memcpy(&zTemp[i], pColl->zName,n+1);          i += n;        }else if( i+4<nTemp-6 ){          memcpy(&zTemp[i],",nil",4);          i += 4;        }      }      zTemp[i++] = ')';      zTemp[i] = 0;      assert( i<nTemp );      zP3 = zTemp;      break;    }    case P3_COLLSEQ: {      CollSeq *pColl = (CollSeq*)pOp->p3;      sqlite3_snprintf(nTemp, zTemp, "collseq(%.20s)", pColl->zName);      zP3 = zTemp;      break;    }    case P3_FUNCDEF: {      FuncDef *pDef = (FuncDef*)pOp->p3;      sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg);      zP3 = zTemp;      break;    }    case P3_INT64: {      sqlite3_snprintf(nTemp, zTemp, "%lld", *(sqlite3_int64*)pOp->p3);      zP3 = zTemp;      break;    }    case P3_REAL: {      sqlite3_snprintf(nTemp, zTemp, "%.16g", *(double*)pOp->p3);      zP3 = zTemp;      break;    }#ifndef SQLITE_OMIT_VIRTUALTABLE    case P3_VTAB: {      sqlite3_vtab *pVtab = (sqlite3_vtab*)pOp->p3;      sqlite3_snprintf(nTemp, zTemp, "vtab:%p:%p", pVtab, pVtab->pModule);      zP3 = zTemp;      break;    }#endif    default: {      zP3 = pOp->p3;      if( zP3==0 || pOp->opcode==OP_Noop ){        zP3 = "";      }    }  }  assert( zP3!=0 );  return zP3;}#endif/*** Declare to the Vdbe that the BTree object at db->aDb[i] is used.***/void sqlite3VdbeUsesBtree(Vdbe *p, int i){  int mask;  assert( i>=0 && i<p->db->nDb );  assert( i<sizeof(p->btreeMask)*8 );  mask = 1<<i;  if( (p->btreeMask & mask)==0 ){    p->btreeMask |= mask;    sqlite3BtreeMutexArrayInsert(&p->aMutex, p->db->aDb[i].pBt);  }}#if defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)/*** Print a single opcode.  This routine is used for debugging only.*/void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){  char *zP3;  char zPtr[50];  static const char *zFormat1 = "%4d %-13s %4d %4d %s\n";  if( pOut==0 ) pOut = stdout;  zP3 = displayP3(pOp, zPtr, sizeof(zPtr));  fprintf(pOut, zFormat1,      pc, sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, zP3);  fflush(pOut);}#endif/*** Release an array of N Mem elements*/static void releaseMemArray(Mem *p, int N){  if( p ){    while( N-->0 ){      assert( N<2 || p[0].db==p[1].db );      sqlite3VdbeMemRelease(p++);    }  }}#ifndef SQLITE_OMIT_EXPLAIN/*** Give a listing of the program in the virtual machine.**** The interface is the same as sqlite3VdbeExec().  But instead of** running the code, it invokes the callback once for each instruction.** This feature is used to implement "EXPLAIN".*/int sqlite3VdbeList(  Vdbe *p                   /* The VDBE */){  sqlite3 *db = p->db;  int i;  int rc = SQLITE_OK;  assert( p->explain );  if( p->magic!=VDBE_MAGIC_RUN ) return SQLITE_MISUSE;  assert( db->magic==SQLITE_MAGIC_BUSY );  assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );  /* Even though this opcode does not put dynamic strings onto the  ** the stack, they may become dynamic if the user calls  ** sqlite3_column_text16(), causing a translation to UTF-16 encoding.  */  if( p->pTos==&p->aStack[4] ){    releaseMemArray(p->aStack, 5);  }  p->resOnStack = 0;  do{    i = p->pc++;  }while( i<p->nOp && p->explain==2 && p->aOp[i].opcode!=OP_Explain );  if( i>=p->nOp ){    p->rc = SQLITE_OK;    rc = SQLITE_DONE;  }else if( db->u1.isInterrupted ){    p->rc = SQLITE_INTERRUPT;    rc = SQLITE_ERROR;    sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(p->rc), (char*)0);  }else{    Op *pOp = &p->aOp[i];    Mem *pMem = p->aStack;    pMem->flags = MEM_Int;    pMem->type = SQLITE_INTEGER;    pMem->u.i = i;                                /* Program counter */    pMem++;    pMem->flags = MEM_Static|MEM_Str|MEM_Term;    pMem->z = (char*)sqlite3OpcodeName(pOp->opcode);  /* Opcode */    assert( pMem->z!=0 );    pMem->n = strlen(pMem->z);    pMem->type = SQLITE_TEXT;    pMem->enc = SQLITE_UTF8;    pMem++;    pMem->flags = MEM_Int;    pMem->u.i = pOp->p1;                          /* P1 */    pMem->type = SQLITE_INTEGER;    pMem++;    pMem->flags = MEM_Int;    pMem->u.i = pOp->p2;                          /* P2 */    pMem->type = SQLITE_INTEGER;    pMem++;    pMem->flags = MEM_Ephem|MEM_Str|MEM_Term;   /* P3 */    pMem->z = displayP3(pOp, pMem->zShort, sizeof(pMem->zShort));    assert( pMem->z!=0 );    pMem->n = strlen(pMem->z);    pMem->type = SQLITE_TEXT;    pMem->enc = SQLITE_UTF8;    p->nResColumn = 5 - 2*(p->explain-1);    p->pTos = pMem;    p->rc = SQLITE_OK;    p->resOnStack = 1;    rc = SQLITE_ROW;  }  return rc;}#endif /* SQLITE_OMIT_EXPLAIN */#ifdef SQLITE_DEBUG/*** Print the SQL that was used to generate a VDBE program.*/void sqlite3VdbePrintSql(Vdbe *p){  int nOp = p->nOp;  VdbeOp *pOp;  if( nOp<1 ) return;  pOp = &p->aOp[nOp-1];  if( pOp->opcode==OP_Noop && pOp->p3!=0 ){    const char *z = pOp->p3;    while( isspace(*(u8*)z) ) z++;    printf("SQL: [%s]\n", z);  }}#endif#if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)/*** Print an IOTRACE message showing SQL content.*/void sqlite3VdbeIOTraceSql(Vdbe *p){  int nOp = p->nOp;  VdbeOp *pOp;  if( sqlite3_io_trace==0 ) return;  if( nOp<1 ) return;  pOp = &p->aOp[nOp-1];  if( pOp->opcode==OP_Noop && pOp->p3!=0 ){    int i, j;    char z[1000];    sqlite3_snprintf(sizeof(z), z, "%s", pOp->p3);    for(i=0; isspace((unsigned char)z[i]); i++){}    for(j=0; z[i]; i++){      if( isspace((unsigned char)z[i]) ){        if( z[i-1]!=' ' ){          z[j++] = ' ';        }      }else{        z[j++] = z[i];      }    }    z[j] = 0;    sqlite3_io_trace("SQL %s\n", z);  }}#endif /* !SQLITE_OMIT_TRACE && SQLITE_ENABLE_IOTRACE *//*** 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 sqlite3VdbeExec().  **** This is the only way to move a VDBE from VDBE_MAGIC_INIT to** VDBE_MAGIC_RUN.*/void sqlite3VdbeMakeReady(  Vdbe *p,                       /* The VDBE */  int nVar,                      /* Number of '?' see in the SQL statement */  int nMem,                      /* Number of memory cells to allocate */  int nCursor,                   /* Number of cursors to allocate */  int isExplain                  /* True if the EXPLAIN keywords is present */){  int n;  sqlite3 *db = p->db;  assert( p!=0 );  assert( p->magic==VDBE_MAGIC_INIT );  /* There should be at least one opcode.  */  assert( p->nOp>0 );  /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. This   * is because the call to resizeOpArray() below may shrink the   * p->aOp[] array to save memory if called when in VDBE_MAGIC_RUN    * state.   */  p->magic = VDBE_MAGIC_RUN;  /* No instruction ever pushes more than a single element onto the  ** stack.  And the stack never grows on successive executions of the

⌨️ 快捷键说明

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