mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-14 00:22:38 +03:00
Changes to reduce the heap space consumed by triggers, views and tables in the in-memory representation of the schema. Also to reduce the space used by prepared statements slightly. (CVS 6305)
FossilOrigin-Name: d9f6ffbc5ea090ba0daac571fc9a6c68b9c864e4
This commit is contained in:
62
src/select.c
62
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.499 2009/02/09 13:19:28 drh Exp $
|
||||
** $Id: select.c,v 1.500 2009/02/19 14:39:25 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@@ -987,8 +987,9 @@ static const char *columnType(
|
||||
** statement.
|
||||
*/
|
||||
NameContext sNC;
|
||||
Select *pS = pExpr->pSelect;
|
||||
Select *pS = pExpr->x.pSelect;
|
||||
Expr *p = pS->pEList->a[0].pExpr;
|
||||
assert( ExprHasProperty(pExpr, EP_xIsSelect) );
|
||||
sNC.pSrcList = pS->pSrc;
|
||||
sNC.pNext = pNC;
|
||||
sNC.pParse = pNC->pParse;
|
||||
@@ -2141,7 +2142,7 @@ static int multiSelectOrderBy(
|
||||
/* Reattach the ORDER BY clause to the query.
|
||||
*/
|
||||
p->pOrderBy = pOrderBy;
|
||||
pPrior->pOrderBy = sqlite3ExprListDup(pParse->db, pOrderBy);
|
||||
pPrior->pOrderBy = sqlite3ExprListDup(pParse->db, pOrderBy, 0);
|
||||
|
||||
/* Allocate a range of temporary registers and the KeyInfo needed
|
||||
** for the logic that removes duplicate result rows when the
|
||||
@@ -2392,23 +2393,26 @@ static void substExpr(
|
||||
}else{
|
||||
Expr *pNew;
|
||||
assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
|
||||
assert( pExpr->pLeft==0 && pExpr->pRight==0 && pExpr->pList==0 );
|
||||
assert( pExpr->pLeft==0 && pExpr->pRight==0 );
|
||||
pNew = pEList->a[pExpr->iColumn].pExpr;
|
||||
assert( pNew!=0 );
|
||||
pExpr->op = pNew->op;
|
||||
assert( pExpr->pLeft==0 );
|
||||
pExpr->pLeft = sqlite3ExprDup(db, pNew->pLeft);
|
||||
pExpr->pLeft = sqlite3ExprDup(db, pNew->pLeft, 0);
|
||||
assert( pExpr->pRight==0 );
|
||||
pExpr->pRight = sqlite3ExprDup(db, pNew->pRight);
|
||||
assert( pExpr->pList==0 );
|
||||
pExpr->pList = sqlite3ExprListDup(db, pNew->pList);
|
||||
pExpr->pRight = sqlite3ExprDup(db, pNew->pRight, 0);
|
||||
pExpr->iTable = pNew->iTable;
|
||||
pExpr->pTab = pNew->pTab;
|
||||
pExpr->iColumn = pNew->iColumn;
|
||||
pExpr->iAgg = pNew->iAgg;
|
||||
sqlite3TokenCopy(db, &pExpr->token, &pNew->token);
|
||||
sqlite3TokenCopy(db, &pExpr->span, &pNew->span);
|
||||
pExpr->pSelect = sqlite3SelectDup(db, pNew->pSelect);
|
||||
assert( pExpr->x.pList==0 && pExpr->x.pSelect==0 );
|
||||
if( ExprHasProperty(pNew, EP_xIsSelect) ){
|
||||
pExpr->x.pSelect = sqlite3SelectDup(db, pNew->x.pSelect, 0);
|
||||
}else{
|
||||
pExpr->x.pList = sqlite3ExprListDup(db, pNew->x.pList, 0);
|
||||
}
|
||||
pExpr->flags = pNew->flags;
|
||||
pExpr->pAggInfo = pNew->pAggInfo;
|
||||
pNew->pAggInfo = 0;
|
||||
@@ -2416,8 +2420,11 @@ static void substExpr(
|
||||
}else{
|
||||
substExpr(db, pExpr->pLeft, iTable, pEList);
|
||||
substExpr(db, pExpr->pRight, iTable, pEList);
|
||||
substSelect(db, pExpr->pSelect, iTable, pEList);
|
||||
substExprList(db, pExpr->pList, iTable, pEList);
|
||||
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
|
||||
substSelect(db, pExpr->x.pSelect, iTable, pEList);
|
||||
}else{
|
||||
substExprList(db, pExpr->x.pList, iTable, pEList);
|
||||
}
|
||||
}
|
||||
}
|
||||
static void substExprList(
|
||||
@@ -2729,7 +2736,7 @@ static int flattenSubquery(
|
||||
p->pSrc = 0;
|
||||
p->pPrior = 0;
|
||||
p->pLimit = 0;
|
||||
pNew = sqlite3SelectDup(db, p);
|
||||
pNew = sqlite3SelectDup(db, p, 0);
|
||||
p->pLimit = pLimit;
|
||||
p->pOrderBy = pOrderBy;
|
||||
p->pSrc = pSrc;
|
||||
@@ -2873,7 +2880,7 @@ static int flattenSubquery(
|
||||
substExprList(db, pParent->pOrderBy, iParent, pSub->pEList);
|
||||
}
|
||||
if( pSub->pWhere ){
|
||||
pWhere = sqlite3ExprDup(db, pSub->pWhere);
|
||||
pWhere = sqlite3ExprDup(db, pSub->pWhere, 0);
|
||||
}else{
|
||||
pWhere = 0;
|
||||
}
|
||||
@@ -2883,9 +2890,9 @@ static int flattenSubquery(
|
||||
pParent->pWhere = pWhere;
|
||||
substExpr(db, pParent->pHaving, iParent, pSub->pEList);
|
||||
pParent->pHaving = sqlite3ExprAnd(db, pParent->pHaving,
|
||||
sqlite3ExprDup(db, pSub->pHaving));
|
||||
sqlite3ExprDup(db, pSub->pHaving, 0));
|
||||
assert( pParent->pGroupBy==0 );
|
||||
pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy);
|
||||
pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy, 0);
|
||||
}else{
|
||||
substExpr(db, pParent->pWhere, iParent, pSub->pEList);
|
||||
pParent->pWhere = sqlite3ExprAnd(db, pParent->pWhere, pWhere);
|
||||
@@ -2934,7 +2941,8 @@ static u8 minMaxQuery(Select *p){
|
||||
|
||||
if( pEList->nExpr!=1 ) return WHERE_ORDERBY_NORMAL;
|
||||
pExpr = pEList->a[0].pExpr;
|
||||
pEList = pExpr->pList;
|
||||
if( ExprHasProperty(pExpr, EP_xIsSelect) ) return 0;
|
||||
pEList = pExpr->x.pList;
|
||||
if( pExpr->op!=TK_AGG_FUNCTION || pEList==0 || pEList->nExpr!=1 ) return 0;
|
||||
if( pEList->a[0].pExpr->op!=TK_AGG_COLUMN ) return WHERE_ORDERBY_NORMAL;
|
||||
if( pExpr->token.n!=3 ) return WHERE_ORDERBY_NORMAL;
|
||||
@@ -3065,7 +3073,7 @@ static int selectExpander(Walker *pWalker, Select *p){
|
||||
** in the inner view.
|
||||
*/
|
||||
if( pFrom->pSelect==0 ){
|
||||
pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect);
|
||||
pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
|
||||
sqlite3WalkSelect(pWalker, pFrom->pSelect);
|
||||
}
|
||||
}
|
||||
@@ -3364,12 +3372,13 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, pFunc->iMem);
|
||||
if( pFunc->iDistinct>=0 ){
|
||||
Expr *pE = pFunc->pExpr;
|
||||
if( pE->pList==0 || pE->pList->nExpr!=1 ){
|
||||
assert( !ExprHasProperty(pE, EP_xIsSelect) );
|
||||
if( pE->x.pList==0 || pE->x.pList->nExpr!=1 ){
|
||||
sqlite3ErrorMsg(pParse, "DISTINCT aggregates must have exactly one "
|
||||
"argument");
|
||||
pFunc->iDistinct = -1;
|
||||
}else{
|
||||
KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->pList);
|
||||
KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList);
|
||||
sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0,
|
||||
(char*)pKeyInfo, P4_KEYINFO_HANDOFF);
|
||||
}
|
||||
@@ -3386,7 +3395,8 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){
|
||||
int i;
|
||||
struct AggInfo_func *pF;
|
||||
for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
|
||||
ExprList *pList = pF->pExpr->pList;
|
||||
ExprList *pList = pF->pExpr->x.pList;
|
||||
assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) );
|
||||
sqlite3VdbeAddOp4(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0, 0,
|
||||
(void*)pF->pFunc, P4_FUNCDEF);
|
||||
}
|
||||
@@ -3407,7 +3417,8 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
|
||||
int nArg;
|
||||
int addrNext = 0;
|
||||
int regAgg;
|
||||
ExprList *pList = pF->pExpr->pList;
|
||||
ExprList *pList = pF->pExpr->x.pList;
|
||||
assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) );
|
||||
if( pList ){
|
||||
nArg = pList->nExpr;
|
||||
regAgg = sqlite3GetTempRange(pParse, nArg);
|
||||
@@ -3657,7 +3668,7 @@ int sqlite3Select(
|
||||
** GROUP BY might use an index, DISTINCT never does.
|
||||
*/
|
||||
if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct && !p->pGroupBy ){
|
||||
p->pGroupBy = sqlite3ExprListDup(db, p->pEList);
|
||||
p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0);
|
||||
pGroupBy = p->pGroupBy;
|
||||
p->selFlags &= ~SF_Distinct;
|
||||
isDistinct = 0;
|
||||
@@ -3780,7 +3791,8 @@ int sqlite3Select(
|
||||
}
|
||||
sAggInfo.nAccumulator = sAggInfo.nColumn;
|
||||
for(i=0; i<sAggInfo.nFunc; i++){
|
||||
sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->pList);
|
||||
assert( !ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_xIsSelect) );
|
||||
sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->x.pList);
|
||||
}
|
||||
if( db->mallocFailed ) goto select_end;
|
||||
|
||||
@@ -4018,7 +4030,9 @@ int sqlite3Select(
|
||||
*/
|
||||
flag = minMaxQuery(p);
|
||||
if( flag ){
|
||||
pDel = pMinMax = sqlite3ExprListDup(db, p->pEList->a[0].pExpr->pList);
|
||||
assert( !ExprHasProperty(p->pEList->a[0].pExpr, EP_xIsSelect) );
|
||||
pMinMax = sqlite3ExprListDup(db, p->pEList->a[0].pExpr->x.pList,0);
|
||||
pDel = pMinMax;
|
||||
if( pMinMax && !db->mallocFailed ){
|
||||
pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0;
|
||||
pMinMax->a[0].pExpr->op = TK_COLUMN;
|
||||
|
||||
Reference in New Issue
Block a user