/ Check-in [b96ec281]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Remove unnecessary code from the VDBE. (CVS 814)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:b96ec281ff29aad8af340b30c6ff4e129ffeeefb
User & Date: drh 2003-01-06 23:54:06
Context
2003-01-07
01:44
Optimizations to the tokenizer. (CVS 815) check-in: 032b3daa user: drh tags: trunk
2003-01-06
23:54
Remove unnecessary code from the VDBE. (CVS 814) check-in: b96ec281 user: drh tags: trunk
2003-01-05
21:41
More optimizations. (CVS 813) check-in: 5809132f user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/vdbe.c.

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
...
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
....
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
....
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
....
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
....
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
....
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
....
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
....
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
....
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
....
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
....
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
....
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
....
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
....
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
....
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
....
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
....
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
....
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
....
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
....
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
....
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
....
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
....
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
....
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
....
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
....
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
....
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
....
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.190 2003/01/05 21:41:42 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** The makefile scans this source file and creates the following
** array of string constants which are the names of all VDBE opcodes.
................................................................................
** once.  This macro only works from within the sqliteVdbeExec()
** function.
*/
#define POPSTACK \
 if( aStack[p->tos].flags & STK_Dyn ) sqliteFree(zStack[p->tos]); \
 p->tos--;

/*
** Make sure space has been allocated to hold at least N
** stack elements.  Allocate additional stack space if
** necessary.
**
** Return 0 on success and non-zero if there are memory
** allocation errors.
*/
#define NeedStack(P,N) (((P)->nStackAlloc<=(N)) ? hardNeedStack(P,N) : 0)
static int hardNeedStack(Vdbe *p, int N){
  int oldAlloc;
  int i;
  if( N>=p->nStackAlloc ){
    Stack *aNew;
    char **zNew;
    oldAlloc = p->nStackAlloc;
    p->nStackAlloc = N + 20;
    aNew = sqliteRealloc(p->aStack, p->nStackAlloc*sizeof(p->aStack[0]));
    zNew = aNew ? sqliteRealloc(p->zStack, p->nStackAlloc*sizeof(char*)) : 0;
    if( zNew==0 ){
      sqliteFree(aNew);
      sqliteFree(p->aStack);
      sqliteFree(p->zStack);
      p->aStack = 0;
      p->zStack = 0;
      p->nStackAlloc = 0;
      p->aStack = 0;
      p->zStack = 0;
      return 1;
    }
    p->aStack = aNew;
    p->zStack = zNew;
    for(i=oldAlloc; i<p->nStackAlloc; i++){
      p->zStack[i] = 0;
      p->aStack[i].flags = 0;
    }
  }
  return 0;
}

/*
** Return TRUE if zNum is a floating-point or integer number.
*/
static int isNumber(const char *zNum){
  if( *zNum=='-' || *zNum=='+' ) zNum++;
  if( !isdigit(*zNum) ) return 0;
  while( isdigit(*zNum) ) zNum++;
................................................................................
  /* No instruction ever pushes more than a single element onto the
  ** stack.  And the stack never grows on successive executions of the
  ** same loop.  So the total number of instructions is an upper bound
  ** on the maximum stack depth required.
  **
  ** Allocation all the stack space we will ever need.
  */
  NeedStack(p, p->nOp);
  zStack = p->zStack;
  aStack = p->aStack;
  p->tos = -1;
#ifdef VDBE_PROFILE
  {
    int i;
    for(i=0; i<p->nOp; i++){
      p->aOp[i].cnt = 0;
      p->aOp[i].cycles = 0;
................................................................................
/* 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;
  VERIFY( if( NeedStack(p, p->tos) ) goto no_mem; )
  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;
  }
................................................................................
**
** 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;
  VERIFY( if( NeedStack(p, p->tos) ) goto no_mem; )
  z = pOp->p3;
  if( z==0 ){
    zStack[i] = 0;
    aStack[i].n = 0;
    aStack[i].flags = STK_Null;
  }else{
    zStack[i] = z;
................................................................................
**
** 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; )
  VERIFY( if( NeedStack(p, p->tos) ) goto no_mem; )
  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;
................................................................................
** 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; )
  VERIFY( if( NeedStack(p, p->tos+2) ) goto no_mem; )
  for(j=i; j<=p->tos; j++){
    if( aStack[j].flags & STK_Null ){
      zStack[j] = 0;
    }else{
      if( Stringify(p, j) ) goto no_mem;
    }
  }
................................................................................
    }else{
      if( Stringify(p, i) ) goto no_mem;
      nByte += aStack[i].n - 1 + nSep;
    }
  }
  if( nByte<0 ){
    if( pOp->p2==0 ) PopStack(p, nField);
    VERIFY( NeedStack(p, p->tos+1); )
    p->tos++;
    aStack[p->tos].flags = STK_Null;
    zStack[p->tos] = 0;
    break;
  }
  zNew = sqliteMallocRaw( nByte );
  if( zNew==0 ) goto no_mem;
................................................................................
    if( nSep>0 && i<p->tos ){
      memcpy(&zNew[j], zSep, nSep);
      j += nSep;
    }
  }
  zNew[j] = 0;
  if( pOp->p2==0 ) PopStack(p, nField);
  VERIFY( NeedStack(p, p->tos+1); )
  p->tos++;
  aStack[p->tos].n = nByte;
  aStack[p->tos].flags = STK_Str|STK_Dyn;
  zStack[p->tos] = zNew;
  break;
}

................................................................................
  ctx.pFunc = (FuncDef*)pOp->p3;
  ctx.s.flags = STK_Null;
  ctx.z = 0;
  ctx.isError = 0;
  ctx.isStep = 0;
  (*ctx.pFunc->xFunc)(&ctx, n, (const char**)&zStack[p->tos-n+1]);
  PopStack(p, n);
  VERIFY( NeedStack(p, p->tos+1); )
  p->tos++;
  aStack[p->tos] = ctx.s;
  if( ctx.s.flags & STK_Dyn ){
    zStack[p->tos] = ctx.z;
  }else if( ctx.s.flags & STK_Str ){
    zStack[p->tos] = aStack[p->tos].z;
  }else{
................................................................................
  for(i=p->tos-nField+1; i<=p->tos; i++){
    if( (aStack[i].flags & STK_Null)==0 ){
      memcpy(&zNewRecord[j], zStack[i], aStack[i].n);
      j += aStack[i].n;
    }
  }
  PopStack(p, nField);
  VERIFY( NeedStack(p, p->tos+1); )
  p->tos++;
  aStack[p->tos].n = nByte;
  aStack[p->tos].flags = STK_Str | STK_Dyn;
  zStack[p->tos] = zNewRecord;
  break;
}

................................................................................
    iKey = intToKey(aStack[p->tos-nField].i);
    memcpy(&zNewKey[j], &iKey, sizeof(u32));
    PopStack(p, nField+1);
    if( pOp->p2 && containsNull ) pc = pOp->p2 - 1;
  }else{
    if( pOp->p2==0 ) PopStack(p, nField+addRowid);
  }
  VERIFY( NeedStack(p, p->tos+1); )
  p->tos++;
  aStack[p->tos].n = nByte;
  aStack[p->tos].flags = STK_Str|STK_Dyn;
  zStack[p->tos] = zNewKey;
  break;
}

................................................................................
** must be started or there must be an open cursor) before
** executing this instruction.
*/
case OP_ReadCookie: {
  int i = ++p->tos;
  int aMeta[SQLITE_N_BTREE_META];
  assert( pOp->p2<SQLITE_N_BTREE_META );
  VERIFY( if( NeedStack(p, p->tos) ) goto no_mem; )
  rc = sqliteBtreeGetMeta(pBt, aMeta);
  aStack[i].i = aMeta[1+pOp->p2];
  aStack[i].flags = STK_Int;
  break;
}

/* Opcode: SetCookie * P2 *
................................................................................

    /* The last four bytes of the key are different from R.  Convert the
    ** last four bytes of the key into an integer and push it onto the
    ** stack.  (These bytes are the record number of an entry that
    ** violates a UNIQUE constraint.)
    */
    p->tos++;
    VERIFY( if( NeedStack(p, p->tos) ) goto no_mem; )
    aStack[tos].i = v;
    aStack[tos].flags = STK_Int;
  }
  break;
}

/* Opcode: NotExists P1 P2 *
................................................................................
      if( rx==SQLITE_OK && res==0 ){
        rc = SQLITE_FULL;
        goto abort_due_to_error;
      }
    }
    pC->recnoIsValid = 0;
  }
  VERIFY( NeedStack(p, p->tos+1); )
  p->tos++;
  aStack[p->tos].i = v;
  aStack[p->tos].flags = STK_Int;
  break;
}

/* Opcode: PutIntKey P1 P2 *
................................................................................
  int tos = p->tos+1;
  Cursor *pC;
  char *zRec;
  BtCursor *pCrsr;
  int idxWidth;
  unsigned char aHdr[10];

  VERIFY( if( NeedStack(p, tos+1) ) goto no_mem; )
  if( i<0 ){
    VERIFY( if( tos+i<0 ) goto bad_instruction; )
    VERIFY( if( (aStack[tos+i].flags & STK_Str)==0 ) goto bad_instruction; )
    zRec = zStack[tos+i];
    payloadSize = aStack[tos+i].n;
  }else if( VERIFY( i>=0 && i<p->nCursor && ) (pC = &p->aCsr[i])->pCursor!=0 ){
    zRec = 0;
................................................................................
** Next opcode.
*/
case OP_Recno: {
  int i = pOp->p1;
  int tos = ++p->tos;
  BtCursor *pCrsr;

  VERIFY( if( NeedStack(p, p->tos) ) goto no_mem; )
  if( VERIFY( i>=0 && i<p->nCursor && ) (pCrsr = p->aCsr[i].pCursor)!=0 ){
    int v;
    if( p->aCsr[i].recnoIsValid ){
      v = p->aCsr[i].lastRecno;
    }else if( p->aCsr[i].nullRow ){
      aStack[tos].flags = STK_Null;
      break;
................................................................................
** integer.  This instruction pushes the entire key as a string.
*/
case OP_FullKey: {
  int i = pOp->p1;
  int tos = ++p->tos;
  BtCursor *pCrsr;

  VERIFY( if( NeedStack(p, p->tos) ) goto no_mem; )
  VERIFY( if( !p->aCsr[i].keyAsData ) goto bad_instruction; )
  if( VERIFY( i>=0 && i<p->nCursor && ) (pCrsr = p->aCsr[i].pCursor)!=0 ){
    int amt;
    char *z;

    sqliteBtreeKeySize(pCrsr, &amt);
    if( amt<=0 ){
................................................................................
** See also: Recno, MakeIdxKey.
*/
case OP_IdxRecno: {
  int i = pOp->p1;
  int tos = ++p->tos;
  BtCursor *pCrsr;

  VERIFY( if( NeedStack(p, p->tos) ) goto no_mem; )
  if( VERIFY( i>=0 && i<p->nCursor && ) (pCrsr = p->aCsr[i].pCursor)!=0 ){
    int v;
    int sz;
    sqliteBtreeKeySize(pCrsr, &sz);
    sqliteBtreeKey(pCrsr, sz - sizeof(u32), sizeof(u32), (char*)&v);
    v = keyToInt(v);
    aStack[tos].i = v;
................................................................................
**
** See documentation on OP_CreateTable for additional information.
*/
case OP_CreateIndex:
case OP_CreateTable: {
  int i = ++p->tos;
  int pgno;
  VERIFY( if( NeedStack(p, p->tos) ) goto no_mem; )
  assert( pOp->p3!=0 && pOp->p3type==P3_POINTER );
  if( pOp->opcode==OP_CreateTable ){
    rc = sqliteBtreeCreateTable(pOp->p2 ? db->pBeTemp : pBt, &pgno);
  }else{
    rc = sqliteBtreeCreateIndex(pOp->p2 ? db->pBeTemp : pBt, &pgno);
  }
  if( rc==SQLITE_OK ){
................................................................................
  int iSet = pOp->p1;
  Set *pSet;
  int j;
  HashElem *i;
  char *z;

  VERIFY( if( iSet<0 || iSet>=p->nSet ) goto bad_instruction; )
  VERIFY( if( NeedStack(p, p->tos) ) goto no_mem; )
  pSet = &p->aSet[iSet];
  nRoot = sqliteHashCount(&pSet->hash);
  aRoot = sqliteMalloc( sizeof(int)*(nRoot+1) );
  for(j=0, i=sqliteHashFirst(&pSet->hash); i; i=sqliteHashNext(i), j++){
    toInt((char*)sqliteHashKey(i), &aRoot[j]);
  }
  aRoot[j] = 0;
................................................................................
  if( pKeylist!=0 ){
    VERIFY(
      if( pKeylist->nRead<0 
        || pKeylist->nRead>=pKeylist->nUsed
        || pKeylist->nRead>=pKeylist->nKey ) goto bad_instruction;
    )
    p->tos++;
    if( NeedStack(p, p->tos) ) goto no_mem;
    aStack[p->tos].i = pKeylist->aKey[pKeylist->nRead++];
    aStack[p->tos].flags = STK_Int;
    zStack[p->tos] = 0;
    if( pKeylist->nRead>=pKeylist->nUsed ){
      p->pList = pKeylist->pNext;
      sqliteFree(pKeylist);
    }
................................................................................
    }else{
      azArg[j] = z;
      strcpy(z, zStack[i]);
      z += aStack[i].n;
    }
  }
  PopStack(p, nField);
  VERIFY( NeedStack(p, p->tos+1); )
  p->tos++;
  aStack[p->tos].n = nByte;
  zStack[p->tos] = (char*)azArg;
  aStack[p->tos].flags = STK_Str|STK_Dyn;
  break;
}

................................................................................
      j += aStack[i].n-1;
      zNewKey[j++] = 0;
    }
  }
  zNewKey[j] = 0;
  assert( j<nByte );
  PopStack(p, nField);
  VERIFY( NeedStack(p, p->tos+1); )
  p->tos++;
  aStack[p->tos].n = nByte;
  aStack[p->tos].flags = STK_Str|STK_Dyn;
  zStack[p->tos] = zNewKey;
  break;
}

................................................................................
** to instruction P2.
*/
case OP_SortNext: {
  Sorter *pSorter = p->pSort;
  if( pSorter!=0 ){
    p->pSort = pSorter->pNext;
    p->tos++;
    VERIFY( NeedStack(p, p->tos); )
    zStack[p->tos] = pSorter->pData;
    aStack[p->tos].n = pSorter->nData;
    aStack[p->tos].flags = STK_Str|STK_Dyn;
    sqliteFree(pSorter->zKey);
    sqliteFree(pSorter);
  }else{
    pc = pOp->p2 - 1;
................................................................................
**
** Push onto the stack the P1-th column of the most recently read line
** from the input file.
*/
case OP_FileColumn: {
  int i = pOp->p1;
  char *z;
  VERIFY( if( NeedStack(p, p->tos+1) ) goto no_mem; )
  if( VERIFY( i>=0 && i<p->nField && ) p->azField ){
    z = p->azField[i];
  }else{
    z = 0;
  }
  p->tos++;
  if( z ){
................................................................................
** the string that is stored in the memory location.  If the memory
** location is subsequently changed (using OP_MemStore) then the
** value pushed onto the stack will change too.
*/
case OP_MemLoad: {
  int tos = ++p->tos;
  int i = pOp->p1;
  VERIFY( if( NeedStack(p, tos) ) goto no_mem; )
  VERIFY( if( i<0 || i>=p->nMem ) goto bad_instruction; )
  memcpy(&aStack[tos], &p->aMem[i].s, sizeof(aStack[tos])-NBFS);;
  if( aStack[tos].flags & STK_Str ){
    zStack[tos] = p->aMem[i].z;
    aStack[tos].flags |= STK_Ephem;
    aStack[tos].flags &= ~(STK_Dyn|STK_Static);
  }
................................................................................
** of the current aggregate.  Strings are not duplicated so
** string values will be ephemeral.
*/
case OP_AggGet: {
  AggElem *pFocus = AggInFocus(p->agg);
  int i = pOp->p2;
  int tos = ++p->tos;
  VERIFY( if( NeedStack(p, tos) ) goto no_mem; )
  if( pFocus==0 ) goto no_mem;
  if( VERIFY( i>=0 && ) i<p->agg.nMem ){
    Mem *pMem = &pFocus->aMem[i];
    aStack[tos] = pMem->s;
    zStack[tos] = pMem->z;
    aStack[tos].flags &= ~STK_Dyn;
    aStack[tos].flags |= STK_Ephem;
................................................................................
    if( pSet->prev==0 ){
      break;
    }else{
      pc = pOp->p2 - 1;
    }
  }
  tos = ++p->tos;
  VERIFY( if( NeedStack(p, p->tos) ) goto no_mem; )
  zStack[tos] = sqliteHashKey(pSet->prev);
  aStack[tos].n = sqliteHashKeysize(pSet->prev);
  aStack[tos].flags = STK_Str | STK_Ephem;
  break;
}

/* An other opcode is illegal...







|







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







<
|
|







 







<







 







<







 







<







 







<







 







<







 







<







 







<







 







<







 







<







 







<







 







<







 







<







 







<







 







<







 







<







 







<







 







<







 







<







 







<







 







<







 







<







 







<







 







<







 







<







 







<







 







<







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
...
928
929
930
931
932
933
934








































935
936
937
938
939
940
941
....
1370
1371
1372
1373
1374
1375
1376

1377
1378
1379
1380
1381
1382
1383
1384
1385
....
1543
1544
1545
1546
1547
1548
1549

1550
1551
1552
1553
1554
1555
1556
....
1561
1562
1563
1564
1565
1566
1567

1568
1569
1570
1571
1572
1573
1574
....
1603
1604
1605
1606
1607
1608
1609

1610
1611
1612
1613
1614
1615
1616
....
1730
1731
1732
1733
1734
1735
1736

1737
1738
1739
1740
1741
1742
1743
....
1817
1818
1819
1820
1821
1822
1823

1824
1825
1826
1827
1828
1829
1830
....
1837
1838
1839
1840
1841
1842
1843

1844
1845
1846
1847
1848
1849
1850
....
1991
1992
1993
1994
1995
1996
1997

1998
1999
2000
2001
2002
2003
2004
....
2766
2767
2768
2769
2770
2771
2772

2773
2774
2775
2776
2777
2778
2779
....
2911
2912
2913
2914
2915
2916
2917

2918
2919
2920
2921
2922
2923
2924
....
3076
3077
3078
3079
3080
3081
3082

3083
3084
3085
3086
3087
3088
3089
....
3532
3533
3534
3535
3536
3537
3538

3539
3540
3541
3542
3543
3544
3545
....
3667
3668
3669
3670
3671
3672
3673

3674
3675
3676
3677
3678
3679
3680
....
3794
3795
3796
3797
3798
3799
3800

3801
3802
3803
3804
3805
3806
3807
....
3900
3901
3902
3903
3904
3905
3906

3907
3908
3909
3910
3911
3912
3913
....
3931
3932
3933
3934
3935
3936
3937

3938
3939
3940
3941
3942
3943
3944
....
4144
4145
4146
4147
4148
4149
4150

4151
4152
4153
4154
4155
4156
4157
....
4271
4272
4273
4274
4275
4276
4277

4278
4279
4280
4281
4282
4283
4284
....
4311
4312
4313
4314
4315
4316
4317

4318
4319
4320
4321
4322
4323
4324
....
4382
4383
4384
4385
4386
4387
4388

4389
4390
4391
4392
4393
4394
4395
....
4509
4510
4511
4512
4513
4514
4515

4516
4517
4518
4519
4520
4521
4522
....
4567
4568
4569
4570
4571
4572
4573

4574
4575
4576
4577
4578
4579
4580
....
4623
4624
4625
4626
4627
4628
4629

4630
4631
4632
4633
4634
4635
4636
....
4807
4808
4809
4810
4811
4812
4813

4814
4815
4816
4817
4818
4819
4820
....
4904
4905
4906
4907
4908
4909
4910

4911
4912
4913
4914
4915
4916
4917
....
5089
5090
5091
5092
5093
5094
5095

5096
5097
5098
5099
5100
5101
5102
....
5260
5261
5262
5263
5264
5265
5266

5267
5268
5269
5270
5271
5272
5273
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.191 2003/01/06 23:54:06 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** The makefile scans this source file and creates the following
** array of string constants which are the names of all VDBE opcodes.
................................................................................
** once.  This macro only works from within the sqliteVdbeExec()
** function.
*/
#define POPSTACK \
 if( aStack[p->tos].flags & STK_Dyn ) sqliteFree(zStack[p->tos]); \
 p->tos--;









































/*
** Return TRUE if zNum is a floating-point or integer number.
*/
static int isNumber(const char *zNum){
  if( *zNum=='-' || *zNum=='+' ) zNum++;
  if( !isdigit(*zNum) ) return 0;
  while( isdigit(*zNum) ) zNum++;
................................................................................
  /* No instruction ever pushes more than a single element onto the
  ** stack.  And the stack never grows on successive executions of the
  ** same loop.  So the total number of instructions is an upper bound
  ** on the maximum stack depth required.
  **
  ** Allocation all the stack space we will ever need.
  */

  zStack = p->zStack = sqliteMalloc( p->nOp*sizeof(zStack[0]) );
  aStack = p->aStack = sqliteMalloc( p->nOp*sizeof(aStack[0]) );
  p->tos = -1;
#ifdef VDBE_PROFILE
  {
    int i;
    for(i=0; i<p->nOp; i++){
      p->aOp[i].cnt = 0;
      p->aOp[i].cycles = 0;
................................................................................
/* 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;
  }
................................................................................
**
** 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;
................................................................................
**
** 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;
................................................................................
** 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{
      if( Stringify(p, j) ) goto no_mem;
    }
  }
................................................................................
    }else{
      if( Stringify(p, i) ) goto no_mem;
      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;
................................................................................
    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;
}

................................................................................
  ctx.pFunc = (FuncDef*)pOp->p3;
  ctx.s.flags = STK_Null;
  ctx.z = 0;
  ctx.isError = 0;
  ctx.isStep = 0;
  (*ctx.pFunc->xFunc)(&ctx, n, (const char**)&zStack[p->tos-n+1]);
  PopStack(p, n);

  p->tos++;
  aStack[p->tos] = ctx.s;
  if( ctx.s.flags & STK_Dyn ){
    zStack[p->tos] = ctx.z;
  }else if( ctx.s.flags & STK_Str ){
    zStack[p->tos] = aStack[p->tos].z;
  }else{
................................................................................
  for(i=p->tos-nField+1; i<=p->tos; i++){
    if( (aStack[i].flags & STK_Null)==0 ){
      memcpy(&zNewRecord[j], zStack[i], aStack[i].n);
      j += aStack[i].n;
    }
  }
  PopStack(p, nField);

  p->tos++;
  aStack[p->tos].n = nByte;
  aStack[p->tos].flags = STK_Str | STK_Dyn;
  zStack[p->tos] = zNewRecord;
  break;
}

................................................................................
    iKey = intToKey(aStack[p->tos-nField].i);
    memcpy(&zNewKey[j], &iKey, sizeof(u32));
    PopStack(p, nField+1);
    if( pOp->p2 && containsNull ) pc = pOp->p2 - 1;
  }else{
    if( pOp->p2==0 ) PopStack(p, nField+addRowid);
  }

  p->tos++;
  aStack[p->tos].n = nByte;
  aStack[p->tos].flags = STK_Str|STK_Dyn;
  zStack[p->tos] = zNewKey;
  break;
}

................................................................................
** must be started or there must be an open cursor) before
** executing this instruction.
*/
case OP_ReadCookie: {
  int i = ++p->tos;
  int aMeta[SQLITE_N_BTREE_META];
  assert( pOp->p2<SQLITE_N_BTREE_META );

  rc = sqliteBtreeGetMeta(pBt, aMeta);
  aStack[i].i = aMeta[1+pOp->p2];
  aStack[i].flags = STK_Int;
  break;
}

/* Opcode: SetCookie * P2 *
................................................................................

    /* The last four bytes of the key are different from R.  Convert the
    ** last four bytes of the key into an integer and push it onto the
    ** stack.  (These bytes are the record number of an entry that
    ** violates a UNIQUE constraint.)
    */
    p->tos++;

    aStack[tos].i = v;
    aStack[tos].flags = STK_Int;
  }
  break;
}

/* Opcode: NotExists P1 P2 *
................................................................................
      if( rx==SQLITE_OK && res==0 ){
        rc = SQLITE_FULL;
        goto abort_due_to_error;
      }
    }
    pC->recnoIsValid = 0;
  }

  p->tos++;
  aStack[p->tos].i = v;
  aStack[p->tos].flags = STK_Int;
  break;
}

/* Opcode: PutIntKey P1 P2 *
................................................................................
  int tos = p->tos+1;
  Cursor *pC;
  char *zRec;
  BtCursor *pCrsr;
  int idxWidth;
  unsigned char aHdr[10];


  if( i<0 ){
    VERIFY( if( tos+i<0 ) goto bad_instruction; )
    VERIFY( if( (aStack[tos+i].flags & STK_Str)==0 ) goto bad_instruction; )
    zRec = zStack[tos+i];
    payloadSize = aStack[tos+i].n;
  }else if( VERIFY( i>=0 && i<p->nCursor && ) (pC = &p->aCsr[i])->pCursor!=0 ){
    zRec = 0;
................................................................................
** Next opcode.
*/
case OP_Recno: {
  int i = pOp->p1;
  int tos = ++p->tos;
  BtCursor *pCrsr;


  if( VERIFY( i>=0 && i<p->nCursor && ) (pCrsr = p->aCsr[i].pCursor)!=0 ){
    int v;
    if( p->aCsr[i].recnoIsValid ){
      v = p->aCsr[i].lastRecno;
    }else if( p->aCsr[i].nullRow ){
      aStack[tos].flags = STK_Null;
      break;
................................................................................
** integer.  This instruction pushes the entire key as a string.
*/
case OP_FullKey: {
  int i = pOp->p1;
  int tos = ++p->tos;
  BtCursor *pCrsr;


  VERIFY( if( !p->aCsr[i].keyAsData ) goto bad_instruction; )
  if( VERIFY( i>=0 && i<p->nCursor && ) (pCrsr = p->aCsr[i].pCursor)!=0 ){
    int amt;
    char *z;

    sqliteBtreeKeySize(pCrsr, &amt);
    if( amt<=0 ){
................................................................................
** See also: Recno, MakeIdxKey.
*/
case OP_IdxRecno: {
  int i = pOp->p1;
  int tos = ++p->tos;
  BtCursor *pCrsr;


  if( VERIFY( i>=0 && i<p->nCursor && ) (pCrsr = p->aCsr[i].pCursor)!=0 ){
    int v;
    int sz;
    sqliteBtreeKeySize(pCrsr, &sz);
    sqliteBtreeKey(pCrsr, sz - sizeof(u32), sizeof(u32), (char*)&v);
    v = keyToInt(v);
    aStack[tos].i = v;
................................................................................
**
** See documentation on OP_CreateTable for additional information.
*/
case OP_CreateIndex:
case OP_CreateTable: {
  int i = ++p->tos;
  int pgno;

  assert( pOp->p3!=0 && pOp->p3type==P3_POINTER );
  if( pOp->opcode==OP_CreateTable ){
    rc = sqliteBtreeCreateTable(pOp->p2 ? db->pBeTemp : pBt, &pgno);
  }else{
    rc = sqliteBtreeCreateIndex(pOp->p2 ? db->pBeTemp : pBt, &pgno);
  }
  if( rc==SQLITE_OK ){
................................................................................
  int iSet = pOp->p1;
  Set *pSet;
  int j;
  HashElem *i;
  char *z;

  VERIFY( if( iSet<0 || iSet>=p->nSet ) goto bad_instruction; )

  pSet = &p->aSet[iSet];
  nRoot = sqliteHashCount(&pSet->hash);
  aRoot = sqliteMalloc( sizeof(int)*(nRoot+1) );
  for(j=0, i=sqliteHashFirst(&pSet->hash); i; i=sqliteHashNext(i), j++){
    toInt((char*)sqliteHashKey(i), &aRoot[j]);
  }
  aRoot[j] = 0;
................................................................................
  if( pKeylist!=0 ){
    VERIFY(
      if( pKeylist->nRead<0 
        || pKeylist->nRead>=pKeylist->nUsed
        || pKeylist->nRead>=pKeylist->nKey ) goto bad_instruction;
    )
    p->tos++;

    aStack[p->tos].i = pKeylist->aKey[pKeylist->nRead++];
    aStack[p->tos].flags = STK_Int;
    zStack[p->tos] = 0;
    if( pKeylist->nRead>=pKeylist->nUsed ){
      p->pList = pKeylist->pNext;
      sqliteFree(pKeylist);
    }
................................................................................
    }else{
      azArg[j] = z;
      strcpy(z, zStack[i]);
      z += aStack[i].n;
    }
  }
  PopStack(p, nField);

  p->tos++;
  aStack[p->tos].n = nByte;
  zStack[p->tos] = (char*)azArg;
  aStack[p->tos].flags = STK_Str|STK_Dyn;
  break;
}

................................................................................
      j += aStack[i].n-1;
      zNewKey[j++] = 0;
    }
  }
  zNewKey[j] = 0;
  assert( j<nByte );
  PopStack(p, nField);

  p->tos++;
  aStack[p->tos].n = nByte;
  aStack[p->tos].flags = STK_Str|STK_Dyn;
  zStack[p->tos] = zNewKey;
  break;
}

................................................................................
** to instruction P2.
*/
case OP_SortNext: {
  Sorter *pSorter = p->pSort;
  if( pSorter!=0 ){
    p->pSort = pSorter->pNext;
    p->tos++;

    zStack[p->tos] = pSorter->pData;
    aStack[p->tos].n = pSorter->nData;
    aStack[p->tos].flags = STK_Str|STK_Dyn;
    sqliteFree(pSorter->zKey);
    sqliteFree(pSorter);
  }else{
    pc = pOp->p2 - 1;
................................................................................
**
** Push onto the stack the P1-th column of the most recently read line
** from the input file.
*/
case OP_FileColumn: {
  int i = pOp->p1;
  char *z;

  if( VERIFY( i>=0 && i<p->nField && ) p->azField ){
    z = p->azField[i];
  }else{
    z = 0;
  }
  p->tos++;
  if( z ){
................................................................................
** the string that is stored in the memory location.  If the memory
** location is subsequently changed (using OP_MemStore) then the
** value pushed onto the stack will change too.
*/
case OP_MemLoad: {
  int tos = ++p->tos;
  int i = pOp->p1;

  VERIFY( if( i<0 || i>=p->nMem ) goto bad_instruction; )
  memcpy(&aStack[tos], &p->aMem[i].s, sizeof(aStack[tos])-NBFS);;
  if( aStack[tos].flags & STK_Str ){
    zStack[tos] = p->aMem[i].z;
    aStack[tos].flags |= STK_Ephem;
    aStack[tos].flags &= ~(STK_Dyn|STK_Static);
  }
................................................................................
** of the current aggregate.  Strings are not duplicated so
** string values will be ephemeral.
*/
case OP_AggGet: {
  AggElem *pFocus = AggInFocus(p->agg);
  int i = pOp->p2;
  int tos = ++p->tos;

  if( pFocus==0 ) goto no_mem;
  if( VERIFY( i>=0 && ) i<p->agg.nMem ){
    Mem *pMem = &pFocus->aMem[i];
    aStack[tos] = pMem->s;
    zStack[tos] = pMem->z;
    aStack[tos].flags &= ~STK_Dyn;
    aStack[tos].flags |= STK_Ephem;
................................................................................
    if( pSet->prev==0 ){
      break;
    }else{
      pc = pOp->p2 - 1;
    }
  }
  tos = ++p->tos;

  zStack[tos] = sqliteHashKey(pSet->prev);
  aStack[tos].n = sqliteHashKeysize(pSet->prev);
  aStack[tos].flags = STK_Str | STK_Ephem;
  break;
}

/* An other opcode is illegal...