/ Check-in [1c508a99]
Login

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

Overview
Comment:Change the OP_Rowid opcode so that a deferred OP_Seek is pending, it simply pulls the rowid from the deferred seek target and does not actually move the cursor or do a seek. Other where.c cleanups. (CVS 6536)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:1c508a99822caa383e7e24b5d09a9bddd2ee3a00
User & Date: drh 2009-04-22 15:32:59
Context
2009-04-22
17:15
Eliminate the OP_VRowid opcode. The regular OP_Rowid now work for both regular and virtual tables. (CVS 6537) check-in: ecbef450 user: drh tags: trunk
15:32
Change the OP_Rowid opcode so that a deferred OP_Seek is pending, it simply pulls the rowid from the deferred seek target and does not actually move the cursor or do a seek. Other where.c cleanups. (CVS 6536) check-in: 1c508a99 user: drh tags: trunk
02:15
Remove the rowhash object from the code. Rowset now fills its role. (CVS 6535) check-in: e963bed0 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/rowset.c.

    56     56   ** The cost of a TEST using the same batch number is O(logN).  The cost
    57     57   ** of the first SMALLEST is O(NlogN).  Second and subsequent SMALLEST
    58     58   ** primitives are constant time.  The cost of DESTROY is O(N).
    59     59   **
    60     60   ** There is an added cost of O(N) when switching between TEST and
    61     61   ** SMALLEST primitives.
    62     62   **
    63         -** $Id: rowset.c,v 1.5 2009/04/22 00:47:01 drh Exp $
           63  +** $Id: rowset.c,v 1.6 2009/04/22 15:32:59 drh Exp $
    64     64   */
    65     65   #include "sqliteInt.h"
    66     66   
    67     67   
    68     68   /*
    69     69   ** Target size for allocation chunks.
    70     70   */
................................................................................
   273    273   ** and return pointers to the first and last elements of the new list.
   274    274   */
   275    275   static void rowSetTreeToList(
   276    276     struct RowSetEntry *pIn,         /* Root of the input tree */
   277    277     struct RowSetEntry **ppFirst,    /* Write head of the output list here */
   278    278     struct RowSetEntry **ppLast      /* Write tail of the output list here */
   279    279   ){
   280         -  if( pIn==0 ){
   281         -    *ppFirst = *ppLast = 0;
   282         -  }
          280  +  assert( pIn!=0 );
   283    281     if( pIn->pLeft ){
   284    282       struct RowSetEntry *p;
   285    283       rowSetTreeToList(pIn->pLeft, ppFirst, &p);
   286    284       p->pRight = pIn;
   287    285     }else{
   288    286       *ppFirst = pIn;
   289    287     }
................................................................................
   340    338   ** as deep as it needs to be in order to contain the entire list.
   341    339   */
   342    340   static struct RowSetEntry *rowSetListToTree(struct RowSetEntry *pList){
   343    341     int iDepth;           /* Depth of the tree so far */
   344    342     struct RowSetEntry *p;       /* Current tree root */
   345    343     struct RowSetEntry *pLeft;   /* Left subtree */
   346    344   
   347         -  if( pList==0 ){
   348         -    return 0;
   349         -  }
          345  +  assert( pList!=0 );
   350    346     p = pList;
   351    347     pList = p->pRight;
   352    348     p->pLeft = p->pRight = 0;
   353    349     for(iDepth=1; pList; iDepth++){
   354    350       pLeft = p;
   355    351       p = pList;
   356    352       pList = p->pRight;

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.858 2009/04/22 02:15:48 drh Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.859 2009/04/22 15:32:59 drh Exp $
    15     15   */
    16     16   #ifndef _SQLITEINT_H_
    17     17   #define _SQLITEINT_H_
    18     18   
    19     19   /*
    20     20   ** Include the configuration header output by 'configure' if we're using the
    21     21   ** autoconf-based build
................................................................................
   215    215   */
   216    216   #if !defined(NDEBUG) || defined(SQLITE_COVERAGE_TEST)
   217    217   # define TESTONLY(X)  X
   218    218   #else
   219    219   # define TESTONLY(X)
   220    220   #endif
   221    221   
          222  +/*
          223  +** Sometimes we need a small amount of code such as a variable initialization
          224  +** to setup for a later assert() statement.  We do not want this code to
          225  +** appear when assert() is disabled.  The following macro is therefore
          226  +** used to contain that setup code.  The "VVA" acronym stands for
          227  +** "Verification, Validation, and Accreditation".  In other words, the
          228  +** code within VVA_ONLY() will only run during verification processes.
          229  +*/
          230  +#ifndef NDEBUG
          231  +# define VVA_ONLY(X)  X
          232  +#else
          233  +# define VVA_ONLY(X)
          234  +#endif
          235  +
   222    236   /*
   223    237   ** The ALWAYS and NEVER macros surround boolean expressions which 
   224    238   ** are intended to always be true or false, respectively.  Such
   225    239   ** expressions could be omitted from the code completely.  But they
   226    240   ** are included in a few cases in order to enhance the resilience
   227    241   ** of SQLite to unexpected behavior - to make the code "self-healing"
   228    242   ** or "ductile" rather than being "brittle" and crashing at the first
................................................................................
   256    270   # define likely(X)    __builtin_expect((X),1)
   257    271   # define unlikely(X)  __builtin_expect((X),0)
   258    272   #else
   259    273   # define likely(X)    !!(X)
   260    274   # define unlikely(X)  !!(X)
   261    275   #endif
   262    276   
   263         -/*
   264         -** Sometimes we need a small amount of code such as a variable initialization
   265         -** to setup for a later assert() statement.  We do not want this code to
   266         -** appear when assert() is disabled.  The following macro is therefore
   267         -** used to contain that setup code.  The "VVA" acronym stands for
   268         -** "Verification, Validation, and Accreditation".  In other words, the
   269         -** code within VVA_ONLY() will only run during verification processes.
   270         -*/
   271         -#ifndef NDEBUG
   272         -# define VVA_ONLY(X)  X
   273         -#else
   274         -# define VVA_ONLY(X)
   275         -#endif
   276         -
   277    277   #include "sqlite3.h"
   278    278   #include "hash.h"
   279    279   #include "parse.h"
   280    280   #include <stdio.h>
   281    281   #include <stdlib.h>
   282    282   #include <string.h>
   283    283   #include <assert.h>

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.837 2009/04/22 02:15:48 drh Exp $
           46  +** $Id: vdbe.c,v 1.838 2009/04/22 15:32:59 drh Exp $
    47     47   */
    48     48   #include "sqliteInt.h"
    49     49   #include "vdbeInt.h"
    50     50   
    51     51   /*
    52     52   ** The following global variable is incremented every time a cursor
    53     53   ** moves, either by the OP_SeekXX, OP_Next, or OP_Prev opcodes.  The test
................................................................................
  3901   3901     int i = pOp->p1;
  3902   3902     VdbeCursor *pC;
  3903   3903     i64 v;
  3904   3904   
  3905   3905     assert( i>=0 && i<p->nCursor );
  3906   3906     pC = p->apCsr[i];
  3907   3907     assert( pC!=0 );
  3908         -  rc = sqlite3VdbeCursorMoveto(pC);
  3909         -  if( rc ) goto abort_due_to_error;
  3910         -  if( pC->rowidIsValid ){
  3911         -    v = pC->lastRowid;
  3912         -  }else if( pC->pseudoTable ){
  3913         -    v = keyToInt(pC->iKey);
  3914         -  }else if( pC->nullRow ){
  3915         -    /* Leave the rowid set to a NULL */
  3916         -    break;
         3908  +  if( pC->deferredMoveto ){
         3909  +    v = pC->movetoTarget;
  3917   3910     }else{
  3918         -    assert( pC->pCursor!=0 );
  3919         -    sqlite3BtreeKeySize(pC->pCursor, &v);
  3920         -    v = keyToInt(v);
         3911  +    rc = sqlite3VdbeCursorMoveto(pC);
         3912  +    if( rc ) goto abort_due_to_error;
         3913  +    if( pC->rowidIsValid ){
         3914  +      v = pC->lastRowid;
         3915  +    }else if( pC->pseudoTable ){
         3916  +      v = keyToInt(pC->iKey);
         3917  +    }else if( pC->nullRow ){
         3918  +      /* Leave the rowid set to a NULL */
         3919  +      break;
         3920  +    }else{
         3921  +      assert( pC->pCursor!=0 );
         3922  +      sqlite3BtreeKeySize(pC->pCursor, &v);
         3923  +      v = keyToInt(v);
         3924  +    }
  3921   3925     }
  3922   3926     pOut->u.i = v;
  3923   3927     MemSetTypeFlag(pOut, MEM_Int);
  3924   3928     break;
  3925   3929   }
  3926   3930   
  3927   3931   /* Opcode: NullRow P1 * * * *

Changes to src/vdbeaux.c.

    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains code used for creating, destroying, and populating
    13     13   ** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.)  Prior
    14     14   ** to version 2.8.7, all this code was combined into the vdbe.c source file.
    15     15   ** But that file was getting too big so this subroutines were split out.
    16     16   **
    17         -** $Id: vdbeaux.c,v 1.453 2009/04/22 02:15:48 drh Exp $
           17  +** $Id: vdbeaux.c,v 1.454 2009/04/22 15:32:59 drh Exp $
    18     18   */
    19     19   #include "sqliteInt.h"
    20     20   #include "vdbeInt.h"
    21     21   
    22     22   
    23     23   
    24     24   /*
................................................................................
  1998   1998   #ifdef SQLITE_TEST
  1999   1999       extern int sqlite3_search_count;
  2000   2000   #endif
  2001   2001       assert( p->isTable );
  2002   2002       rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res);
  2003   2003       if( rc ) return rc;
  2004   2004       p->lastRowid = keyToInt(p->movetoTarget);
  2005         -    p->rowidIsValid = res==0 ?1:0;
  2006         -    if( res<0 ){
         2005  +    p->rowidIsValid = ALWAYS(res==0) ?1:0;
         2006  +    if( NEVER(res<0) ){
  2007   2007         rc = sqlite3BtreeNext(p->pCursor, &res);
  2008   2008         if( rc ) return rc;
  2009   2009       }
  2010   2010   #ifdef SQLITE_TEST
  2011   2011       sqlite3_search_count++;
  2012   2012   #endif
  2013   2013       p->deferredMoveto = 0;

Changes to src/where.c.

    12     12   ** This module contains C code that generates VDBE code used to process
    13     13   ** the WHERE clause of SQL statements.  This module is responsible for
    14     14   ** generating the code that loops through a table looking for applicable
    15     15   ** rows.  Indices are selected and used to speed the search when doing
    16     16   ** so is applicable.  Because this module is responsible for selecting
    17     17   ** indices, you might also think of this module as the "query optimizer".
    18     18   **
    19         -** $Id: where.c,v 1.385 2009/04/22 02:15:49 drh Exp $
           19  +** $Id: where.c,v 1.386 2009/04/22 15:32:59 drh Exp $
    20     20   */
    21     21   #include "sqliteInt.h"
    22     22   
    23     23   /*
    24     24   ** Trace output macros
    25     25   */
    26     26   #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
................................................................................
    39     39   typedef struct WhereOrInfo WhereOrInfo;
    40     40   typedef struct WhereAndInfo WhereAndInfo;
    41     41   typedef struct WhereCost WhereCost;
    42     42   
    43     43   /*
    44     44   ** The query generator uses an array of instances of this structure to
    45     45   ** help it analyze the subexpressions of the WHERE clause.  Each WHERE
    46         -** clause subexpression is separated from the others by AND operators.
    47         -** (Note: the same data structure is also reused to hold a group of terms
    48         -** separated by OR operators.  But at the top-level, everything is AND
    49         -** separated.)
           46  +** clause subexpression is separated from the others by AND operators,
           47  +** usually, or sometimes subexpressions separated by OR.
    50     48   **
    51     49   ** All WhereTerms are collected into a single WhereClause structure.  
    52     50   ** The following identity holds:
    53     51   **
    54     52   **        WhereTerm.pWC->a[WhereTerm.idx] == WhereTerm
    55     53   **
    56     54   ** When a term is of the form:
................................................................................
   371    369     }else{
   372    370       whereSplit(pWC, pExpr->pLeft, op);
   373    371       whereSplit(pWC, pExpr->pRight, op);
   374    372     }
   375    373   }
   376    374   
   377    375   /*
   378         -** Initialize an expression mask set
          376  +** Initialize an expression mask set (a WhereMaskSet object)
   379    377   */
   380    378   #define initMaskSet(P)  memset(P, 0, sizeof(*P))
   381    379   
   382    380   /*
   383    381   ** Return the bitmask for the given cursor number.  Return 0 if
   384    382   ** iCursor is not in the set.
   385    383   */
................................................................................
  2402   2400     WhereTerm *pTerm;               /* A WHERE clause term */
  2403   2401     Parse *pParse;                  /* Parsing context */
  2404   2402     Vdbe *v;                        /* The prepared stmt under constructions */
  2405   2403     struct SrcList_item *pTabItem;  /* FROM clause term being coded */
  2406   2404     int addrBrk;                    /* Jump here to break out of the loop */
  2407   2405     int addrCont;                   /* Jump here to continue with next cycle */
  2408   2406     int regRowSet;       /* Write rowids to this RowSet if non-negative */
  2409         -  int codeRowSetEarly; /* True if index fully constrains the search */
  2410   2407   
  2411   2408     /* Sometimes, this function is required to generate code to do 
  2412         -  ** something with the rowid of each row scanned. Specifically:
  2413         -  **
  2414         -  **   1) If pWInfo->regRowSet is non-zero, then the rowid must be inserted
  2415         -  **      into the RowSet object stored in register pWInfo->regRowSet.
         2409  +  ** something with the rowid of each row scanned. Specifically,
         2410  +  ** If pWInfo->regRowSet is non-zero, then the rowid must be inserted
         2411  +  ** into the RowSet object stored in register pWInfo->regRowSet.
  2416   2412     **
  2417   2413     ** Extracting a rowid value from a VDBE cursor is not always a cheap
  2418   2414     ** operation, especially if the rowid is being extracted from an index
  2419   2415     ** cursor. If the rowid value is available as a by-product of the code
  2420   2416     ** generated to create the top of the scan loop, then it can be reused
  2421         -  ** without extracting
  2422         -  ** it from a cursor. The following two variables are used to communicate
  2423         -  ** the availability of the rowid value to the C-code at the end of this
  2424         -  ** function that generates the rowid-handling VDBE code.
         2417  +  ** without extracting it from a cursor. The following two variables are
         2418  +  ** used to communicate the availability of the rowid value to the C-code
         2419  +  ** at the end of this function that generates the rowid-handling VDBE code.
  2425   2420     */
  2426         -  int iRowidReg = 0;              /* Rowid is stored in this register */
  2427         -  int iReleaseReg = 0;            /* Temp register to free before returning */
         2421  +  int iRowidReg = 0;        /* Rowid is stored in this register, if not zero */
         2422  +  int iReleaseReg = 0;      /* Temp register to free before returning */
  2428   2423   
  2429   2424     pParse = pWInfo->pParse;
  2430   2425     v = pParse->pVdbe;
  2431   2426     pWC = pWInfo->pWC;
  2432   2427     pLevel = &pWInfo->a[iLevel];
  2433   2428     pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
  2434   2429     iCur = pTabItem->iCursor;
  2435   2430     bRev = (pLevel->plan.wsFlags & WHERE_REVERSE)!=0;
  2436   2431     omitTable = (pLevel->plan.wsFlags & WHERE_IDX_ONLY)!=0 
  2437   2432              && (wctrlFlags & WHERE_FILL_ROWTEST)==0;
  2438   2433     regRowSet = pWInfo->regRowSet;
  2439         -  codeRowSetEarly = 0;
  2440   2434   
  2441   2435     /* Create labels for the "break" and "continue" instructions
  2442   2436     ** for the current loop.  Jump to addrBrk to break out of a loop.
  2443   2437     ** Jump to cont to go immediately to the next iteration of the
  2444   2438     ** loop.
  2445   2439     **
  2446   2440     ** When there is an IN operator, we also have a "addrNxt" label that
................................................................................
  2873   2867       ** correct response for the end-of-loop code (the OP_Return) is to 
  2874   2868       ** fall through to the next instruction, just as an OP_Next does if
  2875   2869       ** called on an uninitialized cursor.
  2876   2870       */
  2877   2871       sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset);
  2878   2872       iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn);
  2879   2873   
  2880         -    /* iReleaseReg = iRowidReg = sqlite3GetTempReg(pParse); */
  2881   2874       for(ii=0; ii<pOrWc->nTerm; ii++){
  2882   2875         WhereTerm *pOrTerm = &pOrWc->a[ii];
  2883   2876         if( pOrTerm->leftCursor==iCur || pOrTerm->eOperator==WO_AND ){
  2884   2877           WhereInfo *pSubWInfo;          /* Info for single OR-term scan */
  2885   2878   
  2886   2879           /* Loop through table entries that match term pOrTerm. */
  2887   2880           pSubWInfo = sqlite3WhereBegin(
................................................................................
  2891   2884             /* The call to sqlite3WhereBegin has coded an OP_RowSetTest
  2892   2885             ** at instruction iRowSet. Set P2 (the jump target) of this
  2893   2886             ** instruction to jump past the OP_Gosub coded below. This way,
  2894   2887             ** if the rowid is already in the hash-table, the body of the
  2895   2888             ** loop is not executed.
  2896   2889             */
  2897   2890             int iRowSet = pSubWInfo->iRowidHandler;
         2891  +          assert( iRowSet>0 || pWInfo->pParse->db->mallocFailed );
  2898   2892             sqlite3VdbeChangeP2(v, iRowSet, sqlite3VdbeCurrentAddr(v) + 1);
  2899   2893             sqlite3VdbeChangeP4(v, iRowSet, (char *)iSet, P4_INT32);
  2900   2894             sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody);
  2901   2895   
  2902   2896             /* Finish the loop through table entries that match term pOrTerm. */
  2903   2897             sqlite3WhereEnd(pSubWInfo);
  2904   2898           }
................................................................................
  2987   2981         }else
  2988   2982   #endif
  2989   2983         {
  2990   2984           sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg);
  2991   2985         }
  2992   2986       }
  2993   2987       
  2994         -    pWInfo->iRowidHandler = sqlite3VdbeCurrentAddr(v);
  2995   2988       if( pWInfo->wctrlFlags&WHERE_FILL_ROWSET ){
  2996   2989         sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, iRowidReg);
         2990  +      VVA_ONLY( pWInfo->iRowidHandler = 0; )
  2997   2991       }else{
  2998   2992         assert( pWInfo->wctrlFlags&WHERE_FILL_ROWTEST );
  2999         -      sqlite3VdbeAddOp3(v, OP_RowSetTest, regRowSet, 0, iRowidReg);
         2993  +      pWInfo->iRowidHandler = 
         2994  +        sqlite3VdbeAddOp3(v, OP_RowSetTest, regRowSet, 0, iRowidReg);
  3000   2995       }
  3001   2996     }
  3002   2997     sqlite3ReleaseTempReg(pParse, iReleaseReg);
  3003   2998   
  3004   2999     return notReady;
  3005   3000   }
  3006   3001