Compare commits

...

1 Commits

Author SHA1 Message Date
drh 4ec7960eaf Crazy experimental change to refcount the AggInfo objects.
FossilOrigin-Name: 9a4cc1dbf2a605ccda495ceb8e33cdc95f3436dbc11a1fa8aee4918b125fae90
2020-06-09 14:56:01 +00:00
7 changed files with 77 additions and 102 deletions
+13 -10
View File
@@ -1,5 +1,5 @@
C Give\sthe\sexpression\spointer\sfields\sof\sAggInfo\sdistinctive\snames\sin\sorder\sto\nsimplify\stracking\sof\sall\stheir\suses.
D 2020-06-09T13:38:12.505
C Crazy\sexperimental\schange\sto\srefcount\sthe\sAggInfo\sobjects.
D 2020-06-09T14:56:01.543
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -485,7 +485,7 @@ F src/date.c b29b349d277e3d579dcc295b24c0a2caed83fd8f090a9f7cbe6070c0fd662384
F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
F src/dbstat.c 793deaf88a0904f88285d93d6713c636d55ede0ffd9f08d10f4ea825531d367f
F src/delete.c 88047c8e59878c920fce14582bc1dde4d81157d1ca5ffdf36c2907e6d41996c4
F src/expr.c 5afb8dd59d5617e0eb25f91143ed042b6cd99c006352bdbd441cb9638d2602d8
F src/expr.c 87f1d6b0b25dd3ffb980c6a4119ca745220a2dc6b32a3625cdaeb8788b6975f0
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c 4b575423b0a5d4898b1a7868ce985cf1a8ad91c741c9abbb108ff02536d20f41
F src/func.c 2333eb4277f55a5efdc12ef754e7d7ec9105d257b2fd00301d23ce1e8fa67dc0
@@ -528,17 +528,17 @@ F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a
F src/pragma.c 1b0db48177e52b256c003b8dc6ac708b1079a82cded944a23820574586a4731f
F src/pragma.h 8168e588536bffd95319451f34e9a754dc37d205ebe433031a7813c5b286beae
F src/prepare.c bb996921a85590418f951f27566216646fad2d6856ba131b21594862055b1bd7
F src/prepare.c aeb3ba661e2666dab15c4b5c55f6eb816f01d20e35fa860bb807e4a3b36e1e27
F src/printf.c 94b5419ad0a17269f76a9e968ca19cf9fa37617abed2e246fc48844e511b6bc6
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
F src/resolve.c c2008519a0654f1e7490e9281ed0397d0f14bb840d81f0b96946248afcbdb25d
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
F src/select.c a1f5efdbbfae1f73746242b43daedc974a4ae702d62c305219da650ec10fb08f
F src/select.c 0944abec9afc89dfb89f366a021070af9d676e089edb4e529fdd0225fa23a50d
F src/shell.c.in c6e26593f2738eefded08a39204bf6b48db135cdfaa458c26ffe57055b4fe365
F src/sqlite.h.in 74342b41e9d68ff9e56b192009046f8dd0aa2bd76ce1a588f330de614ba61de7
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 2d1af80082edffd71c6f96f70ad1ce6a4fb46615ad10291fc77fe0dea9ff0197
F src/sqliteInt.h 8fddd3ff00bb5983c45fbe891c9c4134b5d4799d8816a1e97cba38dc66aca4c2
F src/sqliteInt.h 6c523dc65a4886d2fe943ae0e9a78b1e2c31e1e3689f247ea194737f49aadc13
F src/sqliteLimit.h 95cb8479ca459496d9c1c6a9f76b38aee12203a56ce1092fe13e50ae2454c032
F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@@ -624,7 +624,7 @@ F src/where.c 7bcc07ff56d03d73308245135d96de46d2faeaee628bd4badf0bae60ae6a31fe
F src/whereInt.h 6b874aa15f94e43a2cec1080be64d955b04deeafeac90ffb5d6975c0d511be3c
F src/wherecode.c 7b939de85d65cc4b4bfa197513136b9e0ae03167e3b82842ca5a0ba1055ba65d
F src/whereexpr.c 264d58971eaf8256eb5b0917bcd7fc7a1f1109fdda183a8382308a1b18a2dce7
F src/window.c 7d19c08b62b70d5dc2ef4c098cc5ba611fac246a111fa36ebb39505415124b90
F src/window.c ce5e05bb8fab2fafe5b10da8960a71257a6ce876e0e5e90a18712d5831e76745
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
@@ -1867,7 +1867,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P b5711b4eead10ef4b0b61f2e2c54768d215a4105f6d47d2ea78991b6e53a6831
R 45115571336eb976de1e3114a0d3911d
P a53bdd311c4154fd5e1131efbb9665362f79db5a35ce9f7b1547f74b8ee2d8ba
R 3ee13eb60634ef4149de2b3557feb11d
T *branch * refcount-agginfo
T *sym-refcount-agginfo *
T -sym-trunk *
U drh
Z b9fb75855deff6080f9952a1c1c95794
Z 3bf31ff6e0ee54933573322b2a2bdccc
+1 -1
View File
@@ -1 +1 @@
a53bdd311c4154fd5e1131efbb9665362f79db5a35ce9f7b1547f74b8ee2d8ba
9a4cc1dbf2a605ccda495ceb8e33cdc95f3436dbc11a1fa8aee4918b125fae90
+49 -54
View File
@@ -1135,8 +1135,17 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
#endif
}
}
if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
if( !ExprHasProperty(p, EP_Static) ){
if( ExprHasProperty(p, EP_MemToken|EP_AggInfo|EP_Static) ){
if( ExprHasProperty(p, EP_MemToken) ){
sqlite3DbFree(db, p->u.zToken);
}
if( ExprHasProperty(p, EP_AggInfo) ){
sqlite3AggInfoUnref(db, p->pAggInfo, p);
}
if( !ExprHasProperty(p, EP_Static) ){
sqlite3DbFreeNN(db, p);
}
}else{
sqlite3DbFreeNN(db, p);
}
}
@@ -1371,6 +1380,11 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
}
}
if( ExprHasProperty(p, EP_AggInfo) ){
p->pAggInfo->nAggRef++;
//printf("AggInfo (%d/%p) up to %d on dup\n", p->pAggInfo->selId, p->pAggInfo, p->pAggInfo->nAggRef); fflush(stdout);
}
}
return pNew;
}
@@ -5715,61 +5729,34 @@ int sqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){
}
/*
** This is a Walker expression node callback.
** Decrement the reference count on pAggInfo. Delete it when the
** reference count reaches zero.
**
** For Expr nodes that contain pAggInfo pointers, make sure the AggInfo
** object that is referenced does not refer directly to the Expr. If
** it does, make a copy. This is done because the pExpr argument is
** subject to change.
**
** The copy is stored on pParse->pConstExpr with a register number of 0.
** This will cause the expression to be deleted automatically when the
** Parse object is destroyed, but the zero register number means that it
** will not generate any code in the preamble.
** If pExpr is not NULL, that means that the reference count is being
** decremented because pExpr is being deleted. Break the reference
** in pAggInfo to pExpr because pExpr is going away.
*/
static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){
if( ALWAYS(!ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced))
&& pExpr->pAggInfo!=0
){
AggInfo *pAggInfo = pExpr->pAggInfo;
int iAgg = pExpr->iAgg;
Parse *pParse = pWalker->pParse;
sqlite3 *db = pParse->db;
assert( pExpr->op==TK_AGG_COLUMN || pExpr->op==TK_AGG_FUNCTION );
if( pExpr->op==TK_AGG_COLUMN ){
assert( iAgg>=0 && iAgg<pAggInfo->nColumn );
if( pAggInfo->aCol[iAgg].pCExpr==pExpr ){
pExpr = sqlite3ExprDup(db, pExpr, 0);
if( pExpr ){
pAggInfo->aCol[iAgg].pCExpr = pExpr;
pParse->pConstExpr =
sqlite3ExprListAppend(pParse, pParse->pConstExpr, pExpr);
}
}
}else{
assert( iAgg>=0 && iAgg<pAggInfo->nFunc );
if( pAggInfo->aFunc[iAgg].pFExpr==pExpr ){
pExpr = sqlite3ExprDup(db, pExpr, 0);
if( pExpr ){
pAggInfo->aFunc[iAgg].pFExpr = pExpr;
pParse->pConstExpr =
sqlite3ExprListAppend(pParse, pParse->pConstExpr, pExpr);
}
}
}
void sqlite3AggInfoUnref(sqlite3 *db, AggInfo *pAggInfo, Expr *pExpr){
int iAgg;
static Expr nullExpr = { TK_NULL };
if( pAggInfo==0 ) return;
//printf("AggInfo (%d/%p) nRef down to %d\n", pAggInfo->selId, pAggInfo, pAggInfo->nAggRef-1); fflush(stdout);
if( pAggInfo->nAggRef==1 ){
sqlite3DbFree(db, pAggInfo->aCol);
sqlite3DbFree(db, pAggInfo->aFunc);
sqlite3DbFree(db, pAggInfo);
return;
}
pAggInfo->nAggRef--;
if( pExpr==0 ) return;
iAgg = pExpr->iAgg;
assert( iAgg>=0 );
if( iAgg<pAggInfo->nColumn && pAggInfo->aCol[iAgg].pCExpr==pExpr ){
pAggInfo->aCol[iAgg].pCExpr = &nullExpr;
}
if( iAgg<pAggInfo->nFunc && pAggInfo->aFunc[iAgg].pFExpr==pExpr ){
pAggInfo->aFunc[iAgg].pFExpr = &nullExpr;
}
return WRC_Continue;
}
/*
** Initialize a Walker object so that will persist AggInfo entries referenced
** by the tree that is walked.
*/
void sqlite3AggInfoPersistWalkerInit(Walker *pWalker, Parse *pParse){
memset(pWalker, 0, sizeof(*pWalker));
pWalker->pParse = pParse;
pWalker->xExprCallback = agginfoPersistExprCb;
pWalker->xSelectCallback = sqlite3SelectWalkNoop;
}
/*
@@ -5879,8 +5866,12 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
*/
ExprSetVVAProperty(pExpr, EP_NoReduce);
pExpr->pAggInfo = pAggInfo;
pAggInfo->nAggRef++;
//printf("AggInfo (%d/%p) nRef up to %d on col %d\n", pAggInfo->selId, pAggInfo, pAggInfo->nAggRef, k); fflush(stdout);
pExpr->op = TK_AGG_COLUMN;
pExpr->iAgg = (i16)k;
ExprSetProperty(pExpr, EP_AggInfo);
break;
} /* endif pExpr->iTable==pItem->iCursor */
} /* end loop over pSrcList */
@@ -5927,6 +5918,10 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
ExprSetVVAProperty(pExpr, EP_NoReduce);
pExpr->iAgg = (i16)i;
pExpr->pAggInfo = pAggInfo;
pAggInfo->nAggRef++;
//printf("AggInfo (%d/%p) nRef up to %d on func %d\n", pAggInfo->selId, pAggInfo, pAggInfo->nAggRef, i); fflush(stdout);
ExprSetProperty(pExpr, EP_AggInfo);
return WRC_Prune;
}else{
return WRC_Continue;
-15
View File
@@ -530,26 +530,11 @@ int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){
return i;
}
/*
** Deallocate a single AggInfo object
*/
static void agginfoFree(sqlite3 *db, AggInfo *p){
sqlite3DbFree(db, p->aCol);
sqlite3DbFree(db, p->aFunc);
sqlite3DbFree(db, p);
}
/*
** Free all memory allocations in the pParse object
*/
void sqlite3ParserReset(Parse *pParse){
sqlite3 *db = pParse->db;
AggInfo *pThis = pParse->pAggList;
while( pThis ){
AggInfo *pNext = pThis->pNext;
agginfoFree(db, pThis);
pThis = pNext;
}
sqlite3DbFree(db, pParse->aLabel);
sqlite3ExprListDelete(db, pParse->pConstExpr);
if( db ){
+11 -16
View File
@@ -3791,7 +3791,6 @@ static int flattenSubquery(
Expr *pWhere; /* The WHERE clause */
struct SrcList_item *pSubitem; /* The subquery */
sqlite3 *db = pParse->db;
Walker w; /* Walker to persist agginfo data */
/* Check to see if flattening is permitted. Return 0 if not.
*/
@@ -4166,8 +4165,6 @@ static int flattenSubquery(
/* Finially, delete what is left of the subquery and return
** success.
*/
sqlite3AggInfoPersistWalkerInit(&w, pParse);
sqlite3WalkSelect(&w,pSub1);
sqlite3SelectDelete(db, pSub1);
#if SELECTTRACE_ENABLED
@@ -6360,8 +6357,7 @@ int sqlite3Select(
if( pAggInfo==0 ){
goto select_end;
}
pAggInfo->pNext = pParse->pAggList;
pParse->pAggList = pAggInfo;
pAggInfo->nAggRef = 1;
pAggInfo->selId = p->selId;
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = pParse;
@@ -6598,7 +6594,7 @@ int sqlite3Select(
/* End of the loop
*/
if( groupBySort ){
sqlite3VdbeAddOp2(v, OP_SorterNext, pAggInfo->sortingIdx, addrTopOfLoop);
sqlite3VdbeAddOp2(v, OP_SorterNext, pAggInfo->sortingIdx,addrTopOfLoop);
VdbeCoverage(v);
}else{
sqlite3WhereEnd(pWInfo);
@@ -6806,21 +6802,20 @@ select_end:
#ifdef SQLITE_DEBUG
if( pAggInfo ){
for(i=0; i<pAggInfo->nColumn; i++){
Expr *pExpr = pAggInfo->aCol[i].pCExpr;
assert( pExpr!=0 || db->mallocFailed );
if( pExpr==0 ) continue;
assert( pExpr->pAggInfo==pAggInfo );
assert( pExpr->iAgg==i );
Expr *pE = pAggInfo->aCol[i].pCExpr;
assert( pE!=0 || db->mallocFailed );
if( pE==0 ) continue;
assert( pE->pAggInfo==0 || (pE->pAggInfo==pAggInfo && pE->iAgg==i) );
}
for(i=0; i<pAggInfo->nFunc; i++){
Expr *pExpr = pAggInfo->aFunc[i].pFExpr;
assert( pExpr!=0 || db->mallocFailed );
if( pExpr==0 ) continue;
assert( pExpr->pAggInfo==pAggInfo );
assert( pExpr->iAgg==i );
Expr *pE = pAggInfo->aFunc[i].pFExpr;
assert( pE!=0 || db->mallocFailed );
if( pE==0 ) continue;
assert( pE->pAggInfo==0 || (pE->pAggInfo==pAggInfo && pE->iAgg==i) );
}
}
#endif
sqlite3AggInfoUnref(db, pAggInfo, 0);
#if SELECTTRACE_ENABLED
SELECTTRACE(0x1,pParse,p,("end processing\n"));
+3 -4
View File
@@ -2524,7 +2524,7 @@ struct AggInfo {
} *aFunc;
int nFunc; /* Number of entries in aFunc[] */
u32 selId; /* Select to which this AggInfo belongs */
AggInfo *pNext; /* Next in list of them all */
u32 nAggRef; /* Ref counter. Delete when it reaches zero */
};
/*
@@ -2695,7 +2695,7 @@ struct Expr {
#define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
#define EP_Win 0x008000 /* Contains window functions */
#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */
/* 0x020000 // available for reuse */
#define EP_AggInfo 0x020000 /* Use the pAggInfo field */
#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
#define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
@@ -3328,7 +3328,6 @@ struct Parse {
Parse *pToplevel; /* Parse structure for main program (or NULL) */
Table *pTriggerTab; /* Table triggers are being coded for */
Parse *pParentParse; /* Parent parser if this parser is nested */
AggInfo *pAggList; /* List of all AggInfo objects */
int addrCrTab; /* Address of OP_CreateBtree opcode on CREATE TABLE */
u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */
u32 oldmask; /* Mask of old.* columns referenced */
@@ -4295,7 +4294,7 @@ int sqlite3ExprCompareSkip(Expr*, Expr*, int);
int sqlite3ExprListCompare(ExprList*, ExprList*, int);
int sqlite3ExprImpliesExpr(Parse*,Expr*, Expr*, int);
int sqlite3ExprImpliesNonNullRow(Expr*,int);
void sqlite3AggInfoPersistWalkerInit(Walker*,Parse*);
void sqlite3AggInfoUnref(sqlite3*, AggInfo*, Expr*);
void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx);
-2
View File
@@ -964,8 +964,6 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
if( pTab==0 ){
return sqlite3ErrorToParser(db, SQLITE_NOMEM);
}
sqlite3AggInfoPersistWalkerInit(&w, pParse);
sqlite3WalkSelect(&w, p);
p->pSrc = 0;
p->pWhere = 0;