/ Check-in [1a58a870]
Login

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

Overview
Comment:Allow creation of ephemeral pseudo-tables - pseudo-tables that copy a pointer to a row when inserted instead of copying the row data. (CVS 4924)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 1a58a87023f7780aee813ac64dda1a80021002a7
User & Date: danielk1977 2008-03-27 17:59:02
Context
2008-03-27
22:42
Allow the xAccess method in the VFS to return -1 to signal an I/O error, and in particular an SQLITE_IOERR_NOMEM. (CVS 4925) check-in: 3cb704c4 user: drh tags: trunk
17:59
Allow creation of ephemeral pseudo-tables - pseudo-tables that copy a pointer to a row when inserted instead of copying the row data. (CVS 4924) check-in: 1a58a870 user: danielk1977 tags: trunk
15:07
Added the speed4p.test script for testing performance of views and triggers. (CVS 4923) check-in: adf7645f user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

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.421 2008/03/26 12:50:15 drh Exp $
           15  +** $Id: select.c,v 1.422 2008/03/27 17:59:02 danielk1977 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.
................................................................................
   791    791     int regRow;
   792    792     int regRowid;
   793    793   
   794    794     iTab = pOrderBy->iECursor;
   795    795     if( eDest==SRT_Callback || eDest==SRT_Subroutine ){
   796    796       pseudoTab = pParse->nTab++;
   797    797       sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, nColumn);
   798         -    sqlite3VdbeAddOp2(v, OP_OpenPseudo, pseudoTab, 0);
          798  +    sqlite3VdbeAddOp2(v, OP_OpenPseudo, pseudoTab, eDest==SRT_Callback);
   799    799     }
   800    800     addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, brk);
   801    801     codeOffset(v, p, cont);
   802    802     regRow = sqlite3GetTempReg(pParse);
   803    803     regRowid = sqlite3GetTempReg(pParse);
   804    804     sqlite3VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr + 1, regRow);
   805    805     switch( eDest ){
................................................................................
   829    829   #endif
   830    830       case SRT_Callback:
   831    831       case SRT_Subroutine: {
   832    832         int i;
   833    833         sqlite3VdbeAddOp2(v, OP_Integer, 1, regRowid);
   834    834         sqlite3VdbeAddOp3(v, OP_Insert, pseudoTab, regRow, regRowid);
   835    835         for(i=0; i<nColumn; i++){
          836  +        assert( regRow!=pDest->iMem+i );
   836    837           sqlite3VdbeAddOp3(v, OP_Column, pseudoTab, i, pDest->iMem+i);
   837    838         }
   838    839         if( eDest==SRT_Callback ){
   839    840           sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iMem, nColumn);
   840    841         }else{
   841    842           sqlite3VdbeAddOp2(v, OP_Gosub, 0, iParm);
   842    843         }

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.718 2008/03/25 17:23:33 drh Exp $
           46  +** $Id: vdbe.c,v 1.719 2008/03/27 17:59:02 danielk1977 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
................................................................................
  2680   2680         pCx->pIncrKey = &pCx->bogusIncrKey;
  2681   2681       }
  2682   2682     }
  2683   2683     pCx->isIndex = !pCx->isTable;
  2684   2684     break;
  2685   2685   }
  2686   2686   
  2687         -/* Opcode: OpenPseudo P1 * * * *
         2687  +/* Opcode: OpenPseudo P1 P2 * * *
  2688   2688   **
  2689   2689   ** Open a new cursor that points to a fake table that contains a single
  2690   2690   ** row of data.  Any attempt to write a second row of data causes the
  2691   2691   ** first row to be deleted.  All data is deleted when the cursor is
  2692   2692   ** closed.
  2693   2693   **
  2694   2694   ** A pseudo-table created by this opcode is useful for holding the
  2695   2695   ** NEW or OLD tables in a trigger.  Also used to hold the a single
  2696   2696   ** row output from the sorter so that the row can be decomposed into
  2697   2697   ** individual columns using the OP_Column opcode.
         2698  +**
         2699  +** When OP_Insert is executed to insert a row in to the pseudo table,
         2700  +** the pseudo-table cursor may or may not make it's own copy of the
         2701  +** original row data. If P2 is 0, then the pseudo-table will copy the
         2702  +** original row data. Otherwise, a pointer to the original memory cell
         2703  +** is stored. In this case, the vdbe program must ensure that the 
         2704  +** memory cell containing the row data is not overwritten until the
         2705  +** pseudo table is closed (or a new row is inserted into it).
  2698   2706   */
  2699   2707   case OP_OpenPseudo: {
  2700   2708     int i = pOp->p1;
  2701   2709     Cursor *pCx;
  2702   2710     assert( i>=0 );
  2703   2711     pCx = allocateCursor(p, i, &pOp[-1], -1, 0);
  2704   2712     if( pCx==0 ) goto no_mem;
  2705   2713     pCx->nullRow = 1;
  2706   2714     pCx->pseudoTable = 1;
         2715  +  pCx->ephemPseudoTable = pOp->p2;
  2707   2716     pCx->pIncrKey = &pCx->bogusIncrKey;
  2708   2717     pCx->isTable = 1;
  2709   2718     pCx->isIndex = 0;
  2710   2719     break;
  2711   2720   }
  2712   2721   
  2713   2722   /* Opcode: Close P1 * * * *
................................................................................
  3272   3281     if( pData->flags & MEM_Null ){
  3273   3282       pData->z = 0;
  3274   3283       pData->n = 0;
  3275   3284     }else{
  3276   3285       assert( pData->flags & (MEM_Blob|MEM_Str) );
  3277   3286     }
  3278   3287     if( pC->pseudoTable ){
  3279         -    sqlite3_free(pC->pData);
         3288  +    if( !pC->ephemPseudoTable ){
         3289  +      sqlite3_free(pC->pData);
         3290  +    }
  3280   3291       pC->iKey = iKey;
  3281   3292       pC->nData = pData->n;
  3282   3293       if( pData->flags & MEM_Dyn ){
  3283   3294         pC->pData = pData->z;
  3284         -      pData->flags &= ~MEM_Dyn;
  3285         -      pData->flags |= MEM_Ephem;
         3295  +      if( !pC->ephemPseudoTable ){
         3296  +        pData->flags &= ~MEM_Dyn;
         3297  +        pData->flags |= MEM_Ephem;
         3298  +      }
  3286   3299       }else{
  3287   3300         pC->pData = sqlite3_malloc( pC->nData+2 );
  3288   3301         if( !pC->pData ) goto no_mem;
  3289   3302         memcpy(pC->pData, pData->z, pC->nData);
  3290   3303         pC->pData[pC->nData] = 0;
  3291   3304         pC->pData[pC->nData+1] = 0;
  3292   3305       }

Changes to src/vdbeInt.h.

    61     61     Bool zeroed;          /* True if zeroed out and ready for reuse */
    62     62     Bool rowidIsValid;    /* True if lastRowid is valid */
    63     63     Bool atFirst;         /* True if pointing to first entry */
    64     64     Bool useRandomRowid;  /* Generate new record numbers semi-randomly */
    65     65     Bool nullRow;         /* True if pointing to a row with no data */
    66     66     Bool nextRowidValid;  /* True if the nextRowid field is valid */
    67     67     Bool pseudoTable;     /* This is a NEW or OLD pseudo-tables of a trigger */
           68  +  Bool ephemPseudoTable;
    68     69     Bool deferredMoveto;  /* A call to sqlite3BtreeMoveto() is needed */
    69     70     Bool isTable;         /* True if a table requiring integer keys */
    70     71     Bool isIndex;         /* True if an index containing keys only - no data */
    71     72     u8 bogusIncrKey;      /* Something for pIncrKey to point to if pKeyInfo==0 */
    72     73     i64 movetoTarget;     /* Argument to the deferred sqlite3BtreeMoveto() */
    73     74     Btree *pBt;           /* Separate file holding temporary table */
    74     75     int nData;            /* Number of bytes in pData */

Changes to src/vdbeaux.c.

  1077   1077       p->inVtabMethod = 1;
  1078   1078       (void)sqlite3SafetyOff(p->db);
  1079   1079       pModule->xClose(pVtabCursor);
  1080   1080       (void)sqlite3SafetyOn(p->db);
  1081   1081       p->inVtabMethod = 0;
  1082   1082     }
  1083   1083   #endif
  1084         -  sqlite3_free(pCx->pData);
         1084  +  if( !pCx->ephemPseudoTable ){
         1085  +    sqlite3_free(pCx->pData);
         1086  +  }
  1085   1087     memset(pCx, 0, sizeof(Cursor));
  1086   1088     /* sqlite3_free(pCx->aType); */
  1087   1089     /* sqlite3_free(pCx); */
  1088   1090   }
  1089   1091   
  1090   1092   /*
  1091   1093   ** Close all cursors except for VTab cursors that are currently