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

📄 vdbe.c

📁 sqlite-3.4.1,嵌入式数据库.是一个功能强大的开源数据库,给学习和研发以及小型公司的发展带来了全所未有的好处.
💻 C
📖 第 1 页 / 共 5 页
字号:
case OP_Blob: {  pTos++;  assert( pOp->p1 < SQLITE_MAX_LENGTH ); /* Due to SQLITE_MAX_SQL_LENGTH */  sqlite3VdbeMemSetStr(pTos, pOp->p3, pOp->p1, 0, 0);  pTos->enc = encoding;  break;}#endif /* SQLITE_OMIT_BLOB_LITERAL *//* Opcode: Variable P1 * ***** Push the value of variable P1 onto the stack.  A variable is** an unknown in the original SQL string as handed to sqlite3_compile().** Any occurance of the '?' character in the original SQL is considered** a variable.  Variables in the SQL string are number from left to** right beginning with 1.  The values of variables are set using the** sqlite3_bind() API.*/case OP_Variable: {  int j = pOp->p1 - 1;  Mem *pVar;  assert( j>=0 && j<p->nVar );  pVar = &p->aVar[j];  if( sqlite3VdbeMemTooBig(pVar) ){    goto too_big;  }  pTos++;  sqlite3VdbeMemShallowCopy(pTos, &p->aVar[j], MEM_Static);  break;}/* Opcode: Pop P1 * ***** P1 elements are popped off of the top of stack and discarded.*/case OP_Pop: {            /* no-push */  assert( pOp->p1>=0 );  popStack(&pTos, pOp->p1);  assert( pTos>=&p->aStack[-1] );  break;}/* Opcode: Dup P1 P2 ***** A copy of the P1-th element of the stack ** is made and pushed onto the top of the stack.** The top of the stack is element 0.  So the** instruction "Dup 0 0 0" will make a copy of the** top of the stack.**** If the content of the P1-th element is a dynamically** allocated string, then a new copy of that string** is made if P2==0.  If P2!=0, then just a pointer** to the string is copied.**** Also see the Pull instruction.*/case OP_Dup: {  Mem *pFrom = &pTos[-pOp->p1];  assert( pFrom<=pTos && pFrom>=p->aStack );  pTos++;  sqlite3VdbeMemShallowCopy(pTos, pFrom, MEM_Ephem);  if( pOp->p2 ){    Deephemeralize(pTos);  }  break;}/* Opcode: Pull P1 * ***** The P1-th element is removed from its current location on ** the stack and pushed back on top of the stack.  The** top of the stack is element 0, so "Pull 0 0 0" is** a no-op.  "Pull 1 0 0" swaps the top two elements of** the stack.**** See also the Dup instruction.*/case OP_Pull: {            /* no-push */  Mem *pFrom = &pTos[-pOp->p1];  int i;  Mem ts;  ts = *pFrom;  Deephemeralize(pTos);  for(i=0; i<pOp->p1; i++, pFrom++){    Deephemeralize(&pFrom[1]);    assert( (pFrom[1].flags & MEM_Ephem)==0 );    *pFrom = pFrom[1];    if( pFrom->flags & MEM_Short ){      assert( pFrom->flags & (MEM_Str|MEM_Blob) );      assert( pFrom->z==pFrom[1].zShort );      pFrom->z = pFrom->zShort;    }  }  *pTos = ts;  if( pTos->flags & MEM_Short ){    assert( pTos->flags & (MEM_Str|MEM_Blob) );    assert( pTos->z==pTos[-pOp->p1].zShort );    pTos->z = pTos->zShort;  }  break;}/* Opcode: Push P1 * ***** Overwrite the value of the P1-th element down on the** stack (P1==0 is the top of the stack) with the value** of the top of the stack.  Then pop the top of the stack.*/case OP_Push: {            /* no-push */  Mem *pTo = &pTos[-pOp->p1];  assert( pTo>=p->aStack );  sqlite3VdbeMemMove(pTo, pTos);  pTos--;  break;}/* Opcode: Callback P1 * ***** The top P1 values on the stack represent a single result row from** a query.  This opcode causes the sqlite3_step() call to terminate** with an SQLITE_ROW return code and it sets up the sqlite3_stmt** structure to provide access to the top P1 values as the result** row.  When the sqlite3_step() function is run again, the top P1** values will be automatically popped from the stack before the next** instruction executes.*/case OP_Callback: {            /* no-push */  Mem *pMem;  Mem *pFirstColumn;  assert( p->nResColumn==pOp->p1 );  /* Data in the pager might be moved or changed out from under us  ** in between the return from this sqlite3_step() call and the  ** next call to sqlite3_step().  So deephermeralize everything on   ** the stack.  Note that ephemeral data is never stored in memory   ** cells so we do not have to worry about them.  */  pFirstColumn = &pTos[0-pOp->p1];  for(pMem = p->aStack; pMem<pFirstColumn; pMem++){    Deephemeralize(pMem);  }  /* Invalidate all ephemeral cursor row caches */  p->cacheCtr = (p->cacheCtr + 2)|1;  /* Make sure the results of the current row are \000 terminated  ** and have an assigned type.  The results are deephemeralized as  ** as side effect.  */  for(; pMem<=pTos; pMem++ ){    sqlite3VdbeMemNulTerminate(pMem);    storeTypeInfo(pMem, encoding);  }  /* Set up the statement structure so that it will pop the current  ** results from the stack when the statement returns.  */  p->resOnStack = 1;  p->nCallback++;  p->popStack = pOp->p1;  p->pc = pc + 1;  p->pTos = pTos;  return SQLITE_ROW;}/* Opcode: Concat P1 P2 ***** Look at the first P1+2 elements of the stack.  Append them all ** together with the lowest element first.  The original P1+2 elements** are popped from the stack if P2==0 and retained if P2==1.  If** any element of the stack is NULL, then the result is NULL.**** When P1==1, this routine makes a copy of the top stack element** into memory obtained from sqliteMalloc().*/case OP_Concat: {           /* same as TK_CONCAT */  char *zNew;  i64 nByte;  int nField;  int i, j;  Mem *pTerm;  /* Loop through the stack elements to see how long the result will be. */  nField = pOp->p1 + 2;  pTerm = &pTos[1-nField];  nByte = 0;  for(i=0; i<nField; i++, pTerm++){    assert( pOp->p2==0 || (pTerm->flags&MEM_Str) );    if( pTerm->flags&MEM_Null ){      nByte = -1;      break;    }    ExpandBlob(pTerm);    Stringify(pTerm, encoding);    nByte += pTerm->n;  }  if( nByte<0 ){    /* If nByte is less than zero, then there is a NULL value on the stack.    ** In this case just pop the values off the stack (if required) and    ** push on a NULL.    */    if( pOp->p2==0 ){      popStack(&pTos, nField);    }    pTos++;    pTos->flags = MEM_Null;  }else{    /* Otherwise malloc() space for the result and concatenate all the    ** stack values.    */    if( nByte+2>SQLITE_MAX_LENGTH ){      goto too_big;    }    zNew = sqliteMallocRaw( nByte+2 );    if( zNew==0 ) goto no_mem;    j = 0;    pTerm = &pTos[1-nField];    for(i=j=0; i<nField; i++, pTerm++){      int n = pTerm->n;      assert( pTerm->flags & (MEM_Str|MEM_Blob) );      memcpy(&zNew[j], pTerm->z, n);      j += n;    }    zNew[j] = 0;    zNew[j+1] = 0;    assert( j==nByte );    if( pOp->p2==0 ){      popStack(&pTos, nField);    }    pTos++;    pTos->n = j;    pTos->flags = MEM_Str|MEM_Dyn|MEM_Term;    pTos->xDel = 0;    pTos->enc = encoding;    pTos->z = zNew;  }  break;}/* Opcode: Add * * ***** Pop the top two elements from the stack, add them together,** and push the result back onto the stack.  If either element** is a string then it is converted to a double using the atof()** function before the addition.** If either operand is NULL, the result is NULL.*//* Opcode: Multiply * * ***** Pop the top two elements from the stack, multiply them together,** and push the result back onto the stack.  If either element** is a string then it is converted to a double using the atof()** function before the multiplication.** If either operand is NULL, the result is NULL.*//* Opcode: Subtract * * ***** Pop the top two elements from the stack, subtract the** first (what was on top of the stack) from the second (the** next on stack)** and push the result back onto the stack.  If either element** is a string then it is converted to a double using the atof()** function before the subtraction.** If either operand is NULL, the result is NULL.*//* Opcode: Divide * * ***** Pop the top two elements from the stack, divide the** first (what was on top of the stack) from the second (the** next on stack)** and push the result back onto the stack.  If either element** is a string then it is converted to a double using the atof()** function before the division.  Division by zero returns NULL.** If either operand is NULL, the result is NULL.*//* Opcode: Remainder * * ***** Pop the top two elements from the stack, divide the** first (what was on top of the stack) from the second (the** next on stack)** and push the remainder after division onto the stack.  If either element** is a string then it is converted to a double using the atof()** function before the division.  Division by zero returns NULL.** If either operand is NULL, the result is NULL.*/case OP_Add:                   /* same as TK_PLUS, no-push */case OP_Subtract:              /* same as TK_MINUS, no-push */case OP_Multiply:              /* same as TK_STAR, no-push */case OP_Divide:                /* same as TK_SLASH, no-push */case OP_Remainder: {           /* same as TK_REM, no-push */  Mem *pNos = &pTos[-1];  int flags;  assert( pNos>=p->aStack );  flags = pTos->flags | pNos->flags;  if( (flags & MEM_Null)!=0 ){    Release(pTos);    pTos--;    Release(pTos);    pTos->flags = MEM_Null;  }else if( (pTos->flags & pNos->flags & MEM_Int)==MEM_Int ){    i64 a, b;    a = pTos->u.i;    b = pNos->u.i;    switch( pOp->opcode ){      case OP_Add:         b += a;       break;      case OP_Subtract:    b -= a;       break;      case OP_Multiply:    b *= a;       break;      case OP_Divide: {        if( a==0 ) goto divide_by_zero;        /* Dividing the largest possible negative 64-bit integer (1<<63) by         ** -1 returns an integer to large to store in a 64-bit data-type. On        ** some architectures, the value overflows to (1<<63). On others,        ** a SIGFPE is issued. The following statement normalizes this        ** behaviour so that all architectures behave as if integer         ** overflow occured.        */        if( a==-1 && b==(((i64)1)<<63) ) a = 1;        b /= a;        break;      }      default: {        if( a==0 ) goto divide_by_zero;        if( a==-1 ) a = 1;        b %= a;        break;      }    }    Release(pTos);    pTos--;    Release(pTos);    pTos->u.i = b;    pTos->flags = MEM_Int;  }else{    double a, b;    a = sqlite3VdbeRealValue(pTos);    b = sqlite3VdbeRealValue(pNos);    switch( pOp->opcode ){      case OP_Add:         b += a;       break;      case OP_Subtract:    b -= a;       break;      case OP_Multiply:    b *= a;       break;      case OP_Divide: {        if( a==0.0 ) goto divide_by_zero;        b /= a;        break;      }      default: {        i64 ia = (i64)a;        i64 ib = (i64)b;        if( ia==0 ) goto divide_by_zero;        if( ia==-1 ) ia = 1;        b = ib % ia;        break;      }    }    if( sqlite3_isnan(b) ){      goto divide_by_zero;    }    Release(pTos);    pTos--;    Release(pTos);    pTos->r = b;    pTos->flags = MEM_Real;    if( (flags & MEM_Real)==0 ){      sqlite3VdbeIntegerAffinity(pTos);    }  }  break;divide_by_zero:  Release(pTos);  pTos--;  Release(pTos);  pTos->flags = MEM_Null;  break;}/* Opcode: CollSeq * * P3**** P3 is a pointer to a CollSeq struct. If the next call to a user function** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will** be returned. This is used by the built-in min(), max() and nullif()** functions.**** The interface used by the implementation of the aforementioned functions** to retrieve the collation sequence set by this opcode is not available** publicly, only to user functions defined in func.c.*/case OP_CollSeq: {             /* no-push */  assert( pOp->p3type==P3_COLLSEQ );  break;}/* Opcode: Function P1 P2 P3**** Invoke a user function (P3 is a pointer to a Function structure that** defines the function) with P2 arguments taken from the stack.  Pop all** arguments from the stack and push back the result.**** P1 is a 32-bit bitmask indicating whether or not each argument to the ** function was determined to be constant at compile time. If the first** argument was constant then bit 0 of P1 is set. This is used to determine** whether meta data associated with a user function argument using the** sqlite3_set_auxdata() API may be safely retained until the next** invocation of this opcode.**** See also: AggStep and AggFinal*/case OP_Function: {  int i;  Mem *pArg;  sqlite3_context ctx;  sqlite3_value **apVal;  int n = pOp->p2;

⌨️ 快捷键说明

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