]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Modify OP_RegMakeRec to take a base register and count and optionally
authordrh <drh@noemail.net>
Sat, 5 Jan 2008 18:48:24 +0000 (18:48 +0000)
committerdrh <drh@noemail.net>
Sat, 5 Jan 2008 18:48:24 +0000 (18:48 +0000)
store results in the register specified by P3. (CVS 4689)

FossilOrigin-Name: 6bb1b1bc1858028b743a4f660d42d5e9595dc022

manifest
manifest.uuid
src/build.c
src/select.c
src/sqliteInt.h
src/vdbe.c

index 4248e4d700a4ce28f002e958a65ecbcc8329ced9..8c9dd4e2fe7fd7eb670b0899e2158656c9d8ce7c 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\smemory\sleak\sintroduced\swith\s#4687.\s(CVS\s4688)
-D 2008-01-05T18:44:29
+C Modify\sOP_RegMakeRec\sto\stake\sa\sbase\sregister\sand\scount\sand\soptionally\nstore\sresults\sin\sthe\sregister\sspecified\sby\sP3.\s(CVS\s4689)
+D 2008-01-05T18:48:24
 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
 F Makefile.in 30789bf70614bad659351660d76b8e533f3340e9
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -86,7 +86,7 @@ F src/btmutex.c 5d39da37c9d1282f3c6f9967afae6a34ee36b7ff
 F src/btree.c 5164b32950cfd41f2c5c31e8ff82c4a499918aef
 F src/btree.h 19dcf5ad23c17b98855da548e9a8e3eb4429d5eb
 F src/btreeInt.h 1c5a9da165718ef7de81e35ce9ab5d9ba9283f76
-F src/build.c 60a3ec74b45634654e06a72224ac01bd33ac69f1
+F src/build.c 26690c519a4e4d77f128cf3e9865e63bec24afd0
 F src/callback.c 77b302b0d41468dcda78c70e706e5b84577f0fa0
 F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131
 F src/date.c 49c5a6d2de6c12000905b4d36868b07d3011bbf6
@@ -131,12 +131,12 @@ F src/pragma.c dfb200ec383b5ab3e81cd7bc4e1305e71053ef9a
 F src/prepare.c f1bb8eb642082e618a359c08e3e107490eafe0e3
 F src/printf.c eb27822ba2eec669161409ca31279a24c26ac910
 F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da
-F src/select.c fcde4b33ef106b64685ce842dc05e56e1c1116eb
+F src/select.c faf793d135bdc6136c38db898ccf05a28d634d87
 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
 F src/shell.c 5391e889384d2062249f668110d64ed16f601c4b
 F src/sqlite.h.in 2a7e3776534bbe6ff2cdc058f3abebe91e7e429f
 F src/sqlite3ext.h a93f59cdee3638dc0c9c086f80df743a4e68c3cb
-F src/sqliteInt.h 1e7a6545eda5e5e670000775f5d74003e0bc4fbb
+F src/sqliteInt.h 29a9502c0d9152580c3de8cb115da9aa8f9ce094
 F src/sqliteLimit.h ee4430f88f69bf63527967bb35ca52af7b0ccb1e
 F src/table.c 1aeb9eab57b4235db86fe15a35dec76fb445a9c4
 F src/tclsqlite.c 9923abeffc9b3d7dad58e92b319661521f60debf
@@ -168,7 +168,7 @@ F src/update.c f322317ee492c0a648f8a44fd805dd85dbbe2f05
 F src/utf.c ef4b7d83bae533b76c3e1bf635b113fdad86a736
 F src/util.c 05f31144bbd3f1a24f4139ae029c42545cb72624
 F src/vacuum.c 3f34f278809bf3eb0b62ec46ff779e9c385b28f0
-F src/vdbe.c 0c16e643e83c8f14364213c6862864f31dbadca3
+F src/vdbe.c 2dda056501489818fc5e1fc2d90454718a1c7a61
 F src/vdbe.h bb128757b84280504a1243c450fd13ead248ede5
 F src/vdbeInt.h 31bd686595356284d5484592e2dc6e58025aa346
 F src/vdbeapi.c f14174843bf4be2c9afdf2ef48b61e7c3ac62d7c
@@ -604,7 +604,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P c449e04f1870b1ff726c95c0bf1c6c6a22ca588a
-R 7feff0f8e24ec4a4191ddc4ce03d03a2
-U danielk1977
-Z 92958faf5e34756c3b8dada9d72fd997
+P 2b98b0fca82e285ae6b38384587aafa27985fa34
+R 39c27616db1d209bf42cb60b3febdbfc
+U drh
+Z d2a8f69e443e5ecf651b682bda1fceaf
index 3244264c626a802276391102053a1d6e61bdf924..9306d07a7ec52841e41abb047f834d7d59babdf8 100644 (file)
@@ -1 +1 @@
-2b98b0fca82e285ae6b38384587aafa27985fa34
\ No newline at end of file
+6bb1b1bc1858028b743a4f660d42d5e9595dc022
\ No newline at end of file
index 177c1e80563bd2042d1d8d2ba43616f65df2261f..0635fabc8c5ae002ca7f0c45196f4fddb40634d2 100644 (file)
@@ -22,7 +22,7 @@
 **     COMMIT
 **     ROLLBACK
 **
-** $Id: build.c,v 1.459 2008/01/05 05:20:10 drh Exp $
+** $Id: build.c,v 1.460 2008/01/05 18:48:24 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -1491,7 +1491,7 @@ void sqlite3EndTable(
     ** be redundant.
     */
     if( pSelect ){
-      SelectDest dest = {SRT_Table, 1, 0};
+      SelectDest dest = {SRT_Table, 0, 1};
       Table *pSelTab;
       sqlite3VdbeAddOp0(v, OP_Copy);
       sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, 0, iDb);
index 4a3c8c83c4f091c802ecdefd0452995c6f6c8460..98b64e52cdf82acd0709f14cc30a596ea1a7f740 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle SELECT statements in SQLite.
 **
-** $Id: select.c,v 1.388 2008/01/05 18:44:29 danielk1977 Exp $
+** $Id: select.c,v 1.389 2008/01/05 18:48:24 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -463,9 +463,10 @@ static void codeDistinct(
   Vdbe *v,           /* Generate code into this VM */
   int iTab,          /* A sorting index used to test for distinctness */
   int addrRepeat,    /* Jump to here if not distinct */
+  int N,             /* Number of elements */
   int iMem           /* First element */
 ){
-  sqlite3VdbeAddOp2(v, OP_RegMakeRec, iMem, 0);
+  sqlite3VdbeAddOp2(v, OP_RegMakeRec, iMem, N);
   sqlite3VdbeAddOp2(v, OP_Distinct, iTab, sqlite3VdbeCurrentAddr(v)+3);
   sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
   sqlite3VdbeAddOp2(v, OP_Goto, 0, addrRepeat);
@@ -541,19 +542,18 @@ static int selectInnerLoop(
   }else{
     n = pEList->nExpr;
   }
-  iMem = ++pParse->nMem;
-  pParse->nMem += n+1;
-  sqlite3VdbeAddOp2(v, OP_Integer, n, iMem);
+  iMem = pParse->nMem+1;
+  pParse->nMem += n;
   if( nColumn>0 ){
     for(i=0; i<nColumn; i++){
-      sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, iMem+i+1);
+      sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, iMem+i);
     }
   }else if( eDest!=SRT_Exists ){
     /* If the destination is an EXISTS(...) expression, the actual
     ** values returned by the SELECT are not required.
     */
     for(i=0; i<n; i++){
-      sqlite3ExprCode(pParse, pEList->a[i].pExpr, iMem+i+1);
+      sqlite3ExprCode(pParse, pEList->a[i].pExpr, iMem+i);
     }
   }
   nColumn = n;
@@ -565,7 +565,7 @@ static int selectInnerLoop(
   if( hasDistinct ){
     assert( pEList!=0 );
     assert( pEList->nExpr==nColumn );
-    codeDistinct(v, distinct, iContinue, iMem);
+    codeDistinct(v, distinct, iContinue, nColumn, iMem);
     if( pOrderBy==0 ){
       codeOffset(v, p, iContinue, nColumn);
     }
@@ -581,7 +581,7 @@ static int selectInnerLoop(
     */
 #ifndef SQLITE_OMIT_COMPOUND_SELECT
     case SRT_Union: {
-      sqlite3VdbeAddOp2(v, OP_RegMakeRec, iMem, 0);
+      sqlite3VdbeAddOp2(v, OP_RegMakeRec, iMem, nColumn);
       if( aff ){
         sqlite3VdbeChangeP4(v, -1, aff, P4_STATIC);
       }
@@ -595,7 +595,7 @@ static int selectInnerLoop(
     */
     case SRT_Except: {
       int addr;
-      addr = sqlite3VdbeAddOp2(v, OP_RegMakeRec, iMem, 0);
+      addr = sqlite3VdbeAddOp2(v, OP_RegMakeRec, iMem, nColumn);
       sqlite3VdbeChangeP4(v, -1, aff, P4_STATIC);
       sqlite3VdbeAddOp2(v, OP_NotFound, iParm, addr+3);
       sqlite3VdbeAddOp2(v, OP_Delete, iParm, 0);
@@ -607,7 +607,7 @@ static int selectInnerLoop(
     */
     case SRT_Table:
     case SRT_EphemTab: {
-      sqlite3VdbeAddOp2(v, OP_RegMakeRec, iMem, 0);
+      sqlite3VdbeAddOp2(v, OP_RegMakeRec, iMem, nColumn);
       if( pOrderBy ){
         pushOntoSorter(pParse, pOrderBy, p);
       }else{
@@ -627,17 +627,17 @@ static int selectInnerLoop(
       int addr2;
 
       assert( nColumn==1 );
-      addr2 = sqlite3VdbeAddOp2(v, OP_IfMemNull, iMem+1, 0);
+      addr2 = sqlite3VdbeAddOp2(v, OP_IfMemNull, iMem, 0);
       p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affinity);
       if( pOrderBy ){
         /* At first glance you would think we could optimize out the
         ** ORDER BY in this case since the order of entries in the set
         ** does not matter.  But there might be a LIMIT clause, in which
         ** case the order does matter */
-        sqlite3VdbeAddOp2(v, OP_SCopy, iMem+1, 0);
+        sqlite3VdbeAddOp2(v, OP_SCopy, iMem, 0);
         pushOntoSorter(pParse, pOrderBy, p);
       }else{
-        sqlite3VdbeAddOp4(v, OP_RegMakeRec, iMem, 0, 0, &p->affinity, 1);
+        sqlite3VdbeAddOp4(v, OP_RegMakeRec, iMem, 1, 0, &p->affinity, 1);
         sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, 0);
       }
       sqlite3VdbeJumpHere(v, addr2);
@@ -658,7 +658,7 @@ static int selectInnerLoop(
     */
     case SRT_Mem: {
       assert( nColumn==1 );
-      sqlite3VdbeAddOp2(v, OP_SCopy, iMem+1, 0);
+      sqlite3VdbeAddOp2(v, OP_SCopy, iMem, 0);
       if( pOrderBy ){
         pushOntoSorter(pParse, pOrderBy, p);
       }else{
@@ -676,13 +676,13 @@ static int selectInnerLoop(
     case SRT_Subroutine:
     case SRT_Callback: {
       if( pOrderBy ){
-        sqlite3VdbeAddOp2(v, OP_RegMakeRec, iMem, 0);
+        sqlite3VdbeAddOp2(v, OP_RegMakeRec, iMem, nColumn);
         pushOntoSorter(pParse, pOrderBy, p);
       }else if( eDest==SRT_Subroutine ){
-        for(i=0; i<nColumn; i++) sqlite3VdbeAddOp2(v, OP_SCopy, iMem+i+1, 0);
+        for(i=0; i<nColumn; i++) sqlite3VdbeAddOp2(v, OP_SCopy, iMem+i, 0);
         sqlite3VdbeAddOp2(v, OP_Gosub, 0, iParm);
       }else{
-        sqlite3VdbeAddOp2(v, OP_ResultRow, iMem+1, nColumn);
+        sqlite3VdbeAddOp2(v, OP_ResultRow, iMem, nColumn);
       }
       break;
     }
index 53acb136f3c6a3c71e13b7846b31def2c5958e68..762bc250b2f299e5b3dd9e90cdcefe2e56880e57 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.639 2008/01/05 17:39:30 danielk1977 Exp $
+** @(#) $Id: sqliteInt.h,v 1.640 2008/01/05 18:48:24 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -1353,9 +1353,9 @@ struct Select {
 */
 typedef struct SelectDest SelectDest;
 struct SelectDest {
-  int eDest;        /* How to dispose of the results */
+  u8 eDest;         /* How to dispose of the results */
+  u8 affinity;      /* Affinity used when eDest==SRT_Set */
   int iParm;        /* A parameter used by the eDest disposal method */
-  int affinity;     /* Affinity used when eDest==SRT_Set */
 };
 
 /*
index 711653432a8a92c2dc487b0ca17e133af97c353f..8985e8a6d011687da0bd1d0ff0be9abf911a7a8d 100644 (file)
@@ -43,7 +43,7 @@
 ** in this file for details.  If in doubt, do not deviate from existing
 ** commenting and indentation practices when changing or adding code.
 **
-** $Id: vdbe.c,v 1.684 2008/01/05 16:29:28 drh Exp $
+** $Id: vdbe.c,v 1.685 2008/01/05 18:48:24 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -2131,6 +2131,25 @@ case OP_IsNull: {            /* same as TK_ISNULL, no-push, jump */
   break;
 }
 
+/* Opcode: AnyNull P1 P2 P3 * *
+**
+** Check P3 registers beginning with P1.  If any are NULL then jump
+** to P2.
+*/
+case OP_AnyNull: {            /* no-push, jump, in1 */
+  int n = pOp->p3;
+  assert( n>0 && pOp->p1+n<=p->nMem );
+  while( n>0 ){
+    if( pIn1->flags & MEM_Null ){
+      pc = pOp->p2-1;
+      break;
+    }
+    n--;
+    pIn1++;
+  }
+  break;
+}
+
 /* Opcode: NotNull P1 P2 *
 **
 ** Jump to P2 if the top abs(P1) values on the stack are all not NULL.  
@@ -2463,12 +2482,13 @@ op_column_out:
 ** This results in an index key.
 */
 /*
-** Opcode: RegMakeRec P1 P2 P4
+** Opcode: RegMakeRec P1 P2 P3 P4 *
 **
-** Works like OP_MakeRecord except data is taken from registers
-** rather than from the stack.  The P1 register is an integer which
-** is the number of register to use in building the new record.
-** Data is taken from P1+1, P1+2, ..., P1+mem[P1].
+** Builds a record like OP_MakeRecord.  But the data is taken from
+** P2 registers beginning with P1:  P1, P1+1, P1+2, ..., P1+P2-1.
+** The result is written into P3 or pushed onto the stack if P3 is zero.
+** There is no jump on NULL - that can be done with a separate
+** OP_AnyNull opcode.
 */
 /*
 ** Opcode: RegMakeIRec P1 P2 P4
@@ -2526,21 +2546,18 @@ case OP_MakeRecord: {        /* jump */
     leaveOnStack = 0;
     nField = pOp->p1;
   }
-  jumpIfNull = pOp->p2;
   addRowid = pOp->opcode==OP_MakeIdxRec || pOp->opcode==OP_RegMakeIRec;
   zAffinity = pOp->p4.z;
 
   if( pOp->opcode==OP_RegMakeRec || pOp->opcode==OP_RegMakeIRec ){
-    Mem *pCount;
-    assert( nField>0 && nField<=p->nMem );
-    pCount = &p->aMem[nField];
-    assert( pCount->flags & MEM_Int );
-    assert( pCount->u.i>0 && pCount->u.i+nField<=p->nMem );
+    assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=p->nMem );
+    pData0 = &p->aMem[nField];
+    nField = pOp->p2;
     leaveOnStack = 1;
-    nField = pCount->u.i;
-    pData0 = &pCount[1];
+    jumpIfNull = 0;
     pLast = &pData0[nField-1];
   }else{
+    jumpIfNull = pOp->p2;
     pData0 = &pTos[1-nField];
     pLast = pTos;
     assert( pData0>=p->aStack );
@@ -2630,24 +2647,29 @@ case OP_MakeRecord: {        /* jump */
   if( !leaveOnStack ){
     popStack(&pTos, nField+addRowid);
   }
-  pTos++;
-  pTos->n = nByte;
+  if( pOp->p3==0 ){
+    pOut = ++pTos;
+  }else{
+    pOut = &p->aMem[pOp->p3];
+    Release(pOut);
+  }
+  pOut->n = nByte;
   if( nByte<=sizeof(zTemp) ){
     assert( zNewRecord==(unsigned char *)zTemp );
-    pTos->z = pTos->zShort;
-    memcpy(pTos->zShort, zTemp, nByte);
-    pTos->flags = MEM_Blob | MEM_Short;
+    pOut->z = pOut->zShort;
+    memcpy(pOut->zShort, zTemp, nByte);
+    pOut->flags = MEM_Blob | MEM_Short;
   }else{
     assert( zNewRecord!=(unsigned char *)zTemp );
-    pTos->z = (char*)zNewRecord;
-    pTos->flags = MEM_Blob | MEM_Dyn;
-    pTos->xDel = 0;
+    pOut->z = (char*)zNewRecord;
+    pOut->flags = MEM_Blob | MEM_Dyn;
+    pOut->xDel = 0;
   }
   if( nZero ){
-    pTos->u.i = nZero;
-    pTos->flags |= MEM_Zero;
+    pOut->u.i = nZero;
+    pOut->flags |= MEM_Zero;
   }
-  pTos->enc = SQLITE_UTF8;  /* In case the blob is ever converted to text */
+  pOut->enc = SQLITE_UTF8;  /* In case the blob is ever converted to text */
 
   /* If a NULL was encountered and jumpIfNull is non-zero, take the jump. */
   if( jumpIfNull && containsNull ){