/ Check-in [a71a9ff1]
Login

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

Overview
Comment:Remove redundant opcodes OP_MakeKey and OP_MakeIdxKey. (CVS 1612)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: a71a9ff114f2162696d8d37fbc87b315568f6dcb
User & Date: danielk1977 2004-06-17 07:53:02
Context
2004-06-17
19:04
Documentation updates in preparation for the release of version 3.0.0. (CVS 1613) check-in: 9fb29f73 user: drh tags: trunk
07:53
Remove redundant opcodes OP_MakeKey and OP_MakeIdxKey. (CVS 1612) check-in: a71a9ff1 user: danielk1977 tags: trunk
06:13
Handle conflicting ON CONFLICT clauses in table definitions. (CVS 1611) check-in: 12e77e75 user: danielk1977 tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

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   ** to handle DELETE FROM statements.
    14     14   **
    15         -** $Id: delete.c,v 1.74 2004/06/16 12:00:49 danielk1977 Exp $
           15  +** $Id: delete.c,v 1.75 2004/06/17 07:53:02 danielk1977 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.
................................................................................
   409    409       int idx = pIdx->aiColumn[j];
   410    410       if( idx==pTab->iPKey ){
   411    411         sqlite3VdbeAddOp(v, OP_Dup, j, 0);
   412    412       }else{
   413    413         sqlite3VdbeAddOp(v, OP_Column, iCur, idx);
   414    414       }
   415    415     }
   416         -  sqlite3VdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
          416  +  sqlite3VdbeAddOp(v, OP_MakeRecord, pIdx->nColumn, (1<<24));
   417    417     sqlite3IndexAffinityStr(v, pIdx);
   418    418   }

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.143 2004/06/16 12:00:50 danielk1977 Exp $
           15  +** $Id: expr.c,v 1.144 2004/06/17 07:53:03 danielk1977 Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   #include <ctype.h>
    19     19   
    20     20   char const *sqlite3AffinityString(char affinity){
    21     21     switch( affinity ){
    22     22       case SQLITE_AFF_INTEGER: return "i";
................................................................................
   907    907             }
   908    908             if( sqlite3ExprCheck(pParse, pE2, 0, 0) ){
   909    909               return 1;
   910    910             }
   911    911   
   912    912             /* Evaluate the expression and insert it into the temp table */
   913    913             sqlite3ExprCode(pParse, pE2);
   914         -          sqlite3VdbeOp3(v, OP_MakeKey, 1, 0, affStr, P3_STATIC);
          914  +          sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, affStr, P3_STATIC);
   915    915             sqlite3VdbeAddOp(v, OP_String8, 0, 0);
   916    916             sqlite3VdbeAddOp(v, OP_PutStrKey, pExpr->iTable, 0);
   917    917           }
   918    918         }
   919    919         sqlite3VdbeChangeP3(v, addr, (void *)&keyInfo, P3_KEYINFO);
   920    920   
   921    921         break;
................................................................................
  1310   1310       }
  1311   1311       case TK_IN: {
  1312   1312         int addr;
  1313   1313         char const *affStr;
  1314   1314   
  1315   1315         /* Figure out the affinity to use to create a key from the results
  1316   1316         ** of the expression. affinityStr stores a static string suitable for
  1317         -      ** P3 of OP_MakeKey.
         1317  +      ** P3 of OP_MakeRecord.
  1318   1318         */
  1319   1319         affStr = sqlite3AffinityString(comparisonAffinity(pExpr));
  1320   1320   
  1321   1321         sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
  1322   1322   
  1323   1323         /* Code the <expr> from "<expr> IN (...)". The temporary table
  1324   1324         ** pExpr->iTable contains the values that make up the (...) set.
................................................................................
  1325   1325         */
  1326   1326         sqlite3ExprCode(pParse, pExpr->pLeft);
  1327   1327         addr = sqlite3VdbeCurrentAddr(v);
  1328   1328         sqlite3VdbeAddOp(v, OP_NotNull, -1, addr+4);            /* addr + 0 */
  1329   1329         sqlite3VdbeAddOp(v, OP_Pop, 2, 0);
  1330   1330         sqlite3VdbeAddOp(v, OP_String8, 0, 0);
  1331   1331         sqlite3VdbeAddOp(v, OP_Goto, 0, addr+7);
  1332         -      sqlite3VdbeOp3(v, OP_MakeKey, 1, 0, affStr, P3_STATIC); /* addr + 4 */
         1332  +      sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, affStr, P3_STATIC); /* addr + 4 */
  1333   1333         sqlite3VdbeAddOp(v, OP_Found, pExpr->iTable, addr+7);
  1334   1334         sqlite3VdbeAddOp(v, OP_AddImm, -1, 0);                  /* addr + 6 */
  1335   1335   
  1336   1336         break;
  1337   1337       }
  1338   1338       case TK_BETWEEN: {
  1339   1339         int p1;

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.111 2004/06/16 12:00:54 danielk1977 Exp $
           15  +** $Id: insert.c,v 1.112 2004/06/17 07:53:03 danielk1977 Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   
    19     19   /*
    20     20   ** Set P3 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:
................................................................................
   863    863         int idx = pIdx->aiColumn[i];
   864    864         if( idx==pTab->iPKey ){
   865    865           sqlite3VdbeAddOp(v, OP_Dup, i+extra+nCol+1, 1);
   866    866         }else{
   867    867           sqlite3VdbeAddOp(v, OP_Dup, i+extra+nCol-idx, 1);
   868    868         }
   869    869       }
   870         -    jumpInst1 = sqlite3VdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
          870  +    jumpInst1 = sqlite3VdbeAddOp(v, OP_MakeRecord, pIdx->nColumn, (1<<24));
   871    871       sqlite3IndexAffinityStr(v, pIdx);
   872    872   
   873    873       /* Find out what action to take in case there is an indexing conflict */
   874    874       onError = pIdx->onError;
   875    875       if( onError==OE_None ) continue;  /* pIdx is not a UNIQUE index */
   876    876       if( overrideError!=OE_Default ){
   877    877         onError = overrideError;
................................................................................
   932    932           }
   933    933           seenReplace = 1;
   934    934           break;
   935    935         }
   936    936         default: assert(0);
   937    937       }
   938    938       contAddr = sqlite3VdbeCurrentAddr(v);
          939  +    assert( contAddr<(1<<24) );
   939    940   #if NULL_DISTINCT_FOR_UNIQUE
   940         -    sqlite3VdbeChangeP2(v, jumpInst1, contAddr);
          941  +    sqlite3VdbeChangeP2(v, jumpInst1, contAddr | (1<<24));
   941    942   #endif
   942    943       sqlite3VdbeChangeP2(v, jumpInst2, contAddr);
   943    944     }
   944    945   }
   945    946   
   946    947   /*
   947    948   ** This routine generates code to finish the INSERT or UPDATE operation

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.191 2004/06/16 12:02:47 danielk1977 Exp $
           15  +** $Id: select.c,v 1.192 2004/06/17 07:53:03 danielk1977 Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   
    19     19   
    20     20   /*
    21     21   ** Allocate a new Select structure and return a pointer to that
    22     22   ** structure.
................................................................................
   312    312   ** stack into the sorter.
   313    313   */
   314    314   static void pushOntoSorter(Parse *pParse, Vdbe *v, ExprList *pOrderBy){
   315    315     int i;
   316    316     for(i=0; i<pOrderBy->nExpr; i++){
   317    317       sqlite3ExprCode(pParse, pOrderBy->a[i].pExpr);
   318    318     }
   319         -  sqlite3VdbeAddOp(v, OP_MakeKey, pOrderBy->nExpr, 0);
          319  +  sqlite3VdbeAddOp(v, OP_MakeRecord, pOrderBy->nExpr, 0);
   320    320     sqlite3VdbeAddOp(v, OP_SortPut, 0, 0);
   321    321   }
   322    322   
   323    323   /*
   324    324   ** This routine generates the code for the inside of the inner loop
   325    325   ** of a SELECT.
   326    326   **
................................................................................
   380    380     ** and this row has been seen before, then do not make this row
   381    381     ** part of the result.
   382    382     */
   383    383     if( distinct>=0 && pEList && pEList->nExpr>0 ){
   384    384   #if NULL_ALWAYS_DISTINCT
   385    385       sqlite3VdbeAddOp(v, OP_IsNull, -pEList->nExpr, sqlite3VdbeCurrentAddr(v)+7);
   386    386   #endif
   387         -    /* Deliberately leave the affinity string off of the following OP_MakeKey */
   388         -    sqlite3VdbeAddOp(v, OP_MakeKey, pEList->nExpr, 1);
          387  +    /* Deliberately leave the affinity string off of the following
          388  +    ** OP_MakeRecord */
          389  +    sqlite3VdbeAddOp(v, OP_MakeRecord, pEList->nExpr * -1, 0);
   389    390       sqlite3VdbeAddOp(v, OP_Distinct, distinct, sqlite3VdbeCurrentAddr(v)+3);
   390    391       sqlite3VdbeAddOp(v, OP_Pop, pEList->nExpr+1, 0);
   391    392       sqlite3VdbeAddOp(v, OP_Goto, 0, iContinue);
   392    393       sqlite3VdbeAddOp(v, OP_String8, 0, 0);
   393    394       sqlite3VdbeAddOp(v, OP_PutStrKey, distinct, 0);
   394    395     }
   395    396   
................................................................................
   448    449         if( pOrderBy ){
   449    450           pushOntoSorter(pParse, v, pOrderBy);
   450    451         }else{
   451    452           char const *affStr;
   452    453           char aff = (iParm>>16)&0xFF;
   453    454           aff = sqlite3CompareAffinity(pEList->a[0].pExpr, aff);
   454    455           affStr = sqlite3AffinityString(aff);
   455         -        sqlite3VdbeOp3(v, OP_MakeKey, 1, 0, affStr, P3_STATIC);
          456  +        sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, affStr, P3_STATIC);
   456    457           sqlite3VdbeAddOp(v, OP_String8, 0, 0);
   457    458           sqlite3VdbeAddOp(v, OP_PutStrKey, (iParm&0x0000FFFF), 0);
   458    459         }
   459    460         sqlite3VdbeChangeP2(v, addr2, sqlite3VdbeCurrentAddr(v));
   460    461         break;
   461    462       }
   462    463   
................................................................................
   575    576         break;
   576    577       }
   577    578       case SRT_Set: {
   578    579         assert( nColumn==1 );
   579    580         sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
   580    581         sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
   581    582         sqlite3VdbeAddOp(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+3);
   582         -      sqlite3VdbeOp3(v, OP_MakeKey, 1, 0, "n", P3_STATIC);
          583  +      sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, "n", P3_STATIC);
   583    584         sqlite3VdbeAddOp(v, OP_String8, 0, 0);
   584    585         sqlite3VdbeAddOp(v, OP_PutStrKey, (iParm&0x0000FFFF), 0);
   585    586         break;
   586    587       }
   587    588       case SRT_Mem: {
   588    589         assert( nColumn==1 );
   589    590         sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
................................................................................
  2510   2511     else{
  2511   2512       AggExpr *pAgg;
  2512   2513       if( pGroupBy ){
  2513   2514         int lbl1;
  2514   2515         for(i=0; i<pGroupBy->nExpr; i++){
  2515   2516           sqlite3ExprCode(pParse, pGroupBy->a[i].pExpr);
  2516   2517         }
  2517         -      /* No affinity string is attached to the following OP_MakeKey 
         2518  +      /* No affinity string is attached to the following OP_MakeRecord 
  2518   2519         ** because we do not need to do any coercion of datatypes. */
  2519         -      sqlite3VdbeAddOp(v, OP_MakeKey, pGroupBy->nExpr, 0);
         2520  +      sqlite3VdbeAddOp(v, OP_MakeRecord, pGroupBy->nExpr, 0);
  2520   2521         lbl1 = sqlite3VdbeMakeLabel(v);
  2521   2522         sqlite3VdbeAddOp(v, OP_AggFocus, 0, lbl1);
  2522   2523         for(i=0, pAgg=pParse->aAgg; i<pParse->nAgg; i++, pAgg++){
  2523   2524           if( pAgg->isAgg ) continue;
  2524   2525           sqlite3ExprCode(pParse, pAgg->pExpr);
  2525   2526           sqlite3VdbeAddOp(v, OP_AggSet, 0, i);
  2526   2527         }

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.377 2004/06/16 12:02:54 danielk1977 Exp $
           46  +** $Id: vdbe.c,v 1.378 2004/06/17 07:53:03 danielk1977 Exp $
    47     47   */
    48     48   #include "sqliteInt.h"
    49     49   #include "os.h"
    50     50   #include <ctype.h>
    51     51   #include "vdbeInt.h"
    52     52   
    53     53   /*
................................................................................
  2088   2088     /* Release the aType[] memory if we are not dealing with cursor */
  2089   2089     if( !pC ){
  2090   2090       sqliteFree(aType);
  2091   2091     }
  2092   2092     break;
  2093   2093   }
  2094   2094   
  2095         -/* Opcode: MakeKey P1 P2 P3
  2096         -**
  2097         -** Convert the top P1 entries of the stack into a single entry suitable
  2098         -** for use as the key in an index. If P2 is zero, then the original 
  2099         -** entries are popped off the stack. If P2 is not zero, the original 
  2100         -** entries remain on the stack.
  2101         -**
  2102         -** P3 is interpreted in the same way as for MakeIdxKey.
  2103         -*/
  2104         -/* Opcode: MakeIdxKey P1 P2 P3
  2105         -**
  2106         -** Convert the top P1 entries of the stack into a single entry suitable
  2107         -** for use as the key in an index.  In addition, take one additional integer
  2108         -** off of the stack, treat that integer as an eight-byte record number, and
  2109         -** append the integer to the key as a varint.  Thus a total of P1+1 entries
  2110         -** are popped from the stack for this instruction and a single entry is
  2111         -** pushed back.  
  2112         -**
  2113         -** If P2 is not zero and one or more of the P1 entries that go into the
  2114         -** generated key is NULL, then jump to P2 after the new key has been
  2115         -** pushed on the stack.  In other words, jump to P2 if the key is
  2116         -** guaranteed to be unique.  This jump can be used to skip a subsequent
  2117         -** uniqueness test.
  2118         -**
  2119         -** P3 may be a string that is P1 characters long.  The nth character of the
  2120         -** string indicates the column affinity that should be used for the nth
  2121         -** field of the index key (i.e. the first character of P3 corresponds to the
  2122         -** lowest element on the stack).
  2123         -**
  2124         -**  Character      Column affinity
  2125         -**  ------------------------------
  2126         -**  'n'            NUMERIC
  2127         -**  'i'            INTEGER
  2128         -**  't'            TEXT
  2129         -**  'o'            NONE
  2130         -**
  2131         -** If P3 is NULL then no datatype coercion occurs.
  2132         -*/
  2133         -/* Opcode MakeRecord P1 * P3
  2134         -**
  2135         -** Convert the top P1 entries of the stack into a single entry
  2136         -** suitable for use as a data record in a database table.  The
  2137         -** details of the format are irrelavant as long as the OP_Column
  2138         -** opcode can decode the record later.  Refer to source code
  2139         -** comments for the details of the record format.
         2095  +/* Opcode MakeRecord P1 P2 P3
         2096  +**
         2097  +** Convert the top abs(P1) entries of the stack into a single entry
         2098  +** suitable for use as a data record in a database table or as a key
         2099  +** in an index.  The details of the format are irrelavant as long as
         2100  +** the OP_Column opcode can decode the record later and as long as the
         2101  +** sqlite3VdbeRecordCompare function will correctly compare two encoded
         2102  +** records.  Refer to source code comments for the details of the record
         2103  +** format.
         2104  +**
         2105  +** The original stack entries are popped from the stack if P1>0 but
         2106  +** remain on the stack if P1<0.
         2107  +**
         2108  +** The P2 argument is divided into two 16-bit words before it is processed.
         2109  +** If the hi-word is non-zero, then an extra integer is read from the stack
         2110  +** and appended to the record as a varint.  If the low-word of P2 is not
         2111  +** zero and one or more of the entries are NULL, then jump to the value of
         2112  +** the low-word of P2.  This feature can be used to skip a uniqueness test
         2113  +** on indices.
  2140   2114   **
  2141   2115   ** P3 may be a string that is P1 characters long.  The nth character of the
  2142   2116   ** string indicates the column affinity that should be used for the nth
  2143   2117   ** field of the index key (i.e. the first character of P3 corresponds to the
  2144   2118   ** lowest element on the stack).
  2145   2119   **
  2146   2120   **  Character      Column affinity
................................................................................
  2148   2122   **  'n'            NUMERIC
  2149   2123   **  'i'            INTEGER
  2150   2124   **  't'            TEXT
  2151   2125   **  'o'            NONE
  2152   2126   **
  2153   2127   ** If P3 is NULL then all index fields have the affinity NONE.
  2154   2128   */
  2155         -/* Opcode MakeRecord P1 P2 P3
  2156         -**
  2157         -** Convert the top abs(P1) entries of the stack into a single entry
  2158         -** suitable for use as a data record in a database table or as a key
  2159         -** in an index.  The details of the format are irrelavant as long as
  2160         -** the OP_Column opcode can decode the record later and as long as the
  2161         -** sqlite3VdbeRecordCompare function will correctly compare two encoded
  2162         -** records.  Refer to source code comments for the details of the record
  2163         -** format.
  2164         -**
  2165         -** The original stack entries are popped from the stack if P1>0 but
  2166         -** remain on the stack if P1<0.
  2167         -**
  2168         -** If P2 is not zero and one or more of the entries are NULL, then jump
  2169         -** to P2.  This feature can be used to skip a uniqueness test on indices.
  2170         -**
  2171         -** P3 may be a string that is P1 characters long.  The nth character of the
  2172         -** string indicates the column affinity that should be used for the nth
  2173         -** field of the index key (i.e. the first character of P3 corresponds to the
  2174         -** lowest element on the stack).
  2175         -**
  2176         -**  Character      Column affinity
  2177         -**  ------------------------------
  2178         -**  'n'            NUMERIC
  2179         -**  'i'            INTEGER
  2180         -**  't'            TEXT
  2181         -**  'o'            NONE
  2182         -**
  2183         -** If P3 is NULL then all index fields have the affinity NONE.
  2184         -*/
  2185         -case OP_MakeKey:
  2186         -case OP_MakeIdxKey:
  2187   2129   case OP_MakeRecord: {
  2188   2130     /* Assuming the record contains N fields, the record format looks
  2189   2131     ** like this:
  2190   2132     **
  2191   2133     ** ------------------------------------------------------------------------
  2192   2134     ** | hdr-size | type 0 | type 1 | ... | type N-1 | data0 | ... | data N-1 | 
  2193   2135     ** ------------------------------------------------------------------------
................................................................................
  2196   2138     ** the top of the stack.
  2197   2139     **
  2198   2140     ** Each type field is a varint representing the serial type of the 
  2199   2141     ** corresponding data element (see sqlite3VdbeSerialType()). The
  2200   2142     ** hdr-size field is also a varint which is the offset from the beginning
  2201   2143     ** of the record to data0.
  2202   2144     */
  2203         -  int nField = pOp->p1;
  2204   2145     unsigned char *zNewRecord;
  2205   2146     unsigned char *zCsr;
  2206         -  char *zAffinity;
  2207   2147     Mem *pRec;
  2208   2148     Mem *pRowid = 0;
  2209         -  int nData = 0;     /* Number of bytes of data space */
  2210         -  int nHdr = 0;      /* Number of bytes of header space */
  2211         -  int nByte = 0;     /* Space required for this record */
  2212         -  int addRowid;      /* True to append a rowid column at the end */
  2213         -  u32 serial_type;   /* Type field */
  2214         -  int containsNull;  /* True if any of the data fields are NULL */
  2215         -  char zTemp[NBFS];  /* Space to hold small records */
         2149  +  int nData = 0;         /* Number of bytes of data space */
         2150  +  int nHdr = 0;          /* Number of bytes of header space */
         2151  +  int nByte = 0;         /* Space required for this record */
         2152  +  u32 serial_type;       /* Type field */
         2153  +  int containsNull = 0;  /* True if any of the data fields are NULL */
         2154  +  char zTemp[NBFS];      /* Space to hold small records */
         2155  +  Mem *pData0;
  2216   2156   
  2217         -  Mem *pData0 = &pTos[1-nField];
  2218         -  assert( pData0>=p->aStack );
         2157  +  int leaveOnStack;      /* If true, leave the entries on the stack */
         2158  +  int nField;            /* Number of fields in the record */
         2159  +  int jumpIfNull;        /* Jump here if non-zero and any entries are NULL. */
         2160  +  int addRowid;          /* True to append a rowid column at the end */
         2161  +  char *zAffinity;       /* The affinity string for the record */
         2162  +
         2163  +  leaveOnStack = ((pOp->p1<0)?1:0);
         2164  +  nField = pOp->p1 * (leaveOnStack?-1:1);
         2165  +  jumpIfNull = (pOp->p2 & 0x00FFFFFF);
         2166  +  addRowid = ((pOp->p2>>24) & 0x0000FFFF)?1:0;
  2219   2167     zAffinity = pOp->p3;
  2220         -  addRowid = pOp->opcode==OP_MakeIdxKey;
         2168  +
         2169  +  pData0 = &pTos[1-nField];
         2170  +  assert( pData0>=p->aStack );
  2221   2171     containsNull = 0;
  2222   2172   
  2223   2173     /* Loop through the elements that will make up the record to figure
  2224   2174     ** out how much space is required for the new record.
  2225   2175     */
  2226   2176     for(pRec=pData0; pRec<=pTos; pRec++){
  2227   2177       if( zAffinity ){
................................................................................
  2289   2239     ** failed. This indicates a corrupted memory cell or code bug.
  2290   2240     */
  2291   2241     if( zCsr!=(zNewRecord+nByte) ){
  2292   2242       rc = SQLITE_INTERNAL;
  2293   2243       goto abort_due_to_error;
  2294   2244     }
  2295   2245   
  2296         -  /* Pop nField entries from the stack and push the new entry on */
  2297         -  if( addRowid || pOp->p2==0 ){
         2246  +  /* Pop entries off the stack if required. Push the new record on. */
         2247  +  if( !leaveOnStack ){
  2298   2248       popStack(&pTos, nField+addRowid);
  2299   2249     }
  2300   2250     pTos++;
  2301   2251     pTos->n = nByte;
  2302   2252     if( nByte<=sizeof(zTemp) ){
  2303   2253       assert( zNewRecord==(unsigned char *)zTemp );
  2304   2254       pTos->z = pTos->zShort;
................................................................................
  2307   2257     }else{
  2308   2258       assert( zNewRecord!=(unsigned char *)zTemp );
  2309   2259       pTos->z = zNewRecord;
  2310   2260       pTos->flags = MEM_Blob | MEM_Dyn;
  2311   2261       pTos->xDel = 0;
  2312   2262     }
  2313   2263   
  2314         -  /* If P2 is non-zero, and if the key contains a NULL value, and if this
  2315         -  ** was an OP_MakeIdxKey instruction, not OP_MakeKey, jump to P2.
  2316         -  */
  2317         -  if( pOp->p2 && containsNull && addRowid ){
  2318         -    pc = pOp->p2 - 1;
         2264  +  /* If a NULL was encountered and jumpIfNull is non-zero, take the jump. */
         2265  +  if( jumpIfNull && containsNull ){
         2266  +    pc = jumpIfNull - 1;
  2319   2267     }
  2320   2268     break;
  2321   2269   }
  2322   2270   
  2323   2271   /* Opcode: Statement P1 * *
  2324   2272   **
  2325   2273   ** Begin an individual statement transaction which is part of a larger

Changes to src/where.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 module contains C code that generates VDBE code used to process
    13     13   ** the WHERE clause of SQL statements.
    14     14   **
    15         -** $Id: where.c,v 1.106 2004/06/16 12:03:10 danielk1977 Exp $
           15  +** $Id: where.c,v 1.107 2004/06/17 07:53:04 danielk1977 Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   
    19     19   /*
    20     20   ** The query generator uses an array of instances of this structure to
    21     21   ** help it analyze the subexpressions of the WHERE clause.  Each WHERE
    22     22   ** clause subexpression is separated from the others by an AND operator.
................................................................................
   823    823         ** any of these values are NULL.  If they are, they will not match any
   824    824         ** index entries, so skip immediately to the next iteration of the loop */
   825    825         sqlite3VdbeAddOp(v, OP_NotNull, -nColumn, sqlite3VdbeCurrentAddr(v)+3);
   826    826         sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0);
   827    827         sqlite3VdbeAddOp(v, OP_Goto, 0, brk);
   828    828   
   829    829         /* Generate an index key from the top nColumn elements of the stack */
   830         -      sqlite3VdbeAddOp(v, OP_MakeKey, nColumn, 0);
          830  +      sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
   831    831         sqlite3IndexAffinityStr(v, pIdx);
   832    832         sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 0);
   833    833   
   834    834         /* Generate code (1) to move to the first matching element of the table.
   835    835         ** Then generate code (2) that jumps to "brk" after the cursor is past
   836    836         ** the last matching element of the table.  The code (1) is executed
   837    837         ** once to initialize the search, the code (2) is executed before each
................................................................................
  1025   1025         }
  1026   1026         if( testOp!=OP_Noop ){
  1027   1027           int nCol = nEqColumn + (score & 1);
  1028   1028           pLevel->iMem = pParse->nMem++;
  1029   1029           sqlite3VdbeAddOp(v, OP_NotNull, -nCol, sqlite3VdbeCurrentAddr(v)+3);
  1030   1030           sqlite3VdbeAddOp(v, OP_Pop, nCol, 0);
  1031   1031           sqlite3VdbeAddOp(v, OP_Goto, 0, brk);
  1032         -        sqlite3VdbeAddOp(v, OP_MakeKey, nCol, 0);
         1032  +        sqlite3VdbeAddOp(v, OP_MakeRecord, nCol, 0);
  1033   1033           sqlite3IndexAffinityStr(v, pIdx);
  1034   1034           if( pLevel->bRev ){
  1035   1035             int op = leFlag ? OP_MoveLe : OP_MoveLt;
  1036   1036             sqlite3VdbeAddOp(v, op, pLevel->iCur, brk);
  1037   1037           }else{
  1038   1038             sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
  1039   1039           }
................................................................................
  1079   1079           geFlag = 1;
  1080   1080         }
  1081   1081         if( nEqColumn>0 || (score&2)!=0 ){
  1082   1082           int nCol = nEqColumn + ((score&2)!=0);
  1083   1083           sqlite3VdbeAddOp(v, OP_NotNull, -nCol, sqlite3VdbeCurrentAddr(v)+3);
  1084   1084           sqlite3VdbeAddOp(v, OP_Pop, nCol, 0);
  1085   1085           sqlite3VdbeAddOp(v, OP_Goto, 0, brk);
  1086         -        sqlite3VdbeAddOp(v, OP_MakeKey, nCol, 0);
         1086  +        sqlite3VdbeAddOp(v, OP_MakeRecord, nCol, 0);
  1087   1087           sqlite3IndexAffinityStr(v, pIdx);
  1088   1088           if( pLevel->bRev ){
  1089   1089             pLevel->iMem = pParse->nMem++;
  1090   1090             sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
  1091   1091             testOp = OP_IdxLT;
  1092   1092           }else{
  1093   1093             int op = geFlag ? OP_MoveGe : OP_MoveGt;