]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Improved error messages on percentile functions. More tests cases for ordered-set-agg
authordrh <>
Mon, 2 Sep 2024 11:17:04 +0000 (11:17 +0000)
committerdrh <>
Mon, 2 Sep 2024 11:17:04 +0000 (11:17 +0000)
percentile and for ordered-set aggregates.

FossilOrigin-Name: e1bca168e70335fa2f9537632fd16e374c566a564fab4974c0b8f61cb63d08ce

ext/misc/percentile.c
manifest
manifest.uuid
src/parse.y
test/percentile.test

index 3d9ad891936ef34a5e1979d79a6cdae64315c854..320d7a5301ae3b9d5d995c30f46462625db33927 100644 (file)
@@ -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;
   }
 
index 302b6b61060b7723ff10f39b022baa12ef1d59ac..c3fb0bad7a7754644ffb7df7b227c3b39ca4b776 100644 (file)
--- 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.
index ef8888d75be4a0cb8de4d173fda4bad00f47aed3..126ce65bc7d78073afc2ed2aecdf54839e347364 100644 (file)
@@ -1 +1 @@
-3b1cdddf8339cc339ec74cd8be2bfa42e62b500048a444eb9e5d9817bc4702ae
+e1bca168e70335fa2f9537632fd16e374c566a564fab4974c0b8f61cb63d08ce
index 8ff232620257690ef4a5d4395526551eff3b7d22..a6a5e046dbcba88a6db70ca19836530af425f372 100644 (file)
@@ -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 ){
index 3207aea0961f6f52dbfba947cce4a5719252403e..a6a29da34ede1c52b32d3b98b82a11c75fe8b25f 100644 (file)
@@ -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