From: drh <> Date: Mon, 2 Sep 2024 11:17:04 +0000 (+0000) Subject: Improved error messages on percentile functions. More tests cases for X-Git-Tag: version-3.47.0~158^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fheads%2Fordered-set-agg;p=thirdparty%2Fsqlite.git Improved error messages on percentile functions. More tests cases for percentile and for ordered-set aggregates. FossilOrigin-Name: e1bca168e70335fa2f9537632fd16e374c566a564fab4974c0b8f61cb63d08ce --- diff --git a/ext/misc/percentile.c b/ext/misc/percentile.c index 3d9ad89193..320d7a5301 100644 --- a/ext/misc/percentile.c +++ b/ext/misc/percentile.c @@ -213,6 +213,28 @@ static int percentBinarySearch(Percentile *p, double y, int bExact){ return iFirst; } +/* +** Generate an error for a percentile function. +** +** The error format string must have exactly one occurrance of "%%s()" +** (with two '%' characters). That substring will be replaced by the name +** of the function. +*/ +static void percentError(sqlite3_context *pCtx, const char *zFormat, ...){ + PercentileFunc *pFunc = (PercentileFunc*)sqlite3_user_data(pCtx); + char *zMsg1; + char *zMsg2; + va_list ap; + + va_start(ap, zFormat); + zMsg1 = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + zMsg2 = sqlite3_mprintf(zMsg1, pFunc->zName); + sqlite3_result_error(pCtx, zMsg2, -1); + sqlite3_free(zMsg1); + sqlite3_free(zMsg2); +} + /* ** The "step" function for percentile(Y,P) is called once for each ** input row. @@ -235,12 +257,9 @@ static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){ if( (eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT) || rPct<0.0 || rPct>1.0 ){ - char *zMsg; - zMsg = sqlite3_mprintf("the fraction argument to %s()" - " is not between 0.0 and %.1f", - pFunc->zName, (double)pFunc->mxFrac); - sqlite3_result_error(pCtx, zMsg, -1); - sqlite3_free(zMsg); + percentError(pCtx, "the fraction argument to %%s()" + " is not between 0.0 and %.1f", + (double)pFunc->mxFrac); return; } } @@ -255,13 +274,8 @@ static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){ p->rPct = rPct; p->bPctValid = 1; }else if( !percentSameValue(p->rPct,rPct) ){ - PercentileFunc *pFunc = (PercentileFunc*)sqlite3_user_data(pCtx); - char *zMsg; - zMsg = sqlite3_mprintf("the fraction argument to %s()" - " is not the same for all input rows", - pFunc->zName); - sqlite3_result_error(pCtx, zMsg, -1); - sqlite3_free(zMsg); + percentError(pCtx, "the fraction argument to %%s()" + " is not the same for all input rows"); return; } @@ -272,15 +286,14 @@ static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){ /* If not NULL, then Y must be numeric. Otherwise throw an error. ** Requirement 4 */ if( eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT ){ - sqlite3_result_error(pCtx, "1st argument to percentile() is not " - "numeric", -1); + percentError(pCtx, "input to %%s() is not numeric"); return; } /* Throw an error if the Y value is infinity or NaN */ y = sqlite3_value_double(argv[0]); if( percentIsInfinity(y) ){ - sqlite3_result_error(pCtx, "Inf input to percentile()", -1); + percentError(pCtx, "Inf input to %%s()"); return; } diff --git a/manifest b/manifest index 302b6b6106..c3fb0bad7a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sname\sof\sthe\senabling\scompile-time\smacro\sto\nSQLITE_ENABLE_ORDERED_SET_AGGREGATES. -D 2024-09-02T09:40:37.769 +C Improved\serror\smessages\son\spercentile\sfunctions.\s\sMore\stests\scases\sfor\npercentile\sand\sfor\sordered-set\saggregates. +D 2024-09-02T11:17:04.726 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -410,7 +410,7 @@ F ext/misc/nextchar.c 7877914c2a80c2f181dd04c3dbef550dfb54c93495dc03da2403b5dd58 F ext/misc/noop.c f1a21cc9b7a4e667e5c8458d80ba680b8bd4315a003f256006046879f679c5a0 F ext/misc/normalize.c bd84355c118e297522aba74de34a4fd286fc775524e0499b14473918d09ea61f F ext/misc/pcachetrace.c f4227ce03fb16aa8d6f321b72dd051097419d7a028a9853af048bee7645cb405 -F ext/misc/percentile.c b9b06a30882fb588161db3d558fb0bc48a0ae84b2b76471baf19e48b438cfe77 +F ext/misc/percentile.c 4e333fc78d2a7b9cf362e29f30fa3f486cdab9e69fbc9aa0f680399683aa22f7 F ext/misc/prefixes.c 82645f79229877afab08c8b08ca1e7fa31921280906b90a61c294e4f540cd2a6 F ext/misc/qpvtab.c fc189e127f68f791af90a487f4460ec91539a716daf45a0c357e963fd47cc06c F ext/misc/randomjson.c ef835fc64289e76ac4873b85fe12f9463a036168d7683cf2b773e36e6262c4ed @@ -754,7 +754,7 @@ F src/os_win.c 6ff43bac175bd9ed79e7c0f96840b139f2f51d01689a638fd05128becf94908a F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c b08600ebf0db90b6d1e9b8b6577c6fa3877cbe1a100bd0b2899e4c6e9adad4b3 F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a -F src/parse.y c168522b4929c84e11577d61f8f61c998127a5032203e8c386cb8621fe158ee0 +F src/parse.y a7a8d42eeff01d267444ddb476029b0b1726fb70ae3d77984140f17ad02e2d61 F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484 F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5 F src/pcache1.c 49516ad7718a3626f28f710fa7448ef1fce3c07fd169acbb4817341950264319 @@ -1517,7 +1517,7 @@ F test/parser1.test 6ccdf5e459a5dc4673d3273dc311a7e9742ca952dd0551a6a6320d27035c F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442 F test/pendingrace.test e99efc5ab3584da3dfc8cd6a0ec4e5a42214820574f5ea24ee93f1d84655f463 -F test/percentile.test 827b3916a6db87d0521341cb828d0101a10de265e49c43503bbdb56e661f865f +F test/percentile.test 52ba89d6ee6b65f770972b67dace358bab7cdbd532803d3db157845268e789cd F test/permutations.test 405542f1d659942994a6b38a9e024cf5cfd23eaa68c806aeb24a72d7c9186e80 F test/pg_common.tcl 3b27542224db1e713ae387459b5d117c836a5f6e328846922993b6d2b7640d9f F test/pragma.test 11cb9310c42f921918f7f563e3c0b6e70f9f9c3a6a1cf12af8fccb6c574f3882 @@ -2211,8 +2211,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8b91b74931c36e1955ef933a07d8ec40c8b54c882efe7084d179168867c5244f -R 87b66cdb033da0a37b7575ccb3ae22cb +P 3b1cdddf8339cc339ec74cd8be2bfa42e62b500048a444eb9e5d9817bc4702ae +R a80c34160df19b1603ad0e7833a0d0c3 U drh -Z d0d824ad26699ac4f4773aa97bb7dc96 +Z baa1dd0d6096edf0ada0dc3da2ddafed # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ef8888d75b..126ce65bc7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3b1cdddf8339cc339ec74cd8be2bfa42e62b500048a444eb9e5d9817bc4702ae +e1bca168e70335fa2f9537632fd16e374c566a564fab4974c0b8f61cb63d08ce diff --git a/src/parse.y b/src/parse.y index 8ff2326202..a6a5e046db 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1225,7 +1225,7 @@ expr(A) ::= idj(X) LP STAR RP. { u8 enc = ENC(pParse->db); assert( pExpr!=0 ); /* Because otherwise pParse->nErr would not be zero */ assert( p!=0 ); /* Because otherwise pParse->nErr would not be zero */ - pDef = sqlite3FindFunction(pParse->db, pExpr->u.zToken, p->nExpr, enc, 0); + pDef = sqlite3FindFunction(pParse->db, pExpr->u.zToken, -2, enc, 0); if( pDef==0 || (pDef->funcFlags & SQLITE_SELFORDER1)==0 ){ sqlite3ErrorMsg(pParse, "%#T() is not an ordered-set aggregate", pExpr); }else if( isDistinct==SF_Distinct ){ diff --git a/test/percentile.test b/test/percentile.test index 3207aea096..a6a29da34e 100644 --- a/test/percentile.test +++ b/test/percentile.test @@ -9,7 +9,8 @@ # #*********************************************************************** # This file implements regression tests for SQLite library. The -# focus of this file is percentile.c extension +# focus of this file is percentile.c extension. This also tests +# the SQLITE_ENABLE_ORDERED_SET_AGGREGATES compile-time option. # set testdir [file dirname $argv0] @@ -25,50 +26,135 @@ do_test percentile-1.0 { } execsql {SELECT percentile(x,0) FROM t1} } {1.0} -foreach {in out} { - 100 11.0 - 50 8.0 - 12.5 4.0 - 15 4.4 - 20 5.2 - 80 11.0 - 89 11.0 +foreach {in out disc} { + 100 11.0 11.0 + 50 8.0 8.0 + 12.5 4.0 4.0 + 15 4.4 4.0 + 20 5.2 4.0 + 80 11.0 11.0 + 89 11.0 11.0 } { - do_test percentile-1.1.$in { + do_test percentile-1.1.$in.1 { execsql {SELECT percentile(x,$in) FROM t1} } $out + do_test percentile-1.1.$in.2 { + execsql {SELECT percentile_cont(x,$in*0.01) FROM t1} + } $out + do_test percentile-1.1.$in.3 { + execsql {SELECT percentile_disc(x,$in*0.01) FROM t1} + } $disc + if {$in==50} { + do_test percentile-1.1.$in.4 { + execsql {SELECT median(x) FROM t1} + } $out + } + ifcapable ordered_set_aggregates { + do_test percentile-1.1.$in.5 { + execsql {SELECT percentile($in)WITHIN GROUP(ORDER BY x) FROM t1} + } $out + do_test percentile-1.1.$in.6 { + execsql {SELECT percentile_cont($in*0.01) WITHIN GROUP(ORDER BY x) + FROM t1} + } $out + do_test percentile-1.1.$in.7 { + execsql {SELECT percentile_disc($in*0.01) WITHIN GROUP(ORDER BY x) + FROM t1} + } $disc + if {$in==50} { + do_test percentile-1.1.$in.8 { + execsql {SELECT median() WITHIN GROUP (ORDER BY x) FROM t1} + } $out + } + } } do_execsql_test percentile-1.1.median { SELECT median(x) FROM t1; } 8.0 +ifcapable ordered_set_aggregates { + do_execsql_test percentile-1.1.median { + SELECT median() WITHIN GROUP (ORDER BY x) FROM t1; + } 8.0 + do_execsql_test percentile-1.1.distinct.1 { + SELECT median(DISTINCT x) FROM t1; + } 7.0 + do_catchsql_test percentile-1.1.distinct.2 { + SELECT percentile(DISTINCT 50) WITHIN GROUP (ORDER BY x) FROM t1; + } {1 {DISTINCT not allowed on ordered-set aggregate percentile()}} +} else { + do_catchsql_test percentile-1.1.median { + SELECT median() WITHIN GROUP (ORDER BY x) FROM t1; + } {1 {near "(": syntax error}} +} # Add some NULL values. # do_test percentile-1.2 { execsql {INSERT INTO t1 VALUES(NULL),(NULL);} } {} -foreach {in out} { - 100 11.0 - 50 8.0 - 12.5 4.0 - 15 4.4 - 20 5.2 - 80 11.0 - 89 11.0 +foreach {in out disc} { + 100 11.0 11.0 + 50 8.0 8.0 + 12.5 4.0 4.0 + 15 4.4 4.0 + 20 5.2 4.0 + 80 11.0 11.0 + 89 11.0 11.0 } { - do_test percentile-1.3.$in { + do_test percentile-1.3.$in.1 { execsql {SELECT percentile(x,$in) FROM t1} } $out + do_test percentile-1.3.$in.2 { + execsql {SELECT percentile_cont(x,$in*0.01) FROM t1} + } $out + do_test percentile-1.3.$in.3 { + execsql {SELECT percentile_disc(x,$in*0.01) FROM t1} + } $disc + if {$in==50} { + do_test percentile-1.3.$in.4 { + execsql {SELECT median(x) FROM t1} + } $out + } + ifcapable ordered_set_aggregates { + do_test percentile-1.3.$in.5 { + execsql {SELECT percentile($in)WITHIN GROUP(ORDER BY x) FROM t1} + } $out + do_test percentile-1.3.$in.6 { + execsql {SELECT percentile_cont($in*0.01) WITHIN GROUP(ORDER BY x) + FROM t1} + } $out + do_test percentile-1.3.$in.7 { + execsql {SELECT percentile_disc($in*0.01) WITHIN GROUP(ORDER BY x) + FROM t1} + } $disc + if {$in==50} { + do_test percentile-1.3.$in.8 { + execsql {SELECT median() WITHIN GROUP (ORDER BY x) FROM t1} + } $out + } + } } # The second argument to percentile can change some, but not much. # -do_test percentile-1.4 { +do_test percentile-1.4.1 { catchsql {SELECT round(percentile(x, 15+0.000001*rowid),1) FROM t1} } {0 4.4} -do_test percentile-1.5 { - catchsql {SELECT round(percentile(x, 15+0.1*rowid),1) FROM t1} +do_test percentile-1.4.2 { + catchsql {SELECT round(percentile_cont(x,(15+0.000001*rowid)*0.01),1) FROM t1} +} {0 4.4} +do_test percentile-1.4.3 { + catchsql {SELECT percentile_disc(x, (15+0.000001*rowid)*0.01) FROM t1} +} {0 4.0} +do_test percentile-1.5.1 { + catchsql {SELECT percentile(x, 15+0.1*rowid) FROM t1} } {1 {the fraction argument to percentile() is not the same for all input rows}} +do_test percentile-1.5.2 { + catchsql {SELECT percentile_cont(x, (15+0.1*rowid)*0.01) FROM t1} +} {1 {the fraction argument to percentile_cont() is not the same for all input rows}} +do_test percentile-1.5.3 { + catchsql {SELECT percentile_disc(x, (15+0.1*rowid)*0.01) FROM t1} +} {1 {the fraction argument to percentile_disc() is not the same for all input rows}} # Input values in a random order # @@ -78,28 +164,100 @@ do_test percentile-1.6 { INSERT INTO t2 SELECT x+0.0 FROM t1 ORDER BY random(); } } {} -foreach {in out} { - 100 11.0 - 50 8.0 - 12.5 4.0 - 15 4.4 - 20 5.2 - 80 11.0 - 89 11.0 +foreach {in out disc} { + 100 11.0 11.0 + 50 8.0 8.0 + 12.5 4.0 4.0 + 15 4.4 4.0 + 20 5.2 4.0 + 80 11.0 11.0 + 89 11.0 11.0 } { - do_test percentile-1.7.$in { + do_test percentile-1.7.$in.1 { execsql {SELECT percentile(x,$in) FROM t2} } $out + do_test percentile-1.7.$in.2 { + execsql {SELECT percentile_cont(x,$in*0.01) FROM t2} + } $out + do_test percentile-1.7.$in.3 { + execsql {SELECT percentile_disc(x,$in*0.01) FROM t2} + } $disc + if {$in==50} { + do_test percentile-1.7.$in.4 { + execsql {SELECT median(x) FROM t2} + } $out + } + ifcapable ordered_set_aggregates { + do_test percentile-1.7.$in.5 { + execsql {SELECT percentile($in)WITHIN GROUP(ORDER BY x) FROM t2} + } $out + do_test percentile-1.7.$in.6 { + execsql {SELECT percentile_cont($in*0.01) WITHIN GROUP(ORDER BY x) + FROM t2} + } $out + do_test percentile-1.7.$in.7 { + execsql {SELECT percentile_disc($in*0.01) WITHIN GROUP(ORDER BY x) + FROM t2} + } $disc + if {$in==50} { + do_test percentile-1.7.$in.8 { + execsql {SELECT median() WITHIN GROUP (ORDER BY x) FROM t2} + } $out + } + } } # Wrong number of arguments # -do_test percentile-1.8 { +do_test percentile-1.8.1 { catchsql {SELECT percentile(x,0,1) FROM t1} } {1 {wrong number of arguments to function percentile()}} -do_test percentile-1.9 { +do_test percentile-1.8.2 { + catchsql {SELECT percentile_cont(x,0,1) FROM t1} +} {1 {wrong number of arguments to function percentile_cont()}} +do_test percentile-1.8.3 { + catchsql {SELECT percentile_disc(x,0,1) FROM t1} +} {1 {wrong number of arguments to function percentile_disc()}} +do_test percentile-1.8.4 { + catchsql {SELECT median(x,0) FROM t1} +} {1 {wrong number of arguments to function median()}} +ifcapable ordered_set_aggregates { + do_test percentile-1.8.5 { + catchsql {SELECT percentile(0,1) WITHIN GROUP(ORDER BY x) FROM t1} + } {1 {wrong number of arguments to function percentile()}} + do_test percentile-1.8.2 { + catchsql {SELECT percentile_cont(0,1)WITHIN GROUP (ORDER BY x) FROM t1} + } {1 {wrong number of arguments to function percentile_cont()}} + do_test percentile-1.8.3 { + catchsql {SELECT percentile_disc(0,1)WITHIN GROUP (ORDER BY x) FROM t1} + } {1 {wrong number of arguments to function percentile_disc()}} + do_test percentile-1.8.4 { + catchsql {SELECT median(x) WITHIN GROUP (ORDER BY x) FROM t1} + } {1 {wrong number of arguments to function median()}} +} +do_test percentile-1.9.1 { catchsql {SELECT percentile(x) FROM t1} } {1 {wrong number of arguments to function percentile()}} +do_test percentile-1.9.2 { + catchsql {SELECT percentile_cont(x) FROM t1} +} {1 {wrong number of arguments to function percentile_cont()}} +do_test percentile-1.9.3 { + catchsql {SELECT percentile_disc(x) FROM t1} +} {1 {wrong number of arguments to function percentile_disc()}} +do_test percentile-1.9.4 { + catchsql {SELECT median() FROM t1} +} {1 {wrong number of arguments to function median()}} +ifcapable ordered_set_aggregates { + do_test percentile-1.9.5 { + catchsql {SELECT percentile() WITHIN GROUP(ORDER BY x) FROM t1} + } {1 {wrong number of arguments to function percentile()}} + do_test percentile-1.9.6 { + catchsql {SELECT percentile_cont()WITHIN GROUP (ORDER BY x) FROM t1} + } {1 {wrong number of arguments to function percentile_cont()}} + do_test percentile-1.9.7 { + catchsql {SELECT percentile_disc()WITHIN GROUP (ORDER BY x) FROM t1} + } {1 {wrong number of arguments to function percentile_disc()}} +} # Second argument must be numeric # @@ -130,13 +288,28 @@ do_test percentile-1.14.3 { # First argument is not NULL and is not NUMERIC # -do_test percentile-1.15 { +do_test percentile-1.15.1 { catchsql { BEGIN; UPDATE t1 SET x='50' WHERE x IS NULL; SELECT percentile(x, 50) FROM t1; } -} {1 {1st argument to percentile() is not numeric}} +} {1 {input to percentile() is not numeric}} +do_test percentile-1.15.2 { + catchsql { + SELECT percentile_cont(x, 0.50) FROM t1; + } +} {1 {input to percentile_cont() is not numeric}} +do_test percentile-1.15.3 { + catchsql { + SELECT percentile_disc(x, 0.50) FROM t1; + } +} {1 {input to percentile_disc() is not numeric}} +do_test percentile-1.15.4 { + catchsql { + SELECT median(x) FROM t1; + } +} {1 {input to median() is not numeric}} do_test percentile-1.16 { catchsql { ROLLBACK; @@ -144,7 +317,7 @@ do_test percentile-1.16 { UPDATE t1 SET x=x'3530' WHERE x IS NULL; SELECT percentile(x, 50) FROM t1; } -} {1 {1st argument to percentile() is not numeric}} +} {1 {input to percentile() is not numeric}} do_test percentile-1.17 { catchsql { ROLLBACK; @@ -172,7 +345,7 @@ do_test percentile-1.19 { # Infinity as an input # -do_test percentile-1.20 { +do_test percentile-1.20.1 { catchsql { DELETE FROM t1; INSERT INTO t1 SELECT x+0.0 FROM t2; @@ -180,6 +353,43 @@ do_test percentile-1.20 { SELECT percentile(x,50) from t1; } } {1 {Inf input to percentile()}} +do_test percentile-1.20.2 { + catchsql { + SELECT percentile_cont(x,0.50) from t1; + } +} {1 {Inf input to percentile_cont()}} +do_test percentile-1.20.3 { + catchsql { + SELECT percentile_disc(x,0.50) from t1; + } +} {1 {Inf input to percentile_disc()}} +do_test percentile-1.20.4 { + catchsql { + SELECT median(x) from t1; + } +} {1 {Inf input to median()}} +ifcapable ordered_set_aggregates { + do_test percentile-1.20.5 { + catchsql { + SELECT percentile(50) WITHIN GROUP (ORDER BY x) from t1; + } + } {1 {Inf input to percentile()}} + do_test percentile-1.20.6 { + catchsql { + SELECT percentile_cont(0.50) WITHIN GROUP (ORDER BY x) from t1; + } + } {1 {Inf input to percentile_cont()}} + do_test percentile-1.20.7 { + catchsql { + SELECT percentile_disc(0.50) WITHIN GROUP(ORDER BY X) from t1; + } + } {1 {Inf input to percentile_disc()}} + do_test percentile-1.20.8 { + catchsql { + SELECT median() WITHIN GROUP (ORDER BY x) from t1; + } + } {1 {Inf input to median()}} +} do_test percentile-1.21 { catchsql { UPDATE t1 SET x=-1.0e300*1.0e300 WHERE rowid=5; @@ -228,50 +438,63 @@ do_execsql_test percentile-3.0 { (6, 'F', 'three', 0.0), (7, 'G', 'one', 2.7); } -do_execsql_test percentile-3.1 { -SELECT a, b, c, d, - group_concat(b,'.') OVER W1 AS 'elements', - median(d) OVER W1 AS 'median' - FROM t1 - WINDOW W1 AS (ORDER BY c, a ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) -} { - 1 A one 8.4 A.D 9.7 - 4 D one 11.0 A.D.G 8.4 - 7 G one 2.7 D.G.C 5.9 - 3 C three 5.9 G.C.F 2.7 - 6 F three 0.0 C.F.B 5.9 - 2 B two 7.1 F.B.E 7.1 - 5 E two 12.5 B.E 9.8 -} -do_execsql_test percentile-3.2 { -SELECT a, b, c, d, - group_concat(b,'.') OVER W1 AS 'elements', - median(d) OVER W1 AS 'median' - FROM t1 - WINDOW W1 AS (ORDER BY c, a ROWS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING) -} { - 1 A one 8.4 A.D 9.7 - 4 D one 11.0 A.D.G 8.4 - 7 G one 2.7 A.D.G.C 7.15 - 3 C three 5.9 A.D.G.C.F 5.9 - 6 F three 0.0 A.D.G.C.F.B 6.5 - 2 B two 7.1 A.D.G.C.F.B.E 7.1 - 5 E two 12.5 A.D.G.C.F.B.E 7.1 -} -do_execsql_test percentile-3.3 { -SELECT a, b, c, d, - group_concat(b,'.') OVER W1 AS 'elements', - median(d) OVER W1 AS 'median' - FROM t1 - WINDOW W1 AS (ORDER BY c, a ROWS BETWEEN 1 PRECEDING AND UNBOUNDED FOLLOWING) +foreach {id oba expr} { + 1 0 "median(d)" + 2 0 "percentile(d,50)" + 3 0 "percentile_cont(d,0.5)" + 4 1 "median() WITHIN GROUP (ORDER BY d)" + 5 1 "percentile(50) WITHIN GROUP (ORDER BY d)" + 6 1 "percentile_cont(0.5) WITHIN GROUP (ORDER BY d)" } { - 1 A one 8.4 A.D.G.C.F.B.E 7.1 - 4 D one 11.0 A.D.G.C.F.B.E 7.1 - 7 G one 2.7 D.G.C.F.B.E 6.5 - 3 C three 5.9 G.C.F.B.E 5.9 - 6 F three 0.0 C.F.B.E 6.5 - 2 B two 7.1 F.B.E 7.1 - 5 E two 12.5 B.E 9.8 + if {$oba} { + ifcapable !ordered_set_aggregates break + } + set sql "SELECT a, b, c, d, \ + group_concat(b,'.') OVER w1 AS 'elements', \ + $expr OVER w1 AS 'median' \ + FROM t1 \ + WINDOW w1 AS (ORDER BY c, a ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)" + do_execsql_test percentile-3.$id.1 $sql { + 1 A one 8.4 A.D 9.7 + 4 D one 11.0 A.D.G 8.4 + 7 G one 2.7 D.G.C 5.9 + 3 C three 5.9 G.C.F 2.7 + 6 F three 0.0 C.F.B 5.9 + 2 B two 7.1 F.B.E 7.1 + 5 E two 12.5 B.E 9.8 + } + + set sql "SELECT a, b, c, d, \ + group_concat(b,'.') OVER w1 AS 'elements', \ + $expr OVER w1 AS 'median' \ + FROM t1 \ + WINDOW w1 AS (ORDER BY c, a \ + ROWS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING)" + do_execsql_test percentile-3.$id.2 $sql { + 1 A one 8.4 A.D 9.7 + 4 D one 11.0 A.D.G 8.4 + 7 G one 2.7 A.D.G.C 7.15 + 3 C three 5.9 A.D.G.C.F 5.9 + 6 F three 0.0 A.D.G.C.F.B 6.5 + 2 B two 7.1 A.D.G.C.F.B.E 7.1 + 5 E two 12.5 A.D.G.C.F.B.E 7.1 + } + + set sql "SELECT a, b, c, d, \ + group_concat(b,'.') OVER w1 AS 'elements', \ + $expr OVER w1 AS 'median' \ + FROM t1 \ + WINDOW w1 AS (ORDER BY c, a \ + ROWS BETWEEN 1 PRECEDING AND UNBOUNDED FOLLOWING)" + do_execsql_test percentile-3.$id.3 $sql { + 1 A one 8.4 A.D.G.C.F.B.E 7.1 + 4 D one 11.0 A.D.G.C.F.B.E 7.1 + 7 G one 2.7 D.G.C.F.B.E 6.5 + 3 C three 5.9 G.C.F.B.E 5.9 + 6 F three 0.0 C.F.B.E 6.5 + 2 B two 7.1 F.B.E 7.1 + 5 E two 12.5 B.E 9.8 + } } # Test case adapted from examples shown at