Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | When an Expr object is changed and that Expr is referenced by an AggInfo, then also update the AggInfo. Also, persist all AggInfo objects until the Parse object is destroyed. This is a new fix for ticket [c8d3b9f0a750a529] that avoids the follow-on problems identified by tickets [0899cf62f597d7e7], [1f6f353b684fc708], [e5504e987e419fb0], and [f7d890858f361402]. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
6e6b3729e0549de028f6c5bf494b2d69 |
User & Date: | drh 2020-06-08 11:34:40 |
References
2024-02-11
| ||
20:53 | If a term of an ORDER BY or GROUP BY contains an aggregate function or column, then it is not an alias that needs to be resolved, so don't try to. This fixes a harmless assertion found by dbsqlfuzz. This yet another problem that orginated at check-in [6e6b3729e0549de0]. (check-in: d4ec2a5d user: drh tags: trunk) | |
2022-09-01
| ||
13:51 | Defer deleting a transient SELECT statement associated with a flattening of one arm of a compound SELECT until after the parse has completed. This is a follow-up and enhancement to check-in [6e6b3729e0549de0] in response to an assertion fault reported by Chromium. (check-in: 1c4157c7 user: drh tags: trunk) | |
2021-08-21
| ||
16:42 | Defer deleting subqueries in the compound-SELECT code generator until the end of code generation, in order to avoid deleting expressions out from under the aggregation function sanity checking assert()s that occur near the end of SELECT code generation. This fixes the assertion fault described by forum post cfcb4b461d. The problem goes back to check-in [6e6b3729e0549de0]. (check-in: 600f1991 user: drh tags: trunk) | |
2021-03-03
| ||
14:07 | Fix a harmless assertion fault resulting from [6e6b3729e0549de0] that was discovered by dbsqlfuzz. Enhance .selecttrace output to show omitted ORDER BY clauses. New dbsqlfuzz test cases added. (check-in: 27a0388a user: drh tags: trunk) | |
2021-01-19
| ||
20:09 | Fix a problem handling sub-queries with both a correlated WHERE clause and a "HAVING 0" clause where the parent query is itself an aggregate. The problem was apparently introduced by check-in [6e6b3729e0549de0] (check-in: 30a4c323 user: drh tags: branch-3.34) | |
2020-12-22
| ||
16:23 | Fix a problem handling sub-queries with both a correlated WHERE clause and a "HAVING 0" clause where the parent query is itself an aggregate. The problem was apparently introduced by check-in [6e6b3729e0549de0] (check-in: f62f983b user: dan tags: trunk) | |
Context
2020-06-08
| ||
14:43 | Fix a case where a corrupted fts3 record could cause an assert() failure, or spurious SQLITE_NOMEM error in builds with assert() disabled. (check-in: d48af4d2 user: dan tags: trunk) | |
12:49 | When an Expr object is changed and that Expr is referenced by an AggInfo, then also update the AggInfo. Also, persist all AggInfo objects until the Parse object is destroyed. This is a new fix for ticket [c8d3b9f0a750a529]. (check-in: 44a58d6c user: drh tags: branch-3.32) | |
11:34 | When an Expr object is changed and that Expr is referenced by an AggInfo, then also update the AggInfo. Also, persist all AggInfo objects until the Parse object is destroyed. This is a new fix for ticket [c8d3b9f0a750a529] that avoids the follow-on problems identified by tickets [0899cf62f597d7e7], [1f6f353b684fc708], [e5504e987e419fb0], and [f7d890858f361402]. (check-in: 6e6b3729 user: drh tags: trunk) | |
2020-06-07
| ||
22:44 | Fix minor OOM problems. (Closed-Leaf check-in: 8b23d802 user: drh tags: persist-agginfo) | |
2020-06-05
| ||
04:01 | In the debugging treeview output, change the name of "SELECT-expr" expression nodes to be "subquery-expr", so as to not confuse them with actual SELECT nodes. (check-in: c1c8937a user: drh tags: trunk) | |
Changes
Changes to src/build.c.
︙ | ︙ | |||
203 204 205 206 207 208 209 | */ codeTableLocks(pParse); /* Initialize any AUTOINCREMENT data structures required. */ sqlite3AutoincrementBegin(pParse); | | > > > > > > > > | > | 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | */ codeTableLocks(pParse); /* Initialize any AUTOINCREMENT data structures required. */ sqlite3AutoincrementBegin(pParse); /* Code constant expressions that where factored out of inner loops. ** ** The pConstExpr list might also contain expressions that we simply ** want to keep around until the Parse object is deleted. Such ** expressions have iConstExprReg==0. Do not generate code for ** those expressions, of course. */ if( pParse->pConstExpr ){ ExprList *pEL = pParse->pConstExpr; pParse->okConstFactor = 0; for(i=0; i<pEL->nExpr; i++){ int iReg = pEL->a[i].u.iConstExprReg; if( iReg>0 ){ sqlite3ExprCode(pParse, pEL->a[i].pExpr, iReg); } } } /* Finally, jump back to the beginning of the executable code. */ sqlite3VdbeGoto(v, 1); } } |
︙ | ︙ |
Changes to src/expr.c.
︙ | ︙ | |||
48 49 50 51 52 53 54 | assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW ); pExpr = pExpr->pLeft; assert( pExpr!=0 ); } op = pExpr->op; if( op==TK_SELECT ){ assert( pExpr->flags&EP_xIsSelect ); | > > > > | > | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW ); pExpr = pExpr->pLeft; assert( pExpr!=0 ); } op = pExpr->op; if( op==TK_SELECT ){ assert( pExpr->flags&EP_xIsSelect ); if( ALWAYS(pExpr->x.pSelect) && pExpr->x.pSelect->pEList && ALWAYS(pExpr->x.pSelect->pEList->a[0].pExpr) ){ return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr); } } if( op==TK_REGISTER ) op = pExpr->op2; #ifndef SQLITE_OMIT_CAST if( op==TK_CAST ){ assert( !ExprHasProperty(pExpr, EP_IntValue) ); return sqlite3AffinityType(pExpr->u.zToken, 0); } |
︙ | ︙ | |||
5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 | #ifndef SQLITE_OMIT_WINDOWFUNC if( ExprHasProperty(pExpr, EP_WinFunc) ){ sqlite3WalkExpr(&w, pExpr->y.pWin->pFilter); } #endif return cnt.nThis>0 || cnt.nOther==0; } /* ** Add a new element to the pAggInfo->aCol[] array. Return the index of ** the new element. Return a negative number if malloc fails. */ static int addAggInfoColumn(sqlite3 *db, AggInfo *pInfo){ int i; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 | #ifndef SQLITE_OMIT_WINDOWFUNC if( ExprHasProperty(pExpr, EP_WinFunc) ){ sqlite3WalkExpr(&w, pExpr->y.pWin->pFilter); } #endif return cnt.nThis>0 || cnt.nOther==0; } /* ** This is a Walker expression node callback. ** ** 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. */ 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].pExpr==pExpr ){ pExpr = sqlite3ExprDup(db, pExpr, 0); if( pExpr ){ pAggInfo->aCol[iAgg].pExpr = pExpr; pParse->pConstExpr = sqlite3ExprListAppend(pParse, pParse->pConstExpr, pExpr); } } }else{ assert( iAgg>=0 && iAgg<pAggInfo->nFunc ); if( pAggInfo->aFunc[iAgg].pExpr==pExpr ){ pExpr = sqlite3ExprDup(db, pExpr, 0); if( pExpr ){ pAggInfo->aFunc[iAgg].pExpr = pExpr; pParse->pConstExpr = sqlite3ExprListAppend(pParse, pParse->pConstExpr, pExpr); } } } } 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; } /* ** Add a new element to the pAggInfo->aCol[] array. Return the index of ** the new element. Return a negative number if malloc fails. */ static int addAggInfoColumn(sqlite3 *db, AggInfo *pInfo){ int i; |
︙ | ︙ | |||
5735 5736 5737 5738 5739 5740 5741 | db, pInfo->aFunc, sizeof(pInfo->aFunc[0]), &pInfo->nFunc, &i ); return i; | | | 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 | db, pInfo->aFunc, sizeof(pInfo->aFunc[0]), &pInfo->nFunc, &i ); return i; } /* ** This is the xExprCallback for a tree walker. It is used to ** implement sqlite3ExprAnalyzeAggregates(). See sqlite3ExprAnalyzeAggregates ** for additional information. */ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ |
︙ | ︙ |
Changes to src/prepare.c.
︙ | ︙ | |||
525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 | break; } } assert( i>=0 && i<db->nDb ); } return i; } /* ** Free all memory allocations in the pParse object */ void sqlite3ParserReset(Parse *pParse){ sqlite3 *db = pParse->db; sqlite3DbFree(db, pParse->aLabel); sqlite3ExprListDelete(db, pParse->pConstExpr); if( db ){ assert( db->lookaside.bDisable >= pParse->disableLookaside ); db->lookaside.bDisable -= pParse->disableLookaside; db->lookaside.sz = db->lookaside.bDisable ? 0 : db->lookaside.szTrue; } | > > > > > > > > > > > > > > > | 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 | break; } } assert( i>=0 && i<db->nDb ); } 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 ){ assert( db->lookaside.bDisable >= pParse->disableLookaside ); db->lookaside.bDisable -= pParse->disableLookaside; db->lookaside.sz = db->lookaside.bDisable ? 0 : db->lookaside.szTrue; } |
︙ | ︙ |
Changes to src/select.c.
︙ | ︙ | |||
3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 | int iParent; /* VDBE cursor number of the pSub result set temp table */ int iNewParent = -1;/* Replacement table for iParent */ int isLeftJoin = 0; /* True if pSub is the right side of a LEFT JOIN */ int i; /* Loop counter */ Expr *pWhere; /* The WHERE clause */ struct SrcList_item *pSubitem; /* The subquery */ sqlite3 *db = pParse->db; /* Check to see if flattening is permitted. Return 0 if not. */ assert( p!=0 ); assert( p->pPrior==0 ); if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0; pSrc = p->pSrc; | > | 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 | int iParent; /* VDBE cursor number of the pSub result set temp table */ int iNewParent = -1;/* Replacement table for iParent */ int isLeftJoin = 0; /* True if pSub is the right side of a LEFT JOIN */ int i; /* Loop counter */ 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. */ assert( p!=0 ); assert( p->pPrior==0 ); if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0; pSrc = p->pSrc; |
︙ | ︙ | |||
4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 | recomputeColumnsUsed(pParent, &pSrc->a[i+iFrom]); } } /* Finially, delete what is left of the subquery and return ** success. */ sqlite3SelectDelete(db, pSub1); #if SELECTTRACE_ENABLED if( sqlite3SelectTrace & 0x100 ){ SELECTTRACE(0x100,pParse,p,("After flattening:\n")); sqlite3TreeViewSelect(0, p, 0); } | > > | 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 | recomputeColumnsUsed(pParent, &pSrc->a[i+iFrom]); } } /* Finially, delete what is left of the subquery and return ** success. */ sqlite3AggInfoPersistWalkerInit(&w, pParse); sqlite3WalkSelect(&w,pSub1); sqlite3SelectDelete(db, pSub1); #if SELECTTRACE_ENABLED if( sqlite3SelectTrace & 0x100 ){ SELECTTRACE(0x100,pParse,p,("After flattening:\n")); sqlite3TreeViewSelect(0, p, 0); } |
︙ | ︙ | |||
5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 | Vdbe *v; /* The virtual machine under construction */ int isAgg; /* True for select lists like "count(*)" */ ExprList *pEList = 0; /* List of columns to extract. */ SrcList *pTabList; /* List of tables to select from */ Expr *pWhere; /* The WHERE clause. May be NULL */ ExprList *pGroupBy; /* The GROUP BY clause. May be NULL */ Expr *pHaving; /* The HAVING clause. May be NULL */ int rc = 1; /* Value to return from this function */ DistinctCtx sDistinct; /* Info on how to code the DISTINCT keyword */ SortCtx sSort; /* Info on how to code the ORDER BY clause */ | > < < | 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 | Vdbe *v; /* The virtual machine under construction */ int isAgg; /* True for select lists like "count(*)" */ ExprList *pEList = 0; /* List of columns to extract. */ SrcList *pTabList; /* List of tables to select from */ Expr *pWhere; /* The WHERE clause. May be NULL */ ExprList *pGroupBy; /* The GROUP BY clause. May be NULL */ Expr *pHaving; /* The HAVING clause. May be NULL */ AggInfo *pAggInfo = 0; /* Aggregate information */ int rc = 1; /* Value to return from this function */ DistinctCtx sDistinct; /* Info on how to code the DISTINCT keyword */ SortCtx sSort; /* Info on how to code the ORDER BY clause */ int iEnd; /* Address of the end of the query */ sqlite3 *db; /* The database connection */ ExprList *pMinMaxOrderBy = 0; /* Added ORDER BY for min/max queries */ u8 minMaxFlag; /* Flag for min/max queries */ db = pParse->db; v = sqlite3GetVdbe(pParse); if( p==0 || db->mallocFailed || pParse->nErr ){ return 1; } if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; #if SELECTTRACE_ENABLED SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain)); if( sqlite3SelectTrace & 0x100 ){ sqlite3TreeViewSelect(0, p, 0); } #endif |
︙ | ︙ | |||
6350 6351 6352 6353 6354 6355 6356 6357 6358 6359 | /* Create a label to jump to when we want to abort the query */ addrEnd = sqlite3VdbeMakeLabel(pParse); /* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in ** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the ** SELECT statement. */ memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; sNC.pSrcList = pTabList; | > > > > > > | | | | | | | | | | | | | | | | | | 6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 | /* Create a label to jump to when we want to abort the query */ addrEnd = sqlite3VdbeMakeLabel(pParse); /* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in ** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the ** SELECT statement. */ pAggInfo = sqlite3DbMallocZero(db, sizeof(*pAggInfo) ); if( pAggInfo==0 ){ goto select_end; } pAggInfo->pNext = pParse->pAggList; pParse->pAggList = pAggInfo; memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; sNC.pSrcList = pTabList; sNC.uNC.pAggInfo = pAggInfo; VVA_ONLY( sNC.ncFlags = NC_UAggInfo; ) pAggInfo->mnReg = pParse->nMem+1; pAggInfo->nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0; pAggInfo->pGroupBy = pGroupBy; sqlite3ExprAnalyzeAggList(&sNC, pEList); sqlite3ExprAnalyzeAggList(&sNC, sSort.pOrderBy); if( pHaving ){ if( pGroupBy ){ assert( pWhere==p->pWhere ); assert( pHaving==p->pHaving ); assert( pGroupBy==p->pGroupBy ); havingToWhere(pParse, p); pWhere = p->pWhere; } sqlite3ExprAnalyzeAggregates(&sNC, pHaving); } pAggInfo->nAccumulator = pAggInfo->nColumn; if( p->pGroupBy==0 && p->pHaving==0 && pAggInfo->nFunc==1 ){ minMaxFlag = minMaxQuery(db, pAggInfo->aFunc[0].pExpr, &pMinMaxOrderBy); }else{ minMaxFlag = WHERE_ORDERBY_NORMAL; } for(i=0; i<pAggInfo->nFunc; i++){ Expr *pExpr = pAggInfo->aFunc[i].pExpr; assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); sNC.ncFlags |= NC_InAggFunc; sqlite3ExprAnalyzeAggList(&sNC, pExpr->x.pList); #ifndef SQLITE_OMIT_WINDOWFUNC assert( !IsWindowFunc(pExpr) ); if( ExprHasProperty(pExpr, EP_WinFunc) ){ sqlite3ExprAnalyzeAggregates(&sNC, pExpr->y.pWin->pFilter); } #endif sNC.ncFlags &= ~NC_InAggFunc; } pAggInfo->mxReg = pParse->nMem; if( db->mallocFailed ) goto select_end; #if SELECTTRACE_ENABLED if( sqlite3SelectTrace & 0x400 ){ int ii; SELECTTRACE(0x400,pParse,p,("After aggregate analysis %p:\n", pAggInfo)); sqlite3TreeViewSelect(0, p, 0); for(ii=0; ii<pAggInfo->nColumn; ii++){ sqlite3DebugPrintf("agg-column[%d] iMem=%d\n", ii, pAggInfo->aCol[ii].iMem); sqlite3TreeViewExpr(0, pAggInfo->aCol[ii].pExpr, 0); } for(ii=0; ii<pAggInfo->nFunc; ii++){ sqlite3DebugPrintf("agg-func[%d]: iMem=%d\n", ii, pAggInfo->aFunc[ii].iMem); sqlite3TreeViewExpr(0, pAggInfo->aFunc[ii].pExpr, 0); } } #endif /* Processing for aggregates with GROUP BY is very different and ** much more complex than aggregates without a GROUP BY. |
︙ | ︙ | |||
6429 6430 6431 6432 6433 6434 6435 | int regReset; /* Return address register for reset subroutine */ /* If there is a GROUP BY clause we might need a sorting index to ** implement it. Allocate that sorting index now. If it turns out ** that we do not need it after all, the OP_SorterOpen instruction ** will be converted into a Noop. */ | | | > | | 6437 6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 | int regReset; /* Return address register for reset subroutine */ /* If there is a GROUP BY clause we might need a sorting index to ** implement it. Allocate that sorting index now. If it turns out ** that we do not need it after all, the OP_SorterOpen instruction ** will be converted into a Noop. */ pAggInfo->sortingIdx = pParse->nTab++; pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pGroupBy, 0, pAggInfo->nColumn); addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen, pAggInfo->sortingIdx, pAggInfo->nSortingColumn, 0, (char*)pKeyInfo, P4_KEYINFO); /* Initialize memory locations used by GROUP BY aggregate processing */ iUseFlag = ++pParse->nMem; iAbortFlag = ++pParse->nMem; regOutputRow = ++pParse->nMem; |
︙ | ︙ | |||
6487 6488 6489 6490 6491 6492 6493 | (sDistinct.isTnct && (p->selFlags&SF_Distinct)==0) ? "DISTINCT" : "GROUP BY"); groupBySort = 1; nGroupBy = pGroupBy->nExpr; nCol = nGroupBy; j = nGroupBy; | | | | | | | | | | 6496 6497 6498 6499 6500 6501 6502 6503 6504 6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515 6516 6517 6518 6519 6520 6521 6522 6523 6524 6525 6526 6527 6528 6529 6530 6531 6532 6533 6534 6535 6536 6537 6538 6539 | (sDistinct.isTnct && (p->selFlags&SF_Distinct)==0) ? "DISTINCT" : "GROUP BY"); groupBySort = 1; nGroupBy = pGroupBy->nExpr; nCol = nGroupBy; j = nGroupBy; for(i=0; i<pAggInfo->nColumn; i++){ if( pAggInfo->aCol[i].iSorterColumn>=j ){ nCol++; j++; } } regBase = sqlite3GetTempRange(pParse, nCol); sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0, 0); j = nGroupBy; for(i=0; i<pAggInfo->nColumn; i++){ struct AggInfo_col *pCol = &pAggInfo->aCol[i]; if( pCol->iSorterColumn>=j ){ int r1 = j + regBase; sqlite3ExprCodeGetColumnOfTable(v, pCol->pTab, pCol->iTable, pCol->iColumn, r1); j++; } } regRecord = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord); sqlite3VdbeAddOp2(v, OP_SorterInsert, pAggInfo->sortingIdx, regRecord); sqlite3ReleaseTempReg(pParse, regRecord); sqlite3ReleaseTempRange(pParse, regBase, nCol); sqlite3WhereEnd(pWInfo); pAggInfo->sortingIdxPTab = sortPTab = pParse->nTab++; sortOut = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol); sqlite3VdbeAddOp2(v, OP_SorterSort, pAggInfo->sortingIdx, addrEnd); VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v); pAggInfo->useSortingIdx = 1; } /* If the index or temporary table used by the GROUP BY sort ** will naturally deliver rows in the order required by the ORDER BY ** clause, cancel the ephemeral table open coded earlier. ** ** This is an optimization - the correct answer should result regardless. |
︙ | ︙ | |||
6540 6541 6542 6543 6544 6545 6546 | /* Evaluate the current GROUP BY terms and store in b0, b1, b2... ** (b0 is memory location iBMem+0, b1 is iBMem+1, and so forth) ** Then compare the current GROUP BY terms against the GROUP BY terms ** from the previous row currently stored in a0, a1, a2... */ addrTopOfLoop = sqlite3VdbeCurrentAddr(v); if( groupBySort ){ | | | | 6549 6550 6551 6552 6553 6554 6555 6556 6557 6558 6559 6560 6561 6562 6563 6564 6565 6566 6567 6568 6569 6570 | /* Evaluate the current GROUP BY terms and store in b0, b1, b2... ** (b0 is memory location iBMem+0, b1 is iBMem+1, and so forth) ** Then compare the current GROUP BY terms against the GROUP BY terms ** from the previous row currently stored in a0, a1, a2... */ addrTopOfLoop = sqlite3VdbeCurrentAddr(v); if( groupBySort ){ sqlite3VdbeAddOp3(v, OP_SorterData, pAggInfo->sortingIdx, sortOut, sortPTab); } for(j=0; j<pGroupBy->nExpr; j++){ if( groupBySort ){ sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j); }else{ pAggInfo->directMode = 1; sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j); } } sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr, (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO); addr1 = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp3(v, OP_Jump, addr1+1, 0, addr1+1); VdbeCoverage(v); |
︙ | ︙ | |||
6577 6578 6579 6580 6581 6582 6583 | sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); VdbeComment((v, "reset accumulator")); /* Update the aggregate accumulators based on the content of ** the current row */ sqlite3VdbeJumpHere(v, addr1); | | | | 6586 6587 6588 6589 6590 6591 6592 6593 6594 6595 6596 6597 6598 6599 6600 6601 6602 6603 6604 6605 6606 6607 | sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); VdbeComment((v, "reset accumulator")); /* Update the aggregate accumulators based on the content of ** the current row */ sqlite3VdbeJumpHere(v, addr1); updateAccumulator(pParse, iUseFlag, pAggInfo); sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag); VdbeComment((v, "indicate data in accumulator")); /* End of the loop */ if( groupBySort ){ sqlite3VdbeAddOp2(v, OP_SorterNext, pAggInfo->sortingIdx, addrTopOfLoop); VdbeCoverage(v); }else{ sqlite3WhereEnd(pWInfo); sqlite3VdbeChangeToNoop(v, addrSortingIdx); } /* Output the final row of result |
︙ | ︙ | |||
6617 6618 6619 6620 6621 6622 6623 | sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); sqlite3VdbeResolveLabel(v, addrOutputRow); addrOutputRow = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2); VdbeCoverage(v); VdbeComment((v, "Groupby result generator entry point")); sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); | | | | | 6626 6627 6628 6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 6639 6640 6641 6642 6643 6644 6645 6646 6647 6648 6649 6650 6651 6652 6653 6654 6655 6656 6657 6658 6659 | sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); sqlite3VdbeResolveLabel(v, addrOutputRow); addrOutputRow = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2); VdbeCoverage(v); VdbeComment((v, "Groupby result generator entry point")); sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); finalizeAggFunctions(pParse, pAggInfo); sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL); selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest, addrOutputRow+1, addrSetAbort); sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); VdbeComment((v, "end groupby result generator")); /* Generate a subroutine that will reset the group-by accumulator */ sqlite3VdbeResolveLabel(v, addrReset); resetAccumulator(pParse, pAggInfo); sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag); VdbeComment((v, "indicate accumulator empty")); sqlite3VdbeAddOp1(v, OP_Return, regReset); } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */ else { Table *pTab; if( (pTab = isSimpleCount(p, pAggInfo))!=0 ){ /* If isSimpleCount() returns a pointer to a Table structure, then ** the SQL statement is of the form: ** ** SELECT count(*) FROM <tbl> ** ** where the Table structure returned represents table <tbl>. ** |
︙ | ︙ | |||
6691 6692 6693 6694 6695 6696 6697 | } /* Open a read-only cursor, execute the OP_Count, close the cursor. */ sqlite3VdbeAddOp4Int(v, OP_OpenRead, iCsr, iRoot, iDb, 1); if( pKeyInfo ){ sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO); } | | | | | > > | > | > | | | | | 6700 6701 6702 6703 6704 6705 6706 6707 6708 6709 6710 6711 6712 6713 6714 6715 6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726 6727 6728 6729 6730 6731 6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 6746 6747 6748 6749 6750 6751 6752 6753 6754 6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 6765 6766 6767 6768 6769 6770 6771 6772 6773 | } /* Open a read-only cursor, execute the OP_Count, close the cursor. */ sqlite3VdbeAddOp4Int(v, OP_OpenRead, iCsr, iRoot, iDb, 1); if( pKeyInfo ){ sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO); } sqlite3VdbeAddOp2(v, OP_Count, iCsr, pAggInfo->aFunc[0].iMem); sqlite3VdbeAddOp1(v, OP_Close, iCsr); explainSimpleCount(pParse, pTab, pBest); }else{ int regAcc = 0; /* "populate accumulators" flag */ /* If there are accumulator registers but no min() or max() functions ** without FILTER clauses, allocate register regAcc. Register regAcc ** will contain 0 the first time the inner loop runs, and 1 thereafter. ** The code generated by updateAccumulator() uses this to ensure ** that the accumulator registers are (a) updated only once if ** there are no min() or max functions or (b) always updated for the ** first row visited by the aggregate, so that they are updated at ** least once even if the FILTER clause means the min() or max() ** function visits zero rows. */ if( pAggInfo->nAccumulator ){ for(i=0; i<pAggInfo->nFunc; i++){ if( ExprHasProperty(pAggInfo->aFunc[i].pExpr, EP_WinFunc) ){ continue; } if( pAggInfo->aFunc[i].pFunc->funcFlags&SQLITE_FUNC_NEEDCOLL ){ break; } } if( i==pAggInfo->nFunc ){ regAcc = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Integer, 0, regAcc); } } /* This case runs if the aggregate has no GROUP BY clause. The ** processing is much simpler since there is only a single row ** of output. */ assert( p->pGroupBy==0 ); resetAccumulator(pParse, pAggInfo); /* If this query is a candidate for the min/max optimization, then ** minMaxFlag will have been previously set to either ** WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX and pMinMaxOrderBy will ** be an appropriate ORDER BY expression for the optimization. */ assert( minMaxFlag==WHERE_ORDERBY_NORMAL || pMinMaxOrderBy!=0 ); assert( pMinMaxOrderBy==0 || pMinMaxOrderBy->nExpr==1 ); SELECTTRACE(1,pParse,p,("WhereBegin\n")); pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy, 0, minMaxFlag, 0); if( pWInfo==0 ){ goto select_end; } updateAccumulator(pParse, regAcc, pAggInfo); if( regAcc ) sqlite3VdbeAddOp2(v, OP_Integer, 1, regAcc); if( sqlite3WhereIsOrdered(pWInfo)>0 ){ sqlite3VdbeGoto(v, sqlite3WhereBreakLabel(pWInfo)); VdbeComment((v, "%s() by index", (minMaxFlag==WHERE_ORDERBY_MIN?"min":"max"))); } sqlite3WhereEnd(pWInfo); finalizeAggFunctions(pParse, pAggInfo); } sSort.pOrderBy = 0; sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL); selectInnerLoop(pParse, p, -1, 0, 0, pDest, addrEnd, addrEnd); } |
︙ | ︙ | |||
6785 6786 6787 6788 6789 6790 6791 | rc = (pParse->nErr>0); /* Control jumps to here if an error is encountered above, or upon ** successful coding of the SELECT. */ select_end: sqlite3ExprListDelete(db, pMinMaxOrderBy); | > | > > > > > > > > > > > > > > > > | | 6798 6799 6800 6801 6802 6803 6804 6805 6806 6807 6808 6809 6810 6811 6812 6813 6814 6815 6816 6817 6818 6819 6820 6821 6822 6823 6824 6825 6826 6827 6828 6829 6830 6831 6832 | rc = (pParse->nErr>0); /* Control jumps to here if an error is encountered above, or upon ** successful coding of the SELECT. */ select_end: sqlite3ExprListDelete(db, pMinMaxOrderBy); #ifdef SQLITE_DEBUG if( pAggInfo ){ for(i=0; i<pAggInfo->nColumn; i++){ Expr *pExpr = pAggInfo->aCol[i].pExpr; assert( pExpr!=0 || db->mallocFailed ); if( pExpr==0 ) continue; assert( pExpr->pAggInfo==pAggInfo ); assert( pExpr->iAgg==i ); } for(i=0; i<pAggInfo->nFunc; i++){ Expr *pExpr = pAggInfo->aFunc[i].pExpr; assert( pExpr!=0 || db->mallocFailed ); if( pExpr==0 ) continue; assert( pExpr->pAggInfo==pAggInfo ); assert( pExpr->iAgg==i ); } } #endif #if SELECTTRACE_ENABLED SELECTTRACE(0x1,pParse,p,("end processing\n")); if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ sqlite3TreeViewSelect(0, p, 0); } #endif ExplainQueryPlanPop(pParse); return rc; } |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
2502 2503 2504 2505 2506 2507 2508 2509 | int sortingIdx; /* Cursor number of the sorting index */ int sortingIdxPTab; /* Cursor number of pseudo-table */ int nSortingColumn; /* Number of columns in the sorting index */ int mnReg, mxReg; /* Range of registers allocated for aCol and aFunc */ ExprList *pGroupBy; /* The group by clause */ struct AggInfo_col { /* For each column used in source tables */ Table *pTab; /* Source table */ int iTable; /* Cursor number of the source table */ | > > | | < < > > > > > > > > > | 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 | int sortingIdx; /* Cursor number of the sorting index */ int sortingIdxPTab; /* Cursor number of pseudo-table */ int nSortingColumn; /* Number of columns in the sorting index */ int mnReg, mxReg; /* Range of registers allocated for aCol and aFunc */ ExprList *pGroupBy; /* The group by clause */ struct AggInfo_col { /* For each column used in source tables */ Table *pTab; /* Source table */ Expr *pExpr; /* The original expression */ int iTable; /* Cursor number of the source table */ int iMem; /* Memory location that acts as accumulator */ i16 iColumn; /* Column number within the source table */ i16 iSorterColumn; /* Column number in the sorting index */ } *aCol; int nColumn; /* Number of used entries in aCol[] */ int nAccumulator; /* Number of columns that show through to the output. ** Additional columns are used only as parameters to ** aggregate functions */ struct AggInfo_func { /* For each aggregate function */ Expr *pExpr; /* Expression encoding the function */ FuncDef *pFunc; /* The aggregate function implementation */ int iMem; /* Memory location that acts as accumulator */ int iDistinct; /* Ephemeral table used to enforce DISTINCT */ } *aFunc; int nFunc; /* Number of entries in aFunc[] */ #ifdef SQLITE_DEBUG int iAggMagic; /* Magic number when valid */ #endif AggInfo *pNext; /* Next in list of them all */ }; /* ** Value for AggInfo.iAggMagic when the structure is valid */ #define AggInfoMagic 0x2059e99e /* ** The datatype ynVar is a signed integer, either 16-bit or 32-bit. ** Usually it is 16-bits. But if SQLITE_MAX_VARIABLE_NUMBER is greater ** than 32767 we have to make it 32-bit. 16-bit is preferred because ** it uses less memory in the Expr object, which is a big memory user ** in systems with lots of prepared statements. And few applications ** need more than about 10 or 20 variables. But some extreme users want |
︙ | ︙ | |||
3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 | int nTableLock; /* Number of locks in aTableLock */ TableLock *aTableLock; /* Required table locks for shared-cache mode */ #endif AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */ 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 */ 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 */ u32 newmask; /* Mask of new.* columns referenced */ u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */ u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */ u8 disableTriggers; /* True to disable triggers */ | > | 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 | int nTableLock; /* Number of locks in aTableLock */ TableLock *aTableLock; /* Required table locks for shared-cache mode */ #endif AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */ 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 */ u32 newmask; /* Mask of new.* columns referenced */ u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */ u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */ u8 disableTriggers; /* True to disable triggers */ |
︙ | ︙ | |||
4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 | int sqlite3RunVacuum(char**, sqlite3*, int, sqlite3_value*); char *sqlite3NameFromToken(sqlite3*, Token*); int sqlite3ExprCompare(Parse*,Expr*, Expr*, int); int sqlite3ExprCompareSkip(Expr*, Expr*, int); int sqlite3ExprListCompare(ExprList*, ExprList*, int); int sqlite3ExprImpliesExpr(Parse*,Expr*, Expr*, int); int sqlite3ExprImpliesNonNullRow(Expr*,int); void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx); int sqlite3FunctionUsesThisSrc(Expr*, SrcList*); Vdbe *sqlite3GetVdbe(Parse*); #ifndef SQLITE_UNTESTABLE void sqlite3PrngSaveState(void); | > | 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 | int sqlite3RunVacuum(char**, sqlite3*, int, sqlite3_value*); char *sqlite3NameFromToken(sqlite3*, Token*); int sqlite3ExprCompare(Parse*,Expr*, Expr*, int); 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 sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx); int sqlite3FunctionUsesThisSrc(Expr*, SrcList*); Vdbe *sqlite3GetVdbe(Parse*); #ifndef SQLITE_UNTESTABLE void sqlite3PrngSaveState(void); |
︙ | ︙ |
Changes to src/window.c.
︙ | ︙ | |||
952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 | Expr *pHaving = p->pHaving; ExprList *pSort = 0; ExprList *pSublist = 0; /* Expression list for sub-query */ Window *pMWin = p->pWin; /* Master window object */ Window *pWin; /* Window object iterator */ Table *pTab; u32 selFlags = p->selFlags; pTab = sqlite3DbMallocZero(db, sizeof(Table)); if( pTab==0 ){ return sqlite3ErrorToParser(db, SQLITE_NOMEM); } p->pSrc = 0; p->pWhere = 0; p->pGroupBy = 0; p->pHaving = 0; p->selFlags &= ~SF_Aggregate; p->selFlags |= SF_WinRewrite; | > > > > | 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 | Expr *pHaving = p->pHaving; ExprList *pSort = 0; ExprList *pSublist = 0; /* Expression list for sub-query */ Window *pMWin = p->pWin; /* Master window object */ Window *pWin; /* Window object iterator */ Table *pTab; Walker w; u32 selFlags = p->selFlags; pTab = sqlite3DbMallocZero(db, sizeof(Table)); if( pTab==0 ){ return sqlite3ErrorToParser(db, SQLITE_NOMEM); } sqlite3AggInfoPersistWalkerInit(&w, pParse); sqlite3WalkSelect(&w, p); p->pSrc = 0; p->pWhere = 0; p->pGroupBy = 0; p->pHaving = 0; p->selFlags &= ~SF_Aggregate; p->selFlags |= SF_WinRewrite; |
︙ | ︙ | |||
1038 1039 1040 1041 1042 1043 1044 | pSub = sqlite3SelectNew( pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0 ); p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); if( p->pSrc ){ Table *pTab2; | < | 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 | pSub = sqlite3SelectNew( pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0 ); p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); if( p->pSrc ){ Table *pTab2; p->pSrc->a[0].pSelect = pSub; sqlite3SrcListAssignCursors(pParse, p->pSrc); pSub->selFlags |= SF_Expanded; pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE); pSub->selFlags |= (selFlags & SF_Aggregate); if( pTab2==0 ){ /* Might actually be some other kind of error, but in that case |
︙ | ︙ |
Changes to test/fuzzdata8.db.
cannot compute difference between binary files
Changes to test/window1.test.
︙ | ︙ | |||
1739 1740 1741 1742 1743 1744 1745 1746 1747 | JOIN a AS b ON a.c=4 JOIN a AS e ON a.c=e.c WHERE a.c=(SELECT (SELECT coalesce(lead(2) OVER(),0) + sum(d.c)) FROM a AS d WHERE a.c); } {4 4 4 4} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 | JOIN a AS b ON a.c=4 JOIN a AS e ON a.c=e.c WHERE a.c=(SELECT (SELECT coalesce(lead(2) OVER(),0) + sum(d.c)) FROM a AS d WHERE a.c); } {4 4 4 4} #------------------------------------------------------------------------- reset_db do_execsql_test 54.1 { CREATE TABLE t1(a VARCHAR(20), b FLOAT); INSERT INTO t1 VALUES('1',10.0); } do_catchsql_test 54.2 { SELECT * FROM ( SELECT sum(b) OVER() AS c FROM t1 UNION SELECT b AS c FROM t1 ) WHERE c>10; } {1 {misuse of window function sum()}} do_execsql_test 54.3 { INSERT INTO t1 VALUES('2',5.0); INSERT INTO t1 VALUES('3',15.0); } do_catchsql_test 54.4 { SELECT * FROM ( SELECT sum(b) OVER() AS c FROM t1 UNION SELECT b AS c FROM t1 ) WHERE c>10; } {1 {misuse of window function sum()}} # 2020-06-05 ticket c8d3b9f0a750a529 reset_db do_execsql_test 55.1 { CREATE TABLE a(b); SELECT (SELECT b FROM a GROUP BY b HAVING (SELECT COUNT()OVER() + lead(b)OVER(ORDER BY SUM(DISTINCT b) + b)) ) FROM a UNION SELECT 99 ORDER BY 1; } {99} #------------------------------------------------------------------------ reset_db do_execsql_test 56.1 { CREATE TABLE t1(a, b INTEGER); CREATE TABLE t2(c, d); } do_catchsql_test 56.2 { SELECT avg(b) FROM t1 UNION ALL SELECT min(c) OVER () FROM t2 ORDER BY nosuchcolumn; } {1 {1st ORDER BY term does not match any column in the result set}} reset_db do_execsql_test 57.1 { CREATE TABLE t4(a, b, c, d, e); } do_catchsql_test 57.2 { SELECT b FROM t4 UNION SELECT a FROM t4 ORDER BY ( SELECT sum(x) OVER() FROM ( SELECT c AS x FROM t4 UNION SELECT d FROM t4 ORDER BY (SELECT e FROM t4) ) ); } {1 {1st ORDER BY term does not match any column in the result set}} # 2020-06-06 various dbsqlfuzz finds and # ticket 0899cf62f597d7e7 # reset_db do_execsql_test 57.1 { CREATE TABLE t1(a, b, c); INSERT INTO t1 VALUES(NULL,NULL,NULL); SELECT sum(a), min(b) OVER (), count(c) OVER (ORDER BY b) FROM t1; } {{} {} 0} do_execsql_test 57.2 { CREATE TABLE v0 ( v1 INTEGER PRIMARY KEY ) ; INSERT INTO v0 VALUES ( 10 ) ; SELECT DISTINCT v1, lead(v1) OVER() FROM v0 GROUP BY v1 ORDER BY 2; } {10 {}} do_catchsql_test 57.3 { DROP TABLE t1; CREATE TABLE t1(a); INSERT INTO t1(a) VALUES(22); CREATE TABLE t3(y); INSERT INTO t3(y) VALUES(5),(11),(-9); SELECT ( SELECT max(y) OVER( ORDER BY (SELECT x FROM (SELECT sum(y) AS x FROM t1))) ) FROM t3; } {1 {misuse of aggregate: sum()}} # 2020-06-06 ticket 1f6f353b684fc708 reset_db do_execsql_test 58.1 { CREATE TABLE a(a, b, c); INSERT INTO a VALUES(1, 2, 3); INSERT INTO a VALUES(4, 5, 6); SELECT sum(345+b) OVER (ORDER BY b), sum(avg(678)) OVER (ORDER BY c) FROM a; } {347 678.0} # 2020-06-06 ticket e5504e987e419fb0 do_catchsql_test 59.1 { DROP TABLE IF EXISTS t1; CREATE TABLE t1(x INTEGER PRIMARY KEY); INSERT INTO t1 VALUES (123); SELECT ntile( (SELECT sum(x)) ) OVER(ORDER BY x), min(x) OVER(ORDER BY x) FROM t1; } {1 {misuse of aggregate: sum()}} # 2020-06-07 ticket f7d890858f361402 do_execsql_test 60.1 { DROP TABLE IF EXISTS t1; CREATE TABLE t1 (x INTEGER PRIMARY KEY); INSERT INTO t1 VALUES (99); SELECT EXISTS(SELECT count(*) OVER() FROM t1 ORDER BY sum(x) OVER()); } {1} # 2020-06-07 test case generated by dbsqlfuzz showing how an AggInfo # object might be referenced after the sqlite3Select() call that created # it returns. This proves the need to persist all AggInfo objects until # the Parse object is destroyed. # reset_db do_execsql_test 61.1 { CREATE TABLE t1(a); INSERT INTO t1 VALUES(5),(NULL),('seventeen'); SELECT (SELECT max(x)OVER(ORDER BY x) % min(x)OVER(ORDER BY CASE x WHEN 889 THEN x WHEN x THEN x END)) FROM (SELECT (SELECT sum(CAST(a IN(SELECT (SELECT max(x)OVER(ORDER BY CASE x WHEN 889 THEN 299 WHEN 863 THEN 863 END)) FROM (SELECT (SELECT sum(CAST((SELECT (SELECT max(x)OVER(ORDER BY x) / min(x)OVER(ORDER BY CASE x WHEN 889 THEN 299 WHEN -true THEN 863 END)) FROM (SELECT (SELECT sum(CAST(a IN(SELECT (SELECT max(x) & sum ( a )OVER(ORDER BY CASE x WHEN -8 THEN 299 WHEN 863 THEN 863 END)) FROM (SELECT (SELECT sum(CAST(a AS )) FROM t1) AS x FROM t1)) AS t1 )) FROM t1) AS x FROM t1)) AS x )) FROM t1) AS x FROM t1)) AS real)) FROM t1) AS x FROM t1); } {{} {} {}} finish_test |