Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Alternative fix to ticket [c8d3b9f0a750a529]: Prior to deleting or modifying an Expr not that is referenced by an AggInfo, modify the AggInfo to get its own copy of the original Expr. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | persist-agginfo |
Files: | files | file ages | folders |
SHA3-256: |
7682d8a768fbccfe0cc956e9f6481637 |
User & Date: | drh 2020-06-07 17:33:18 |
Context
2020-06-07
| ||
20:18 | AggInfo objects might be referenced even after the sqlite3Select() function that created them has exited. So AggInfo cannot be a stack variable. And it must not be freed until the Parse object is destroyed. (check-in: 3c840b4d user: drh tags: persist-agginfo) | |
17:33 | Alternative fix to ticket [c8d3b9f0a750a529]: Prior to deleting or modifying an Expr not that is referenced by an AggInfo, modify the AggInfo to get its own copy of the original Expr. (check-in: 7682d8a7 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.
︙ | ︙ | |||
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; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 5704 5705 5706 5707 5708 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 | #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( !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( pAggInfo->iAggMagic==AggInfoMagic ); assert( pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN || pExpr->op==TK_FUNCTION || pExpr->op==TK_AGG_FUNCTION ); if( pExpr->op==TK_COLUMN || 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; | | | 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 | 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/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); } |
︙ | ︙ | |||
5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 | 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; memset(&sAggInfo, 0, sizeof(sAggInfo)); #if SELECTTRACE_ENABLED SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain)); if( sqlite3SelectTrace & 0x100 ){ sqlite3TreeViewSelect(0, p, 0); } #endif | > > > | 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 | 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; memset(&sAggInfo, 0, sizeof(sAggInfo)); #ifdef SQLITE_DEBUG sAggInfo.iAggMagic = AggInfoMagic; #endif #if SELECTTRACE_ENABLED SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain)); if( sqlite3SelectTrace & 0x100 ){ sqlite3TreeViewSelect(0, p, 0); } #endif |
︙ | ︙ | |||
5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 | #if SELECTTRACE_ENABLED SELECTTRACE(0x1,pParse,p,("end compound-select processing\n")); if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ sqlite3TreeViewSelect(0, p, 0); } #endif if( p->pNext==0 ) ExplainQueryPlanPop(pParse); return rc; } #endif /* Do the WHERE-clause constant propagation optimization if this is ** a join. No need to speed time on this operation for non-join queries ** as the equivalent optimization will be handled by query planner in | > | 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 5932 5933 | #if SELECTTRACE_ENABLED SELECTTRACE(0x1,pParse,p,("end compound-select processing\n")); if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ sqlite3TreeViewSelect(0, p, 0); } #endif if( p->pNext==0 ) ExplainQueryPlanPop(pParse); assert( sAggInfo.nFunc==0 && sAggInfo.nColumn==0 ); return rc; } #endif /* Do the WHERE-clause constant propagation optimization if this is ** a join. No need to speed time on this operation for non-join queries ** as the equivalent optimization will be handled by query planner in |
︙ | ︙ | |||
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); | > > > > > > > > > > | > > > > > > > > > > > | > > > > > | 6792 6793 6794 6795 6796 6797 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 6833 6834 6835 | 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); if( sAggInfo.aCol ){ #ifdef SQLITE_DEBUG for(i=0; i<sAggInfo.nColumn; i++){ Expr *pExpr = sAggInfo.aCol[i].pExpr; assert( pExpr!=0 || pParse->db->mallocFailed ); if( pExpr==0 ) continue; assert( pExpr->pAggInfo==&sAggInfo ); assert( pExpr->iAgg==i ); } #endif sqlite3DbFree(db, sAggInfo.aCol); } if( sAggInfo.aFunc ){ #ifdef SQLITE_DEBUG for(i=0; i<sAggInfo.nFunc; i++){ Expr *pExpr = sAggInfo.aFunc[i].pExpr; assert( pExpr!=0 || pParse->db->mallocFailed ); if( pExpr==0 ) continue; assert( pExpr->pAggInfo==&sAggInfo ); assert( pExpr->iAgg==i ); } #endif sqlite3DbFree(db, sAggInfo.aFunc); } #ifdef SQLITE_DEBUG sAggInfo.iAggMagic = 0; #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 | 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 }; /* ** 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 |
︙ | ︙ | |||
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); | > | 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 | 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.
︙ | ︙ | |||
1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 | FROM a 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 | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1738 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 | FROM a 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} reset_db finish_test |