diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/expr.c | 8 | ||||
-rw-r--r-- | src/select.c | 41 | ||||
-rw-r--r-- | src/sqliteInt.h | 14 | ||||
-rw-r--r-- | src/vdbe.h | 3 | ||||
-rw-r--r-- | src/vdbeaux.c | 15 |
5 files changed, 31 insertions, 50 deletions
diff --git a/src/expr.c b/src/expr.c index 857294739..f427c3fa6 100644 --- a/src/expr.c +++ b/src/expr.c @@ -12,7 +12,7 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.256 2006/03/06 20:55:46 drh Exp $ +** $Id: expr.c,v 1.257 2006/03/17 13:56:34 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -1381,11 +1381,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ ** expression we need to rerun this code each time. */ if( testAddr>0 && !sqlite3ExprIsConstant(pE2) ){ - VdbeOp *aOp = sqlite3VdbeGetOp(v, testAddr-1); - int j; - for(j=0; j<3; j++){ - aOp[j].opcode = OP_Noop; - } + sqlite3VdbeChangeToNoop(v, testAddr-1, 3); testAddr = 0; } diff --git a/src/select.c b/src/select.c index d1b6df2f7..7566c117e 100644 --- a/src/select.c +++ b/src/select.c @@ -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.308 2006/03/17 00:04:03 drh Exp $ +** $Id: select.c,v 1.309 2006/03/17 13:56:34 drh Exp $ */ #include "sqliteInt.h" @@ -411,22 +411,18 @@ static void codeOffset( ** seen combinations of the N values. A new entry is made in iTab ** if the current N values are new. ** -** A jump to addrRepeat is made and the K values are popped from the +** A jump to addrRepeat is made and the N+1 values are popped from the ** stack if the top N elements are not distinct. */ 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, /* The top N elements of the stack must be distinct */ - int K /* Pop K elements from the stack if indistinct */ + int N /* The top N elements of the stack must be distinct */ ){ -#if NULL_ALWAYS_DISTINCT - sqlite3VdbeAddOp(v, OP_IsNull, -N, sqlite3VdbeCurrentAddr(v)+6); -#endif sqlite3VdbeAddOp(v, OP_MakeRecord, -N, 0); sqlite3VdbeAddOp(v, OP_Distinct, iTab, sqlite3VdbeCurrentAddr(v)+3); - sqlite3VdbeAddOp(v, OP_Pop, K, 0); + sqlite3VdbeAddOp(v, OP_Pop, N+1, 0); sqlite3VdbeAddOp(v, OP_Goto, 0, addrRepeat); VdbeComment((v, "# skip indistinct records")); sqlite3VdbeAddOp(v, OP_IdxInsert, iTab, 0); @@ -487,8 +483,9 @@ static int selectInnerLoop( ** part of the result. */ if( hasDistinct ){ - int n = pEList->nExpr; - codeDistinct(v, distinct, iContinue, n, n+1); + assert( pEList!=0 ); + assert( pEList->nExpr==nColumn ); + codeDistinct(v, distinct, iContinue, nColumn); if( pOrderBy==0 ){ codeOffset(v, p, iContinue, nColumn); } @@ -500,7 +497,7 @@ static int selectInnerLoop( */ #ifndef SQLITE_OMIT_COMPOUND_SELECT case SRT_Union: { - sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, NULL_ALWAYS_DISTINCT); + sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0); if( aff ){ sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC); } @@ -514,7 +511,7 @@ static int selectInnerLoop( */ case SRT_Except: { int addr; - addr = sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, NULL_ALWAYS_DISTINCT); + addr = sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0); sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC); sqlite3VdbeAddOp(v, OP_NotFound, iParm, addr+3); sqlite3VdbeAddOp(v, OP_Delete, iParm, 0); @@ -1546,20 +1543,6 @@ static void createSortingIndex(Parse *pParse, Select *p, ExprList *pOrderBy){ } } -/* -** The opcode at addr is an OP_OpenVirtual that created a sorting -** index tha we ended up not needing. This routine changes that -** opcode to OP_Noop. -*/ -static void uncreateSortingIndex(Parse *pParse, int addr){ - Vdbe *v = pParse->pVdbe; - VdbeOp *pOp = sqlite3VdbeGetOp(v, addr); - sqlite3VdbeChangeP3(v, addr, 0, 0); - pOp->opcode = OP_Noop; - pOp->p1 = 0; - pOp->p2 = 0; -} - #ifndef SQLITE_OMIT_COMPOUND_SELECT /* ** Return the appropriate collating sequence for the iCol-th column of @@ -2693,7 +2676,7 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){ if( pF->iDistinct>=0 ){ addrNext = sqlite3VdbeMakeLabel(v); assert( nArg==1 ); - codeDistinct(v, pF->iDistinct, addrNext, 1, 2); + codeDistinct(v, pF->iDistinct, addrNext, 1); } if( pF->pFunc->needCollSeq ){ CollSeq *pColl = 0; @@ -2984,7 +2967,7 @@ int sqlite3Select( ** into an OP_Noop. */ if( addrSortIndex>=0 && pOrderBy==0 ){ - uncreateSortingIndex(pParse, addrSortIndex); + sqlite3VdbeChangeToNoop(v, addrSortIndex, 1); p->addrOpenVirt[2] = -1; } @@ -3230,7 +3213,7 @@ int sqlite3Select( sqlite3VdbeAddOp(v, OP_Next, sAggInfo.sortingIdx, addrTopOfLoop); }else{ sqlite3WhereEnd(pWInfo); - uncreateSortingIndex(pParse, addrSortingIdx); + sqlite3VdbeChangeToNoop(v, addrSortingIdx, 1); } /* Output the final row of result diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 93d7b9df1..719397dac 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.490 2006/03/17 00:04:04 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.491 2006/03/17 13:56:34 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -114,18 +114,6 @@ /* ** If the following macro is set to 1, then NULL values are considered -** distinct for the SELECT DISTINCT statement and for UNION or EXCEPT -** compound queries. No other SQL database engine (among those tested) -** works this way except for OCELOT. But the SQL92 spec implies that -** this is how things should work. -** -** If the following macro is set to 0, then NULLs are indistinct for -** SELECT DISTINCT and for UNION. -*/ -#define NULL_ALWAYS_DISTINCT 0 - -/* -** If the following macro is set to 1, then NULL values are considered ** distinct when determining whether or not two entries are the same ** in a UNIQUE index. This is the way PostgreSQL, Oracle, DB2, MySQL, ** OCELOT, and Firebird all work. The SQL92 spec explicitly says this diff --git a/src/vdbe.h b/src/vdbe.h index b79efcbd1..46045423d 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -15,7 +15,7 @@ ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** -** $Id: vdbe.h,v 1.101 2006/02/10 03:06:10 danielk1977 Exp $ +** $Id: vdbe.h,v 1.102 2006/03/17 13:56:34 drh Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ @@ -117,6 +117,7 @@ int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp); void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1); void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2); void sqlite3VdbeJumpHere(Vdbe*, int addr); +void sqlite3VdbeChangeToNoop(Vdbe*, int addr, int N); void sqlite3VdbeChangeP3(Vdbe*, int addr, const char *zP1, int N); VdbeOp *sqlite3VdbeGetOp(Vdbe*, int); int sqlite3VdbeMakeLabel(Vdbe*); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 4214352db..f5710b121 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -361,7 +361,7 @@ void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){ } /* -** Change teh P2 operand of instruction addr so that it points to +** Change the P2 operand of instruction addr so that it points to ** the address of the next instruction to be coded. */ void sqlite3VdbeJumpHere(Vdbe *p, int addr){ @@ -396,6 +396,19 @@ static void freeP3(int p3type, void *p3){ /* +** Change N opcodes starting at addr to No-ops. +*/ +void sqlite3VdbeChangeToNoop(Vdbe *p, int addr, int N){ + VdbeOp *pOp = &p->aOp[addr]; + while( N-- ){ + freeP3(pOp->p3type, pOp->p3); + memset(pOp, 0, sizeof(pOp[0])); + pOp->opcode = OP_Noop; + pOp++; + } +} + +/* ** Change the value of the P3 operand for a specific instruction. ** This routine is useful when a large program is loaded from a ** static array using sqlite3VdbeAddOpList but we want to make a |