-C Fix\sfor\sticket\s#813.\s(CVS\s1820)
-D 2004-07-19T19:30:50
+C Limit\soccurs\safter\sDISTINCT.\s\sTicket\s#749.\s(CVS\s1824)
+D 2004-07-19T23:33:03
F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
F src/pragma.c f9c157b0591419d2d3407dac90222020d2a6d822
F src/printf.c 378ec63d9303993eef24814a56a9fc7260aacbea
F src/random.c 775913e0b7fbd6295d21f12a7bd35b46387c44b2
-F src/select.c b8fe5c69d414af1a831593e41439f93e793874dc
+F src/select.c 894bdac9404d1a42097e0c9717b644f762bf9b5e
F src/shell.c 920af040d3a33ea8919c82cee45b424ad841cee0
F src/sqlite.h.in 35bec264dfb4965bbfeb7e75221f8658f210c30d
F src/sqliteInt.h 3e9203f16d12baf3a364fae9d64903d813651abd
F test/join2.test c97e4c5aa65dea462145529e58212a709b4722b8
F test/lastinsert.test 31382f88b9b0270333ac9e4a17f2c2f4732da718
F test/laststmtchanges.test cabd11bdfbaf73a4486c50b58297d9c2038ccc18
-F test/limit.test e28ce938ddacefdff860d082be45e1e5e2801441
+F test/limit.test c6365450f3180170c0fa1b0bf1ae48522c33b731
F test/lock.test 226ef831dad60ad4d200dc83e25479ba952aac7e
F test/main.test 6a851b5992c4881a725a3d9647e629199df8de9d
F test/malloc.test 2cfcffb7c858640e01e6520ee1cd54ca57d98e80
F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P 5ba0acd6c788b6ec07b29dc40c17265f8fb8a337
-R 04b738396073cd6e3f5def26476223ed
+P 0cc612f8aa458034d3dc246861c529c57ac5b2b1
+R ac26673074971ea42a1c00adb7738364
U drh
-Z e025b922d80b327cd770a3f0a861e529
+Z 92f099eb6b982fdc1c22acb201e5fa38
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
-** $Id: select.c,v 1.161.2.1 2004/07/18 21:14:05 drh Exp $
+** $Id: select.c,v 1.161.2.2 2004/07/19 23:33:03 drh Exp $
*/
#include "sqliteInt.h"
sqliteVdbeChangeP3(v, -1, zType, P3_DYNAMIC);
}
+/*
+** Add code to implement the OFFSET and LIMIT
+*/
+static void codeLimiter(
+ Vdbe *v, /* Generate code into this VM */
+ Select *p, /* The SELECT statement being coded */
+ int iContinue, /* Jump here to skip the current record */
+ int iBreak, /* Jump here to end the loop */
+ int nPop /* Number of times to pop stack when jumping */
+){
+ if( p->iOffset>=0 ){
+ int addr = sqliteVdbeCurrentAddr(v) + 2;
+ if( nPop>0 ) addr++;
+ sqliteVdbeAddOp(v, OP_MemIncr, p->iOffset, addr);
+ if( nPop>0 ){
+ sqliteVdbeAddOp(v, OP_Pop, nPop, 0);
+ }
+ sqliteVdbeAddOp(v, OP_Goto, 0, iContinue);
+ }
+ if( p->iLimit>=0 ){
+ sqliteVdbeAddOp(v, OP_MemIncr, p->iLimit, iBreak);
+ }
+}
+
/*
** This routine generates the code for the inside of the inner loop
** of a SELECT.
){
Vdbe *v = pParse->pVdbe;
int i;
+ int hasDistinct; /* True if the DISTINCT keyword is present */
if( v==0 ) return 0;
assert( pEList!=0 );
/* If there was a LIMIT clause on the SELECT statement, then do the check
** to see if this row should be output.
*/
- if( pOrderBy==0 ){
- if( p->iOffset>=0 ){
- int addr = sqliteVdbeCurrentAddr(v);
- sqliteVdbeAddOp(v, OP_MemIncr, p->iOffset, addr+2);
- sqliteVdbeAddOp(v, OP_Goto, 0, iContinue);
- }
- if( p->iLimit>=0 ){
- sqliteVdbeAddOp(v, OP_MemIncr, p->iLimit, iBreak);
- }
+ hasDistinct = distinct>=0 && pEList && pEList->nExpr>0;
+ if( pOrderBy==0 && !hasDistinct ){
+ codeLimiter(v, p, iContinue, iBreak, 0);
}
/* Pull the requested columns.
** and this row has been seen before, then do not make this row
** part of the result.
*/
- if( distinct>=0 && pEList && pEList->nExpr>0 ){
+ if( hasDistinct ){
#if NULL_ALWAYS_DISTINCT
sqliteVdbeAddOp(v, OP_IsNull, -pEList->nExpr, sqliteVdbeCurrentAddr(v)+7);
#endif
sqliteVdbeAddOp(v, OP_Goto, 0, iContinue);
sqliteVdbeAddOp(v, OP_String, 0, 0);
sqliteVdbeAddOp(v, OP_PutStrKey, distinct, 0);
+ if( pOrderBy==0 ){
+ codeLimiter(v, p, iContinue, iBreak, nColumn);
+ }
}
switch( eDest ){
if( eDest==SRT_Sorter ) return;
sqliteVdbeAddOp(v, OP_Sort, 0, 0);
addr = sqliteVdbeAddOp(v, OP_SortNext, 0, end1);
- if( p->iOffset>=0 ){
- sqliteVdbeAddOp(v, OP_MemIncr, p->iOffset, addr+4);
- sqliteVdbeAddOp(v, OP_Pop, 1, 0);
- sqliteVdbeAddOp(v, OP_Goto, 0, addr);
- }
- if( p->iLimit>=0 ){
- sqliteVdbeAddOp(v, OP_MemIncr, p->iLimit, end2);
- }
+ codeLimiter(v, p, addr, end2, 1);
switch( eDest ){
case SRT_Callback: {
sqliteVdbeAddOp(v, OP_SortCallback, nColumn, 0);