aboutsummaryrefslogtreecommitdiff
path: root/src/select.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/select.c')
-rw-r--r--src/select.c77
1 files changed, 41 insertions, 36 deletions
diff --git a/src/select.c b/src/select.c
index 9eb6279c1..bde278b43 100644
--- a/src/select.c
+++ b/src/select.c
@@ -105,14 +105,14 @@ Select *sqlite3SelectNew(
ExprList *pGroupBy, /* the GROUP BY clause */
Expr *pHaving, /* the HAVING clause */
ExprList *pOrderBy, /* the ORDER BY clause */
- u16 selFlags, /* Flag parameters, such as SF_Distinct */
+ u32 selFlags, /* Flag parameters, such as SF_Distinct */
Expr *pLimit, /* LIMIT value. NULL means not used */
Expr *pOffset /* OFFSET value. NULL means no offset */
){
Select *pNew;
Select standin;
sqlite3 *db = pParse->db;
- pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) );
+ pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) );
if( pNew==0 ){
assert( db->mallocFailed );
pNew = &standin;
@@ -1016,7 +1016,7 @@ KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){
p->nRef = 1;
memset(&p[1], 0, nExtra);
}else{
- db->mallocFailed = 1;
+ sqlite3OomFault(db);
}
return p;
}
@@ -1677,7 +1677,7 @@ int sqlite3ColumnsFromExprList(
pCol->zName = zName;
sqlite3ColumnPropertiesFromName(0, pCol);
if( zName && sqlite3HashInsert(&ht, zName, pCol)==pCol ){
- db->mallocFailed = 1;
+ sqlite3OomFault(db);
}
}
sqlite3HashClear(&ht);
@@ -1688,7 +1688,7 @@ int sqlite3ColumnsFromExprList(
sqlite3DbFree(db, aCol);
*paCol = 0;
*pnCol = 0;
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
return SQLITE_OK;
}
@@ -1764,7 +1764,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
}
/* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside
** is disabled */
- assert( db->lookaside.bEnabled==0 );
+ assert( db->lookaside.bDisable );
pTab->nRef = 1;
pTab->zName = 0;
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
@@ -1845,8 +1845,9 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
VdbeComment((v, "LIMIT counter"));
if( n==0 ){
sqlite3VdbeGoto(v, iBreak);
- }else if( n>=0 && p->nSelectRow>(u64)n ){
- p->nSelectRow = n;
+ }else if( n>=0 && p->nSelectRow>sqlite3LogEst((u64)n) ){
+ p->nSelectRow = sqlite3LogEst((u64)n);
+ p->selFlags |= SF_FixedLimit;
}
}else{
sqlite3ExprCode(pParse, p->pLimit, iLimit);
@@ -1860,10 +1861,8 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
sqlite3ExprCode(pParse, p->pOffset, iOffset);
sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v);
VdbeComment((v, "OFFSET counter"));
- sqlite3VdbeAddOp3(v, OP_SetIfNotPos, iOffset, iOffset, 0);
- sqlite3VdbeAddOp3(v, OP_Add, iLimit, iOffset, iOffset+1);
+ sqlite3VdbeAddOp3(v, OP_OffsetLimit, iLimit, iOffset+1, iOffset);
VdbeComment((v, "LIMIT+OFFSET"));
- sqlite3VdbeAddOp3(v, OP_SetIfNotPos, iLimit, iOffset+1, -1);
}
}
}
@@ -2280,9 +2279,8 @@ static int multiSelect(
addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v);
VdbeComment((v, "Jump ahead if LIMIT reached"));
if( p->iOffset ){
- sqlite3VdbeAddOp3(v, OP_SetIfNotPos, p->iOffset, p->iOffset, 0);
- sqlite3VdbeAddOp3(v, OP_Add, p->iLimit, p->iOffset, p->iOffset+1);
- sqlite3VdbeAddOp3(v, OP_SetIfNotPos, p->iLimit, p->iOffset+1, -1);
+ sqlite3VdbeAddOp3(v, OP_OffsetLimit,
+ p->iLimit, p->iOffset+1, p->iOffset);
}
}
explainSetInteger(iSub2, pParse->iNextSelectId);
@@ -2290,12 +2288,12 @@ static int multiSelect(
testcase( rc!=SQLITE_OK );
pDelete = p->pPrior;
p->pPrior = pPrior;
- p->nSelectRow += pPrior->nSelectRow;
+ p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
if( pPrior->pLimit
&& sqlite3ExprIsInteger(pPrior->pLimit, &nLimit)
- && nLimit>0 && p->nSelectRow > (u64)nLimit
+ && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit)
){
- p->nSelectRow = nLimit;
+ p->nSelectRow = sqlite3LogEst((u64)nLimit);
}
if( addr ){
sqlite3VdbeJumpHere(v, addr);
@@ -2367,7 +2365,9 @@ static int multiSelect(
pDelete = p->pPrior;
p->pPrior = pPrior;
p->pOrderBy = 0;
- if( p->op==TK_UNION ) p->nSelectRow += pPrior->nSelectRow;
+ if( p->op==TK_UNION ){
+ p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
+ }
sqlite3ExprDelete(db, p->pLimit);
p->pLimit = pLimit;
p->pOffset = pOffset;
@@ -2502,7 +2502,7 @@ static int multiSelect(
nCol = p->pEList->nExpr;
pKeyInfo = sqlite3KeyInfoAlloc(db, nCol, 1);
if( !pKeyInfo ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto multi_select_end;
}
for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
@@ -2857,7 +2857,7 @@ static int multiSelectOrderBy(
}
if( j==nOrderBy ){
Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
- if( pNew==0 ) return SQLITE_NOMEM;
+ if( pNew==0 ) return SQLITE_NOMEM_BKPT;
pNew->flags |= EP_IntValue;
pNew->u.iValue = i;
pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
@@ -2873,10 +2873,11 @@ static int multiSelectOrderBy(
** to the right and the left are evaluated, they use the correct
** collation.
*/
- aPermute = sqlite3DbMallocRaw(db, sizeof(int)*nOrderBy);
+ aPermute = sqlite3DbMallocRawNN(db, sizeof(int)*(nOrderBy + 1));
if( aPermute ){
struct ExprList_item *pItem;
- for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){
+ aPermute[0] = nOrderBy;
+ for(i=1, pItem=pOrderBy->a; i<=nOrderBy; i++, pItem++){
assert( pItem->u.x.iOrderByCol>0 );
assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr );
aPermute[i] = pItem->u.x.iOrderByCol - 1;
@@ -2954,7 +2955,7 @@ static int multiSelectOrderBy(
pPrior->iLimit = regLimitA;
explainSetInteger(iSub1, pParse->iNextSelectId);
sqlite3Select(pParse, pPrior, &destA);
- sqlite3VdbeAddOp1(v, OP_EndCoroutine, regAddrA);
+ sqlite3VdbeEndCoroutine(v, regAddrA);
sqlite3VdbeJumpHere(v, addr1);
/* Generate a coroutine to evaluate the SELECT statement on
@@ -2971,7 +2972,7 @@ static int multiSelectOrderBy(
sqlite3Select(pParse, p, &destB);
p->iLimit = savedLimit;
p->iOffset = savedOffset;
- sqlite3VdbeAddOp1(v, OP_EndCoroutine, regAddrB);
+ sqlite3VdbeEndCoroutine(v, regAddrB);
/* Generate a subroutine that outputs the current row of the A
** select as the next output row of the compound select.
@@ -3003,7 +3004,7 @@ static int multiSelectOrderBy(
addrEofA_noB = sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, labelEnd);
VdbeCoverage(v);
sqlite3VdbeGoto(v, addrEofA);
- p->nSelectRow += pPrior->nSelectRow;
+ p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
}
/* Generate a subroutine to run when the results from select B
@@ -4093,7 +4094,7 @@ static int withExpand(
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid;
pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0);
- if( db->mallocFailed ) return SQLITE_NOMEM;
+ if( db->mallocFailed ) return SQLITE_NOMEM_BKPT;
assert( pFrom->pSelect );
/* Check if this is a recursive CTE. */
@@ -4438,8 +4439,7 @@ static int selectExpander(Walker *pWalker, Select *p){
pExpr = pRight;
}
pNew = sqlite3ExprListAppend(pParse, pNew, pExpr);
- sColname.z = zColname;
- sColname.n = sqlite3Strlen30(zColname);
+ sqlite3TokenInit(&sColname, zColname);
sqlite3ExprListSetName(pParse, pNew, &sColname, 0);
if( pNew && (p->selFlags & SF_NestedFrom)!=0 ){
struct ExprList_item *pX = &pNew->a[pNew->nExpr-1];
@@ -4990,10 +4990,10 @@ int sqlite3Select(
sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
sqlite3Select(pParse, pSub, &dest);
- pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow);
+ pItem->pTab->nRowLogEst = pSub->nSelectRow;
pItem->fg.viaCoroutine = 1;
pItem->regResult = dest.iSdst;
- sqlite3VdbeAddOp1(v, OP_EndCoroutine, pItem->regReturn);
+ sqlite3VdbeEndCoroutine(v, pItem->regReturn);
sqlite3VdbeJumpHere(v, addrTop-1);
sqlite3ClearTempRegCache(pParse);
}else{
@@ -5021,7 +5021,7 @@ int sqlite3Select(
sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
sqlite3Select(pParse, pSub, &dest);
- pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow);
+ pItem->pTab->nRowLogEst = pSub->nSelectRow;
if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn);
VdbeComment((v, "end %s", pItem->pTab->zName));
@@ -5104,7 +5104,7 @@ int sqlite3Select(
/* Set the limiter.
*/
iEnd = sqlite3VdbeMakeLabel(v);
- p->nSelectRow = LARGEST_INT64;
+ p->nSelectRow = 320; /* 4 billion rows */
computeLimitRegisters(pParse, p, iEnd);
if( p->iLimit==0 && sSort.addrSortIndex>=0 ){
sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen);
@@ -5128,10 +5128,12 @@ int sqlite3Select(
if( !isAgg && pGroupBy==0 ){
/* No aggregate functions and no GROUP BY clause */
u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0);
+ assert( WHERE_USE_LIMIT==SF_FixedLimit );
+ wctrlFlags |= p->selFlags & SF_FixedLimit;
/* Begin the database scan. */
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy,
- p->pEList, wctrlFlags, 0);
+ p->pEList, wctrlFlags, p->nSelectRow);
if( pWInfo==0 ) goto select_end;
if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){
p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo);
@@ -5191,9 +5193,11 @@ int sqlite3Select(
for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){
pItem->u.x.iAlias = 0;
}
- if( p->nSelectRow>100 ) p->nSelectRow = 100;
+ assert( 66==sqlite3LogEst(100) );
+ if( p->nSelectRow>66 ) p->nSelectRow = 66;
}else{
- p->nSelectRow = 1;
+ assert( 0==sqlite3LogEst(1) );
+ p->nSelectRow = 0;
}
/* If there is both a GROUP BY and an ORDER BY clause and they are
@@ -5565,7 +5569,8 @@ int sqlite3Select(
if( flag ){
pMinMax = sqlite3ExprListDup(db, pMinMax, 0);
pDel = pMinMax;
- if( pMinMax && !db->mallocFailed ){
+ assert( db->mallocFailed || pMinMax!=0 );
+ if( !db->mallocFailed ){
pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0;
pMinMax->a[0].pExpr->op = TK_COLUMN;
}