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

📄 vdbe.c

📁 sqlite-source-2_8_16.zip 轻量级嵌入式数据库源码
💻 C
📖 第 1 页 / 共 5 页
字号:
** invoke the callback function using the newly formed array as the** 3rd parameter.*/case OP_Callback: {  int i;  char **azArgv = p->zArgv;  Mem *pCol;  pCol = &pTos[1-pOp->p1];  assert( pCol>=p->aStack );  for(i=0; i<pOp->p1; i++, pCol++){    if( pCol->flags & MEM_Null ){      azArgv[i] = 0;    }else{      Stringify(pCol);      azArgv[i] = pCol->z;    }  }  azArgv[i] = 0;  p->nCallback++;  p->azResColumn = azArgv;  assert( p->nResColumn==pOp->p1 );  p->popStack = pOp->p1;  p->pc = pc + 1;  p->pTos = pTos;  return SQLITE_ROW;}/* Opcode: Concat P1 P2 P3**** Look at the first P1 elements of the stack.  Append them all ** together with the lowest element first.  Use P3 as a separator.  ** Put the result on the top of the stack.  The original P1 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.**** If P3 is NULL, then use no separator.  When P1==1, this routine** makes a copy of the top stack element into memory obtained** from sqliteMalloc().*/case OP_Concat: {  char *zNew;  int nByte;  int nField;  int i, j;  char *zSep;  int nSep;  Mem *pTerm;  nField = pOp->p1;  zSep = pOp->p3;  if( zSep==0 ) zSep = "";  nSep = strlen(zSep);  assert( &pTos[1-nField] >= p->aStack );  nByte = 1 - nSep;  pTerm = &pTos[1-nField];  for(i=0; i<nField; i++, pTerm++){    if( pTerm->flags & MEM_Null ){      nByte = -1;      break;    }else{      Stringify(pTerm);      nByte += pTerm->n - 1 + nSep;    }  }  if( nByte<0 ){    if( pOp->p2==0 ){      popStack(&pTos, nField);    }    pTos++;    pTos->flags = MEM_Null;    break;  }  zNew = sqliteMallocRaw( nByte );  if( zNew==0 ) goto no_mem;  j = 0;  pTerm = &pTos[1-nField];  for(i=j=0; i<nField; i++, pTerm++){    assert( pTerm->flags & MEM_Str );    memcpy(&zNew[j], pTerm->z, pTerm->n-1);    j += pTerm->n-1;    if( nSep>0 && i<nField-1 ){      memcpy(&zNew[j], zSep, nSep);      j += nSep;    }  }  zNew[j] = 0;  if( pOp->p2==0 ){    popStack(&pTos, nField);  }  pTos++;  pTos->n = nByte;  pTos->flags = MEM_Str|MEM_Dyn;  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:case OP_Subtract:case OP_Multiply:case OP_Divide:case OP_Remainder: {  Mem *pNos = &pTos[-1];  assert( pNos>=p->aStack );  if( ((pTos->flags | pNos->flags) & MEM_Null)!=0 ){    Release(pTos);    pTos--;    Release(pTos);    pTos->flags = MEM_Null;  }else if( (pTos->flags & pNos->flags & MEM_Int)==MEM_Int ){    int a, b;    a = pTos->i;    b = pNos->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;        b /= a;        break;      }      default: {        if( a==0 ) goto divide_by_zero;        b %= a;        break;      }    }    Release(pTos);    pTos--;    Release(pTos);    pTos->i = b;    pTos->flags = MEM_Int;  }else{    double a, b;    Realify(pTos);    Realify(pNos);    a = pTos->r;    b = pNos->r;    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: {        int ia = (int)a;        int ib = (int)b;        if( ia==0.0 ) goto divide_by_zero;        b = ib % ia;        break;      }    }    Release(pTos);    pTos--;    Release(pTos);    pTos->r = b;    pTos->flags = MEM_Real;  }  break;divide_by_zero:  Release(pTos);  pTos--;  Release(pTos);  pTos->flags = MEM_Null;  break;}/* Opcode: Function P1 * P3**** Invoke a user function (P3 is a pointer to a Function structure that** defines the function) with P1 string arguments taken from the stack.** Pop all arguments from the stack and push back the result.**** See also: AggFunc*/case OP_Function: {  int n, i;  Mem *pArg;  char **azArgv;  sqlite_func ctx;  n = pOp->p1;  pArg = &pTos[1-n];  azArgv = p->zArgv;  for(i=0; i<n; i++, pArg++){    if( pArg->flags & MEM_Null ){      azArgv[i] = 0;    }else{      Stringify(pArg);      azArgv[i] = pArg->z;    }  }  ctx.pFunc = (FuncDef*)pOp->p3;  ctx.s.flags = MEM_Null;  ctx.s.z = 0;  ctx.isError = 0;  ctx.isStep = 0;  if( sqliteSafetyOff(db) ) goto abort_due_to_misuse;  (*ctx.pFunc->xFunc)(&ctx, n, (const char**)azArgv);  if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;  popStack(&pTos, n);  pTos++;  *pTos = ctx.s;  if( pTos->flags & MEM_Short ){    pTos->z = pTos->zShort;  }  if( ctx.isError ){    sqliteSetString(&p->zErrMsg,        (pTos->flags & MEM_Str)!=0 ? pTos->z : "user function error", (char*)0);    rc = SQLITE_ERROR;  }  break;}/* Opcode: BitAnd * * ***** Pop the top two elements from the stack.  Convert both elements** to integers.  Push back onto the stack the bit-wise AND of the** two elements.** If either operand is NULL, the result is NULL.*//* Opcode: BitOr * * ***** Pop the top two elements from the stack.  Convert both elements** to integers.  Push back onto the stack the bit-wise OR of the** two elements.** If either operand is NULL, the result is NULL.*//* Opcode: ShiftLeft * * ***** Pop the top two elements from the stack.  Convert both elements** to integers.  Push back onto the stack the top element shifted** left by N bits where N is the second element on the stack.** If either operand is NULL, the result is NULL.*//* Opcode: ShiftRight * * ***** Pop the top two elements from the stack.  Convert both elements** to integers.  Push back onto the stack the top element shifted** right by N bits where N is the second element on the stack.** If either operand is NULL, the result is NULL.*/case OP_BitAnd:case OP_BitOr:case OP_ShiftLeft:case OP_ShiftRight: {  Mem *pNos = &pTos[-1];  int a, b;  assert( pNos>=p->aStack );  if( (pTos->flags | pNos->flags) & MEM_Null ){    popStack(&pTos, 2);    pTos++;    pTos->flags = MEM_Null;    break;  }  Integerify(pTos);  Integerify(pNos);  a = pTos->i;  b = pNos->i;  switch( pOp->opcode ){    case OP_BitAnd:      a &= b;     break;    case OP_BitOr:       a |= b;     break;    case OP_ShiftLeft:   a <<= b;    break;    case OP_ShiftRight:  a >>= b;    break;    default:   /* CANT HAPPEN */     break;  }  assert( (pTos->flags & MEM_Dyn)==0 );  assert( (pNos->flags & MEM_Dyn)==0 );  pTos--;  Release(pTos);  pTos->i = a;  pTos->flags = MEM_Int;  break;}/* Opcode: AddImm  P1 * *** ** Add the value P1 to whatever is on top of the stack.  The result** is always an integer.**** To force the top of the stack to be an integer, just add 0.*/case OP_AddImm: {  assert( pTos>=p->aStack );  Integerify(pTos);  pTos->i += pOp->p1;  break;}/* Opcode: ForceInt P1 P2 ***** Convert the top of the stack into an integer.  If the current top of** the stack is not numeric (meaning that is is a NULL or a string that** does not look like an integer or floating point number) then pop the** stack and jump to P2.  If the top of the stack is numeric then** convert it into the least integer that is greater than or equal to its** current value if P1==0, or to the least integer that is strictly** greater than its current value if P1==1.*/case OP_ForceInt: {  int v;  assert( pTos>=p->aStack );  if( (pTos->flags & (MEM_Int|MEM_Real))==0         && ((pTos->flags & MEM_Str)==0 || sqliteIsNumber(pTos->z)==0) ){    Release(pTos);    pTos--;    pc = pOp->p2 - 1;    break;  }  if( pTos->flags & MEM_Int ){    v = pTos->i + (pOp->p1!=0);  }else{    Realify(pTos);    v = (int)pTos->r;    if( pTos->r>(double)v ) v++;    if( pOp->p1 && pTos->r==(double)v ) v++;  }  Release(pTos);  pTos->i = v;  pTos->flags = MEM_Int;  break;}/* Opcode: MustBeInt P1 P2 *** ** Force the top of the stack to be an integer.  If the top of the** stack is not an integer and cannot be converted into an integer** with out data loss, then jump immediately to P2, or if P2==0** raise an SQLITE_MISMATCH exception.**** If the top of the stack is not an integer and P2 is not zero and** P1 is 1, then the stack is popped.  In all other cases, the depth** of the stack is unchanged.*/case OP_MustBeInt: {  assert( pTos>=p->aStack );  if( pTos->flags & MEM_Int ){    /* Do nothing */  }else if( pTos->flags & MEM_Real ){    int i = (int)pTos->r;    double r = (double)i;    if( r!=pTos->r ){      goto mismatch;    }    pTos->i = i;  }else if( pTos->flags & MEM_Str ){    int v;    if( !toInt(pTos->z, &v) ){      double r;      if( !sqliteIsNumber(pTos->z) ){        goto mismatch;      }      Realify(pTos);      v = (int)pTos->r;      r = (double)v;      if( r!=pTos->r ){        goto mismatch;      }    }    pTos->i = v;  }else{    goto mismatch;  }  Release(pTos);  pTos->flags = MEM_Int;  break;mismatch:  if( pOp->p2==0 ){    rc = SQLITE_MISMATCH;    goto abort_due_to_error;  }else{    if( pOp->p1 ) popStack(&pTos, 1);    pc = pOp->p2 - 1;  }  break;}

⌨️ 快捷键说明

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