/ Check-in [a6dddebc]
Login

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

Overview
Comment:Continuing work toward converting the VM into a register machine. (CVS 4707)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:a6dddebcc5ccbbf3009c9d06163a8b59036331de
User & Date: drh 2008-01-12 12:48:08
Context
2008-01-12
19:03
Continuing work toward converting the VM to a register machine. (CVS 4708) check-in: 426f31ec user: drh tags: trunk
12:48
Continuing work toward converting the VM into a register machine. (CVS 4707) check-in: a6dddebc user: drh tags: trunk
2008-01-11
15:27
Do explicit range tests before attempting to convert a 64-bit float into a 64-bit integer. Some systems (windows) seem to throw exceptions if the conversion is out of range. Ticket #2880. (CVS 4706) check-in: 4744257d user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/analyze.c.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains code associated with the ANALYZE command.
    13     13   **
    14         -** @(#) $Id: analyze.c,v 1.37 2008/01/10 23:50:11 drh Exp $
           14  +** @(#) $Id: analyze.c,v 1.38 2008/01/12 12:48:08 drh Exp $
    15     15   */
    16     16   #ifndef SQLITE_OMIT_ANALYZE
    17     17   #include "sqliteInt.h"
    18     18   
    19     19   /*
    20     20   ** This routine generates code that opens the sqlite_stat1 table on cursor
    21     21   ** iStatCur.
................................................................................
    29     29     int iDb,                /* The database we are looking in */
    30     30     int iStatCur,           /* Open the sqlite_stat1 table on this cursor */
    31     31     const char *zWhere      /* Delete entries associated with this table */
    32     32   ){
    33     33     sqlite3 *db = pParse->db;
    34     34     Db *pDb;
    35     35     int iRootPage;
           36  +  int createStat1 = 0;
    36     37     Table *pStat;
    37     38     Vdbe *v = sqlite3GetVdbe(pParse);
    38     39   
    39     40     if( v==0 ) return;
    40     41     assert( sqlite3BtreeHoldsAllMutexes(db) );
    41     42     assert( sqlite3VdbeDb(v)==db );
    42     43     pDb = &db->aDb[iDb];
    43     44     if( (pStat = sqlite3FindTable(db, "sqlite_stat1", pDb->zName))==0 ){
    44     45       /* The sqlite_stat1 tables does not exist.  Create it.  
    45     46       ** Note that a side-effect of the CREATE TABLE statement is to leave
    46         -    ** the rootpage of the new table on the top of the stack.  This is
           47  +    ** the rootpage of the new table in register pParse->regRoot.  This is
    47     48       ** important because the OpenWrite opcode below will be needing it. */
    48     49       sqlite3NestedParse(pParse,
    49     50         "CREATE TABLE %Q.sqlite_stat1(tbl,idx,stat)",
    50     51         pDb->zName
    51     52       );
    52         -    iRootPage = 0;  /* Cause rootpage to be taken from top of stack */
           53  +    iRootPage = pParse->regRoot;
           54  +    createStat1 = 1;  /* Cause rootpage to be taken from top of stack */
    53     55     }else if( zWhere ){
    54     56       /* The sqlite_stat1 table exists.  Delete all entries associated with
    55     57       ** the table zWhere. */
    56     58       sqlite3NestedParse(pParse,
    57     59          "DELETE FROM %Q.sqlite_stat1 WHERE tbl=%Q",
    58     60          pDb->zName, zWhere
    59     61       );
................................................................................
    65     67     }
    66     68   
    67     69     /* Open the sqlite_stat1 table for writing. Unless it was created
    68     70     ** by this vdbe program, lock it for writing at the shared-cache level. 
    69     71     ** If this vdbe did create the sqlite_stat1 table, then it must have 
    70     72     ** already obtained a schema-lock, making the write-lock redundant.
    71     73     */
    72         -  if( iRootPage>0 ){
           74  +  if( !createStat1 ){
    73     75       sqlite3TableLock(pParse, iDb, iRootPage, 1, "sqlite_stat1");
    74     76     }
    75     77     sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur, iRootPage, iDb);
    76         -  if( iRootPage==0 ){
    77         -    sqlite3VdbeChangeP5(v, 1);
    78         -  }
           78  +  sqlite3VdbeChangeP5(v, createStat1);
    79     79     sqlite3VdbeAddOp2(v, OP_SetNumColumns, iStatCur, 3);
    80     80   }
    81     81   
    82     82   /*
    83     83   ** Generate code to do an analysis of all indices associated with
    84     84   ** a single table.
    85     85   */

Changes to src/build.c.

    18     18   **     CREATE INDEX
    19     19   **     DROP INDEX
    20     20   **     creating ID lists
    21     21   **     BEGIN TRANSACTION
    22     22   **     COMMIT
    23     23   **     ROLLBACK
    24     24   **
    25         -** $Id: build.c,v 1.463 2008/01/10 23:50:11 drh Exp $
           25  +** $Id: build.c,v 1.464 2008/01/12 12:48:08 drh Exp $
    26     26   */
    27     27   #include "sqliteInt.h"
    28     28   #include <ctype.h>
    29     29   
    30     30   /*
    31     31   ** This routine is called when a new SQL statement is beginning to
    32     32   ** be parsed.  Initialize the pParse structure as needed.
................................................................................
   834    834     ** and allocate the record number for the table entry now.  Before any
   835    835     ** PRIMARY KEY or UNIQUE keywords are parsed.  Those keywords will cause
   836    836     ** indices to be created and the table record must come before the 
   837    837     ** indices.  Hence, the record number for the table must be allocated
   838    838     ** now.
   839    839     */
   840    840     if( !db->init.busy && (v = sqlite3GetVdbe(pParse))!=0 ){
   841         -    int lbl;
          841  +    int j1;
   842    842       int fileFormat;
          843  +    int reg1, reg2, reg3;
   843    844       sqlite3BeginWriteOperation(pParse, 0, iDb);
   844    845   
   845    846   #ifndef SQLITE_OMIT_VIRTUALTABLE
   846    847       if( isVirtual ){
   847    848         sqlite3VdbeAddOp0(v, OP_VBegin);
   848    849       }
   849    850   #endif
   850    851   
   851    852       /* If the file format and encoding in the database have not been set, 
   852    853       ** set them now.
   853    854       */
   854         -    sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, 0, 1);   /* file_format */
          855  +    reg1 = pParse->regRowid = ++pParse->nMem;
          856  +    reg2 = pParse->regRoot = ++pParse->nMem;
          857  +    reg3 = ++pParse->nMem;
          858  +    sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, 1);   /* file_format */
   855    859       sqlite3VdbeUsesBtree(v, iDb);
   856         -    lbl = sqlite3VdbeMakeLabel(v);
   857         -    sqlite3VdbeAddOp2(v, OP_If, 0, lbl);
          860  +    j1 = sqlite3VdbeAddOp1(v, OP_If, reg3);
   858    861       fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ?
   859    862                     1 : SQLITE_MAX_FILE_FORMAT;
   860         -    sqlite3VdbeAddOp1(v, OP_Integer, fileFormat);
   861         -    sqlite3VdbeAddOp2(v, OP_SetCookie, iDb, 1);
   862         -    sqlite3VdbeAddOp1(v, OP_Integer, ENC(db));
   863         -    sqlite3VdbeAddOp2(v, OP_SetCookie, iDb, 4);
   864         -    sqlite3VdbeResolveLabel(v, lbl);
          863  +    sqlite3VdbeAddOp2(v, OP_Integer, fileFormat, reg3);
          864  +    sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, 1, reg3);
          865  +    sqlite3VdbeAddOp2(v, OP_Integer, ENC(db), reg3);
          866  +    sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, 4, reg3);
          867  +    sqlite3VdbeJumpHere(v, j1);
   865    868   
   866    869       /* This just creates a place-holder record in the sqlite_master table.
   867    870       ** The record created does not contain anything yet.  It will be replaced
   868    871       ** by the real entry in code generated at sqlite3EndTable().
   869    872       **
   870    873       ** The rowid for the new entry is left on the top of the stack.
   871    874       ** The rowid value is needed by the code that sqlite3EndTable will
   872    875       ** generate.
   873    876       */
   874    877   #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
   875    878       if( isView || isVirtual ){
   876         -      sqlite3VdbeAddOp0(v, OP_Integer);
          879  +      sqlite3VdbeAddOp2(v, OP_Integer, 0, reg2);
   877    880       }else
   878    881   #endif
   879    882       {
   880         -      sqlite3VdbeAddOp1(v, OP_CreateTable, iDb);
          883  +      sqlite3VdbeAddOp2(v, OP_CreateTable, iDb, reg2);
   881    884       }
   882    885       sqlite3OpenMasterTable(pParse, iDb);
   883         -    sqlite3VdbeAddOp0(v, OP_NewRowid);
   884         -    sqlite3VdbeAddOp0(v, OP_Copy);
   885         -    sqlite3VdbeAddOp0(v, OP_Null);
   886         -    sqlite3CodeInsert(pParse, 0, OPFLAG_APPEND);
          886  +    sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1);
          887  +    sqlite3VdbeAddOp2(v, OP_Null, 0, reg3);
          888  +    sqlite3VdbeAddOp3(v, OP_Insert, 0, reg3, reg1);
          889  +    sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
   887    890       sqlite3VdbeAddOp0(v, OP_Close);
   888         -    sqlite3VdbeAddOp1(v, OP_Pull, 1);
   889    891     }
   890    892   
   891    893     /* Normal (non-error) return. */
   892    894     return;
   893    895   
   894    896     /* If an error occurs, we jump here */
   895    897   begin_table_error:
................................................................................
  1490   1492       ** a schema-lock excludes all other database users, the write-lock would
  1491   1493       ** be redundant.
  1492   1494       */
  1493   1495       if( pSelect ){
  1494   1496         SelectDest dest;
  1495   1497         Table *pSelTab;
  1496   1498   
  1497         -      sqlite3VdbeAddOp0(v, OP_Copy);
  1498         -      sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, 0, iDb);
         1499  +      sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb);
  1499   1500         sqlite3VdbeChangeP5(v, 1);
  1500   1501         pParse->nTab = 2;
  1501   1502         sqlite3SelectDestInit(&dest, SRT_Table, 1);
  1502   1503         sqlite3Select(pParse, pSelect, &dest, 0, 0, 0, 0);
  1503   1504         sqlite3VdbeAddOp1(v, OP_Close, 1);
  1504   1505         if( pParse->nErr==0 ){
  1505   1506           pSelTab = sqlite3ResultSetOfSelect(pParse, 0, pSelect);
................................................................................
  1527   1528       ** SQLITE_MASTER table.  We just need to update that slot with all
  1528   1529       ** the information we've collected.  The rowid for the preallocated
  1529   1530       ** slot is the 2nd item on the stack.  The top of the stack is the
  1530   1531       ** root page for the new table (or a 0 if this is a view).
  1531   1532       */
  1532   1533       sqlite3NestedParse(pParse,
  1533   1534         "UPDATE %Q.%s "
  1534         -         "SET type='%s', name=%Q, tbl_name=%Q, rootpage=#0, sql=%Q "
  1535         -       "WHERE rowid=#1",
         1535  +         "SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q "
         1536  +       "WHERE rowid=#%d",
  1536   1537         db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
  1537   1538         zType,
  1538   1539         p->zName,
  1539   1540         p->zName,
  1540         -      zStmt
         1541  +      pParse->regRoot,
         1542  +      zStmt,
         1543  +      pParse->regRowid
  1541   1544       );
  1542   1545       sqlite3_free(zStmt);
  1543   1546       sqlite3ChangeCookie(db, v, iDb);
  1544   1547   
  1545   1548   #ifndef SQLITE_OMIT_AUTOINCREMENT
  1546   1549       /* Check to see if we need to create an sqlite_sequence table for
  1547   1550       ** keeping track of autoincrement keys.
................................................................................
  1831   1834   ** Write code to erase the table with root-page iTable from database iDb.
  1832   1835   ** Also write code to modify the sqlite_master table and internal schema
  1833   1836   ** if a root-page of another table is moved by the btree-layer whilst
  1834   1837   ** erasing iTable (this can happen with an auto-vacuum database).
  1835   1838   */ 
  1836   1839   static void destroyRootPage(Parse *pParse, int iTable, int iDb){
  1837   1840     Vdbe *v = sqlite3GetVdbe(pParse);
  1838         -  sqlite3VdbeAddOp3(v, OP_Destroy, iTable, 0, iDb);
         1841  +  int r1 = sqlite3GetTempReg(pParse);
         1842  +  sqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb);
  1839   1843   #ifndef SQLITE_OMIT_AUTOVACUUM
  1840         -  /* OP_Destroy pushes an integer onto the stack. If this integer
         1844  +  /* OP_Destroy stores an in integer r1. If this integer
  1841   1845     ** is non-zero, then it is the root page number of a table moved to
  1842   1846     ** location iTable. The following code modifies the sqlite_master table to
  1843   1847     ** reflect this.
  1844   1848     **
  1845         -  ** The "#0" in the SQL is a special constant that means whatever value
         1849  +  ** The "#%d" in the SQL is a special constant that means whatever value
  1846   1850     ** is on the top of the stack.  See sqlite3RegisterExpr().
  1847   1851     */
  1848   1852     sqlite3NestedParse(pParse, 
  1849         -     "UPDATE %Q.%s SET rootpage=%d WHERE #0 AND rootpage=#0",
  1850         -     pParse->db->aDb[iDb].zName, SCHEMA_TABLE(iDb), iTable);
         1853  +     "UPDATE %Q.%s SET rootpage=%d WHERE #%d AND rootpage=#%d",
         1854  +     pParse->db->aDb[iDb].zName, SCHEMA_TABLE(iDb), iTable, r1, r1);
  1851   1855   #endif
         1856  +  sqlite3ReleaseTempReg(pParse, r1);
  1852   1857   }
  1853   1858   
  1854   1859   /*
  1855   1860   ** Write VDBE code to erase table pTab and all associated indices on disk.
  1856   1861   ** Code to update the sqlite_master tables and internal schema definitions
  1857   1862   ** in case a root-page belonging to another table is moved by the btree layer
  1858   1863   ** is also added (this can happen with an auto-vacuum database).
................................................................................
  2645   2650       v = sqlite3GetVdbe(pParse);
  2646   2651       if( v==0 ) goto exit_create_index;
  2647   2652   
  2648   2653   
  2649   2654       /* Create the rootpage for the index
  2650   2655       */
  2651   2656       sqlite3BeginWriteOperation(pParse, 1, iDb);
  2652         -    sqlite3VdbeAddOp1(v, OP_CreateIndex, iDb);
  2653         -    sqlite3VdbeAddOp2(v, OP_Copy, 0, iMem);
         2657  +    sqlite3VdbeAddOp2(v, OP_CreateIndex, iDb, iMem);
  2654   2658   
  2655   2659       /* Gather the complete text of the CREATE INDEX statement into
  2656   2660       ** the zStmt variable
  2657   2661       */
  2658   2662       if( pStart && pEnd ){
  2659   2663         /* A named index with an explicit CREATE INDEX statement */
  2660   2664         zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s",
................................................................................
  2666   2670         /* zStmt = sqlite3MPrintf(""); */
  2667   2671         zStmt = 0;
  2668   2672       }
  2669   2673   
  2670   2674       /* Add an entry in sqlite_master for this index
  2671   2675       */
  2672   2676       sqlite3NestedParse(pParse, 
  2673         -        "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#0,%Q);",
         2677  +        "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);",
  2674   2678           db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
  2675   2679           pIndex->zName,
  2676   2680           pTab->zName,
         2681  +        iMem,
  2677   2682           zStmt
  2678   2683       );
  2679         -    sqlite3VdbeAddOp1(v, OP_Pop, 1);
  2680   2684       sqlite3_free(zStmt);
  2681   2685   
  2682   2686       /* Fill the index with data and reparse the schema. Code an OP_Expire
  2683   2687       ** to invalidate all pre-compiled statements.
  2684   2688       */
  2685   2689       if( pTblName ){
  2686   2690         sqlite3RefillIndex(pParse, pIndex, iMem);

Changes to src/delete.c.

     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains C code routines that are called by the parser
    13     13   ** in order to generate code for DELETE FROM statements.
    14     14   **
    15         -** $Id: delete.c,v 1.156 2008/01/10 23:50:11 drh Exp $
           15  +** $Id: delete.c,v 1.157 2008/01/12 12:48:08 drh Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   
    19     19   /*
    20     20   ** Look up every table that is named in pSrc.  If any table is not found,
    21     21   ** add an error message to pParse->zErrMsg and return NULL.  If all tables
    22     22   ** are found, return a pointer to the last table.
................................................................................
    56     56       sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);
    57     57       return 1;
    58     58     }
    59     59   #endif
    60     60     return 0;
    61     61   }
    62     62   
    63         -/*
    64         -** This function is a temporary measure required because OP_Insert now
    65         -** reads the key and data to insert from memory cells.
    66         -*/
    67         -void sqlite3CodeInsert(Parse *p, int iCur, u8 flags){
    68         -  int iData = ++p->nMem;
    69         -  int iKey = ++p->nMem;
    70         -  Vdbe *v = sqlite3GetVdbe(p);
    71         -  sqlite3VdbeAddOp2(v, OP_Move, 0, iData);
    72         -  sqlite3VdbeAddOp2(v, OP_Move, 0, iKey);
    73         -  sqlite3VdbeAddOp3(v, OP_Insert, iCur, iData, iKey);
    74         -  sqlite3VdbeChangeP5(v, flags);
    75         -}
    76         -
    77     63   /*
    78     64   ** Allocate nVal contiguous memory cells and return the index of the
    79     65   ** first. Also pop nVal elements from the stack and store them in the 
    80     66   ** registers. The element on the top of the stack is stored in the
    81     67   ** register with the largest index.
    82     68   */
    83     69   int sqlite3StackToReg(Parse *p, int nVal){
................................................................................
    87     73     assert(v);
    88     74     p->nMem += nVal;
    89     75     for(i=nVal-1; i>=0; i--){
    90     76       sqlite3VdbeAddOp2(v, OP_Move, 0, iRet+i);
    91     77     }
    92     78     return iRet;
    93     79   }
    94         -void sqlite3RegToStack(Parse *p, int iReg, int nVal){
    95         -  int i;
    96         -  Vdbe *v = sqlite3GetVdbe(p);
    97         -  assert(v);
    98         -  for(i=0; i<nVal; i++){
    99         -    sqlite3VdbeAddOp2(v, OP_SCopy, iReg+i, 0);
   100         -  }
   101         -}
   102     80   
   103     81   /*
   104     82   ** Generate code that will open a table for reading.
   105     83   */
   106     84   void sqlite3OpenTable(
   107     85     Parse *p,       /* Generate code into this VDBE */
   108     86     int iCur,       /* The cursor number of the table */

Changes to src/expr.c.

     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains routines used for analyzing expressions and
    13     13   ** for generating VDBE code that evaluates expressions in SQLite.
    14     14   **
    15         -** $Id: expr.c,v 1.342 2008/01/10 23:50:11 drh Exp $
           15  +** $Id: expr.c,v 1.343 2008/01/12 12:48:08 drh Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   #include <ctype.h>
    19     19   
    20     20   /*
    21     21   ** Return the 'affinity' of the expression pExpr if any.
    22     22   **
................................................................................
   285    285     const Token *pToken     /* Argument token */
   286    286   ){
   287    287     return sqlite3Expr(pParse->db, op, pLeft, pRight, pToken);
   288    288   }
   289    289   
   290    290   /*
   291    291   ** When doing a nested parse, you can include terms in an expression
   292         -** that look like this:   #0 #1 #2 ...  These terms refer to elements
   293         -** on the stack.  "#0" means the top of the stack.
   294         -** "#1" means the next down on the stack.  And so forth.
          292  +** that look like this:   #1 #2 ...  These terms refer to registers
          293  +** in the virtual machine.  #N is the N-th register.
   295    294   **
   296    295   ** This routine is called by the parser to deal with on of those terms.
   297    296   ** It immediately generates code to store the value in a memory location.
   298    297   ** The returns an expression that will code to extract the value from
   299    298   ** that memory location as needed.
   300    299   */
   301    300   Expr *sqlite3RegisterExpr(Parse *pParse, Token *pToken){
   302    301     Vdbe *v = pParse->pVdbe;
   303    302     Expr *p;
   304         -  int depth;
   305    303     if( pParse->nested==0 ){
   306    304       sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", pToken);
   307    305       return sqlite3PExpr(pParse, TK_NULL, 0, 0, 0);
   308    306     }
   309    307     if( v==0 ) return 0;
   310    308     p = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, pToken);
   311    309     if( p==0 ){
   312    310       return 0;  /* Malloc failed */
   313    311     }
   314         -  depth = atoi((char*)&pToken->z[1]);
   315         -  p->iTable = ++pParse->nMem;
   316         -  sqlite3VdbeAddOp2(v, OP_Copy, -depth, p->iTable);
          312  +  p->iTable = atoi((char*)&pToken->z[1]);
   317    313     return p;
   318    314   }
   319    315   
   320    316   /*
   321    317   ** Join two expressions using an AND operator.  If either expression is
   322    318   ** NULL, then just return the other expression.
   323    319   */

Changes to src/insert.c.

     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains C code routines that are called by the parser
    13     13   ** to handle INSERT statements in SQLite.
    14     14   **
    15         -** $Id: insert.c,v 1.222 2008/01/10 23:50:11 drh Exp $
           15  +** $Id: insert.c,v 1.223 2008/01/12 12:48:08 drh Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   
    19     19   /*
    20     20   ** Set P4 of the most recently inserted opcode to a column affinity
    21     21   ** string for index pIdx. A column affinity string has one character
    22     22   ** for each column in the table, according to the affinity of the column:
................................................................................
   515    515         useTempTable = 1;
   516    516       }
   517    517   
   518    518       if( useTempTable ){
   519    519         /* Generate the subroutine that SELECT calls to process each row of
   520    520         ** the result.  Store the result in a temporary table
   521    521         */
          522  +      int regRec, regRowid;
          523  +
   522    524         srcTab = pParse->nTab++;
          525  +      regRec = sqlite3GetTempReg(pParse);
          526  +      regRowid = sqlite3GetTempReg(pParse);
   523    527         sqlite3VdbeResolveLabel(v, iInsertBlock);
   524         -      sqlite3VdbeAddOp2(v, OP_RegMakeRec, regFromSelect, nColumn);
   525         -      sqlite3VdbeAddOp1(v, OP_NewRowid, srcTab);
   526         -      sqlite3VdbeAddOp2(v, OP_Pull, 1, 0);
   527         -      sqlite3CodeInsert(pParse, srcTab, OPFLAG_APPEND);
          528  +      sqlite3VdbeAddOp3(v, OP_RegMakeRec, regFromSelect, nColumn, regRec);
          529  +      sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regRowid);
          530  +      sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regRowid);
   528    531         sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
          532  +      sqlite3ReleaseTempReg(pParse, regRec);
          533  +      sqlite3ReleaseTempReg(pParse, regRowid);
   529    534   
   530    535         /* The following code runs first because the GOTO at the very top
   531    536         ** of the program jumps to it.  Create the temporary table, then jump
   532    537         ** back up and execute the SELECT code above.
   533    538         */
   534    539         sqlite3VdbeJumpHere(v, iInitCode);
   535    540         sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, 0);
................................................................................
   659    664     if( useTempTable ){
   660    665       iBreak = sqlite3VdbeMakeLabel(v);
   661    666       sqlite3VdbeAddOp2(v, OP_Rewind, srcTab, iBreak);
   662    667       iCont = sqlite3VdbeCurrentAddr(v);
   663    668     }else if( pSelect ){
   664    669       sqlite3VdbeAddOp2(v, OP_Goto, 0, iSelectLoop);
   665    670       sqlite3VdbeResolveLabel(v, iInsertBlock);
   666         -    sqlite3RegToStack(pParse, regFromSelect, nColumn);
   667    671       sqlite3VdbeAddOp2(v, OP_StackDepth, -1, 0);
   668    672     }
   669    673   
   670    674     /* Allocate registers for holding the rowid of the new row,
   671    675     ** the content of the new row, and the assemblied row record.
   672    676     */
   673    677     regRecord = ++pParse->nMem;
................................................................................
   766    770         /* The row that the VUpdate opcode will delete: none */
   767    771         sqlite3VdbeAddOp2(v, OP_Null, 0, regIns);
   768    772       }
   769    773       if( keyColumn>=0 ){
   770    774         if( useTempTable ){
   771    775           sqlite3VdbeAddOp3(v, OP_Column, srcTab, keyColumn, regRowid);
   772    776         }else if( pSelect ){
   773         -        sqlite3VdbeAddOp2(v, OP_SCopy, -(nColumn - keyColumn - 1), regRowid);
          777  +        sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+keyColumn, regRowid);
   774    778         }else{
   775    779           VdbeOp *pOp;
   776    780           sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, 0);
   777    781           pOp = sqlite3VdbeGetOp(v, sqlite3VdbeCurrentAddr(v) - 1);
   778    782           if( pOp && pOp->opcode==OP_Null ){
   779    783             appendFlag = 1;
   780    784             pOp->opcode = OP_NewRowid;
................................................................................
   831    835           }
   832    836         }
   833    837         if( j<0 || nColumn==0 || (pColumn && j>=pColumn->nId) ){
   834    838           sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, iRegStore);
   835    839         }else if( useTempTable ){
   836    840           sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, iRegStore); 
   837    841         }else if( pSelect ){
   838         -        sqlite3VdbeAddOp2(v, OP_SCopy, -(nColumn-j-1), iRegStore);
          842  +        sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+j, iRegStore);
   839    843         }else{
   840    844           sqlite3ExprCode(pParse, pList->a[j].pExpr, iRegStore);
   841    845         }
   842    846       }
   843    847   
   844    848       /* Generate code to check constraints and generate index keys and
   845    849       ** do the insertion.
................................................................................
   895    899     */
   896    900     sqlite3VdbeResolveLabel(v, endOfLoop);
   897    901     if( useTempTable ){
   898    902       sqlite3VdbeAddOp2(v, OP_Next, srcTab, iCont);
   899    903       sqlite3VdbeResolveLabel(v, iBreak);
   900    904       sqlite3VdbeAddOp2(v, OP_Close, srcTab, 0);
   901    905     }else if( pSelect ){
   902         -    sqlite3VdbeAddOp2(v, OP_Pop, nColumn, 0);
   903    906       sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
   904    907       sqlite3VdbeResolveLabel(v, iCleanup);
   905    908     }
   906    909   
   907    910     if( !IsVirtual(pTab) && !isView ){
   908    911       /* Close all tables opened */
   909    912       sqlite3VdbeAddOp2(v, OP_Close, baseCur, 0);
................................................................................
  1275   1278   ){
  1276   1279     int i;
  1277   1280     Vdbe *v;
  1278   1281     int nIdx;
  1279   1282     Index *pIdx;
  1280   1283     int pik_flags;
  1281   1284     int regData;
         1285  +  int regRec;
  1282   1286   
  1283   1287     v = sqlite3GetVdbe(pParse);
  1284   1288     assert( v!=0 );
  1285   1289     assert( pTab->pSelect==0 );  /* This table is not a VIEW */
  1286   1290     for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
  1287   1291     for(i=nIdx-1; i>=0; i--){
  1288   1292       if( aRegIdx[i]==0 ) continue;
  1289   1293       sqlite3VdbeAddOp2(v, OP_IdxInsert, baseCur+i+1, aRegIdx[i]);
  1290   1294     }
  1291   1295     regData = regRowid + 1;
  1292         -  sqlite3VdbeAddOp1(v, OP_SCopy, regRowid);
  1293         -  sqlite3VdbeAddOp2(v, OP_RegMakeRec, regData, pTab->nCol);
         1296  +  regRec = sqlite3GetTempReg(pParse);
         1297  +  sqlite3VdbeAddOp3(v, OP_RegMakeRec, regData, pTab->nCol, regRec);
  1294   1298     sqlite3TableAffinityStr(v, pTab);
  1295   1299   #ifndef SQLITE_OMIT_TRIGGER
  1296   1300     if( newIdx>=0 ){
  1297         -    sqlite3VdbeAddOp1(v, OP_SCopy, regRowid);
  1298         -    sqlite3VdbeAddOp1(v, OP_SCopy, -1);
  1299         -    sqlite3CodeInsert(pParse, newIdx, 0);
         1301  +    sqlite3VdbeAddOp3(v, OP_Insert, newIdx, regRec, regRowid);
  1300   1302     }
  1301   1303   #endif
  1302   1304     if( pParse->nested ){
  1303   1305       pik_flags = 0;
  1304   1306     }else{
  1305   1307       pik_flags = OPFLAG_NCHANGE;
  1306   1308       pik_flags |= (isUpdate?OPFLAG_ISUPDATE:OPFLAG_LASTROWID);
  1307   1309     }
  1308   1310     if( appendBias ){
  1309   1311       pik_flags |= OPFLAG_APPEND;
  1310   1312     }
  1311         -  sqlite3CodeInsert(pParse, baseCur, pik_flags);
         1313  +  sqlite3VdbeAddOp3(v, OP_Insert, baseCur, regRec, regRowid);
  1312   1314     if( !pParse->nested ){
  1313   1315       sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC);
  1314   1316     }
         1317  +  sqlite3VdbeChangeP5(v, pik_flags);
  1315   1318   }
  1316   1319   
  1317   1320   /*
  1318   1321   ** Generate code that will open cursors for a table and for all
  1319   1322   ** indices of that table.  The "baseCur" parameter is the cursor number used
  1320   1323   ** for the table.  Indices are opened on subsequent cursors.
  1321   1324   **
................................................................................
  1461   1464     int addr1, addr2;                /* Loop addresses */
  1462   1465     int emptyDestTest;               /* Address of test for empty pDest */
  1463   1466     int emptySrcTest;                /* Address of test for empty pSrc */
  1464   1467     Vdbe *v;                         /* The VDBE we are building */
  1465   1468     KeyInfo *pKey;                   /* Key information for an index */
  1466   1469     int regAutoinc;                  /* Memory register used by AUTOINC */
  1467   1470     int destHasUniqueIdx = 0;        /* True if pDest has a UNIQUE index */
         1471  +  int regData, regRowid;           /* Registers holding data and rowid */
  1468   1472   
  1469   1473     if( pSelect==0 ){
  1470   1474       return 0;   /* Must be of the form  INSERT INTO ... SELECT ... */
  1471   1475     }
  1472   1476     if( pDest->pTrigger ){
  1473   1477       return 0;   /* tab1 must not have triggers */
  1474   1478     }
................................................................................
  1608   1612       emptyDestTest = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
  1609   1613       sqlite3VdbeJumpHere(v, addr1);
  1610   1614     }else{
  1611   1615       emptyDestTest = 0;
  1612   1616     }
  1613   1617     sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead);
  1614   1618     emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
         1619  +  regData = sqlite3GetTempReg(pParse);
         1620  +  regRowid = sqlite3GetTempReg(pParse);
  1615   1621     if( pDest->iPKey>=0 ){
  1616         -    addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, 0);
  1617         -    sqlite3VdbeAddOp0(v, OP_Copy);
  1618         -    addr2 = sqlite3VdbeAddOp2(v, OP_NotExists, iDest, 0);
         1622  +    addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
         1623  +    addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid);
  1619   1624       sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0,
  1620   1625                         "PRIMARY KEY must be unique", P4_STATIC);
  1621   1626       sqlite3VdbeJumpHere(v, addr2);
  1622         -    autoIncStep(pParse, regAutoinc, 0);
         1627  +    autoIncStep(pParse, regAutoinc, regRowid);
  1623   1628     }else if( pDest->pIndex==0 ){
  1624         -    addr1 = sqlite3VdbeAddOp1(v, OP_NewRowid, iDest);
         1629  +    addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, regRowid);
  1625   1630     }else{
  1626         -    addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, 0);
         1631  +    addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
  1627   1632       assert( pDest->autoInc==0 );
  1628   1633     }
  1629         -  sqlite3VdbeAddOp1(v, OP_RowData, iSrc);
  1630         -  sqlite3CodeInsert(pParse,iDest,OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND);
         1634  +  sqlite3VdbeAddOp2(v, OP_RowData, iSrc, regData);
         1635  +  sqlite3VdbeAddOp3(v, OP_Insert, iDest, regData, regRowid);
         1636  +  sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND);
  1631   1637     sqlite3VdbeChangeP4(v, -1, pDest->zName, 0);
  1632   1638     sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1);
  1633   1639     autoIncEnd(pParse, iDbDest, pDest, regAutoinc);
  1634   1640     for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
  1635   1641       for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){
  1636   1642         if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
  1637   1643       }
................................................................................
  1643   1649                         (char*)pKey, P4_KEYINFO_HANDOFF);
  1644   1650       VdbeComment((v, "%s", pSrcIdx->zName));
  1645   1651       pKey = sqlite3IndexKeyinfo(pParse, pDestIdx);
  1646   1652       sqlite3VdbeAddOp4(v, OP_OpenWrite, iDest, pDestIdx->tnum, iDbDest,
  1647   1653                         (char*)pKey, P4_KEYINFO_HANDOFF);
  1648   1654       VdbeComment((v, "%s", pDestIdx->zName));
  1649   1655       addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
  1650         -    sqlite3VdbeAddOp1(v, OP_RowKey, iSrc);
  1651         -    sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, 0, 1);
         1656  +    sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, regData);
         1657  +    sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1);
  1652   1658       sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1);
  1653   1659       sqlite3VdbeJumpHere(v, addr1);
  1654   1660     }
  1655   1661     sqlite3VdbeJumpHere(v, emptySrcTest);
         1662  +  sqlite3ReleaseTempReg(pParse, regRowid);
         1663  +  sqlite3ReleaseTempReg(pParse, regData);
  1656   1664     sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
  1657   1665     sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
  1658   1666     if( emptyDestTest ){
  1659   1667       sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, 0);
  1660   1668       sqlite3VdbeJumpHere(v, emptyDestTest);
  1661   1669       sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
  1662   1670       return 0;
  1663   1671     }else{
  1664   1672       return 1;
  1665   1673     }
  1666   1674   }
  1667   1675   #endif /* SQLITE_OMIT_XFER_OPT */

Changes to src/select.c.

     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains C code routines that are called by the parser
    13     13   ** to handle SELECT statements in SQLite.
    14     14   **
    15         -** $Id: select.c,v 1.397 2008/01/10 23:50:11 drh Exp $
           15  +** $Id: select.c,v 1.398 2008/01/12 12:48:08 drh Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   
    19     19   
    20     20   /*
    21     21   ** Delete all the content of a Select structure but do not deallocate
    22     22   ** the select structure itself.
................................................................................
   390    390   /*
   391    391   ** Insert code into "v" that will push the record on the top of the
   392    392   ** stack into the sorter.
   393    393   */
   394    394   static void pushOntoSorter(
   395    395     Parse *pParse,         /* Parser context */
   396    396     ExprList *pOrderBy,    /* The ORDER BY clause */
   397         -  Select *pSelect        /* The whole SELECT statement */
          397  +  Select *pSelect,       /* The whole SELECT statement */
          398  +  int regData            /* Register holding data to be sorted */
   398    399   ){
   399    400     Vdbe *v = pParse->pVdbe;
   400    401     int nExpr = pOrderBy->nExpr;
   401    402     int regBase = sqlite3GetTempRange(pParse, nExpr+2);
   402    403     int regRecord = sqlite3GetTempReg(pParse);
   403    404     sqlite3ExprCodeExprList(pParse, pOrderBy, regBase);
   404    405     sqlite3VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, regBase+nExpr);
   405         -  sqlite3VdbeAddOp2(v, OP_Move, 0, regBase+nExpr+1);
          406  +  sqlite3VdbeAddOp2(v, OP_Move, regData, regBase+nExpr+1);
   406    407     sqlite3VdbeAddOp3(v, OP_RegMakeRec, regBase, nExpr + 2, regRecord);
   407    408     sqlite3VdbeAddOp2(v, OP_IdxInsert, pOrderBy->iECursor, regRecord);
   408    409     sqlite3ReleaseTempReg(pParse, regRecord);
   409    410     sqlite3ReleaseTempRange(pParse, regBase, nExpr+2);
   410    411     if( pSelect->iLimit>=0 ){
   411    412       int addr1, addr2;
   412         -    addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, pSelect->iLimit+1);
   413         -    sqlite3VdbeAddOp2(v, OP_AddImm, pSelect->iLimit+1, -1);
          413  +    int iLimit;
          414  +    if( pSelect->pOffset ){
          415  +      iLimit = pSelect->iOffset+1;
          416  +    }else{
          417  +      iLimit = pSelect->iLimit;
          418  +    }
          419  +    addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, iLimit);
          420  +    sqlite3VdbeAddOp2(v, OP_AddImm, iLimit, -1);
   414    421       addr2 = sqlite3VdbeAddOp0(v, OP_Goto);
   415    422       sqlite3VdbeJumpHere(v, addr1);
   416    423       sqlite3VdbeAddOp1(v, OP_Last, pOrderBy->iECursor);
   417    424       sqlite3VdbeAddOp1(v, OP_Delete, pOrderBy->iECursor);
   418    425       sqlite3VdbeJumpHere(v, addr2);
   419    426       pSelect->iLimit = -1;
   420    427     }
................................................................................
   422    429   
   423    430   /*
   424    431   ** Add code to implement the OFFSET
   425    432   */
   426    433   static void codeOffset(
   427    434     Vdbe *v,          /* Generate code into this VM */
   428    435     Select *p,        /* The SELECT statement being coded */
   429         -  int iContinue,    /* Jump here to skip the current record */
   430         -  int nPop          /* Number of times to pop stack when jumping */
          436  +  int iContinue     /* Jump here to skip the current record */
   431    437   ){
   432    438     if( p->iOffset>=0 && iContinue!=0 ){
   433    439       int addr;
   434    440       sqlite3VdbeAddOp2(v, OP_AddImm, p->iOffset, -1);
   435    441       addr = sqlite3VdbeAddOp1(v, OP_IfNeg, p->iOffset);
   436         -    if( nPop>0 ){
   437         -      sqlite3VdbeAddOp1(v, OP_Pop, nPop);
   438         -    }
   439    442       sqlite3VdbeAddOp2(v, OP_Goto, 0, iContinue);
   440    443       VdbeComment((v, "skip OFFSET records"));
   441    444       sqlite3VdbeJumpHere(v, addr);
   442    445     }
   443    446   }
   444    447   
   445    448   /*
................................................................................
   520    523     assert( pEList!=0 );
   521    524   
   522    525     /* If there was a LIMIT clause on the SELECT statement, then do the check
   523    526     ** to see if this row should be output.
   524    527     */
   525    528     hasDistinct = distinct>=0 && pEList->nExpr>0;
   526    529     if( pOrderBy==0 && !hasDistinct ){
   527         -    codeOffset(v, p, iContinue, 0);
          530  +    codeOffset(v, p, iContinue);
   528    531     }
   529    532   
   530    533     /* Pull the requested columns.
   531    534     */
   532    535     if( nColumn>0 ){
   533    536       n = nColumn;
   534    537     }else{
................................................................................
   559    562     ** part of the result.
   560    563     */
   561    564     if( hasDistinct ){
   562    565       assert( pEList!=0 );
   563    566       assert( pEList->nExpr==nColumn );
   564    567       codeDistinct(v, distinct, iContinue, nColumn, iMem);
   565    568       if( pOrderBy==0 ){
   566         -      codeOffset(v, p, iContinue, nColumn);
          569  +      codeOffset(v, p, iContinue);
   567    570       }
   568    571     }
   569    572   
   570    573     if( checkForMultiColumnSelectError(pParse, pDest, pEList->nExpr) ){
   571    574       return 0;
   572    575     }
   573    576   
................................................................................
   599    602       }
   600    603   #endif
   601    604   
   602    605       /* Store the result as data using a unique key.
   603    606       */
   604    607       case SRT_Table:
   605    608       case SRT_EphemTab: {
   606         -      sqlite3VdbeAddOp2(v, OP_RegMakeRec, iMem, nColumn);
          609  +      int r1 = sqlite3GetTempReg(pParse);
          610  +      sqlite3VdbeAddOp3(v, OP_RegMakeRec, iMem, nColumn, r1);
   607    611         if( pOrderBy ){
   608         -        pushOntoSorter(pParse, pOrderBy, p);
          612  +        pushOntoSorter(pParse, pOrderBy, p, r1);
   609    613         }else{
   610         -        sqlite3VdbeAddOp1(v, OP_NewRowid, iParm);
   611         -        sqlite3VdbeAddOp2(v, OP_Pull, 1, 0);
   612         -        sqlite3CodeInsert(pParse, iParm, OPFLAG_APPEND);
          614  +        int r2 = sqlite3GetTempReg(pParse);
          615  +        sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2);
          616  +        sqlite3VdbeAddOp3(v, OP_Insert, iParm, r1, r2);
          617  +        sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
          618  +        sqlite3ReleaseTempReg(pParse, r2);
   613    619         }
          620  +      sqlite3ReleaseTempReg(pParse, r1);
   614    621         break;
   615    622       }
   616    623   
   617    624   #ifndef SQLITE_OMIT_SUBQUERY
   618    625       /* If we are creating a set for an "expr IN (SELECT ...)" construct,
   619    626       ** then there should be a single item on the stack.  Write this
   620    627       ** item into the set table with bogus data.
................................................................................
   626    633         addr2 = sqlite3VdbeAddOp2(v, OP_IsNull, iMem, 0);
   627    634         p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affinity);
   628    635         if( pOrderBy ){
   629    636           /* At first glance you would think we could optimize out the
   630    637           ** ORDER BY in this case since the order of entries in the set
   631    638           ** does not matter.  But there might be a LIMIT clause, in which
   632    639           ** case the order does matter */
   633         -        sqlite3VdbeAddOp2(v, OP_SCopy, iMem, 0);
   634         -        pushOntoSorter(pParse, pOrderBy, p);
          640  +        pushOntoSorter(pParse, pOrderBy, p, iMem);
   635    641         }else{
   636         -        sqlite3VdbeAddOp4(v, OP_RegMakeRec, iMem, 1, 0, &p->affinity, 1);
   637         -        sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, 0);
          642  +        int r1 = sqlite3GetTempReg(pParse);
          643  +        sqlite3VdbeAddOp4(v, OP_RegMakeRec, iMem, 1, r1, &p->affinity, 1);
          644  +        sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1);
          645  +        sqlite3ReleaseTempReg(pParse, r1);
   638    646         }
   639    647         sqlite3VdbeJumpHere(v, addr2);
   640    648         break;
   641    649       }
   642    650   
   643    651       /* If any row exist in the result set, record that fact and abort.
   644    652       */
................................................................................
   650    658   
   651    659       /* If this is a scalar select that is part of an expression, then
   652    660       ** store the results in the appropriate memory cell and break out
   653    661       ** of the scan loop.
   654    662       */
   655    663       case SRT_Mem: {
   656    664         assert( nColumn==1 );
   657         -      sqlite3VdbeAddOp2(v, OP_SCopy, iMem, 0);
   658    665         if( pOrderBy ){
   659         -        pushOntoSorter(pParse, pOrderBy, p);
          666  +        pushOntoSorter(pParse, pOrderBy, p, iMem);
   660    667         }else{
   661         -        sqlite3VdbeAddOp2(v, OP_Move, 0, iParm);
          668  +        sqlite3VdbeAddOp2(v, OP_Move, iMem, iParm);
   662    669           /* The LIMIT clause will jump out of the loop for us */
   663    670         }
   664    671         break;
   665    672       }
   666    673   #endif /* #ifndef SQLITE_OMIT_SUBQUERY */
   667    674   
   668    675       /* Send the data to the callback function or to a subroutine.  In the
   669    676       ** case of a subroutine, the subroutine itself is responsible for
   670    677       ** popping the data from the stack.
   671    678       */
   672    679       case SRT_Subroutine:
   673    680       case SRT_Callback: {
   674    681         if( pOrderBy ){
   675         -        sqlite3VdbeAddOp2(v, OP_RegMakeRec, iMem, nColumn);
   676         -        pushOntoSorter(pParse, pOrderBy, p);
          682  +        int r1 = sqlite3GetTempReg(pParse);
          683  +        sqlite3VdbeAddOp3(v, OP_RegMakeRec, iMem, nColumn, r1);
          684  +        pushOntoSorter(pParse, pOrderBy, p, r1);
          685  +        sqlite3ReleaseTempReg(pParse, r1);
   677    686         }else if( eDest==SRT_Subroutine ){
   678    687           sqlite3VdbeAddOp2(v, OP_Gosub, 0, iParm);
   679    688         }else{
   680    689           sqlite3VdbeAddOp2(v, OP_ResultRow, iMem, nColumn);
   681    690         }
   682    691         break;
   683    692       }
................................................................................
   775    784     iTab = pOrderBy->iECursor;
   776    785     if( eDest==SRT_Callback || eDest==SRT_Subroutine ){
   777    786       pseudoTab = pParse->nTab++;
   778    787       sqlite3VdbeAddOp2(v, OP_OpenPseudo, pseudoTab, 0);
   779    788       sqlite3VdbeAddOp2(v, OP_SetNumColumns, pseudoTab, nColumn);
   780    789     }
   781    790     addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, brk);
   782         -  codeOffset(v, p, cont, 0);
          791  +  codeOffset(v, p, cont);
   783    792     regRow = sqlite3GetTempReg(pParse);
   784    793     regRowid = sqlite3GetTempReg(pParse);
   785    794     sqlite3VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr + 1, regRow);
   786    795     switch( eDest ){
   787    796       case SRT_Table:
   788    797       case SRT_EphemTab: {
   789    798         sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);
................................................................................
  1733   1742   ** the reuse of the same limit and offset registers across multiple
  1734   1743   ** SELECT statements.
  1735   1744   */
  1736   1745   static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
  1737   1746     Vdbe *v = 0;
  1738   1747     int iLimit = 0;
  1739   1748     int iOffset;
  1740         -  int addr1, addr2;
         1749  +  int addr1;
  1741   1750   
  1742   1751     /* 
  1743   1752     ** "LIMIT -1" always shows all rows.  There is some
  1744   1753     ** contraversy about what the correct behavior should be.
  1745   1754     ** The current implementation interprets "LIMIT 0" to mean
  1746   1755     ** no rows.
  1747   1756     */
  1748   1757     if( p->pLimit ){
  1749   1758       p->iLimit = iLimit = ++pParse->nMem;
  1750         -    pParse->nMem++;
  1751   1759       v = sqlite3GetVdbe(pParse);
  1752   1760       if( v==0 ) return;
  1753         -    sqlite3ExprCode(pParse, p->pLimit, 0);
  1754         -    sqlite3VdbeAddOp0(v, OP_MustBeInt);
  1755         -    sqlite3VdbeAddOp2(v, OP_Move, 0, iLimit);
         1761  +    sqlite3ExprCode(pParse, p->pLimit, iLimit);
         1762  +    sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit);
  1756   1763       VdbeComment((v, "LIMIT counter"));
  1757   1764       sqlite3VdbeAddOp2(v, OP_IfZero, iLimit, iBreak);
  1758         -    sqlite3VdbeAddOp2(v, OP_SCopy, iLimit, 0);
  1759   1765     }
  1760   1766     if( p->pOffset ){
  1761   1767       p->iOffset = iOffset = ++pParse->nMem;
         1768  +    if( p->pLimit ){
         1769  +      pParse->nMem++;   /* Allocate an extra register for limit+offset */
         1770  +    }
  1762   1771       v = sqlite3GetVdbe(pParse);
  1763   1772       if( v==0 ) return;
  1764         -    sqlite3ExprCode(pParse, p->pOffset, 0);
  1765         -    sqlite3VdbeAddOp0(v, OP_MustBeInt);
  1766         -    sqlite3VdbeAddOp2(v, p->pLimit==0 ? OP_Move : OP_Copy, 0, iOffset);
         1773  +    sqlite3ExprCode(pParse, p->pOffset, iOffset);
         1774  +    sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset);
  1767   1775       VdbeComment((v, "OFFSET counter"));
  1768   1776       addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iOffset);
  1769         -    sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
  1770         -    sqlite3VdbeAddOp2(v, OP_Integer, 0, 0);
         1777  +    sqlite3VdbeAddOp2(v, OP_Integer, 0, iOffset);
  1771   1778       sqlite3VdbeJumpHere(v, addr1);
  1772   1779       if( p->pLimit ){
  1773         -      sqlite3VdbeAddOp2(v, OP_Add, 0, 0);
         1780  +      sqlite3VdbeAddOp3(v, OP_Add, iLimit, iOffset, iOffset+1);
         1781  +      VdbeComment((v, "LIMIT+OFFSET"));
         1782  +      addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iLimit);
         1783  +      sqlite3VdbeAddOp2(v, OP_Integer, -1, iOffset+1);
         1784  +      sqlite3VdbeJumpHere(v, addr1);
  1774   1785       }
  1775   1786     }
  1776         -  if( p->pLimit ){
  1777         -    addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iLimit);
  1778         -    sqlite3VdbeAddOp1(v, OP_Pop, 1);
  1779         -    sqlite3VdbeAddOp2(v, OP_Integer, -1, iLimit+1);
  1780         -    addr2 = sqlite3VdbeAddOp0(v, OP_Goto);
  1781         -    sqlite3VdbeJumpHere(v, addr1);
  1782         -    sqlite3VdbeAddOp2(v, OP_Move, 0, iLimit+1);
  1783         -    VdbeComment((v, "LIMIT+OFFSET"));
  1784         -    sqlite3VdbeJumpHere(v, addr2);
  1785         -  }
  1786   1787   }
  1787   1788   
  1788   1789   /*
  1789   1790   ** Allocate a virtual index to use for sorting.
  1790   1791   */
  1791   1792   static void createSortingIndex(Parse *pParse, Select *p, ExprList *pOrderBy){
  1792   1793     if( pOrderBy ){

Changes to src/sqliteInt.h.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Internal interface definitions for SQLite.
    13     13   **
    14         -** @(#) $Id: sqliteInt.h,v 1.647 2008/01/10 23:50:11 drh Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.648 2008/01/12 12:48:08 drh Exp $
    15     15   */
    16     16   #ifndef _SQLITEINT_H_
    17     17   #define _SQLITEINT_H_
    18     18   
    19     19   /*
    20     20   ** The macro unlikely() is a hint that surrounds a boolean
    21     21   ** expression that is usually false.  Macro likely() surrounds
................................................................................
  1416   1416     int nTableLock;        /* Number of locks in aTableLock */
  1417   1417     TableLock *aTableLock; /* Required table locks for shared-cache mode */
  1418   1418   #endif
  1419   1419   
  1420   1420     /* Above is constant between recursions.  Below is reset before and after
  1421   1421     ** each recursion */
  1422   1422   
         1423  +  int regRowid;        /* Register holding rowid of CREATE TABLE entry */
         1424  +  int regRoot;         /* Register holding root page number for new objects */
  1423   1425     int nVar;            /* Number of '?' variables seen in the SQL so far */
  1424   1426     int nVarExpr;        /* Number of used slots in apVarExpr[] */
  1425   1427     int nVarExprAlloc;   /* Number of allocated slots in apVarExpr[] */
  1426   1428     Expr **apVarExpr;    /* Pointers to :aaa and $aaaa wildcard expressions */
  1427   1429     u8 explain;          /* True if the EXPLAIN flag is found on the query */
  1428   1430     Token sErrToken;     /* The token at which the error occurred */
  1429   1431     Token sNameToken;    /* Token with unqualified schema object name */
................................................................................
  1941   1943     void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*));
  1942   1944   int sqlite3ApiExit(sqlite3 *db, int);
  1943   1945   int sqlite3OpenTempDatabase(Parse *);
  1944   1946   
  1945   1947   void sqlite3StrAccumAppend(StrAccum*,const char*,int);
  1946   1948   char *sqlite3StrAccumFinish(StrAccum*);
  1947   1949   void sqlite3StrAccumReset(StrAccum*);
  1948         -void sqlite3CodeInsert(Parse *, int, u8);
  1949   1950   int sqlite3StackToReg(Parse *, int);
  1950         -void sqlite3RegToStack(Parse *, int, int);
  1951   1951   void sqlite3SelectDestInit(SelectDest*,int,int);
  1952   1952   
  1953   1953   /*
  1954   1954   ** The interface to the LEMON-generated parser
  1955   1955   */
  1956   1956   void *sqlite3ParserAlloc(void*(*)(size_t));
  1957   1957   void sqlite3ParserFree(void*, void(*)(void*));

Changes to src/vdbe.c.

    39     39   **
    40     40   ** Various scripts scan this source file in order to generate HTML
    41     41   ** documentation, headers files, or other derived files.  The formatting
    42     42   ** of the code in this file is, therefore, important.  See other comments
    43     43   ** in this file for details.  If in doubt, do not deviate from existing
    44     44   ** commenting and indentation practices when changing or adding code.
    45     45   **
    46         -** $Id: vdbe.c,v 1.692 2008/01/10 23:50:11 drh Exp $
           46  +** $Id: vdbe.c,v 1.693 2008/01/12 12:48:08 drh Exp $
    47     47   */
    48     48   #include "sqliteInt.h"
    49     49   #include <ctype.h>
    50     50   #include "vdbeInt.h"
    51     51   
    52     52   /*
    53     53   ** The following global variable is incremented every time a cursor
................................................................................
    90     90   ** is working correctly.   This variable has no function other than to
    91     91   ** help verify the correct operation of the library.
    92     92   */
    93     93   #ifdef SQLITE_TEST
    94     94   int sqlite3_max_blobsize = 0;
    95     95   #endif
    96     96   
           97  +/*
           98  +** Test a register to see if it exceeds the current maximum blob size.
           99  +** If it does, record the new maximum blob size.
          100  +*/
          101  +#ifdef SQLITE_TEST
          102  +# define UPDATE_MAX_BLOBSIZE(P)  if( ((P)->flags&(MEM_Str|MEM_Blob))!=0 \
          103  +                                      && (P)->n>sqlite3_max_blobsize ) \
          104  +                                          {sqlite3_max_blobsize = (P)->n;}
          105  +#else
          106  +# define UPDATE_MAX_BLOBSIZE(P)
          107  +#endif
          108  +
    97    109   /*
    98    110   ** Release the memory associated with the given stack level.  This
    99    111   ** leaves the Mem.flags field in an inconsistent state.
   100    112   */
   101    113   #define Release(P) if((P)->flags&MEM_Dyn){ sqlite3VdbeMemRelease(P); }
   102    114   
   103    115   /*
................................................................................
   935    947       }
   936    948       pOp->p4type = P4_DYNAMIC;
   937    949       pOp->p4.z = pOut->z;
   938    950       pOp->p1 = pOut->n;
   939    951       if( pOp->p1>SQLITE_MAX_LENGTH ){
   940    952         goto too_big;
   941    953       }
          954  +    UPDATE_MAX_BLOBSIZE(pOut);
   942    955       break;
   943    956     }
   944    957   #endif
   945    958     if( pOp->p1>SQLITE_MAX_LENGTH ){
   946    959       goto too_big;
   947    960     }
   948    961     /* Fall through to the next case, OP_String */
................................................................................
   955    968   */
   956    969   case OP_String: {          /* out2-prerelease */
   957    970     assert( pOp->p4.z!=0 );
   958    971     pOut->flags = MEM_Str|MEM_Static|MEM_Term;
   959    972     pOut->z = pOp->p4.z;
   960    973     pOut->n = pOp->p1;
   961    974     pOut->enc = encoding;
          975  +  UPDATE_MAX_BLOBSIZE(pOut);
   962    976     break;
   963    977   }
   964    978   
   965    979   /* Opcode: Null * P2 * * *
   966    980   **
   967    981   ** Write a NULL into register P2 or push a NULL onto the stack 
   968    982   ** if P2==0.
................................................................................
  1015   1029   ** the blob as P4. This opcode is transformed to an OP_Blob
  1016   1030   ** the first time it is executed.
  1017   1031   */
  1018   1032   case OP_Blob: {                /* out2-prerelease */
  1019   1033     assert( pOp->p1 <= SQLITE_MAX_LENGTH );
  1020   1034     sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0);
  1021   1035     pOut->enc = encoding;
         1036  +  UPDATE_MAX_BLOBSIZE(pOut);
  1022   1037     break;
  1023   1038   }
  1024   1039   #endif /* SQLITE_OMIT_BLOB_LITERAL */
  1025   1040   
  1026   1041   /* Opcode: Variable P1 P2 * * *
  1027   1042   **
  1028   1043   ** The value of variable P1 is written into register P2 or pushed
................................................................................
  1039   1054     assert( j>=0 && j<p->nVar );
  1040   1055   
  1041   1056     pVar = &p->aVar[j];
  1042   1057     if( sqlite3VdbeMemTooBig(pVar) ){
  1043   1058       goto too_big;
  1044   1059     }
  1045   1060     sqlite3VdbeMemShallowCopy(pOut, &p->aVar[j], MEM_Static);
         1061  +  UPDATE_MAX_BLOBSIZE(pOut);
  1046   1062     break;
  1047   1063   }
  1048   1064   
  1049   1065   /* Opcode: Pop P1 * * * *
  1050   1066   **
  1051   1067   ** P1 elements are popped off of the top of stack and discarded.
  1052   1068   */
................................................................................
  1132   1148         Deephemeralize(pOut);
  1133   1149       }
  1134   1150     }
  1135   1151     REGISTER_TRACE(pOp->p2, pOut);
  1136   1152     break;
  1137   1153   }
  1138   1154   
  1139         -/* Opcode: Pull P1 * *
  1140         -**
  1141         -** The P1-th element is removed from its current location on 
  1142         -** the stack and pushed back on top of the stack.  The
  1143         -** top of the stack is element 0, so "Pull 0 0 0" is
  1144         -** a no-op.  "Pull 1 0 0" swaps the top two elements of
  1145         -** the stack.
  1146         -*/
  1147         -case OP_Pull: {            /* no-push */
  1148         -  Mem *pFrom = &pTos[-pOp->p1];
  1149         -  int i;
  1150         -  Mem ts;
  1151         -
  1152         -  ts = *pFrom;
  1153         -  Deephemeralize(pTos);
  1154         -  for(i=0; i<pOp->p1; i++, pFrom++){
  1155         -    Deephemeralize(&pFrom[1]);
  1156         -    assert( (pFrom[1].flags & MEM_Ephem)==0 );
  1157         -    *pFrom = pFrom[1];
  1158         -    if( pFrom->flags & MEM_Short ){
  1159         -      assert( pFrom->flags & (MEM_Str|MEM_Blob) );
  1160         -      assert( pFrom->z==pFrom[1].zShort );
  1161         -      pFrom->z = pFrom->zShort;
  1162         -    }
  1163         -  }
  1164         -  *pTos = ts;
  1165         -  if( pTos->flags & MEM_Short ){
  1166         -    assert( pTos->flags & (MEM_Str|MEM_Blob) );
  1167         -    assert( pTos->z==pTos[-pOp->p1].zShort );
  1168         -    pTos->z = pTos->zShort;
  1169         -  }
  1170         -  break;
  1171         -}
  1172         -
  1173   1155   /* Opcode: ResultRow P1 P2 *
  1174   1156   **
  1175   1157   ** The registers P1 throught P1+P2-1 contain a single row of
  1176   1158   ** results. This opcode causes the sqlite3_step() call to terminate
  1177   1159   ** with an SQLITE_ROW return code and it sets up the sqlite3_stmt
  1178   1160   ** structure to provide access to the top P1 values as the result
  1179   1161   ** row.  When the sqlite3_step() function is run again, the top P1
................................................................................
  1253   1235     zNew[nByte+1] = 0;
  1254   1236     Release(pOut);
  1255   1237     pOut->n = nByte;
  1256   1238     pOut->flags = MEM_Str|MEM_Dyn|MEM_Term;
  1257   1239     pOut->xDel = 0;
  1258   1240     pOut->enc = encoding;
  1259   1241     pOut->z = zNew;
         1242  +  UPDATE_MAX_BLOBSIZE(pOut);
  1260   1243     break;
  1261   1244   }
  1262   1245   
  1263   1246   /* Opcode: Add P1 P2 P3 * *
  1264   1247   **
  1265   1248   ** Add the value in P1 to the value in P2 and store the result in P3.
  1266   1249   ** If either operand is NULL, the result is NULL.
................................................................................
  1485   1468     }else{
  1486   1469       pOut = &p->aMem[pOp->p3];
  1487   1470     }
  1488   1471     sqlite3VdbeMemMove(pOut, &ctx.s);
  1489   1472     if( sqlite3VdbeMemTooBig(pOut) ){
  1490   1473       goto too_big;
  1491   1474     }
         1475  +  UPDATE_MAX_BLOBSIZE(pOut);
  1492   1476     break;
  1493   1477   }
  1494   1478   
  1495   1479   /* Opcode: BitAnd P1 P2 P3 * *
  1496   1480   **
  1497   1481   ** Take the bit-wise AND of the values in register P1 and P2 and
  1498   1482   ** store the result in register P3.
................................................................................
  1654   1638     if( pIn1->flags & MEM_Null ) break;
  1655   1639     assert( MEM_Str==(MEM_Blob>>3) );
  1656   1640     pIn1->flags |= (pIn1->flags&MEM_Blob)>>3;
  1657   1641     applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding);
  1658   1642     rc = ExpandBlob(pIn1);
  1659   1643     assert( pIn1->flags & MEM_Str );
  1660   1644     pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_Blob);
         1645  +  UPDATE_MAX_BLOBSIZE(pIn1);
  1661   1646     break;
  1662   1647   }
  1663   1648   
  1664   1649   /* Opcode: ToBlob P1 * * * *
  1665   1650   **
  1666   1651   ** Force the value in register P1 to be a BLOB.
  1667   1652   ** If the value is numeric, convert it to a string first.
................................................................................
  1675   1660     if( pIn1->flags & MEM_Null ) break;
  1676   1661     if( (pIn1->flags & MEM_Blob)==0 ){
  1677   1662       applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding);
  1678   1663       assert( pIn1->flags & MEM_Str );
  1679   1664       pIn1->flags |= MEM_Blob;
  1680   1665     }
  1681   1666     pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_Str);
         1667  +  UPDATE_MAX_BLOBSIZE(pIn1);
  1682   1668     break;
  1683   1669   }
  1684   1670   
  1685   1671   /* Opcode: ToNumeric P1 * * * *
  1686   1672   **
  1687   1673   ** Force the value in register P1 to be numeric (either an
  1688   1674   ** integer or a floating-point number.)
................................................................................
  2333   2319     }
  2334   2320   
  2335   2321     /* pDest->z might be pointing to sMem.zShort[].  Fix that so that we
  2336   2322     ** can abandon sMem */
  2337   2323     rc = sqlite3VdbeMemMakeWriteable(pDest);
  2338   2324   
  2339   2325   op_column_out:
         2326  +  UPDATE_MAX_BLOBSIZE(pDest);
  2340   2327     REGISTER_TRACE(pOp->p3, pDest);
  2341   2328     break;
  2342   2329   }
  2343   2330   
  2344   2331   /* Opcode: MakeRecord P1 P2 P4
  2345   2332   **
  2346   2333   ** Convert the top abs(P1) entries of the stack into a single entry
................................................................................
  2521   2508     }
  2522   2509     if( nZero ){
  2523   2510       pOut->u.i = nZero;
  2524   2511       pOut->flags |= MEM_Zero;
  2525   2512     }
  2526   2513     pOut->enc = SQLITE_UTF8;  /* In case the blob is ever converted to text */
  2527   2514     REGISTER_TRACE(pOp->p3, pOut);
         2515  +  UPDATE_MAX_BLOBSIZE(pOut);
  2528   2516   
  2529   2517     /* If a NULL was encountered and jumpIfNull is non-zero, take the jump. */
  2530   2518     if( jumpIfNull && containsNull ){
  2531   2519       pc = jumpIfNull - 1;
  2532   2520     }
  2533   2521     break;
  2534   2522   }
................................................................................
  2679   2667   ** executing this instruction.
  2680   2668   */
  2681   2669   case OP_ReadCookie: {               /* out2-prerelease */
  2682   2670     int iMeta;
  2683   2671     int iDb = pOp->p1;
  2684   2672     int iCookie = pOp->p3;
  2685   2673   
  2686         -  assert( pOp->p2<SQLITE_N_BTREE_META );
         2674  +  assert( pOp->p3<SQLITE_N_BTREE_META );
  2687   2675     if( iDb<0 ){
  2688   2676       iDb = (-1*(iDb+1));
  2689   2677       iCookie *= -1;
  2690   2678     }
  2691   2679     assert( iDb>=0 && iDb<db->nDb );
  2692   2680     assert( db->aDb[iDb].pBt!=0 );
  2693   2681     assert( (p->btreeMask & (1<<iDb))!=0 );
................................................................................
  3815   3803       assert( pC->nData<=SQLITE_MAX_LENGTH );
  3816   3804       pOut->z = pC->pData;
  3817   3805       pOut->flags = MEM_Blob|MEM_Ephem;
  3818   3806     }else{
  3819   3807       pOut->flags = MEM_Null;
  3820   3808     }
  3821   3809     pOut->enc = SQLITE_UTF8;  /* In case the blob is ever cast to text */
         3810  +  UPDATE_MAX_BLOBSIZE(pOut);
  3822   3811     break;
  3823   3812   }
  3824   3813   
  3825   3814   /* Opcode: Rowid P1 P2 * * *
  3826   3815   **
  3827   3816   ** Store in register P2 an integer which is the key of the table entry that
  3828   3817   ** P1 is currently point to.  If p2==0 then push the integer.
................................................................................
  4436   4425     }else{
  4437   4426       pIn1->z = z;
  4438   4427       pIn1->n = strlen(z);
  4439   4428       pIn1->flags = MEM_Str | MEM_Dyn | MEM_Term;
  4440   4429       pIn1->xDel = 0;
  4441   4430     }
  4442   4431     pIn1->enc = SQLITE_UTF8;
         4432  +  UPDATE_MAX_BLOBSIZE(pIn1);
  4443   4433     sqlite3VdbeChangeEncoding(pIn1, encoding);
  4444   4434     sqlite3_free(aRoot);
  4445   4435     break;
  4446   4436   }
  4447   4437   #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
  4448   4438   
  4449   4439   /* Opcode: FifoWrite P1 * * * *
................................................................................
  4652   4642     assert( pOp->p1>0 && pOp->p1<=p->nMem );
  4653   4643     pMem = &p->aMem[pOp->p1];
  4654   4644     assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
  4655   4645     rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
  4656   4646     if( rc==SQLITE_ERROR ){
  4657   4647       sqlite3SetString(&p->zErrMsg, sqlite3_value_text(pMem), (char*)0);
  4658   4648     }
         4649  +  UPDATE_MAX_BLOBSIZE(pMem);
  4659   4650     if( sqlite3VdbeMemTooBig(pMem) ){
  4660   4651       goto too_big;
  4661   4652     }
  4662   4653     break;
  4663   4654   }
  4664   4655   
  4665   4656   
................................................................................
  4957   4948         pDest = &p->aMem[pOp->p3];
  4958   4949         REGISTER_TRACE(pOp->p3, pDest);
  4959   4950       }else{
  4960   4951         pDest = ++pTos;
  4961   4952         pDest->flags = 0;
  4962   4953       }
  4963   4954       sqlite3VdbeMemMove(pDest, &sContext.s);
         4955  +    UPDATE_MAX_BLOBSIZE(pDest);
  4964   4956   
  4965   4957       if( sqlite3SafetyOn(db) ){
  4966   4958         goto abort_due_to_misuse;
  4967   4959       }
  4968   4960       if( sqlite3VdbeMemTooBig(pDest) ){
  4969   4961         goto too_big;
  4970   4962       }
................................................................................
  5128   5120         pOp->cycles += elapse;
  5129   5121         pOp->cnt++;
  5130   5122   #if 0
  5131   5123           fprintf(stdout, "%10lld ", elapse);
  5132   5124           sqlite3VdbePrintOp(stdout, origPc, &p->aOp[origPc]);
  5133   5125   #endif
  5134   5126       }
  5135         -#endif
  5136         -
  5137         -#ifdef SQLITE_TEST
  5138         -    /* Keep track of the size of the largest BLOB or STR that has appeared
  5139         -    ** on the top of the VDBE stack.
  5140         -    */
  5141         -    if( pTos>=p->aStack && (pTos->flags & (MEM_Blob|MEM_Str))!=0
  5142         -         && pTos->n>sqlite3_max_blobsize ){
  5143         -      sqlite3_max_blobsize = pTos->n;
  5144         -    }
  5145   5127   #endif
  5146   5128   
  5147   5129       /* The following code adds nothing to the actual functionality
  5148   5130       ** of the program.  It is only here for testing and debugging.
  5149   5131       ** On the other hand, it does burn CPU cycles every time through
  5150   5132       ** the evaluator loop.  So we can leave it out when NDEBUG is defined.
  5151   5133       */

Changes to src/vtab.c.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains code used to help implement virtual tables.
    13     13   **
    14         -** $Id: vtab.c,v 1.60 2008/01/03 00:01:25 drh Exp $
           14  +** $Id: vtab.c,v 1.61 2008/01/12 12:48:08 drh Exp $
    15     15   */
    16     16   #ifndef SQLITE_OMIT_VIRTUALTABLE
    17     17   #include "sqliteInt.h"
    18     18   
    19     19   static int createModule(
    20     20     sqlite3 *db,                    /* Database in which module is registered */
    21     21     const char *zName,              /* Name assigned to this module */
................................................................................
   255    255       }
   256    256       zStmt = sqlite3MPrintf(db, "CREATE VIRTUAL TABLE %T", &pParse->sNameToken);
   257    257   
   258    258       /* A slot for the record has already been allocated in the 
   259    259       ** SQLITE_MASTER table.  We just need to update that slot with all
   260    260       ** the information we've collected.  
   261    261       **
   262         -    ** The top of the stack is the rootpage allocated by sqlite3StartTable().
   263         -    ** This value is always 0 and is ignored, a virtual table does not have a
   264         -    ** rootpage. The next entry on the stack is the rowid of the record
   265         -    ** in the sqlite_master table.
          262  +    ** The VM register number pParse->regRowid holds the rowid of an
          263  +    ** entry in the sqlite_master table tht was created for this vtab
          264  +    ** by sqlite3StartTable().
   266    265       */
   267    266       iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
   268    267       sqlite3NestedParse(pParse,
   269    268         "UPDATE %Q.%s "
   270    269            "SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q "
   271         -       "WHERE rowid=#1",
          270  +       "WHERE rowid=#%d",
   272    271         db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
   273    272         pTab->zName,
   274    273         pTab->zName,
   275         -      zStmt
          274  +      zStmt,
          275  +      pParse->regRowid
   276    276       );
   277    277       sqlite3_free(zStmt);
   278    278       v = sqlite3GetVdbe(pParse);
   279    279       sqlite3ChangeCookie(db, v, iDb);
   280    280   
   281    281       sqlite3VdbeAddOp2(v, OP_Expire, 0, 0);
   282    282       zWhere = sqlite3MPrintf(db, "name='%q'", pTab->zName);

Changes to test/select4.test.

     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this file is testing UNION, INTERSECT and EXCEPT operators
    13     13   # in SELECT statements.
    14     14   #
    15         -# $Id: select4.test,v 1.24 2007/12/13 07:58:51 danielk1977 Exp $
           15  +# $Id: select4.test,v 1.25 2008/01/12 12:48:09 drh Exp $
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
    19     19   
    20     20   # Most tests in this file depend on compound-select. But there are a couple
    21     21   # right at the end that test DISTINCT, so we cannot omit the entire file.
    22     22   #
................................................................................
   613    613       SELECT * FROM (SELECT 1 AS a, 2 AS b UNION ALL SELECT 3 AS e, 4 AS b)
   614    614        WHERE b>0
   615    615     }
   616    616   } {a 1 b 2 a 3 b 4}
   617    617   } ;# ifcapable subquery
   618    618   
   619    619   } ;# ifcapable compound
          620  +
          621  +# Try combining DISTINCT, LIMIT, and OFFSET.  Make sure they all work
          622  +# together.
          623  +#
          624  +do_test select4-10.1 {
          625  +  execsql {
          626  +    SELECT DISTINCT log FROM t1 ORDER BY log
          627  +  }
          628  +} {0 1 2 3 4 5}
          629  +do_test select4-10.2 {
          630  +  execsql {
          631  +    SELECT DISTINCT log FROM t1 ORDER BY log LIMIT 4
          632  +  }
          633  +} {0 1 2 3}
          634  +do_test select4-10.3 {
          635  +  execsql {
          636  +    SELECT DISTINCT log FROM t1 ORDER BY log LIMIT 0
          637  +  }
          638  +} {}
          639  +do_test select4-10.4 {
          640  +  execsql {
          641  +    SELECT DISTINCT log FROM t1 ORDER BY log LIMIT -1
          642  +  }
          643  +} {0 1 2 3 4 5}
          644  +do_test select4-10.5 {
          645  +  execsql {
          646  +    SELECT DISTINCT log FROM t1 ORDER BY log LIMIT -1 OFFSET 2
          647  +  }
          648  +} {2 3 4 5}
          649  +do_test select4-10.6 {
          650  +  execsql {
          651  +    SELECT DISTINCT log FROM t1 ORDER BY log LIMIT 3 OFFSET 2
          652  +  }
          653  +} {2 3 4}
          654  +do_test select4-10.7 {
          655  +  execsql {
          656  +    SELECT DISTINCT log FROM t1 ORDER BY +log LIMIT 3 OFFSET 20
          657  +  }
          658  +} {}
          659  +do_test select4-10.8 {
          660  +  execsql {
          661  +    SELECT DISTINCT log FROM t1 ORDER BY log LIMIT 0 OFFSET 3
          662  +  }
          663  +} {}
          664  +do_test select4-10.9 {
          665  +breakpoint
          666  +  execsql {
          667  +    SELECT DISTINCT max(n), log FROM t1 ORDER BY +log; -- LIMIT 2 OFFSET 1
          668  +  }
          669  +} {31 5}
          670  +
   620    671   
   621    672   finish_test

Added test/select8.test.

            1  +# 2001 September 15
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +# This file implements regression tests for SQLite library. 
           12  +#
           13  +# The focus of this file is testing that LIMIT and OFFSET work for
           14  +# unusual combinations SELECT statements.
           15  +#
           16  +# $Id: select8.test,v 1.1 2008/01/12 12:48:09 drh Exp $
           17  +
           18  +set testdir [file dirname $argv0]
           19  +source $testdir/tester.tcl
           20  +
           21  +execsql {
           22  +  CREATE TABLE songs(songid, artist, timesplayed);
           23  +  INSERT INTO songs VALUES(1,'one',1);
           24  +  INSERT INTO songs VALUES(2,'one',2);
           25  +  INSERT INTO songs VALUES(3,'two',3);
           26  +  INSERT INTO songs VALUES(4,'three',5);
           27  +  INSERT INTO songs VALUES(5,'one',7);
           28  +  INSERT INTO songs VALUES(6,'two',11);
           29  +}
           30  +set result [execsql {
           31  +  SELECT DISTINCT artist,sum(timesplayed) AS total      
           32  +  FROM songs      
           33  +  GROUP BY LOWER(artist)      
           34  +}]
           35  +puts result=$result
           36  +do_test select8-1.1 {
           37  +  execsql {
           38  +    SELECT DISTINCT artist,sum(timesplayed) AS total      
           39  +    FROM songs      
           40  +    GROUP BY LOWER(artist)      
           41  +    LIMIT 1 OFFSET 1
           42  +  }
           43  +} [lrange $result 2 3]
           44  +do_test select8-1.2 {
           45  +  execsql {
           46  +    SELECT DISTINCT artist,sum(timesplayed) AS total      
           47  +    FROM songs      
           48  +    GROUP BY LOWER(artist)      
           49  +    LIMIT 2 OFFSET 1
           50  +  }
           51  +} [lrange $result 2 5]
           52  +do_test select8-1.3 {
           53  +  execsql {
           54  +    SELECT DISTINCT artist,sum(timesplayed) AS total      
           55  +    FROM songs      
           56  +    GROUP BY LOWER(artist)      
           57  +    LIMIT -1 OFFSET 2
           58  +  }
           59  +} [lrange $result 4 end]
           60  +
           61  +
           62  +finish_test