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

📄 vdbe.c

📁 SQLite 2.8.6 源代码,用来在Linux/Unix/Windows上编译安装.它是一个小型的数据库,但是非常好用,速度也快,一般的数据库查询之类的操作据统计比MySQL,PostgreSQL
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Opcode: Integer P1 * P3**** The integer value P1 is pushed onto the stack.  If P3 is not zero** then it is assumed to be a string representation of the same integer.*/case OP_Integer: {  int i = ++p->tos;  aStack[i].i = pOp->p1;  aStack[i].flags = STK_Int;  if( pOp->p3 ){    zStack[i] = pOp->p3;    aStack[i].flags |= STK_Str | STK_Static;    aStack[i].n = strlen(pOp->p3)+1;  }  break;}/* Opcode: String * * P3**** The string value P3 is pushed onto the stack.  If P3==0 then a** NULL is pushed onto the stack.*/case OP_String: {  int i = ++p->tos;  char *z;  z = pOp->p3;  if( z==0 ){    zStack[i] = 0;    aStack[i].n = 0;    aStack[i].flags = STK_Null;  }else{    zStack[i] = z;    aStack[i].n = strlen(z) + 1;    aStack[i].flags = STK_Str | STK_Static;  }  break;}/* Opcode: Pop P1 * ***** P1 elements are popped off of the top of stack and discarded.*/case OP_Pop: {  assert( p->tos+1>=pOp->p1 );  PopStack(p, pOp->p1);  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: {  int i = p->tos - pOp->p1;  int j = ++p->tos;  VERIFY( if( i<0 ) goto not_enough_stack; )  memcpy(&aStack[j], &aStack[i], sizeof(aStack[i])-NBFS);  if( aStack[j].flags & STK_Str ){    int isStatic = (aStack[j].flags & STK_Static)!=0;    if( pOp->p2 || isStatic ){      zStack[j] = zStack[i];      aStack[j].flags &= ~STK_Dyn;      if( !isStatic ) aStack[j].flags |= STK_Ephem;    }else if( aStack[i].n<=NBFS ){      memcpy(aStack[j].z, zStack[i], aStack[j].n);      zStack[j] = aStack[j].z;      aStack[j].flags &= ~(STK_Static|STK_Dyn|STK_Ephem);    }else{      zStack[j] = sqliteMallocRaw( aStack[j].n );      if( zStack[j]==0 ) goto no_mem;      memcpy(zStack[j], zStack[i], aStack[j].n);      aStack[j].flags &= ~(STK_Static|STK_Ephem);      aStack[j].flags |= STK_Dyn;    }  }  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: {  int from = p->tos - pOp->p1;  int to = p->tos;  int i;  Stack ts;  char *tz;  VERIFY( if( from<0 ) goto not_enough_stack; )  Deephemeralize(p, from);  ts = aStack[from];  tz = zStack[from];  Deephemeralize(p, to);  for(i=from; i<to; i++){    Deephemeralize(p, i+1);    aStack[i] = aStack[i+1];    assert( (aStack[i].flags & STK_Ephem)==0 );    if( aStack[i].flags & (STK_Dyn|STK_Static) ){      zStack[i] = zStack[i+1];    }else{      zStack[i] = aStack[i].z;    }  }  aStack[to] = ts;  assert( (aStack[to].flags & STK_Ephem)==0 );  if( aStack[to].flags & (STK_Dyn|STK_Static) ){    zStack[to] = tz;  }else{    zStack[to] = aStack[to].z;  }  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: {  int from = p->tos;  int to = p->tos - pOp->p1;  VERIFY( if( to<0 ) goto not_enough_stack; )  if( aStack[to].flags & STK_Dyn ){    sqliteFree(zStack[to]);  }  Deephemeralize(p, from);  aStack[to] = aStack[from];  if( aStack[to].flags & (STK_Dyn|STK_Static|STK_Ephem) ){    zStack[to] = zStack[from];  }else{    zStack[to] = aStack[to].z;  }  aStack[from].flags = 0;  p->tos--;  break;}/* Opcode: ColumnName P1 * P3**** P3 becomes the P1-th column name (first is 0).  An array of pointers** to all column names is passed as the 4th parameter to the callback.*/case OP_ColumnName: {  assert( pOp->p1>=0 && pOp->p1<p->nOp );  p->azColName[pOp->p1] = pOp->p3;  p->nCallback = 0;  break;}/* Opcode: Callback P1 * ***** Pop P1 values off the stack and form them into an array.  Then** invoke the callback function using the newly formed array as the** 3rd parameter.*/case OP_Callback: {  int i = p->tos - pOp->p1 + 1;  int j;  VERIFY( if( i<0 ) goto not_enough_stack; )  for(j=i; j<=p->tos; j++){    if( aStack[j].flags & STK_Null ){      zStack[j] = 0;    }else{      Stringify(p, j);    }  }  zStack[p->tos+1] = 0;  if( p->xCallback==0 ){    p->azResColumn = &zStack[i];    p->nResColumn = pOp->p1;    p->popStack = pOp->p1;    p->pc = pc + 1;    return SQLITE_ROW;  }  if( sqliteSafetyOff(db) ) goto abort_due_to_misuse;   if( p->xCallback(p->pCbArg, pOp->p1, &zStack[i], p->azColName)!=0 ){    rc = SQLITE_ABORT;  }  if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;  p->nCallback++;  PopStack(p, pOp->p1);  if( sqlite_malloc_failed ) goto no_mem;  break;}/* Opcode: NullCallback P1 * ***** Invoke the callback function once with the 2nd argument (the** number of columns) equal to P1 and with the 4th argument (the** names of the columns) set according to prior OP_ColumnName** instructions.  This is all like the regular** OP_Callback or OP_SortCallback opcodes.  But the 3rd argument** which normally contains a pointer to an array of pointers to** data is NULL.**** The callback is only invoked if there have been no prior calls** to OP_Callback or OP_SortCallback.**** This opcode is used to report the number and names of columns** in cases where the result set is empty.*/case OP_NullCallback: {  if( p->nCallback==0 && p->xCallback!=0 ){    if( sqliteSafetyOff(db) ) goto abort_due_to_misuse;     if( p->xCallback(p->pCbArg, pOp->p1, 0, p->azColName)!=0 ){      rc = SQLITE_ABORT;    }    if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;    p->nCallback++;    if( sqlite_malloc_failed ) goto no_mem;  }  p->nResColumn = pOp->p1;  break;}/* 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;  nField = pOp->p1;  zSep = pOp->p3;  if( zSep==0 ) zSep = "";  nSep = strlen(zSep);  VERIFY( if( p->tos+1<nField ) goto not_enough_stack; )  nByte = 1 - nSep;  for(i=p->tos-nField+1; i<=p->tos; i++){    if( aStack[i].flags & STK_Null ){      nByte = -1;      break;    }else{      Stringify(p, i);      nByte += aStack[i].n - 1 + nSep;    }  }  if( nByte<0 ){    if( pOp->p2==0 ) PopStack(p, nField);    p->tos++;    aStack[p->tos].flags = STK_Null;    zStack[p->tos] = 0;    break;  }  zNew = sqliteMallocRaw( nByte );  if( zNew==0 ) goto no_mem;  j = 0;  for(i=p->tos-nField+1; i<=p->tos; i++){    if( (aStack[i].flags & STK_Null)==0 ){      memcpy(&zNew[j], zStack[i], aStack[i].n-1);      j += aStack[i].n-1;    }    if( nSep>0 && i<p->tos ){      memcpy(&zNew[j], zSep, nSep);      j += nSep;    }  }  zNew[j] = 0;  if( pOp->p2==0 ) PopStack(p, nField);  p->tos++;  aStack[p->tos].n = nByte;  aStack[p->tos].flags = STK_Str|STK_Dyn;  zStack[p->tos] = 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: {  int tos = p->tos;  int nos = tos - 1;  VERIFY( if( nos<0 ) goto not_enough_stack; )  if( ((aStack[tos].flags | aStack[nos].flags) & STK_Null)!=0 ){    POPSTACK;    Release(p, nos);    aStack[nos].flags = STK_Null;  }else if( (aStack[tos].flags & aStack[nos].flags & STK_Int)==STK_Int ){    int a, b;    a = aStack[tos].i;    b = aStack[nos].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;      }    }    POPSTACK;    Release(p, nos);    aStack[nos].i = b;    aStack[nos].flags = STK_Int;  }else{    double a, b;    Realify(p, tos);    Realify(p, nos);    a = aStack[tos].r;    b = aStack[nos].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;      }    }    POPSTACK;    Release(p, nos);    aStack[nos].r = b;    aStack[nos].flags = STK_Real;  }  break;divide_by_zero:  PopStack(p, 2);  p->tos = nos;  aStack[nos].flags = STK_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;  sqlite_func ctx;  n = pOp->p1;  VERIFY( if( n<0 ) goto bad_instruction; )  VERIFY( if( p->tos+1<n ) goto not

⌨️ 快捷键说明

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