diff options
author | Ilia Alshanetsky <iliaa@php.net> | 2005-09-07 15:10:15 +0000 |
---|---|---|
committer | Ilia Alshanetsky <iliaa@php.net> | 2005-09-07 15:10:15 +0000 |
commit | 2195f7ec74c445404dd5d38378dadc956cf6fe60 (patch) | |
tree | 528f29ea6e1aa1986ac01f66f35ec783dec07885 /ext/sqlite/libsqlite/src/select.c | |
parent | 49cf0eff6a9880d751c7c4be872d3612969bc995 (diff) | |
download | php-git-2195f7ec74c445404dd5d38378dadc956cf6fe60.tar.gz |
Upgraded sqlite2 lib to 2.8.16
Diffstat (limited to 'ext/sqlite/libsqlite/src/select.c')
-rw-r--r-- | ext/sqlite/libsqlite/src/select.c | 76 |
1 files changed, 49 insertions, 27 deletions
diff --git a/ext/sqlite/libsqlite/src/select.c b/ext/sqlite/libsqlite/src/select.c index 871f2e2c71..c19c2bac86 100644 --- a/ext/sqlite/libsqlite/src/select.c +++ b/ext/sqlite/libsqlite/src/select.c @@ -365,6 +365,30 @@ void sqliteAddKeyType(Vdbe *v, ExprList *pEList){ } /* +** 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. ** @@ -388,6 +412,7 @@ static int selectInnerLoop( ){ Vdbe *v = pParse->pVdbe; int i; + int hasDistinct; /* True if the DISTINCT keyword is present */ if( v==0 ) return 0; assert( pEList!=0 ); @@ -395,15 +420,9 @@ static int selectInnerLoop( /* 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. @@ -423,7 +442,7 @@ static int selectInnerLoop( ** 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 @@ -434,6 +453,9 @@ static int selectInnerLoop( 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 ){ @@ -570,14 +592,7 @@ static void generateSortTail( 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); @@ -810,8 +825,9 @@ Table *sqliteResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){ }else{ char zBuf[30]; sprintf(zBuf, "column%d", i+1); - pTab->aCol[i].zName = sqliteStrDup(zBuf); + aCol[i].zName = sqliteStrDup(zBuf); } + sqliteDequote(aCol[i].zName); } pTab->iPKey = -1; return pTab; @@ -943,11 +959,11 @@ static int fillInColumnList(Parse *pParse, Select *p){ /* This expression is a "*" or a "TABLE.*" and needs to be ** expanded. */ int tableSeen = 0; /* Set to 1 when TABLE matches */ - Token *pName; /* text of name of TABLE */ + char *zTName; /* text of name of TABLE */ if( pE->op==TK_DOT && pE->pLeft ){ - pName = &pE->pLeft->token; + zTName = sqliteTableNameFromToken(&pE->pLeft->token); }else{ - pName = 0; + zTName = 0; } for(i=0; i<pTabList->nSrc; i++){ Table *pTab = pTabList->a[i].pTab; @@ -955,9 +971,8 @@ static int fillInColumnList(Parse *pParse, Select *p){ if( zTabName==0 || zTabName[0]==0 ){ zTabName = pTab->zName; } - if( pName && (zTabName==0 || zTabName[0]==0 || - sqliteStrNICmp(pName->z, zTabName, pName->n)!=0 || - zTabName[pName->n]!=0) ){ + if( zTName && (zTabName==0 || zTabName[0]==0 || + sqliteStrICmp(zTName, zTabName)!=0) ){ continue; } tableSeen = 1; @@ -1002,13 +1017,14 @@ static int fillInColumnList(Parse *pParse, Select *p){ } } if( !tableSeen ){ - if( pName ){ - sqliteErrorMsg(pParse, "no such table: %T", pName); + if( zTName ){ + sqliteErrorMsg(pParse, "no such table: %s", zTName); }else{ sqliteErrorMsg(pParse, "no tables specified"); } rc = 1; } + sqliteFree(zTName); } } sqliteExprListDelete(pEList); @@ -1916,6 +1932,12 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){ }else{ sqliteVdbeAddOp(v, OP_Integer, pIdx->iDb, 0); sqliteVdbeOp3(v, OP_OpenRead, base+1, pIdx->tnum, pIdx->zName, P3_STATIC); + if( seekOp==OP_Rewind ){ + sqliteVdbeAddOp(v, OP_String, 0, 0); + sqliteVdbeAddOp(v, OP_MakeKey, 1, 0); + sqliteVdbeAddOp(v, OP_IncrKey, 0, 0); + seekOp = OP_MoveTo; + } sqliteVdbeAddOp(v, seekOp, base+1, 0); sqliteVdbeAddOp(v, OP_IdxRecno, base+1, 0); sqliteVdbeAddOp(v, OP_Close, base+1, 0); |