mirror of
				https://github.com/sqlite/sqlite.git
				synced 2025-11-03 16:53:36 +03:00 
			
		
		
		
	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) FossilOrigin-Name: 1c508a99822caa383e7e24b5d09a9bddd2ee3a00
This commit is contained in:
		
							
								
								
									
										20
									
								
								manifest
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								manifest
									
									
									
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
C Remove\sthe\srowhash\sobject\sfrom\sthe\scode.\s\sRowset\snow\sfills\sits\srole.\s(CVS\s6535)
 | 
					C Change\sthe\sOP_Rowid\sopcode\sso\sthat\sa\sdeferred\sOP_Seek\sis\spending,\sit\ssimply\npulls\sthe\srowid\sfrom\sthe\sdeferred\sseek\starget\sand\sdoes\snot\sactually\smove\nthe\scursor\sor\sdo\sa\sseek.\s\sOther\swhere.c\scleanups.\s(CVS\s6536)
 | 
				
			||||||
D 2009-04-22T02:15:48
 | 
					D 2009-04-22T15:32:59
 | 
				
			||||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 | 
					F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 | 
				
			||||||
F Makefile.in 583e87706abc3026960ed759aff6371faf84c211
 | 
					F Makefile.in 583e87706abc3026960ed759aff6371faf84c211
 | 
				
			||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
 | 
					F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
 | 
				
			||||||
@@ -154,12 +154,12 @@ F src/prepare.c 72d74e6d3b9c8eb0663b33ec6438aa718096ac79
 | 
				
			|||||||
F src/printf.c ea2d76000cc5f4579d7e9cb2f5460433eec0d384
 | 
					F src/printf.c ea2d76000cc5f4579d7e9cb2f5460433eec0d384
 | 
				
			||||||
F src/random.c 676b9d7ac820fe81e6fb2394ac8c10cff7f38628
 | 
					F src/random.c 676b9d7ac820fe81e6fb2394ac8c10cff7f38628
 | 
				
			||||||
F src/resolve.c 094e44450371fb27869eb8bf679aacbe51fdc56d
 | 
					F src/resolve.c 094e44450371fb27869eb8bf679aacbe51fdc56d
 | 
				
			||||||
F src/rowset.c ee0f774f20bf3fd27470603d2d56d1767bbe1013
 | 
					F src/rowset.c 14d12b5e81b5907b87d511f6f4219805f96a4b55
 | 
				
			||||||
F src/select.c 35225756c247484f473678e5bd191d70a6e4dba0
 | 
					F src/select.c 35225756c247484f473678e5bd191d70a6e4dba0
 | 
				
			||||||
F src/shell.c 0a11f831603f17fea20ca97133c0f64e716af4a7
 | 
					F src/shell.c 0a11f831603f17fea20ca97133c0f64e716af4a7
 | 
				
			||||||
F src/sqlite.h.in 8e0e256079bac2319380bdfebf403fcbe630510f
 | 
					F src/sqlite.h.in 8e0e256079bac2319380bdfebf403fcbe630510f
 | 
				
			||||||
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
 | 
					F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
 | 
				
			||||||
F src/sqliteInt.h dc64bc8198a2ad3532a996fcecda71ff89a578f0
 | 
					F src/sqliteInt.h b663bb04bc2d71d8f156f559ff267045de64787a
 | 
				
			||||||
F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
 | 
					F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
 | 
				
			||||||
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
 | 
					F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
 | 
				
			||||||
F src/table.c cc86ad3d6ad54df7c63a3e807b5783c90411a08d
 | 
					F src/table.c cc86ad3d6ad54df7c63a3e807b5783c90411a08d
 | 
				
			||||||
@@ -200,16 +200,16 @@ F src/update.c 8ededddcde6f7b6da981dd0429a5d34518a475b7
 | 
				
			|||||||
F src/utf.c 9541d28f40441812c0b40f00334372a0542c00ff
 | 
					F src/utf.c 9541d28f40441812c0b40f00334372a0542c00ff
 | 
				
			||||||
F src/util.c 828c552a22a1d5b650b8a5ea0009546715c45d93
 | 
					F src/util.c 828c552a22a1d5b650b8a5ea0009546715c45d93
 | 
				
			||||||
F src/vacuum.c 07121a727beeee88f27d704a00313ad6a7c9bef0
 | 
					F src/vacuum.c 07121a727beeee88f27d704a00313ad6a7c9bef0
 | 
				
			||||||
F src/vdbe.c 13f976672cd9d7fce04f9847d74da8c3b869a013
 | 
					F src/vdbe.c ff8870fd2a4a5a3f7f8d24e5d0f4e73c22402c4f
 | 
				
			||||||
F src/vdbe.h 35a648bc3279a120da24f34d9a25213ec15daf8a
 | 
					F src/vdbe.h 35a648bc3279a120da24f34d9a25213ec15daf8a
 | 
				
			||||||
F src/vdbeInt.h 8726f7b4e3b55c8acf6d304a5b5f727ac1b6c5ab
 | 
					F src/vdbeInt.h 8726f7b4e3b55c8acf6d304a5b5f727ac1b6c5ab
 | 
				
			||||||
F src/vdbeapi.c 015c9d0fb7047657a13a7bb6aa886f75e43db02d
 | 
					F src/vdbeapi.c 015c9d0fb7047657a13a7bb6aa886f75e43db02d
 | 
				
			||||||
F src/vdbeaux.c fdad66c73adb1c6ca6a0cd7a0f9517e5df758122
 | 
					F src/vdbeaux.c 34524d499fc6081e97771dcfdf6c2523d5877ef5
 | 
				
			||||||
F src/vdbeblob.c e67757450ae8581a8b354d9d7e467e41502dfe38
 | 
					F src/vdbeblob.c e67757450ae8581a8b354d9d7e467e41502dfe38
 | 
				
			||||||
F src/vdbemem.c 111d8193859d16aefd5d3cb57472808584ea5503
 | 
					F src/vdbemem.c 111d8193859d16aefd5d3cb57472808584ea5503
 | 
				
			||||||
F src/vtab.c 6118d71c5137e20a7ac51fb5d9beb0361fbedb89
 | 
					F src/vtab.c 6118d71c5137e20a7ac51fb5d9beb0361fbedb89
 | 
				
			||||||
F src/walker.c 7cdf63223c953d4343c6833e940f110281a378ee
 | 
					F src/walker.c 7cdf63223c953d4343c6833e940f110281a378ee
 | 
				
			||||||
F src/where.c 48f711d293486b43bf87ab3d1eeeebae50cb6839
 | 
					F src/where.c 576a21f6e0bb6651f3354b5cee7ecc67b935b2a5
 | 
				
			||||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
 | 
					F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
 | 
				
			||||||
F test/alias.test 597662c5d777a122f9a3df0047ea5c5bd383a911
 | 
					F test/alias.test 597662c5d777a122f9a3df0047ea5c5bd383a911
 | 
				
			||||||
F test/all.test 14165b3e32715b700b5f0cbf8f6e3833dda0be45
 | 
					F test/all.test 14165b3e32715b700b5f0cbf8f6e3833dda0be45
 | 
				
			||||||
@@ -720,7 +720,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
 | 
				
			|||||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 | 
					F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 | 
				
			||||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 | 
					F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 | 
				
			||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 | 
					F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 | 
				
			||||||
P b101cf70b75c9772aaf50e0eadd0cfa37c84d193
 | 
					P e963bed0fe3ce5fa32f04b930e5ed0956dc2aa47
 | 
				
			||||||
R 4b293c104cb64e8cb94e481dce760f86
 | 
					R 1585578003f3d07014cf9b3e3edcfb74
 | 
				
			||||||
U drh
 | 
					U drh
 | 
				
			||||||
Z 77e80e656a1a39cdd643ee53416f4c84
 | 
					Z e0df7c75ae1c0bc5ef9879b2922e6098
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1 +1 @@
 | 
				
			|||||||
e963bed0fe3ce5fa32f04b930e5ed0956dc2aa47
 | 
					1c508a99822caa383e7e24b5d09a9bddd2ee3a00
 | 
				
			||||||
							
								
								
									
										10
									
								
								src/rowset.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								src/rowset.c
									
									
									
									
									
								
							@@ -60,7 +60,7 @@
 | 
				
			|||||||
** There is an added cost of O(N) when switching between TEST and
 | 
					** There is an added cost of O(N) when switching between TEST and
 | 
				
			||||||
** SMALLEST primitives.
 | 
					** SMALLEST primitives.
 | 
				
			||||||
**
 | 
					**
 | 
				
			||||||
** $Id: rowset.c,v 1.5 2009/04/22 00:47:01 drh Exp $
 | 
					** $Id: rowset.c,v 1.6 2009/04/22 15:32:59 drh Exp $
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
#include "sqliteInt.h"
 | 
					#include "sqliteInt.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -277,9 +277,7 @@ static void rowSetTreeToList(
 | 
				
			|||||||
  struct RowSetEntry **ppFirst,    /* Write head of the output list here */
 | 
					  struct RowSetEntry **ppFirst,    /* Write head of the output list here */
 | 
				
			||||||
  struct RowSetEntry **ppLast      /* Write tail of the output list here */
 | 
					  struct RowSetEntry **ppLast      /* Write tail of the output list here */
 | 
				
			||||||
){
 | 
					){
 | 
				
			||||||
  if( pIn==0 ){
 | 
					  assert( pIn!=0 );
 | 
				
			||||||
    *ppFirst = *ppLast = 0;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  if( pIn->pLeft ){
 | 
					  if( pIn->pLeft ){
 | 
				
			||||||
    struct RowSetEntry *p;
 | 
					    struct RowSetEntry *p;
 | 
				
			||||||
    rowSetTreeToList(pIn->pLeft, ppFirst, &p);
 | 
					    rowSetTreeToList(pIn->pLeft, ppFirst, &p);
 | 
				
			||||||
@@ -344,9 +342,7 @@ static struct RowSetEntry *rowSetListToTree(struct RowSetEntry *pList){
 | 
				
			|||||||
  struct RowSetEntry *p;       /* Current tree root */
 | 
					  struct RowSetEntry *p;       /* Current tree root */
 | 
				
			||||||
  struct RowSetEntry *pLeft;   /* Left subtree */
 | 
					  struct RowSetEntry *pLeft;   /* Left subtree */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if( pList==0 ){
 | 
					  assert( pList!=0 );
 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  p = pList;
 | 
					  p = pList;
 | 
				
			||||||
  pList = p->pRight;
 | 
					  pList = p->pRight;
 | 
				
			||||||
  p->pLeft = p->pRight = 0;
 | 
					  p->pLeft = p->pRight = 0;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,7 @@
 | 
				
			|||||||
*************************************************************************
 | 
					*************************************************************************
 | 
				
			||||||
** Internal interface definitions for SQLite.
 | 
					** Internal interface definitions for SQLite.
 | 
				
			||||||
**
 | 
					**
 | 
				
			||||||
** @(#) $Id: sqliteInt.h,v 1.858 2009/04/22 02:15:48 drh Exp $
 | 
					** @(#) $Id: sqliteInt.h,v 1.859 2009/04/22 15:32:59 drh Exp $
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
#ifndef _SQLITEINT_H_
 | 
					#ifndef _SQLITEINT_H_
 | 
				
			||||||
#define _SQLITEINT_H_
 | 
					#define _SQLITEINT_H_
 | 
				
			||||||
@@ -219,6 +219,20 @@
 | 
				
			|||||||
# define TESTONLY(X)
 | 
					# define TESTONLY(X)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					** Sometimes we need a small amount of code such as a variable initialization
 | 
				
			||||||
 | 
					** to setup for a later assert() statement.  We do not want this code to
 | 
				
			||||||
 | 
					** appear when assert() is disabled.  The following macro is therefore
 | 
				
			||||||
 | 
					** used to contain that setup code.  The "VVA" acronym stands for
 | 
				
			||||||
 | 
					** "Verification, Validation, and Accreditation".  In other words, the
 | 
				
			||||||
 | 
					** code within VVA_ONLY() will only run during verification processes.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					#ifndef NDEBUG
 | 
				
			||||||
 | 
					# define VVA_ONLY(X)  X
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					# define VVA_ONLY(X)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
** The ALWAYS and NEVER macros surround boolean expressions which 
 | 
					** The ALWAYS and NEVER macros surround boolean expressions which 
 | 
				
			||||||
** are intended to always be true or false, respectively.  Such
 | 
					** are intended to always be true or false, respectively.  Such
 | 
				
			||||||
@@ -260,20 +274,6 @@
 | 
				
			|||||||
# define unlikely(X)  !!(X)
 | 
					# define unlikely(X)  !!(X)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
** Sometimes we need a small amount of code such as a variable initialization
 | 
					 | 
				
			||||||
** to setup for a later assert() statement.  We do not want this code to
 | 
					 | 
				
			||||||
** appear when assert() is disabled.  The following macro is therefore
 | 
					 | 
				
			||||||
** used to contain that setup code.  The "VVA" acronym stands for
 | 
					 | 
				
			||||||
** "Verification, Validation, and Accreditation".  In other words, the
 | 
					 | 
				
			||||||
** code within VVA_ONLY() will only run during verification processes.
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
#ifndef NDEBUG
 | 
					 | 
				
			||||||
# define VVA_ONLY(X)  X
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
# define VVA_ONLY(X)
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "sqlite3.h"
 | 
					#include "sqlite3.h"
 | 
				
			||||||
#include "hash.h"
 | 
					#include "hash.h"
 | 
				
			||||||
#include "parse.h"
 | 
					#include "parse.h"
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										30
									
								
								src/vdbe.c
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								src/vdbe.c
									
									
									
									
									
								
							@@ -43,7 +43,7 @@
 | 
				
			|||||||
** in this file for details.  If in doubt, do not deviate from existing
 | 
					** in this file for details.  If in doubt, do not deviate from existing
 | 
				
			||||||
** commenting and indentation practices when changing or adding code.
 | 
					** commenting and indentation practices when changing or adding code.
 | 
				
			||||||
**
 | 
					**
 | 
				
			||||||
** $Id: vdbe.c,v 1.837 2009/04/22 02:15:48 drh Exp $
 | 
					** $Id: vdbe.c,v 1.838 2009/04/22 15:32:59 drh Exp $
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
#include "sqliteInt.h"
 | 
					#include "sqliteInt.h"
 | 
				
			||||||
#include "vdbeInt.h"
 | 
					#include "vdbeInt.h"
 | 
				
			||||||
@@ -3905,19 +3905,23 @@ case OP_Rowid: {                 /* out2-prerelease */
 | 
				
			|||||||
  assert( i>=0 && i<p->nCursor );
 | 
					  assert( i>=0 && i<p->nCursor );
 | 
				
			||||||
  pC = p->apCsr[i];
 | 
					  pC = p->apCsr[i];
 | 
				
			||||||
  assert( pC!=0 );
 | 
					  assert( pC!=0 );
 | 
				
			||||||
  rc = sqlite3VdbeCursorMoveto(pC);
 | 
					  if( pC->deferredMoveto ){
 | 
				
			||||||
  if( rc ) goto abort_due_to_error;
 | 
					    v = pC->movetoTarget;
 | 
				
			||||||
  if( pC->rowidIsValid ){
 | 
					 | 
				
			||||||
    v = pC->lastRowid;
 | 
					 | 
				
			||||||
  }else if( pC->pseudoTable ){
 | 
					 | 
				
			||||||
    v = keyToInt(pC->iKey);
 | 
					 | 
				
			||||||
  }else if( pC->nullRow ){
 | 
					 | 
				
			||||||
    /* Leave the rowid set to a NULL */
 | 
					 | 
				
			||||||
    break;
 | 
					 | 
				
			||||||
  }else{
 | 
					  }else{
 | 
				
			||||||
    assert( pC->pCursor!=0 );
 | 
					    rc = sqlite3VdbeCursorMoveto(pC);
 | 
				
			||||||
    sqlite3BtreeKeySize(pC->pCursor, &v);
 | 
					    if( rc ) goto abort_due_to_error;
 | 
				
			||||||
    v = keyToInt(v);
 | 
					    if( pC->rowidIsValid ){
 | 
				
			||||||
 | 
					      v = pC->lastRowid;
 | 
				
			||||||
 | 
					    }else if( pC->pseudoTable ){
 | 
				
			||||||
 | 
					      v = keyToInt(pC->iKey);
 | 
				
			||||||
 | 
					    }else if( pC->nullRow ){
 | 
				
			||||||
 | 
					      /* Leave the rowid set to a NULL */
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    }else{
 | 
				
			||||||
 | 
					      assert( pC->pCursor!=0 );
 | 
				
			||||||
 | 
					      sqlite3BtreeKeySize(pC->pCursor, &v);
 | 
				
			||||||
 | 
					      v = keyToInt(v);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  pOut->u.i = v;
 | 
					  pOut->u.i = v;
 | 
				
			||||||
  MemSetTypeFlag(pOut, MEM_Int);
 | 
					  MemSetTypeFlag(pOut, MEM_Int);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@
 | 
				
			|||||||
** to version 2.8.7, all this code was combined into the vdbe.c source file.
 | 
					** to version 2.8.7, all this code was combined into the vdbe.c source file.
 | 
				
			||||||
** But that file was getting too big so this subroutines were split out.
 | 
					** But that file was getting too big so this subroutines were split out.
 | 
				
			||||||
**
 | 
					**
 | 
				
			||||||
** $Id: vdbeaux.c,v 1.453 2009/04/22 02:15:48 drh Exp $
 | 
					** $Id: vdbeaux.c,v 1.454 2009/04/22 15:32:59 drh Exp $
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
#include "sqliteInt.h"
 | 
					#include "sqliteInt.h"
 | 
				
			||||||
#include "vdbeInt.h"
 | 
					#include "vdbeInt.h"
 | 
				
			||||||
@@ -2002,8 +2002,8 @@ int sqlite3VdbeCursorMoveto(VdbeCursor *p){
 | 
				
			|||||||
    rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res);
 | 
					    rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res);
 | 
				
			||||||
    if( rc ) return rc;
 | 
					    if( rc ) return rc;
 | 
				
			||||||
    p->lastRowid = keyToInt(p->movetoTarget);
 | 
					    p->lastRowid = keyToInt(p->movetoTarget);
 | 
				
			||||||
    p->rowidIsValid = res==0 ?1:0;
 | 
					    p->rowidIsValid = ALWAYS(res==0) ?1:0;
 | 
				
			||||||
    if( res<0 ){
 | 
					    if( NEVER(res<0) ){
 | 
				
			||||||
      rc = sqlite3BtreeNext(p->pCursor, &res);
 | 
					      rc = sqlite3BtreeNext(p->pCursor, &res);
 | 
				
			||||||
      if( rc ) return rc;
 | 
					      if( rc ) return rc;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										37
									
								
								src/where.c
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								src/where.c
									
									
									
									
									
								
							@@ -16,7 +16,7 @@
 | 
				
			|||||||
** so is applicable.  Because this module is responsible for selecting
 | 
					** so is applicable.  Because this module is responsible for selecting
 | 
				
			||||||
** indices, you might also think of this module as the "query optimizer".
 | 
					** indices, you might also think of this module as the "query optimizer".
 | 
				
			||||||
**
 | 
					**
 | 
				
			||||||
** $Id: where.c,v 1.385 2009/04/22 02:15:49 drh Exp $
 | 
					** $Id: where.c,v 1.386 2009/04/22 15:32:59 drh Exp $
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
#include "sqliteInt.h"
 | 
					#include "sqliteInt.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -43,10 +43,8 @@ typedef struct WhereCost WhereCost;
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
** The query generator uses an array of instances of this structure to
 | 
					** The query generator uses an array of instances of this structure to
 | 
				
			||||||
** help it analyze the subexpressions of the WHERE clause.  Each WHERE
 | 
					** help it analyze the subexpressions of the WHERE clause.  Each WHERE
 | 
				
			||||||
** clause subexpression is separated from the others by AND operators.
 | 
					** clause subexpression is separated from the others by AND operators,
 | 
				
			||||||
** (Note: the same data structure is also reused to hold a group of terms
 | 
					** usually, or sometimes subexpressions separated by OR.
 | 
				
			||||||
** separated by OR operators.  But at the top-level, everything is AND
 | 
					 | 
				
			||||||
** separated.)
 | 
					 | 
				
			||||||
**
 | 
					**
 | 
				
			||||||
** All WhereTerms are collected into a single WhereClause structure.  
 | 
					** All WhereTerms are collected into a single WhereClause structure.  
 | 
				
			||||||
** The following identity holds:
 | 
					** The following identity holds:
 | 
				
			||||||
@@ -375,7 +373,7 @@ static void whereSplit(WhereClause *pWC, Expr *pExpr, int op){
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
** Initialize an expression mask set
 | 
					** Initialize an expression mask set (a WhereMaskSet object)
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
#define initMaskSet(P)  memset(P, 0, sizeof(*P))
 | 
					#define initMaskSet(P)  memset(P, 0, sizeof(*P))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2406,25 +2404,22 @@ static Bitmask codeOneLoopStart(
 | 
				
			|||||||
  int addrBrk;                    /* Jump here to break out of the loop */
 | 
					  int addrBrk;                    /* Jump here to break out of the loop */
 | 
				
			||||||
  int addrCont;                   /* Jump here to continue with next cycle */
 | 
					  int addrCont;                   /* Jump here to continue with next cycle */
 | 
				
			||||||
  int regRowSet;       /* Write rowids to this RowSet if non-negative */
 | 
					  int regRowSet;       /* Write rowids to this RowSet if non-negative */
 | 
				
			||||||
  int codeRowSetEarly; /* True if index fully constrains the search */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Sometimes, this function is required to generate code to do 
 | 
					  /* Sometimes, this function is required to generate code to do 
 | 
				
			||||||
  ** something with the rowid of each row scanned. Specifically:
 | 
					  ** something with the rowid of each row scanned. Specifically,
 | 
				
			||||||
  **
 | 
					  ** If pWInfo->regRowSet is non-zero, then the rowid must be inserted
 | 
				
			||||||
  **   1) If pWInfo->regRowSet is non-zero, then the rowid must be inserted
 | 
					  ** into the RowSet object stored in register pWInfo->regRowSet.
 | 
				
			||||||
  **      into the RowSet object stored in register pWInfo->regRowSet.
 | 
					 | 
				
			||||||
  **
 | 
					  **
 | 
				
			||||||
  ** Extracting a rowid value from a VDBE cursor is not always a cheap
 | 
					  ** Extracting a rowid value from a VDBE cursor is not always a cheap
 | 
				
			||||||
  ** operation, especially if the rowid is being extracted from an index
 | 
					  ** operation, especially if the rowid is being extracted from an index
 | 
				
			||||||
  ** cursor. If the rowid value is available as a by-product of the code
 | 
					  ** cursor. If the rowid value is available as a by-product of the code
 | 
				
			||||||
  ** generated to create the top of the scan loop, then it can be reused
 | 
					  ** generated to create the top of the scan loop, then it can be reused
 | 
				
			||||||
  ** without extracting
 | 
					  ** without extracting it from a cursor. The following two variables are
 | 
				
			||||||
  ** it from a cursor. The following two variables are used to communicate
 | 
					  ** used to communicate the availability of the rowid value to the C-code
 | 
				
			||||||
  ** the availability of the rowid value to the C-code at the end of this
 | 
					  ** at the end of this function that generates the rowid-handling VDBE code.
 | 
				
			||||||
  ** function that generates the rowid-handling VDBE code.
 | 
					 | 
				
			||||||
  */
 | 
					  */
 | 
				
			||||||
  int iRowidReg = 0;              /* Rowid is stored in this register */
 | 
					  int iRowidReg = 0;        /* Rowid is stored in this register, if not zero */
 | 
				
			||||||
  int iReleaseReg = 0;            /* Temp register to free before returning */
 | 
					  int iReleaseReg = 0;      /* Temp register to free before returning */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pParse = pWInfo->pParse;
 | 
					  pParse = pWInfo->pParse;
 | 
				
			||||||
  v = pParse->pVdbe;
 | 
					  v = pParse->pVdbe;
 | 
				
			||||||
@@ -2436,7 +2431,6 @@ static Bitmask codeOneLoopStart(
 | 
				
			|||||||
  omitTable = (pLevel->plan.wsFlags & WHERE_IDX_ONLY)!=0 
 | 
					  omitTable = (pLevel->plan.wsFlags & WHERE_IDX_ONLY)!=0 
 | 
				
			||||||
           && (wctrlFlags & WHERE_FILL_ROWTEST)==0;
 | 
					           && (wctrlFlags & WHERE_FILL_ROWTEST)==0;
 | 
				
			||||||
  regRowSet = pWInfo->regRowSet;
 | 
					  regRowSet = pWInfo->regRowSet;
 | 
				
			||||||
  codeRowSetEarly = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Create labels for the "break" and "continue" instructions
 | 
					  /* Create labels for the "break" and "continue" instructions
 | 
				
			||||||
  ** for the current loop.  Jump to addrBrk to break out of a loop.
 | 
					  ** for the current loop.  Jump to addrBrk to break out of a loop.
 | 
				
			||||||
@@ -2877,7 +2871,6 @@ static Bitmask codeOneLoopStart(
 | 
				
			|||||||
    sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset);
 | 
					    sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset);
 | 
				
			||||||
    iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn);
 | 
					    iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* iReleaseReg = iRowidReg = sqlite3GetTempReg(pParse); */
 | 
					 | 
				
			||||||
    for(ii=0; ii<pOrWc->nTerm; ii++){
 | 
					    for(ii=0; ii<pOrWc->nTerm; ii++){
 | 
				
			||||||
      WhereTerm *pOrTerm = &pOrWc->a[ii];
 | 
					      WhereTerm *pOrTerm = &pOrWc->a[ii];
 | 
				
			||||||
      if( pOrTerm->leftCursor==iCur || pOrTerm->eOperator==WO_AND ){
 | 
					      if( pOrTerm->leftCursor==iCur || pOrTerm->eOperator==WO_AND ){
 | 
				
			||||||
@@ -2895,6 +2888,7 @@ static Bitmask codeOneLoopStart(
 | 
				
			|||||||
          ** loop is not executed.
 | 
					          ** loop is not executed.
 | 
				
			||||||
          */
 | 
					          */
 | 
				
			||||||
          int iRowSet = pSubWInfo->iRowidHandler;
 | 
					          int iRowSet = pSubWInfo->iRowidHandler;
 | 
				
			||||||
 | 
					          assert( iRowSet>0 || pWInfo->pParse->db->mallocFailed );
 | 
				
			||||||
          sqlite3VdbeChangeP2(v, iRowSet, sqlite3VdbeCurrentAddr(v) + 1);
 | 
					          sqlite3VdbeChangeP2(v, iRowSet, sqlite3VdbeCurrentAddr(v) + 1);
 | 
				
			||||||
          sqlite3VdbeChangeP4(v, iRowSet, (char *)iSet, P4_INT32);
 | 
					          sqlite3VdbeChangeP4(v, iRowSet, (char *)iSet, P4_INT32);
 | 
				
			||||||
          sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody);
 | 
					          sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody);
 | 
				
			||||||
@@ -2991,12 +2985,13 @@ static Bitmask codeOneLoopStart(
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    pWInfo->iRowidHandler = sqlite3VdbeCurrentAddr(v);
 | 
					 | 
				
			||||||
    if( pWInfo->wctrlFlags&WHERE_FILL_ROWSET ){
 | 
					    if( pWInfo->wctrlFlags&WHERE_FILL_ROWSET ){
 | 
				
			||||||
      sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, iRowidReg);
 | 
					      sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, iRowidReg);
 | 
				
			||||||
 | 
					      VVA_ONLY( pWInfo->iRowidHandler = 0; )
 | 
				
			||||||
    }else{
 | 
					    }else{
 | 
				
			||||||
      assert( pWInfo->wctrlFlags&WHERE_FILL_ROWTEST );
 | 
					      assert( pWInfo->wctrlFlags&WHERE_FILL_ROWTEST );
 | 
				
			||||||
      sqlite3VdbeAddOp3(v, OP_RowSetTest, regRowSet, 0, iRowidReg);
 | 
					      pWInfo->iRowidHandler = 
 | 
				
			||||||
 | 
					        sqlite3VdbeAddOp3(v, OP_RowSetTest, regRowSet, 0, iRowidReg);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  sqlite3ReleaseTempReg(pParse, iReleaseReg);
 | 
					  sqlite3ReleaseTempReg(pParse, iReleaseReg);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user