From: dan Date: Thu, 28 Mar 2019 16:15:05 +0000 (+0000) Subject: Prevent aliases of window functions expressions from being used as arguments to aggre... X-Git-Tag: version-3.28.0~78 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4ded26a53c4df312e9fd06facbbf70377e969983;p=thirdparty%2Fsqlite.git Prevent aliases of window functions expressions from being used as arguments to aggregate or other window functions. FossilOrigin-Name: 1e16d3e8fc60d39ca3899759ff15d355fdd7d3e23b325d8d2b0f954e11ce8dce --- diff --git a/manifest b/manifest index 204ab6c6a1..71ae74e2c8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Show\sthe\spointer\saddress\sfor\sWindow\sobjects\sin\sthe\sTreeView\sdisplay. -D 2019-03-28T13:53:12.447 +C Prevent\saliases\sof\swindow\sfunctions\sexpressions\sfrom\sbeing\sused\sas\sarguments\sto\saggregate\sor\sother\swindow\sfunctions. +D 2019-03-28T16:15:05.163 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -514,14 +514,14 @@ F src/pragma.h a776bb9c915207e9d1117b5754743ddf1bf6a39cc092a4a44e74e6cb5fab1177 F src/prepare.c 78027c6231fbb19ca186a5f5f0c0a1375d9c2cec0655273f9bd90d9ff74a34b3 F src/printf.c 93a3d539019264683a444bc043c875e9a6cca43fe935ae7bf6cfff0af3bba118 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c f20cb5b953bd927e8c6b6e01662cce066a632b5d3a21d2938b93de0825aef5d5 +F src/resolve.c f201b8f9fbcfecb9a3af7cab04ceec30649ac33689bbeb4f9dcaa13d1ead943f F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c 9263f5c30dd44c7ac2eb29f40a7ec64322a96885b71c00de6bc30b756c2e1c49 F src/shell.c.in c1986496062f9dba4ed5b70db06b5e0f32e1954cdcfab0b30372c6c186796810 F src/sqlite.h.in f765fce74038607388d3a96cd7fad892f363bdcde24911565edf610ecf69534c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 960f1b86c3610fa23cb6a267572a97dcf286e77aa0dd3b9b23292ffaa1ea8683 -F src/sqliteInt.h 773a43d21001311853e2e213f693ed5ac64c5ec2cf4c7fc492715421f244454f +F src/sqliteInt.h 15e1fab2ca4c522140a56f783376be059fdcc5791e6874d118c8d92c70101742 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1690,8 +1690,8 @@ F test/window7.tcl 6a1210f05d40ec89c22960213a22cd3f98d4e2f2eb20646c83c8c30d4d761 F test/window7.test ce7f865241fdd1c5c4db869cd7bb2986c3be836bc2e73649a6846dd920f63e0f F test/window8.tcl 97de3829e0e1aae2c3aaae41a55c54bc1b0751bbc80dfdd93020431b7a889dad F test/window8.test 0dd7e2d32605bf59dc6163b924faeff5951419c1c17a9e506e5a38606e97ab7e -F test/windowerr.tcl 727d77959ac512b473dd2d659937f58688ce5460482a442c2d569fc8656491e5 -F test/windowerr.test 7962cf9b39f27b11ea5c62105ab2322a61ceac098dce536e2b8569c3053f62e7 +F test/windowerr.tcl 678bb2c3ddcaaf605163bd9fe647454fa0097688cfd2fecc5dd9f3a5b45b13f2 +F test/windowerr.test 7eb7439332d3855dd53c58dca8838f6990746f40fac7045c0153172083a9452b F test/windowfault.test cb27a4d8c85982733b123af667921df3a96e23d3739b15d414de75054b334cbe F test/with1.test a07b5aad7f77acdf13e52e8814ea94606fcc72e9ea4c99baf293e9d7c63940be F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1ab @@ -1813,7 +1813,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d6a07433421ac9a475ff0014587f0beefdf88ce89aef9443f8a20cd26083731f -R 3deaf590c74da9946fe9cff2d3a982aa -U drh -Z 76c6e9606a0268ca5b5e4d17c3f7d054 +P 1ae70ad2ffd36c27b154940126c5e3ed00c05c0d8761d9320a65a03b1b4e4dc6 +R 36583bf16af85997a9baf6b6d0ad966b +U dan +Z 077880857f391af66669ac86aa73717d diff --git a/manifest.uuid b/manifest.uuid index 1182e56496..345720bd38 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1ae70ad2ffd36c27b154940126c5e3ed00c05c0d8761d9320a65a03b1b4e4dc6 \ No newline at end of file +1e16d3e8fc60d39ca3899759ff15d355fdd7d3e23b325d8d2b0f954e11ce8dce \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index 2644e069fa..eb9e137fdc 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -435,6 +435,10 @@ static int lookupName( sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs); return WRC_Abort; } + if( (pNC->ncFlags&NC_AllowWin)==0 && ExprHasProperty(pOrig, EP_Win) ){ + sqlite3ErrorMsg(pParse, "misuse of aliased window function %s",zAs); + return WRC_Abort; + } if( sqlite3ExprVectorSize(pOrig)!=1 ){ sqlite3ErrorMsg(pParse, "row value misused"); return WRC_Abort; @@ -725,6 +729,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ const char *zId; /* The function name. */ FuncDef *pDef; /* Information about the function */ u8 enc = ENC(pParse->db); /* The database encoding */ + int savedAllowFlags = (pNC->ncFlags & (NC_AllowAgg | NC_AllowWin)); assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); zId = pExpr->u.zToken; @@ -846,8 +851,11 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ pNC->nErr++; } if( is_agg ){ + /* Window functions may not be arguments of aggregate functions. + ** Or arguments of other window functions. But aggregate functions + ** may be arguments for window functions. */ #ifndef SQLITE_OMIT_WINDOWFUNC - pNC->ncFlags &= ~(pExpr->y.pWin ? NC_AllowWin : NC_AllowAgg); + pNC->ncFlags &= ~(NC_AllowWin | (!pExpr->y.pWin ? NC_AllowAgg : 0)); #else pNC->ncFlags &= ~NC_AllowAgg; #endif @@ -868,7 +876,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ pExpr->y.pWin->pNextWin = pSel->pWin; pSel->pWin = pExpr->y.pWin; } - pNC->ncFlags |= NC_AllowWin; + pNC->ncFlags |= NC_HasWin; }else #endif /* SQLITE_OMIT_WINDOWFUNC */ { @@ -886,8 +894,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX); } - pNC->ncFlags |= NC_AllowAgg; } + pNC->ncFlags |= savedAllowFlags; } /* FIX ME: Compute pExpr->affinity based on the expected return ** type of the function @@ -1648,8 +1656,8 @@ int sqlite3ResolveExprNames( Walker w; if( pExpr==0 ) return SQLITE_OK; - savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg); - pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg); + savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin); + pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin); w.pParse = pNC->pParse; w.xExprCallback = resolveExprStep; w.xSelectCallback = resolveSelectStep; @@ -1668,6 +1676,9 @@ int sqlite3ResolveExprNames( if( pNC->ncFlags & NC_HasAgg ){ ExprSetProperty(pExpr, EP_Agg); } + if( pNC->ncFlags & NC_HasWin ){ + ExprSetProperty(pExpr, EP_Win); + } pNC->ncFlags |= savedHasAgg; return pNC->nErr>0 || w.pParse->nErr>0; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 13f2339dad..7480fecf47 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2524,6 +2524,7 @@ struct Expr { #define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */ #define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */ #define EP_Quoted 0x4000000 /* TK_ID was originally quoted */ +#define EP_Win 0x8000000 /* Contains window functions */ /* ** The EP_Propagate mask is a set of properties that automatically propagate @@ -2780,6 +2781,7 @@ struct NameContext { #define NC_MinMaxAgg 0x1000 /* min/max aggregates seen. See note above */ #define NC_Complex 0x2000 /* True if a function or subquery seen */ #define NC_AllowWin 0x4000 /* Window functions are allowed here */ +#define NC_HasWin 0x8000 /* One or more window functions seen */ /* ** An instance of the following object describes a single ON CONFLICT diff --git a/test/windowerr.tcl b/test/windowerr.tcl index d69d8b7f9e..8e404de88a 100644 --- a/test/windowerr.tcl +++ b/test/windowerr.tcl @@ -47,6 +47,14 @@ foreach {tn frame} { ) FROM t1 ORDER BY 1 " } +errorsql_test 2.1 { + SELECT sum( sum(a) OVER () ) FROM t1; +} + +errorsql_test 2.2 { + SELECT sum(a) OVER () AS xyz FROM t1 ORDER BY sum(xyz); +} + finish_test diff --git a/test/windowerr.test b/test/windowerr.test index 80503afeec..63d1af27d7 100644 --- a/test/windowerr.test +++ b/test/windowerr.test @@ -86,4 +86,14 @@ do_test 1.8 { catch { execsql { ) FROM t1 ORDER BY 1 } } } 1 +# PG says ERROR: aggregate function calls cannot contain window function calls +do_test 2.1 { catch { execsql { + SELECT sum( sum(a) OVER () ) FROM t1; +} } } 1 + +# PG says ERROR: column "xyz" does not exist +do_test 2.2 { catch { execsql { + SELECT sum(a) OVER () AS xyz FROM t1 ORDER BY sum(xyz); +} } } 1 + finish_test