Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | When translating arguments of aggregate functions into references to expression indexes, make sure to only translate them for the current aggregate when there are nested aggregates. Forum post 409ebc7368. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
898bfa1afd8260eaaf2aa6db94e74d99 |
User & Date: | drh 2023-04-03 23:49:00 |
Original Comment: | When translating arguments of aggregate functions into references to expression indexes, make sure to only translate them for the current aggregate when there are nested aggregates. [forum/forumpost/409ebc7368|Forum post 409ebc7368]. |
Context
2023-04-04
| ||
08:49 | Omit shell call to sqlite3_dbdata_init() when it is omitted. (check-in: 0421cc03 user: larrybr tags: trunk) | |
2023-04-03
| ||
23:55 | When translating arguments of aggregate functions into references to expression indexes, make sure to only translate them for the current aggregate when there are nested aggregates. (check-in: 7ea98aba user: drh tags: branch-3.41) | |
23:49 | When translating arguments of aggregate functions into references to expression indexes, make sure to only translate them for the current aggregate when there are nested aggregates. Forum post 409ebc7368. (check-in: 898bfa1a user: drh tags: trunk) | |
20:11 | Improved diagnostic output from PRAGMA vdbe_addoptrace. (check-in: 050958c1 user: drh tags: trunk) | |
Changes
Changes to src/expr.c.
︙ | ︙ | |||
6284 6285 6286 6287 6288 6289 6290 | ){ AggInfo *pAggInfo = pExpr->pAggInfo; int iAgg = pExpr->iAgg; Parse *pParse = pWalker->pParse; sqlite3 *db = pParse->db; assert( iAgg>=0 ); if( pExpr->op!=TK_AGG_FUNCTION ){ | | | 6284 6285 6286 6287 6288 6289 6290 6291 6292 6293 6294 6295 6296 6297 6298 | ){ AggInfo *pAggInfo = pExpr->pAggInfo; int iAgg = pExpr->iAgg; Parse *pParse = pWalker->pParse; sqlite3 *db = pParse->db; assert( iAgg>=0 ); if( pExpr->op!=TK_AGG_FUNCTION ){ if( ALWAYS(iAgg<pAggInfo->nColumn) && pAggInfo->aCol[iAgg].pCExpr==pExpr ){ pExpr = sqlite3ExprDup(db, pExpr, 0); if( pExpr ){ pAggInfo->aCol[iAgg].pCExpr = pExpr; sqlite3ExprDeferredDelete(pParse, pExpr); } |
︙ | ︙ | |||
6437 6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 6450 6451 6452 6453 | assert( pNC->ncFlags & NC_UAggInfo ); assert( pAggInfo->iFirstReg==0 ); switch( pExpr->op ){ default: { IndexedExpr *pIEpr; Expr tmp; assert( pParse->iSelfTab==0 ); if( (pNC->ncFlags & NC_InAggFunc)==0 ) break; if( pParse->pIdxEpr==0 ) break; for(pIEpr=pParse->pIdxEpr; pIEpr; pIEpr=pIEpr->pIENext){ int iDataCur = pIEpr->iDataCur; if( iDataCur<0 ) continue; if( sqlite3ExprCompare(0, pExpr, pIEpr->pExpr, iDataCur)==0 ) break; } if( pIEpr==0 ) break; if( NEVER(!ExprUseYTab(pExpr)) ) break; | > > > > > | | 6437 6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 6460 6461 6462 6463 6464 6465 6466 | assert( pNC->ncFlags & NC_UAggInfo ); assert( pAggInfo->iFirstReg==0 ); switch( pExpr->op ){ default: { IndexedExpr *pIEpr; Expr tmp; int i; assert( pParse->iSelfTab==0 ); if( (pNC->ncFlags & NC_InAggFunc)==0 ) break; if( pParse->pIdxEpr==0 ) break; for(pIEpr=pParse->pIdxEpr; pIEpr; pIEpr=pIEpr->pIENext){ int iDataCur = pIEpr->iDataCur; if( iDataCur<0 ) continue; if( sqlite3ExprCompare(0, pExpr, pIEpr->pExpr, iDataCur)==0 ) break; } if( pIEpr==0 ) break; if( NEVER(!ExprUseYTab(pExpr)) ) break; for(i=0; i<pSrcList->nSrc; i++){ if( pSrcList->a[0].iCursor==pIEpr->iDataCur ) break; } if( i>=pSrcList->nSrc ) break; if( NEVER(pExpr->pAggInfo!=0) ) break; /* Resolved by outer context */ if( pParse->nErr ){ return WRC_Abort; } /* If we reach this point, it means that expression pExpr can be ** translated into a reference to an index column as described by ** pIEpr. */ memset(&tmp, 0, sizeof(tmp)); |
︙ | ︙ |
Changes to src/select.c.
︙ | ︙ | |||
6481 6482 6483 6484 6485 6486 6487 | struct AggInfo_col *pCol; UNUSED_PARAMETER(pWalker); if( pExpr->pAggInfo==0 ) return WRC_Continue; if( pExpr->op==TK_AGG_COLUMN ) return WRC_Continue; if( pExpr->op==TK_AGG_FUNCTION ) return WRC_Continue; if( pExpr->op==TK_IF_NULL_ROW ) return WRC_Continue; pAggInfo = pExpr->pAggInfo; | | | 6481 6482 6483 6484 6485 6486 6487 6488 6489 6490 6491 6492 6493 6494 6495 | struct AggInfo_col *pCol; UNUSED_PARAMETER(pWalker); if( pExpr->pAggInfo==0 ) return WRC_Continue; if( pExpr->op==TK_AGG_COLUMN ) return WRC_Continue; if( pExpr->op==TK_AGG_FUNCTION ) return WRC_Continue; if( pExpr->op==TK_IF_NULL_ROW ) return WRC_Continue; pAggInfo = pExpr->pAggInfo; if( NEVER(pExpr->iAgg>=pAggInfo->nColumn) ) return WRC_Continue; assert( pExpr->iAgg>=0 ); pCol = &pAggInfo->aCol[pExpr->iAgg]; pExpr->op = TK_AGG_COLUMN; pExpr->iTable = pCol->iTable; pExpr->iColumn = pCol->iColumn; ExprClearProperty(pExpr, EP_Skip|EP_Collate); return WRC_Prune; |
︙ | ︙ |
Changes to test/indexexpr2.test.
︙ | ︙ | |||
405 406 407 408 409 410 411 412 413 | CREATE TABLE t2(a TEXT); INSERT INTO t2 VALUES('alice'),('bob'),('cindy'),('david'); CREATE INDEX t2x ON t2 (+a COLLATE NOCASE); SELECT count(+a COLLATE NOCASE IN (SELECT 1)) AS x FROM t2 GROUP BY SUBSTR(0,0); } 4 finish_test | > > > > > > > > > > > > > > > | 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 | CREATE TABLE t2(a TEXT); INSERT INTO t2 VALUES('alice'),('bob'),('cindy'),('david'); CREATE INDEX t2x ON t2 (+a COLLATE NOCASE); SELECT count(+a COLLATE NOCASE IN (SELECT 1)) AS x FROM t2 GROUP BY SUBSTR(0,0); } 4 # 2023-04-03 https://sqlite.org/forum/forumpost/409ebc7368 # When a generated column appears in both an outer and an inner loop # (that is to say, the same table is used in both loops) and the # generated column is indexed and it is used inside an aggregate function, # make sure that the terms resolve to the correct aggregate. # do_execsql_test 11.0 { CREATE TABLE t3 (a INT, b AS (-a)); CREATE INDEX t3x ON t3(b, a); INSERT INTO t3(a) VALUES(44); SELECT * FROM t3 AS a0 WHERE (SELECT sum(-a0.a=b) FROM t3 GROUP BY b) GROUP BY b; } {44 -44} finish_test |