/ Check-in [92deff07]
Login

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

Overview
Comment:Continued work toward converting to a register-based VM. (CVS 4698)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 92deff07bba2089bbe011f44defb3a0ac1362d56
User & Date: drh 2008-01-09 02:15:39
Context
2008-01-09
18:31
Fix the build for AIX and other systems where "char" is unsigned by default. (CVS 4699) check-in: 47672af0 user: drh tags: trunk
02:15
Continued work toward converting to a register-based VM. (CVS 4698) check-in: 92deff07 user: drh tags: trunk
2008-01-08
23:54
Registerify the comparison opcodes. (CVS 4697) check-in: 8862ce9c user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/expr.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
2117
2118
2119
2120
2121
2122
2123






2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
....
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
....
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
....
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
....
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.338 2008/01/08 23:54:25 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**
................................................................................
      if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){
        Token *p = &pLeft->token;
        if( pLeft->op==TK_FLOAT ){
          codeReal(v, (char*)p->z, p->n, 1, target);
        }else{
          codeInteger(v, (char*)p->z, p->n, 1, target);
        }






        inReg = target;
        break;
      }
      /* Fall through into TK_NOT */
    }
    case TK_BITNOT:
    case TK_NOT: {
      assert( TK_BITNOT==OP_BitNot );
      assert( TK_NOT==OP_Not );
      sqlite3ExprCode(pParse, pExpr->pLeft, 0);
      sqlite3VdbeAddOp0(v, op);
................................................................................
      sqlite3VdbeAddOp0(v, OP_SCopy);
      j1 = sqlite3VdbeAddOp0(v, OP_NotNull);
      sqlite3VdbeAddOp1(v, OP_Pop, 2);
      sqlite3VdbeAddOp0(v, OP_Null);
      j2  = sqlite3VdbeAddOp0(v, OP_Goto);
      sqlite3VdbeJumpHere(v, j1);
      if( eType==IN_INDEX_ROWID ){
        j3 = sqlite3VdbeAddOp1(v, OP_MustBeInt, 1);
        j4 = sqlite3VdbeAddOp1(v, OP_NotExists, pExpr->iTable);
        j5 = sqlite3VdbeAddOp0(v, OP_Goto);
        sqlite3VdbeJumpHere(v, j3);
        sqlite3VdbeJumpHere(v, j4);
      }else{
        sqlite3VdbeAddOp4(v, OP_MakeRecord, 1, 0, 0, &affinity, 1);
        j5 = sqlite3VdbeAddOp1(v, OP_Found, pExpr->iTable);
................................................................................
        sqlite3ExprCode(pParse, aListelem[i].pExpr, 0);
        if( pExpr->pLeft ){
          sqlite3VdbeAddOp1(v, OP_SCopy, -1);
          jumpInst = codeCompare(pParse, pExpr->pLeft, aListelem[i].pExpr,
                                 OP_Ne, 0, 0, 0, SQLITE_JUMPIFNULL);
          sqlite3VdbeAddOp1(v, OP_Pop, 1);
        }else{
          jumpInst = sqlite3VdbeAddOp2(v, OP_IfNot, 1, 0);
        }
        sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target);
        sqlite3VdbeAddOp2(v, OP_Goto, 0, expr_end_label);
        sqlite3VdbeJumpHere(v, jumpInst);
      }
      if( pExpr->pLeft ){
        sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
................................................................................
      sqlite3VdbeAddOp2(v, OP_Integer, 0, 0);
      sqlite3VdbeJumpHere(v, addr);
      sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
      break;
    }
    default: {
      sqlite3ExprCode(pParse, pExpr, 0);
      sqlite3VdbeAddOp2(v, OP_If, jumpIfNull, dest);
      break;
    }
  }
}

/*
** Generate code for a boolean expression such that a jump is made
................................................................................
      sqlite3ExprCode(pParse, pRight, 0);
      codeCompare(pParse, pLeft, pRight, OP_Gt,
                  0, 0, dest, jumpIfNull);
      break;
    }
    default: {
      sqlite3ExprCode(pParse, pExpr, 0);
      sqlite3VdbeAddOp2(v, OP_IfNot, jumpIfNull, dest);
      break;
    }
  }
}

/*
** Do a deep comparison of two expression trees.  Return TRUE (non-zero)







|







 







>
>
>
>
>
>
|
|
<
<







 







|







 







|







 







|







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131


2132
2133
2134
2135
2136
2137
2138
....
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
....
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
....
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
....
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.339 2008/01/09 02:15:39 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**
................................................................................
      if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){
        Token *p = &pLeft->token;
        if( pLeft->op==TK_FLOAT ){
          codeReal(v, (char*)p->z, p->n, 1, target);
        }else{
          codeInteger(v, (char*)p->z, p->n, 1, target);
        }
      }else{
        int r1 = ++pParse->nMem;
        sqlite3VdbeAddOp2(v, OP_Integer, 0, r1);
        sqlite3ExprCode(pParse, pExpr->pLeft, target);
        sqlite3VdbeAddOp3(v, OP_Subtract, target, r1, target);
      }
      inReg = target;
      break;


    }
    case TK_BITNOT:
    case TK_NOT: {
      assert( TK_BITNOT==OP_BitNot );
      assert( TK_NOT==OP_Not );
      sqlite3ExprCode(pParse, pExpr->pLeft, 0);
      sqlite3VdbeAddOp0(v, op);
................................................................................
      sqlite3VdbeAddOp0(v, OP_SCopy);
      j1 = sqlite3VdbeAddOp0(v, OP_NotNull);
      sqlite3VdbeAddOp1(v, OP_Pop, 2);
      sqlite3VdbeAddOp0(v, OP_Null);
      j2  = sqlite3VdbeAddOp0(v, OP_Goto);
      sqlite3VdbeJumpHere(v, j1);
      if( eType==IN_INDEX_ROWID ){
        j3 = sqlite3VdbeAddOp3(v, OP_MustBeInt, 0, 0, 1);
        j4 = sqlite3VdbeAddOp1(v, OP_NotExists, pExpr->iTable);
        j5 = sqlite3VdbeAddOp0(v, OP_Goto);
        sqlite3VdbeJumpHere(v, j3);
        sqlite3VdbeJumpHere(v, j4);
      }else{
        sqlite3VdbeAddOp4(v, OP_MakeRecord, 1, 0, 0, &affinity, 1);
        j5 = sqlite3VdbeAddOp1(v, OP_Found, pExpr->iTable);
................................................................................
        sqlite3ExprCode(pParse, aListelem[i].pExpr, 0);
        if( pExpr->pLeft ){
          sqlite3VdbeAddOp1(v, OP_SCopy, -1);
          jumpInst = codeCompare(pParse, pExpr->pLeft, aListelem[i].pExpr,
                                 OP_Ne, 0, 0, 0, SQLITE_JUMPIFNULL);
          sqlite3VdbeAddOp1(v, OP_Pop, 1);
        }else{
          jumpInst = sqlite3VdbeAddOp3(v, OP_IfNot, 0, 0, 1);
        }
        sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target);
        sqlite3VdbeAddOp2(v, OP_Goto, 0, expr_end_label);
        sqlite3VdbeJumpHere(v, jumpInst);
      }
      if( pExpr->pLeft ){
        sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
................................................................................
      sqlite3VdbeAddOp2(v, OP_Integer, 0, 0);
      sqlite3VdbeJumpHere(v, addr);
      sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
      break;
    }
    default: {
      sqlite3ExprCode(pParse, pExpr, 0);
      sqlite3VdbeAddOp3(v, OP_If, 0, dest, jumpIfNull!=0);
      break;
    }
  }
}

/*
** Generate code for a boolean expression such that a jump is made
................................................................................
      sqlite3ExprCode(pParse, pRight, 0);
      codeCompare(pParse, pLeft, pRight, OP_Gt,
                  0, 0, dest, jumpIfNull);
      break;
    }
    default: {
      sqlite3ExprCode(pParse, pExpr, 0);
      sqlite3VdbeAddOp3(v, OP_IfNot, 0, dest, jumpIfNull!=0);
      break;
    }
  }
}

/*
** Do a deep comparison of two expression trees.  Return TRUE (non-zero)

Changes to src/insert.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
** $Id: insert.c,v 1.218 2008/01/08 23:54:25 drh Exp $
*/
#include "sqliteInt.h"

/*
** Set P4 of the most recently inserted opcode to a column affinity
** string for index pIdx. A column affinity string has one character
** for each column in the table, according to the affinity of the column:
................................................................................
          sqlite3VdbeAddOp2(v, OP_Move, 0, regRowid);
        }
      }
      /* If the PRIMARY KEY expression is NULL, then use OP_NewRowid
      ** to generate a unique primary key value.
      */
      if( !appendFlag ){
        sqlite3VdbeAddOp2(v, OP_IfMemNull, regRowid, sqlite3VdbeCurrentAddr(v)+2);
        sqlite3VdbeAddOp2(v, OP_Goto, -1, sqlite3VdbeCurrentAddr(v)+2);
        sqlite3VdbeAddOp3(v, OP_NewRowid, baseCur, regRowid, regAutoinc);
        sqlite3VdbeAddOp3(v, OP_MustBeInt, 0, 0, regRowid);
      }
    }else if( IsVirtual(pTab) ){
      sqlite3VdbeAddOp2(v, OP_Null, 0, regRowid);
    }else{
      sqlite3VdbeAddOp3(v, OP_NewRowid, baseCur, regRowid, regAutoinc);
      appendFlag = 1;
    }







|







 







|


|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
** $Id: insert.c,v 1.219 2008/01/09 02:15:39 drh Exp $
*/
#include "sqliteInt.h"

/*
** Set P4 of the most recently inserted opcode to a column affinity
** string for index pIdx. A column affinity string has one character
** for each column in the table, according to the affinity of the column:
................................................................................
          sqlite3VdbeAddOp2(v, OP_Move, 0, regRowid);
        }
      }
      /* If the PRIMARY KEY expression is NULL, then use OP_NewRowid
      ** to generate a unique primary key value.
      */
      if( !appendFlag ){
        sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, sqlite3VdbeCurrentAddr(v)+2);
        sqlite3VdbeAddOp2(v, OP_Goto, -1, sqlite3VdbeCurrentAddr(v)+2);
        sqlite3VdbeAddOp3(v, OP_NewRowid, baseCur, regRowid, regAutoinc);
        sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid);
      }
    }else if( IsVirtual(pTab) ){
      sqlite3VdbeAddOp2(v, OP_Null, 0, regRowid);
    }else{
      sqlite3VdbeAddOp3(v, OP_NewRowid, baseCur, regRowid, regAutoinc);
      appendFlag = 1;
    }

Changes to src/pragma.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
294
295
296
297
298
299
300
301
302
303
304

305
306
307
308
309
310
311
312
313
314

315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
...
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
...
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
...
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
...
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.162 2008/01/07 19:20:25 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/* Ignore this whole file if pragmas are disabled
*/
#if !defined(SQLITE_OMIT_PRAGMA) && !defined(SQLITE_OMIT_PARSER)
................................................................................
  ** database file.  The cache size is actually the absolute value of
  ** this memory location.  The sign of meta-value 2 determines the
  ** synchronous setting.  A negative value means synchronous is off
  ** and a positive value means synchronous is on.
  */
  if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){
    static const VdbeOpList getCacheSize[] = {
      { OP_ReadCookie,  0, 0,        2},  /* 0 */
      { OP_AbsValue,    0, 0,        0},
      { OP_Copy,        0, 0,        0},
      { OP_Integer,     0, 0,        0},

      { OP_Ne,          0, 6,        0},
      { OP_Integer,     0, 0,        0},  /* 5 */
      { OP_Callback,    1, 0,        0},
    };
    int addr;
    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
    sqlite3VdbeUsesBtree(v, iDb);
    if( !zRight ){
      sqlite3VdbeSetNumCols(v, 1);
      sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", P4_STATIC);

      addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
      sqlite3VdbeChangeP1(v, addr, iDb);
      sqlite3VdbeChangeP1(v, addr+5, SQLITE_DEFAULT_CACHE_SIZE);
    }else{
      int size = atoi(zRight);
      if( size<0 ) size = -size;
      sqlite3BeginWriteOperation(pParse, 0, iDb);
      sqlite3VdbeAddOp2(v, OP_Integer, size, 0);
      sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, 0, 2);
      addr = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0);
      sqlite3VdbeAddOp2(v, OP_Ge, 0, addr+3);
      sqlite3VdbeAddOp2(v, OP_Negative, 0, 0);
      sqlite3VdbeAddOp2(v, OP_SetCookie, iDb, 2);
      pDb->pSchema->cache_size = size;
      sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
    }
  }else

  /*
................................................................................
      goto pragma_out;
    }
    if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){
      iLimit = 0x7fffffff;
    }
    sqlite3BeginWriteOperation(pParse, 0, iDb);
    sqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1);
    addr = sqlite3VdbeAddOp2(v, OP_IncrVacuum, iDb, 0);
    sqlite3VdbeAddOp2(v, OP_Callback, 0, 0);
    sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
    sqlite3VdbeAddOp2(v, OP_IfMemPos, 1, addr);
    sqlite3VdbeJumpHere(v, addr);
  }else
#endif

#ifndef SQLITE_OMIT_PAGER_PRAGMAS
  /*
  **  PRAGMA [database.]cache_size
................................................................................
      HashElem *x;
      Hash *pTbls;
      int cnt = 0;

      if( OMIT_TEMPDB && i==1 ) continue;

      sqlite3CodeVerifySchema(pParse, i);
      addr = sqlite3VdbeAddOp2(v, OP_IfMemPos, 1, 0);
      sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
      sqlite3VdbeJumpHere(v, addr);

      /* Do an integrity check of the B-Tree
      */
      pTbls = &db->aDb[i].pSchema->tblHash;
      for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
................................................................................
      */
      for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){
        Table *pTab = sqliteHashData(x);
        Index *pIdx;
        int loopTop;

        if( pTab->pIndex==0 ) continue;
        addr = sqlite3VdbeAddOp2(v, OP_IfMemPos, 1, 0);
        sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
        sqlite3VdbeJumpHere(v, addr);
        sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);
        sqlite3VdbeAddOp2(v, OP_Integer, 0, 2);
        loopTop = sqlite3VdbeAddOp2(v, OP_Rewind, 1, 0);
        sqlite3VdbeAddOp2(v, OP_AddImm, 2, 1);
        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
................................................................................
             { OP_AddImm,       1, -1,  0},
             { OP_String8,      0,  0,  0},  /* 8 */
             { OP_String8,      0,  0,  0},  /* 9 */
             { OP_Concat,       0,  0,  0},
             { OP_Callback,     1,  0,  0},
          };
          if( pIdx->tnum==0 ) continue;
          addr = sqlite3VdbeAddOp2(v, OP_IfMemPos, 1, 0);
          sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
          sqlite3VdbeJumpHere(v, addr);
          addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
          sqlite3VdbeChangeP1(v, addr+1, j+2);
          sqlite3VdbeChangeP2(v, addr+1, addr+4);
          sqlite3VdbeChangeP1(v, addr+3, j+2);
          sqlite3VdbeChangeP2(v, addr+3, addr+2);







|







 







|
|
<
|
>
|
|
|







>







|

|
|
|







 







|
|

|







 







|







 







|







 







|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
294
295
296
297
298
299
300
301
302

303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
...
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
...
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
...
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
...
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.163 2008/01/09 02:15:39 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/* Ignore this whole file if pragmas are disabled
*/
#if !defined(SQLITE_OMIT_PRAGMA) && !defined(SQLITE_OMIT_PARSER)
................................................................................
  ** database file.  The cache size is actually the absolute value of
  ** this memory location.  The sign of meta-value 2 determines the
  ** synchronous setting.  A negative value means synchronous is off
  ** and a positive value means synchronous is on.
  */
  if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){
    static const VdbeOpList getCacheSize[] = {
      { OP_ReadCookie,  0, 1,        2},  /* 0 */
      { OP_IfPos,       1, 6,        0},

      { OP_Integer,     0, 2,        0},
      { OP_Subtract,    1, 2,        1},
      { OP_IfPos,       1, 6,        0},
      { OP_Integer,     0, 1,        0},  /* 5 */
      { OP_ResultRow,   1, 1,        0},
    };
    int addr;
    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
    sqlite3VdbeUsesBtree(v, iDb);
    if( !zRight ){
      sqlite3VdbeSetNumCols(v, 1);
      sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", P4_STATIC);
      pParse->nMem += 2;
      addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
      sqlite3VdbeChangeP1(v, addr, iDb);
      sqlite3VdbeChangeP1(v, addr+5, SQLITE_DEFAULT_CACHE_SIZE);
    }else{
      int size = atoi(zRight);
      if( size<0 ) size = -size;
      sqlite3BeginWriteOperation(pParse, 0, iDb);
      sqlite3VdbeAddOp1(v, OP_Integer, size);
      sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, 0, 2);
      addr = sqlite3VdbeAddOp2(v, OP_IfPos, 0, 0);
      sqlite3VdbeAddOp1(v, OP_Integer, -size);
      sqlite3VdbeJumpHere(v, addr);
      sqlite3VdbeAddOp2(v, OP_SetCookie, iDb, 2);
      pDb->pSchema->cache_size = size;
      sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
    }
  }else

  /*
................................................................................
      goto pragma_out;
    }
    if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){
      iLimit = 0x7fffffff;
    }
    sqlite3BeginWriteOperation(pParse, 0, iDb);
    sqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1);
    addr = sqlite3VdbeAddOp1(v, OP_IncrVacuum, iDb);
    sqlite3VdbeAddOp0(v, OP_Callback);
    sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
    sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr);
    sqlite3VdbeJumpHere(v, addr);
  }else
#endif

#ifndef SQLITE_OMIT_PAGER_PRAGMAS
  /*
  **  PRAGMA [database.]cache_size
................................................................................
      HashElem *x;
      Hash *pTbls;
      int cnt = 0;

      if( OMIT_TEMPDB && i==1 ) continue;

      sqlite3CodeVerifySchema(pParse, i);
      addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1);
      sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
      sqlite3VdbeJumpHere(v, addr);

      /* Do an integrity check of the B-Tree
      */
      pTbls = &db->aDb[i].pSchema->tblHash;
      for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
................................................................................
      */
      for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){
        Table *pTab = sqliteHashData(x);
        Index *pIdx;
        int loopTop;

        if( pTab->pIndex==0 ) continue;
        addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1);
        sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
        sqlite3VdbeJumpHere(v, addr);
        sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);
        sqlite3VdbeAddOp2(v, OP_Integer, 0, 2);
        loopTop = sqlite3VdbeAddOp2(v, OP_Rewind, 1, 0);
        sqlite3VdbeAddOp2(v, OP_AddImm, 2, 1);
        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
................................................................................
             { OP_AddImm,       1, -1,  0},
             { OP_String8,      0,  0,  0},  /* 8 */
             { OP_String8,      0,  0,  0},  /* 9 */
             { OP_Concat,       0,  0,  0},
             { OP_Callback,     1,  0,  0},
          };
          if( pIdx->tnum==0 ) continue;
          addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1);
          sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
          sqlite3VdbeJumpHere(v, addr);
          addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
          sqlite3VdbeChangeP1(v, addr+1, j+2);
          sqlite3VdbeChangeP2(v, addr+1, addr+4);
          sqlite3VdbeChangeP1(v, addr+3, j+2);
          sqlite3VdbeChangeP2(v, addr+3, addr+2);

Changes to src/prepare.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
265
266
267
268
269
270
271

272
273
274
275
276
277
278
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the implementation of the sqlite3_prepare()
** interface, and routines that contribute to loading the database schema
** from disk.
**
** $Id: prepare.c,v 1.70 2008/01/03 07:09:48 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Fill the InitData structure with an error message that indicates
** that the database is corrupt.
................................................................................
  }else{
    DbSetProperty(db, iDb, DB_Empty);
  }
  pDb->pSchema->enc = ENC(db);

  size = meta[2];
  if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; }

  pDb->pSchema->cache_size = size;
  sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);

  /*
  ** file_format==1    Version 3.0.0.
  ** file_format==2    Version 3.1.3.  // ALTER TABLE ADD COLUMN
  ** file_format==3    Version 3.1.4.  // ditto but with non-NULL defaults







|







 







>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the implementation of the sqlite3_prepare()
** interface, and routines that contribute to loading the database schema
** from disk.
**
** $Id: prepare.c,v 1.71 2008/01/09 02:15:39 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Fill the InitData structure with an error message that indicates
** that the database is corrupt.
................................................................................
  }else{
    DbSetProperty(db, iDb, DB_Empty);
  }
  pDb->pSchema->enc = ENC(db);

  size = meta[2];
  if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; }
  if( size<0 ) size = -size;
  pDb->pSchema->cache_size = size;
  sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);

  /*
  ** file_format==1    Version 3.0.0.
  ** file_format==2    Version 3.1.3.  // ALTER TABLE ADD COLUMN
  ** file_format==3    Version 3.1.4.  // ditto but with non-NULL defaults

Changes to src/select.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
...
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
...
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
...
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
...
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
....
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
....
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
....
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
....
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.393 2008/01/08 23:54:25 drh Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.
................................................................................
static void pushOntoSorter(
  Parse *pParse,         /* Parser context */
  ExprList *pOrderBy,    /* The ORDER BY clause */
  Select *pSelect        /* The whole SELECT statement */
){
  Vdbe *v = pParse->pVdbe;
  sqlite3ExprCodeExprList(pParse, pOrderBy, 0);
  sqlite3VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, 0);
  sqlite3VdbeAddOp2(v, OP_Pull, pOrderBy->nExpr + 1, 0);
  sqlite3VdbeAddOp2(v, OP_MakeRecord, pOrderBy->nExpr + 2, 0);
  sqlite3VdbeAddOp2(v, OP_IdxInsert, pOrderBy->iECursor, 0);
  if( pSelect->iLimit>=0 ){
    int addr1, addr2;
    addr1 = sqlite3VdbeAddOp2(v, OP_IfMemZero, pSelect->iLimit+1, 0);
    sqlite3VdbeAddOp2(v, OP_AddImm, pSelect->iLimit+1, -1);
    addr2 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
    sqlite3VdbeJumpHere(v, addr1);
    sqlite3VdbeAddOp2(v, OP_Last, pOrderBy->iECursor, 0);
    sqlite3VdbeAddOp2(v, OP_Delete, pOrderBy->iECursor, 0);
    sqlite3VdbeJumpHere(v, addr2);
    pSelect->iLimit = -1;
  }
}

/*
** Add code to implement the OFFSET
................................................................................
  Select *p,        /* The SELECT statement being coded */
  int iContinue,    /* Jump here to skip the current record */
  int nPop          /* Number of times to pop stack when jumping */
){
  if( p->iOffset>=0 && iContinue!=0 ){
    int addr;
    sqlite3VdbeAddOp2(v, OP_AddImm, p->iOffset, -1);
    addr = sqlite3VdbeAddOp2(v, OP_IfMemNeg, p->iOffset, 0);
    if( nPop>0 ){
      sqlite3VdbeAddOp2(v, OP_Pop, nPop, 0);
    }
    sqlite3VdbeAddOp2(v, OP_Goto, 0, iContinue);
    VdbeComment((v, "skip OFFSET records"));
    sqlite3VdbeJumpHere(v, addr);
  }
}

................................................................................
    ** then there should be a single item on the stack.  Write this
    ** item into the set table with bogus data.
    */
    case SRT_Set: {
      int addr2;

      assert( nColumn==1 );
      addr2 = sqlite3VdbeAddOp2(v, OP_IfMemNull, iMem, 0);
      p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affinity);
      if( pOrderBy ){
        /* At first glance you would think we could optimize out the
        ** ORDER BY in this case since the order of entries in the set
        ** does not matter.  But there might be a LIMIT clause, in which
        ** case the order does matter */
        sqlite3VdbeAddOp2(v, OP_SCopy, iMem, 0);
................................................................................
#endif
  }

  /* Jump to the end of the loop if the LIMIT is reached.
  */
  if( p->iLimit>=0 && pOrderBy==0 ){
    sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1);
    sqlite3VdbeAddOp2(v, OP_IfMemZero, p->iLimit, iBreak);
  }
  return 0;
}

/*
** Given an expression list, generate a KeyInfo structure that records
** the collating sequence for each expression in that expression list.
................................................................................
    }
  }

  /* Jump to the end of the loop when the LIMIT is reached
  */
  if( p->iLimit>=0 ){
    sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1);
    sqlite3VdbeAddOp2(v, OP_IfMemZero, p->iLimit, brk);
  }

  /* The bottom of the loop
  */
  sqlite3VdbeResolveLabel(v, cont);
  sqlite3VdbeAddOp2(v, OP_Next, iTab, addr);
  sqlite3VdbeResolveLabel(v, brk);
................................................................................
  */
  if( p->pLimit ){
    p->iLimit = iLimit = ++pParse->nMem;
    pParse->nMem++;
    v = sqlite3GetVdbe(pParse);
    if( v==0 ) return;
    sqlite3ExprCode(pParse, p->pLimit, 0);
    sqlite3VdbeAddOp2(v, OP_MustBeInt, 0, 0);
    sqlite3VdbeAddOp2(v, OP_Move, 0, iLimit);
    VdbeComment((v, "LIMIT counter"));
    sqlite3VdbeAddOp2(v, OP_IfMemZero, iLimit, iBreak);
    sqlite3VdbeAddOp2(v, OP_SCopy, iLimit, 0);
  }
  if( p->pOffset ){
    p->iOffset = iOffset = ++pParse->nMem;
    v = sqlite3GetVdbe(pParse);
    if( v==0 ) return;
    sqlite3ExprCode(pParse, p->pOffset, 0);
    sqlite3VdbeAddOp2(v, OP_MustBeInt, 0, 0);
    sqlite3VdbeAddOp2(v, p->pLimit==0 ? OP_Move : OP_Copy, 0, iOffset);
    VdbeComment((v, "OFFSET counter"));
    addr1 = sqlite3VdbeAddOp2(v, OP_IfMemPos, iOffset, 0);
    sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
    sqlite3VdbeAddOp2(v, OP_Integer, 0, 0);
    sqlite3VdbeJumpHere(v, addr1);
    if( p->pLimit ){
      sqlite3VdbeAddOp2(v, OP_Add, 0, 0);
    }
  }
  if( p->pLimit ){
    addr1 = sqlite3VdbeAddOp2(v, OP_IfMemPos, iLimit, 0);
    sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
    sqlite3VdbeAddOp2(v, OP_Integer, -1, iLimit+1);
    addr2 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
    sqlite3VdbeJumpHere(v, addr1);
    sqlite3VdbeAddOp2(v, OP_Move, 0, iLimit+1);
    VdbeComment((v, "LIMIT+OFFSET"));
    sqlite3VdbeJumpHere(v, addr2);
  }
}

................................................................................
        if( rc ){
          goto multi_select_end;
        }
        p->pPrior = 0;
        p->iLimit = pPrior->iLimit;
        p->iOffset = pPrior->iOffset;
        if( p->iLimit>=0 ){
          addr = sqlite3VdbeAddOp2(v, OP_IfMemZero, p->iLimit, 0);
          VdbeComment((v, "Jump ahead if LIMIT reached"));
        }
        rc = sqlite3Select(pParse, p, &dest, 0, 0, 0, aff);
        p->pPrior = pPrior;
        if( rc ){
          goto multi_select_end;
        }
................................................................................
      ** order to signal the caller to abort.
      */
      addrSetAbort = sqlite3VdbeCurrentAddr(v);
      sqlite3VdbeAddOp2(v, OP_Integer, 1, iAbortFlag);
      VdbeComment((v, "set abort flag"));
      sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
      addrOutputRow = sqlite3VdbeCurrentAddr(v);
      sqlite3VdbeAddOp2(v, OP_IfMemPos, iUseFlag, addrOutputRow+2);
      VdbeComment((v, "Groupby result generator entry point"));
      sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
      finalizeAggFunctions(pParse, &sAggInfo);
      if( pHaving ){
        sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL);
      }
      rc = selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy,
................................................................................
      */
      sqlite3VdbeResolveLabel(v, addrGroupByChange);
      for(j=0; j<pGroupBy->nExpr; j++){
        sqlite3VdbeAddOp2(v, OP_Move, iBMem+j, iAMem+j);
      }
      sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrOutputRow);
      VdbeComment((v, "output one row"));
      sqlite3VdbeAddOp2(v, OP_IfMemPos, iAbortFlag, addrEnd);
      VdbeComment((v, "check abort flag"));
      sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrReset);
      VdbeComment((v, "reset accumulator"));

      /* Update the aggregate accumulators based on the content of
      ** the current row
      */







|







 







|
|
|
|


|

|

|
|







 







|

|







 







|







 







|







 







|







 







|


|







|


|








|
|

|







 







|







 







|







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
...
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
...
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
...
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
...
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
....
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
....
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
....
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
....
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.394 2008/01/09 02:15:42 drh Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.
................................................................................
static void pushOntoSorter(
  Parse *pParse,         /* Parser context */
  ExprList *pOrderBy,    /* The ORDER BY clause */
  Select *pSelect        /* The whole SELECT statement */
){
  Vdbe *v = pParse->pVdbe;
  sqlite3ExprCodeExprList(pParse, pOrderBy, 0);
  sqlite3VdbeAddOp1(v, OP_Sequence, pOrderBy->iECursor);
  sqlite3VdbeAddOp1(v, OP_Pull, pOrderBy->nExpr + 1);
  sqlite3VdbeAddOp1(v, OP_MakeRecord, pOrderBy->nExpr + 2);
  sqlite3VdbeAddOp1(v, OP_IdxInsert, pOrderBy->iECursor);
  if( pSelect->iLimit>=0 ){
    int addr1, addr2;
    addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, pSelect->iLimit+1);
    sqlite3VdbeAddOp2(v, OP_AddImm, pSelect->iLimit+1, -1);
    addr2 = sqlite3VdbeAddOp0(v, OP_Goto);
    sqlite3VdbeJumpHere(v, addr1);
    sqlite3VdbeAddOp1(v, OP_Last, pOrderBy->iECursor);
    sqlite3VdbeAddOp1(v, OP_Delete, pOrderBy->iECursor);
    sqlite3VdbeJumpHere(v, addr2);
    pSelect->iLimit = -1;
  }
}

/*
** Add code to implement the OFFSET
................................................................................
  Select *p,        /* The SELECT statement being coded */
  int iContinue,    /* Jump here to skip the current record */
  int nPop          /* Number of times to pop stack when jumping */
){
  if( p->iOffset>=0 && iContinue!=0 ){
    int addr;
    sqlite3VdbeAddOp2(v, OP_AddImm, p->iOffset, -1);
    addr = sqlite3VdbeAddOp1(v, OP_IfNeg, p->iOffset);
    if( nPop>0 ){
      sqlite3VdbeAddOp1(v, OP_Pop, nPop);
    }
    sqlite3VdbeAddOp2(v, OP_Goto, 0, iContinue);
    VdbeComment((v, "skip OFFSET records"));
    sqlite3VdbeJumpHere(v, addr);
  }
}

................................................................................
    ** then there should be a single item on the stack.  Write this
    ** item into the set table with bogus data.
    */
    case SRT_Set: {
      int addr2;

      assert( nColumn==1 );
      addr2 = sqlite3VdbeAddOp2(v, OP_IsNull, iMem, 0);
      p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affinity);
      if( pOrderBy ){
        /* At first glance you would think we could optimize out the
        ** ORDER BY in this case since the order of entries in the set
        ** does not matter.  But there might be a LIMIT clause, in which
        ** case the order does matter */
        sqlite3VdbeAddOp2(v, OP_SCopy, iMem, 0);
................................................................................
#endif
  }

  /* Jump to the end of the loop if the LIMIT is reached.
  */
  if( p->iLimit>=0 && pOrderBy==0 ){
    sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1);
    sqlite3VdbeAddOp2(v, OP_IfZero, p->iLimit, iBreak);
  }
  return 0;
}

/*
** Given an expression list, generate a KeyInfo structure that records
** the collating sequence for each expression in that expression list.
................................................................................
    }
  }

  /* Jump to the end of the loop when the LIMIT is reached
  */
  if( p->iLimit>=0 ){
    sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1);
    sqlite3VdbeAddOp2(v, OP_IfZero, p->iLimit, brk);
  }

  /* The bottom of the loop
  */
  sqlite3VdbeResolveLabel(v, cont);
  sqlite3VdbeAddOp2(v, OP_Next, iTab, addr);
  sqlite3VdbeResolveLabel(v, brk);
................................................................................
  */
  if( p->pLimit ){
    p->iLimit = iLimit = ++pParse->nMem;
    pParse->nMem++;
    v = sqlite3GetVdbe(pParse);
    if( v==0 ) return;
    sqlite3ExprCode(pParse, p->pLimit, 0);
    sqlite3VdbeAddOp0(v, OP_MustBeInt);
    sqlite3VdbeAddOp2(v, OP_Move, 0, iLimit);
    VdbeComment((v, "LIMIT counter"));
    sqlite3VdbeAddOp2(v, OP_IfZero, iLimit, iBreak);
    sqlite3VdbeAddOp2(v, OP_SCopy, iLimit, 0);
  }
  if( p->pOffset ){
    p->iOffset = iOffset = ++pParse->nMem;
    v = sqlite3GetVdbe(pParse);
    if( v==0 ) return;
    sqlite3ExprCode(pParse, p->pOffset, 0);
    sqlite3VdbeAddOp0(v, OP_MustBeInt);
    sqlite3VdbeAddOp2(v, p->pLimit==0 ? OP_Move : OP_Copy, 0, iOffset);
    VdbeComment((v, "OFFSET counter"));
    addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iOffset);
    sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
    sqlite3VdbeAddOp2(v, OP_Integer, 0, 0);
    sqlite3VdbeJumpHere(v, addr1);
    if( p->pLimit ){
      sqlite3VdbeAddOp2(v, OP_Add, 0, 0);
    }
  }
  if( p->pLimit ){
    addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iLimit);
    sqlite3VdbeAddOp1(v, OP_Pop, 1);
    sqlite3VdbeAddOp2(v, OP_Integer, -1, iLimit+1);
    addr2 = sqlite3VdbeAddOp0(v, OP_Goto);
    sqlite3VdbeJumpHere(v, addr1);
    sqlite3VdbeAddOp2(v, OP_Move, 0, iLimit+1);
    VdbeComment((v, "LIMIT+OFFSET"));
    sqlite3VdbeJumpHere(v, addr2);
  }
}

................................................................................
        if( rc ){
          goto multi_select_end;
        }
        p->pPrior = 0;
        p->iLimit = pPrior->iLimit;
        p->iOffset = pPrior->iOffset;
        if( p->iLimit>=0 ){
          addr = sqlite3VdbeAddOp1(v, OP_IfZero, p->iLimit);
          VdbeComment((v, "Jump ahead if LIMIT reached"));
        }
        rc = sqlite3Select(pParse, p, &dest, 0, 0, 0, aff);
        p->pPrior = pPrior;
        if( rc ){
          goto multi_select_end;
        }
................................................................................
      ** order to signal the caller to abort.
      */
      addrSetAbort = sqlite3VdbeCurrentAddr(v);
      sqlite3VdbeAddOp2(v, OP_Integer, 1, iAbortFlag);
      VdbeComment((v, "set abort flag"));
      sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
      addrOutputRow = sqlite3VdbeCurrentAddr(v);
      sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2);
      VdbeComment((v, "Groupby result generator entry point"));
      sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
      finalizeAggFunctions(pParse, &sAggInfo);
      if( pHaving ){
        sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL);
      }
      rc = selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy,
................................................................................
      */
      sqlite3VdbeResolveLabel(v, addrGroupByChange);
      for(j=0; j<pGroupBy->nExpr; j++){
        sqlite3VdbeAddOp2(v, OP_Move, iBMem+j, iAMem+j);
      }
      sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrOutputRow);
      VdbeComment((v, "output one row"));
      sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd);
      VdbeComment((v, "check abort flag"));
      sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrReset);
      VdbeComment((v, "reset accumulator"));

      /* Update the aggregate accumulators based on the content of
      ** the current row
      */

Changes to src/update.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
** $Id: update.c,v 1.164 2008/01/08 18:57:50 drh Exp $
*/
#include "sqliteInt.h"

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Forward declaration */
static void updateVirtualTable(
  Parse *pParse,       /* The parsing context */
................................................................................

    /* If the record number will change, push the record number as it
    ** will be after the update. (The old record number is currently
    ** on top of the stack.)
    */
    if( chngRowid ){
      sqlite3ExprCode(pParse, pRowidExpr, regNewRowid);
      sqlite3VdbeAddOp3(v, OP_MustBeInt, 0, 0, regNewRowid);
    }

    /* Compute new data for this record.  
    */
    for(i=0; i<pTab->nCol; i++){
      if( i==pTab->iPKey ){
        sqlite3VdbeAddOp2(v, OP_Null, 0, regData+i);







|







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
** $Id: update.c,v 1.165 2008/01/09 02:15:42 drh Exp $
*/
#include "sqliteInt.h"

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Forward declaration */
static void updateVirtualTable(
  Parse *pParse,       /* The parsing context */
................................................................................

    /* If the record number will change, push the record number as it
    ** will be after the update. (The old record number is currently
    ** on top of the stack.)
    */
    if( chngRowid ){
      sqlite3ExprCode(pParse, pRowidExpr, regNewRowid);
      sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid);
    }

    /* Compute new data for this record.  
    */
    for(i=0; i<pTab->nCol; i++){
      if( i==pTab->iPKey ){
        sqlite3VdbeAddOp2(v, OP_Null, 0, regData+i);

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
....
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
....
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
....
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324


1325
1326
1327
1328
1329
1330
1331
1332
1333
1334


1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
....
1644
1645
1646
1647
1648
1649
1650

1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667

1668
1669
1670
1671
1672
1673

1674

1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
....
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033

2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
....
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090


2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
....
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
**
** 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.689 2008/01/08 23:54:25 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
................................................................................
*/
case OP_Real: {            /* same as TK_FLOAT, out2-prerelease */
  pOut->flags = MEM_Real;
  pOut->r = *pOp->p4.pReal;
  break;
}

/* Opcode: String8 * * P4
**
** P4 points to a nul terminated UTF-8 string. This opcode is transformed 
** into an OP_String before it is executed for the first time.
*/
case OP_String8: {         /* same as TK_STRING, out2-prerelease */
  assert( pOp->p4.z!=0 );
  pOp->opcode = OP_String;
................................................................................
  assert( pOp->p1 <= SQLITE_MAX_LENGTH );
  sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0);
  pOut->enc = encoding;
  break;
}
#endif /* SQLITE_OMIT_BLOB_LITERAL */

/* Opcode: Variable P1 * *
**
** The value of variable P1 is written into register P2 or pushed
** onto the stack if P2 is zero.  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
................................................................................
  if( sqlite3VdbeMemTooBig(pVar) ){
    goto too_big;
  }
  sqlite3VdbeMemShallowCopy(pOut, &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] );
................................................................................
  pOut->flags = MEM_Str|MEM_Dyn|MEM_Term;
  pOut->xDel = 0;
  pOut->enc = encoding;
  pOut->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, in1, in2, out3 */
case OP_Subtract:              /* same as TK_MINUS, in1, in2, out3 */
case OP_Multiply:              /* same as TK_STAR, in1, in2, out3 */
case OP_Divide:                /* same as TK_SLASH, in1, in2, out3 */
case OP_Remainder: {           /* same as TK_REM, in1, in2, out3 */
................................................................................
  pIn1->u.i = v;
  pIn1->flags = MEM_Int;
  break;
}

/* Opcode: MustBeInt P1 P2 P3
** 

** 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
** without 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.
**
** If P3 is not zero, then act on the value in register P3 instead
** of using the stack.
*/
case OP_MustBeInt: {            /* no-push, jump */
  Mem *pMem = ((pOp->p3==0)?pTos:&p->aMem[pOp->p3]);
  assert( pOp->p3 || pTos>=p->aStack );
  assert( pOp->p3>=0 && pOp->p3<=p->nMem );
  REGISTER_TRACE(pOp->p3, pMem);

  applyAffinity(pMem, SQLITE_AFF_NUMERIC, encoding);
  if( (pMem->flags & MEM_Int)==0 ){
    if( pOp->p2==0 ){
      rc = SQLITE_MISMATCH;
      goto abort_due_to_error;
    }else if( pMem==pTos ){

      if( pOp->p1 ) popStack(&pTos, 1);

      pc = pOp->p2 - 1;
    }
  }else{
    Release(pMem);
    pMem->flags = MEM_Int;
  }
  break;
}

/* Opcode: RealAffinity P1 * * * *
**
** If register P1 holds an integer convert it to a real value.
................................................................................
  }else{
    pOut->u.i = v1;
    pOut->flags = MEM_Int;
  }
  break;
}

/* Opcode: Negative * * *
**
** Treat the top of the stack as a numeric quantity.  Replace it
** with its additive inverse.  If the top of the stack is NULL
** its value is unchanged.
*/
/* Opcode: AbsValue * * *
**
** Treat the top of the stack as a numeric quantity.  Replace it
** with its absolute value. If the top of the stack is NULL
** its value is unchanged.
*/
case OP_Negative:              /* same as TK_UMINUS, no-push */
case OP_AbsValue: {
  assert( pTos>=p->aStack );
  if( (pTos->flags & (MEM_Real|MEM_Int|MEM_Null))==0 ){
    sqlite3VdbeMemNumerify(pTos);
  }
  if( pTos->flags & MEM_Real ){
    Release(pTos);
    if( pOp->opcode==OP_Negative || pTos->r<0.0 ){
      pTos->r = -pTos->r;
    }
    pTos->flags = MEM_Real;
  }else if( pTos->flags & MEM_Int ){
    Release(pTos);
    if( pOp->opcode==OP_Negative || pTos->u.i<0 ){
      pTos->u.i = -pTos->u.i;
    }
    pTos->flags = MEM_Int;
  }
  break;
}

/* Opcode: Not * * *
**
** Interpret the top of the stack as a boolean value.  Replace it
** with its complement.  If the top of the stack is NULL its value
** is unchanged.
*/
case OP_Not: {                /* same as TK_NOT, no-push */
  assert( pTos>=p->aStack );

  if( pTos->flags & MEM_Null ) break;  /* Do nothing to NULLs */
  sqlite3VdbeMemIntegerify(pTos);
  assert( (pTos->flags & MEM_Dyn)==0 );
  pTos->u.i = !pTos->u.i;
  pTos->flags = MEM_Int;
  break;
}

/* Opcode: BitNot * * *
**
** Interpret the top of the stack as an value.  Replace it
** with its ones-complement.  If the top of the stack is NULL its
** value is unchanged.
*/
case OP_BitNot: {             /* same as TK_BITNOT, no-push */
  assert( pTos>=p->aStack );
  if( pTos->flags & MEM_Null ) break;  /* Do nothing to NULLs */
  sqlite3VdbeMemIntegerify(pTos);
  assert( (pTos->flags & MEM_Dyn)==0 );
  pTos->u.i = ~pTos->u.i;
  pTos->flags = MEM_Int;
  break;
}

/* Opcode: Noop * * *
**
** Do nothing.  This instruction is often useful as a jump
** destination.
................................................................................
** the same as a no-op.  This opcodesnever appears in a real VM program.
*/
case OP_Explain:
case OP_Noop: {            /* no-push */
  break;
}

/* Opcode: If P1 P2 *
**
** Pop a single boolean from the stack.  If the boolean popped is
** true, then jump to p2.  Otherwise continue to the next instruction.
** An integer is false if zero and true otherwise.  A string is
** false if it has zero length and true otherwise.
**
** If the value popped of the stack is NULL, then take the jump if P1
** is true and fall through if P1 is false.
*/
/* Opcode: IfNot P1 P2 *
**
** Pop a single boolean from the stack.  If the boolean popped is
** false, then jump to p2.  Otherwise continue to the next instruction.
** An integer is false if zero and true otherwise.  A string is
** false if it has zero length and true otherwise.
**


** If the value popped of the stack is NULL, then take the jump if P1
** is true and fall through if P1 is false.
*/
case OP_If:                 /* no-push, jump */
case OP_IfNot: {            /* no-push, jump */
  int c;
  assert( pTos>=p->aStack );
  if( pTos->flags & MEM_Null ){
    c = pOp->p1;
  }else{
#ifdef SQLITE_OMIT_FLOATING_POINT
    c = sqlite3VdbeIntValue(pTos);
#else
    c = sqlite3VdbeRealValue(pTos)!=0.0;
#endif
    if( pOp->opcode==OP_IfNot ) c = !c;
  }
  Release(pTos);
  pTos--;
  if( c ) pc = pOp->p2-1;
  break;
}

/* Opcode: StackIsNull P1 P2 *
**
** Check the top of the stack and jump to P2 if the top of the stack
** is NULL.  If P1 is positive, then pop P1 elements from the stack
................................................................................
  if( pMem->u.i<pNew->u.i){
    pMem->u.i = pNew->u.i;
  }
  break;
}
#endif /* SQLITE_OMIT_AUTOINCREMENT */

/* Opcode: IfMemPos P1 P2 *
**
** If the value of memory cell P1 is 1 or greater, jump to P2.
**
** It is illegal to use this instruction on a memory cell that does
** not contain an integer.  An assertion fault will result if you try.
*/
case OP_IfMemPos: {        /* no-push, jump */
  int i = pOp->p1;
  Mem *pMem;
  assert( i>0 && i<=p->nMem );
  pMem = &p->aMem[i];
  assert( pMem->flags==MEM_Int );
  if( pMem->u.i>0 ){
     pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: IfMemNeg P1 P2 *
**
** If the value of memory cell P1 is less than zero, jump to P2. 
**
** It is illegal to use this instruction on a memory cell that does
** not contain an integer.  An assertion fault will result if you try.
*/
case OP_IfMemNeg: {        /* no-push, jump */
  int i = pOp->p1;
  Mem *pMem;
  assert( i>0 && i<=p->nMem );
  pMem = &p->aMem[i];
  assert( pMem->flags==MEM_Int );
  if( pMem->u.i<0 ){
     pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: IfMemZero P1 P2 *
**
** If the value of memory cell P1 is exactly 0, jump to P2. 
**
** It is illegal to use this instruction on a memory cell that does
** not contain an integer.  An assertion fault will result if you try.
*/
case OP_IfMemZero: {        /* no-push, jump */
  int i = pOp->p1;
  Mem *pMem;
  assert( i>0 && i<=p->nMem );
  pMem = &p->aMem[i];
  assert( pMem->flags==MEM_Int );
  if( pMem->u.i==0 ){
     pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: IfMemNull P1 P2 *
**
** If the value of memory cell P1 is NULL, jump to P2. 
*/
case OP_IfMemNull: {        /* no-push, jump */
  int i = pOp->p1;
  assert( i>0 && i<=p->nMem );
  if( p->aMem[i].flags & MEM_Null ){
     pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: AggStep P1 P2 P4
**







|







 







|







 







|







 







|







 







|

|
<
<
<


|

<
<
<
<
>
>


|

<
<
<
<
<
<
>
>




|
|
<
<
<
<




|
|
|
<
<
<







 







>
|
|



|
|
|
<
<
<

|
<
<
<
<
>
|
|



|
>
|
>



|
|







 







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






|
<
>
|
|
|
|
|









|
|
|
|
|
|
|







 







|

|
|
<
<
<
|
<

|

<
<
<
<
<
>
>
|
<

|
|

<
|
|


|

|



|
|
|







 







|






|
<
<
<
<
|
|





|






|
<
<
<
<
|
|





|






|
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
....
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
....
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
....
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313



1314
1315
1316
1317




1318
1319
1320
1321
1322
1323






1324
1325
1326
1327
1328
1329
1330
1331




1332
1333
1334
1335
1336
1337
1338



1339
1340
1341
1342
1343
1344
1345
....
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643



1644
1645




1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
....
1966
1967
1968
1969
1970
1971
1972


































1973
1974
1975
1976
1977
1978
1979

1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
....
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024



2025

2026
2027
2028





2029
2030
2031

2032
2033
2034
2035

2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
....
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706




4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721




4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736




4737
4738













4739
4740
4741
4742
4743
4744
4745
**
** 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.690 2008/01/09 02:15:42 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
................................................................................
*/
case OP_Real: {            /* same as TK_FLOAT, out2-prerelease */
  pOut->flags = MEM_Real;
  pOut->r = *pOp->p4.pReal;
  break;
}

/* Opcode: String8 * P2 * P4 *
**
** P4 points to a nul terminated UTF-8 string. This opcode is transformed 
** into an OP_String before it is executed for the first time.
*/
case OP_String8: {         /* same as TK_STRING, out2-prerelease */
  assert( pOp->p4.z!=0 );
  pOp->opcode = OP_String;
................................................................................
  assert( pOp->p1 <= SQLITE_MAX_LENGTH );
  sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0);
  pOut->enc = encoding;
  break;
}
#endif /* SQLITE_OMIT_BLOB_LITERAL */

/* Opcode: Variable P1 P2 * * *
**
** The value of variable P1 is written into register P2 or pushed
** onto the stack if P2 is zero.  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
................................................................................
  if( sqlite3VdbeMemTooBig(pVar) ){
    goto too_big;
  }
  sqlite3VdbeMemShallowCopy(pOut, &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] );
................................................................................
  pOut->flags = MEM_Str|MEM_Dyn|MEM_Term;
  pOut->xDel = 0;
  pOut->enc = encoding;
  pOut->z = zNew;
  break;
}

/* Opcode: Add P1 P2 P3 * *
**
** Add the value in P1 to the value in P2 and store the result in P3.



** If either operand is NULL, the result is NULL.
*/
/* Opcode: Multiply P1 P2 P3 * *
**




**
** Multiply the value in P1 by the value in P2 and store the result in P3.
** If either operand is NULL, the result is NULL.
*/
/* Opcode: Subtract P1 P2 P3 * *
**






** Subtract the value in P1 from the value in P2 and store the result
** in P3.
** If either operand is NULL, the result is NULL.
*/
/* Opcode: Divide * * *
**
** Divide the value in P1 by the value in P2 and store the result
** in P3.  If the value in P2 is zero, then the result is NULL.




** If either operand is NULL, the result is NULL.
*/
/* Opcode: Remainder * * *
**
** Compute the remainder after integer division of the value in
** register P1 by the value in register P2 and store the result in P3. 
** If the value in register P2 is zero the result is NULL.



** If either operand is NULL, the result is NULL.
*/
case OP_Add:                   /* same as TK_PLUS, in1, in2, out3 */
case OP_Subtract:              /* same as TK_MINUS, in1, in2, out3 */
case OP_Multiply:              /* same as TK_STAR, in1, in2, out3 */
case OP_Divide:                /* same as TK_SLASH, in1, in2, out3 */
case OP_Remainder: {           /* same as TK_REM, in1, in2, out3 */
................................................................................
  pIn1->u.i = v;
  pIn1->flags = MEM_Int;
  break;
}

/* Opcode: MustBeInt P1 P2 P3
** 
** Force the value in register P1 to be an integer.  If P1==0 then
** use the top of the stack.  If the value in P1 
** is not an integer and cannot be converted into an integer
** without data loss, then jump immediately to P2, or if P2==0
** raise an SQLITE_MISMATCH exception.
**
** If the P1==0 and the top of the stack is not an integer
** and P2 is not zero and P3 is 1, then the stack is popped.
** In all other cases, the depth of the stack is unchanged.



*/
case OP_MustBeInt: {            /* no-push, jump, in1 */




  nPop = 0;
  applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding);
  if( (pIn1->flags & MEM_Int)==0 ){
    if( pOp->p2==0 ){
      rc = SQLITE_MISMATCH;
      goto abort_due_to_error;
    }else{
      if( pOp->p3 && pOp->p1==0 ){
        popStack(&pTos, 1);
      }
      pc = pOp->p2 - 1;
    }
  }else{
    Release(pIn1);
    pIn1->flags = MEM_Int;
  }
  break;
}

/* Opcode: RealAffinity P1 * * * *
**
** If register P1 holds an integer convert it to a real value.
................................................................................
  }else{
    pOut->u.i = v1;
    pOut->flags = MEM_Int;
  }
  break;
}



































/* Opcode: Not * * *
**
** Interpret the top of the stack as a boolean value.  Replace it
** with its complement.  If the top of the stack is NULL its value
** is unchanged.
*/
case OP_Not: {                /* same as TK_NOT, no-push, in1 */

  nPop = 0;
  if( pIn1->flags & MEM_Null ) break;  /* Do nothing to NULLs */
  sqlite3VdbeMemIntegerify(pIn1);
  assert( (pIn1->flags & MEM_Dyn)==0 );
  pIn1->u.i = !pTos->u.i;
  pIn1->flags = MEM_Int;
  break;
}

/* Opcode: BitNot * * *
**
** Interpret the top of the stack as an value.  Replace it
** with its ones-complement.  If the top of the stack is NULL its
** value is unchanged.
*/
case OP_BitNot: {             /* same as TK_BITNOT, no-push, in1 */
  nPop = 0;
  if( pIn1->flags & MEM_Null ) break;  /* Do nothing to NULLs */
  sqlite3VdbeMemIntegerify(pIn1);
  assert( (pIn1->flags & MEM_Dyn)==0 );
  pIn1->u.i = ~pTos->u.i;
  pIn1->flags = MEM_Int;
  break;
}

/* Opcode: Noop * * *
**
** Do nothing.  This instruction is often useful as a jump
** destination.
................................................................................
** the same as a no-op.  This opcodesnever appears in a real VM program.
*/
case OP_Explain:
case OP_Noop: {            /* no-push */
  break;
}

/* Opcode: If P1 P2 P3 * *
**
** Jump to P2 if the value in register P1 is true.  The value is
** is considered true if it is numeric and non-zero.  If the value



** in P1 is NULL then take the jump if P3 is true.

*/
/* Opcode: IfNot P1 P2 P3 * *
**





** Jump to P2 if the value in register P1 is False.  The value is
** is considered true if it has a numeric value of zero.  If the value
** in P1 is NULL then take the jump if P3 is true.

*/
case OP_If:                 /* no-push, jump, in1 */
case OP_IfNot: {            /* no-push, jump, in1 */
  int c;

  if( pIn1->flags & MEM_Null ){
    c = pOp->p3;
  }else{
#ifdef SQLITE_OMIT_FLOATING_POINT
    c = sqlite3VdbeIntValue(pIn1);
#else
    c = sqlite3VdbeRealValue(pIn1)!=0.0;
#endif
    if( pOp->opcode==OP_IfNot ) c = !c;
  }
  if( c ){
    pc = pOp->p2-1;
  }
  break;
}

/* Opcode: StackIsNull P1 P2 *
**
** Check the top of the stack and jump to P2 if the top of the stack
** is NULL.  If P1 is positive, then pop P1 elements from the stack
................................................................................
  if( pMem->u.i<pNew->u.i){
    pMem->u.i = pNew->u.i;
  }
  break;
}
#endif /* SQLITE_OMIT_AUTOINCREMENT */

/* Opcode: IfPos P1 P2 *
**
** If the value of memory cell P1 is 1 or greater, jump to P2.
**
** It is illegal to use this instruction on a memory cell that does
** not contain an integer.  An assertion fault will result if you try.
*/
case OP_IfPos: {        /* no-push, jump, in1 */




  assert( pIn1->flags==MEM_Int );
  if( pIn1->u.i>0 ){
     pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: IfNeg P1 P2 *
**
** If the value of memory cell P1 is less than zero, jump to P2. 
**
** It is illegal to use this instruction on a memory cell that does
** not contain an integer.  An assertion fault will result if you try.
*/
case OP_IfNeg: {        /* no-push, jump, in1 */




  assert( pIn1->flags==MEM_Int );
  if( pIn1->u.i<0 ){
     pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: IfZero P1 P2 *
**
** If the value of memory cell P1 is exactly 0, jump to P2. 
**
** It is illegal to use this instruction on a memory cell that does
** not contain an integer.  An assertion fault will result if you try.
*/
case OP_IfZero: {        /* no-push, jump, in1 */




  assert( pIn1->flags==MEM_Int );
  if( pIn1->u.i==0 ){













     pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: AggStep P1 P2 P4
**

Changes to src/where.c.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
....
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
....
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
....
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
** This module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements.  This module is reponsible for
** generating the code that loops through a table looking for applicable
** rows.  Indices are selected and used to speed the search when doing
** so is applicable.  Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer".
**
** $Id: where.c,v 1.278 2008/01/08 23:54:26 drh Exp $
*/
#include "sqliteInt.h"

/*
** The number of bits in a Bitmask.  "BMS" means "BitMask Size".
*/
#define BMS  (sizeof(Bitmask)*8)
................................................................................
      pTerm = findTerm(&wc, iCur, -1, notReady, WO_EQ|WO_IN, 0);
      assert( pTerm!=0 );
      assert( pTerm->pExpr!=0 );
      assert( pTerm->leftCursor==iCur );
      assert( omitTable==0 );
      codeEqualityTerm(pParse, pTerm, pLevel);
      nxt = pLevel->nxt;
      sqlite3VdbeAddOp2(v, OP_MustBeInt, 1, nxt);
      sqlite3VdbeAddOp2(v, OP_NotExists, iCur, nxt);
      VdbeComment((v, "pk"));
      pLevel->op = OP_Noop;
    }else if( pLevel->flags & WHERE_ROWID_RANGE ){
      /* Case 2:  We have an inequality comparison against the ROWID field.
      */
      int testOp = OP_Noop;
................................................................................
        sqlite3VdbeJumpHere(v, pIn->topAddr-1);
      }
      sqlite3_free(pLevel->aInLoop);
    }
    sqlite3VdbeResolveLabel(v, pLevel->brk);
    if( pLevel->iLeftJoin ){
      int addr;
      addr = sqlite3VdbeAddOp2(v, OP_IfMemPos, pLevel->iLeftJoin, 0);
      sqlite3VdbeAddOp2(v, OP_NullRow, pTabList->a[i].iCursor, 0);
      if( pLevel->iIdxCur>=0 ){
        sqlite3VdbeAddOp2(v, OP_NullRow, pLevel->iIdxCur, 0);
      }
      sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->top);
      sqlite3VdbeJumpHere(v, addr);
    }
  }

  /* The "break" point is here, just past the end of the outer loop.
................................................................................
  */
  for(i=0, pLevel=pWInfo->a; i<pTabList->nSrc; i++, pLevel++){
    struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom];
    Table *pTab = pTabItem->pTab;
    assert( pTab!=0 );
    if( pTab->isEphem || pTab->pSelect ) continue;
    if( (pLevel->flags & WHERE_IDX_ONLY)==0 ){
      sqlite3VdbeAddOp2(v, OP_Close, pTabItem->iCursor, 0);
    }
    if( pLevel->pIdx!=0 ){
      sqlite3VdbeAddOp2(v, OP_Close, pLevel->iIdxCur, 0);
    }

    /* If this scan uses an index, make code substitutions to read data
    ** from the index in preference to the table. Sometimes, this means
    ** the table need never be read from. This is a performance boost,
    ** as the vdbe level waits until the table is read before actually
    ** seeking the table cursor to the record corresponding to the current







|







 







|







 







|
|

|







 







|


|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
....
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
....
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
....
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
** This module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements.  This module is reponsible for
** generating the code that loops through a table looking for applicable
** rows.  Indices are selected and used to speed the search when doing
** so is applicable.  Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer".
**
** $Id: where.c,v 1.279 2008/01/09 02:15:42 drh Exp $
*/
#include "sqliteInt.h"

/*
** The number of bits in a Bitmask.  "BMS" means "BitMask Size".
*/
#define BMS  (sizeof(Bitmask)*8)
................................................................................
      pTerm = findTerm(&wc, iCur, -1, notReady, WO_EQ|WO_IN, 0);
      assert( pTerm!=0 );
      assert( pTerm->pExpr!=0 );
      assert( pTerm->leftCursor==iCur );
      assert( omitTable==0 );
      codeEqualityTerm(pParse, pTerm, pLevel);
      nxt = pLevel->nxt;
      sqlite3VdbeAddOp3(v, OP_MustBeInt, 0, nxt, 1);
      sqlite3VdbeAddOp2(v, OP_NotExists, iCur, nxt);
      VdbeComment((v, "pk"));
      pLevel->op = OP_Noop;
    }else if( pLevel->flags & WHERE_ROWID_RANGE ){
      /* Case 2:  We have an inequality comparison against the ROWID field.
      */
      int testOp = OP_Noop;
................................................................................
        sqlite3VdbeJumpHere(v, pIn->topAddr-1);
      }
      sqlite3_free(pLevel->aInLoop);
    }
    sqlite3VdbeResolveLabel(v, pLevel->brk);
    if( pLevel->iLeftJoin ){
      int addr;
      addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin);
      sqlite3VdbeAddOp1(v, OP_NullRow, pTabList->a[i].iCursor);
      if( pLevel->iIdxCur>=0 ){
        sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur);
      }
      sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->top);
      sqlite3VdbeJumpHere(v, addr);
    }
  }

  /* The "break" point is here, just past the end of the outer loop.
................................................................................
  */
  for(i=0, pLevel=pWInfo->a; i<pTabList->nSrc; i++, pLevel++){
    struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom];
    Table *pTab = pTabItem->pTab;
    assert( pTab!=0 );
    if( pTab->isEphem || pTab->pSelect ) continue;
    if( (pLevel->flags & WHERE_IDX_ONLY)==0 ){
      sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor);
    }
    if( pLevel->pIdx!=0 ){
      sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur);
    }

    /* If this scan uses an index, make code substitutions to read data
    ** from the index in preference to the table. Sometimes, this means
    ** the table need never be read from. This is a performance boost,
    ** as the vdbe level waits until the table is read before actually
    ** seeking the table cursor to the record corresponding to the current