lincoln-lil commented on code in PR #25291:
URL: https://github.com/apache/flink/pull/25291#discussion_r1746405379


##########
docs/data/sql_functions.yml:
##########
@@ -251,6 +251,21 @@ arithmetic:
   - sql: TRUNCATE(numeric1, integer2)
     table: NUMERIC1.truncate(INTEGER2)
     description: Returns a numeric of truncated to integer2 decimal places. 
Returns NULL if numeric1 or integer2 is NULL. If integer2 is 0, the result has 
no decimal point or fractional part. integer2 can be negative to cause integer2 
digits left of the decimal point of the value to become zero. This function can 
also pass in only one numeric1 parameter and not set integer2 to use. If 
integer2 is not set, the function truncates as if integer2 were 0. E.g. 
42.324.truncate(2) to 42.32. and 42.324.truncate() to 42.0.
+  - sql: PERCENTILE(expr, percentage[, frequency])
+    table: expr.percentile(percentage[, frequency])
+    description: |
+      Returns the exact percentile value of expr at the specified percentage 
in a group.
+      
+      percentage must be a literal numeric value between `[0.0, 1.0]` or an 
array of such values. If a variable expression is passed to this function, the 
result will be calculated using any one of them.
+      frequency describes how many times expr should be counted, the default 
value is 1.
+      
+      If no expr lies exactly at the desired percentile, the result is 
calculated using linear interpolation of the two nearest exprs. If expr or 
frequency is `NULL`, or frequency is not positive, the input row will be 
ignored.
+      
+      `value <NUMERIC>, percentage [<NUMERIC NOT NULL> | <ARRAY<NUMERIC NOT 
NULL> NOT NULL>], frequency <INTEGER_NUMERIC>`
+      `(INTEGER_NUMERIC: TINYINT, SMALLINT, INTEGER, BIGINT)`
+      `(NUMERIC: INTEGER_NUMERIC, FLOAT, DOUBLE, DECIMAL)`
+      
+      Returns a `DOUBLE` if percentage is numeric, or an `ARRAY<DOUBLE>` if 
percentage is an array. `NULL` if percentage is an empty array.
 

Review Comment:
   It would be good to add some hints about performance, such as suggesting 
that the user consider applying this agg func in a window scenario (which 
usually yields better performance), whereas in a normal group agg scenario, the 
performance overhead of a full sort triggered by each record is something the 
user needs to be concerned about.



##########
flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/functions/BuiltInAggregateFunctionTestBase.java:
##########
@@ -362,6 +387,70 @@ public void execute(TableEnvironment tEnv, Table 
sourceTable) {
         protected abstract TableResult getResult(TableEnvironment tEnv, Table 
sourceTable);
     }
 
+    private abstract static class ValidationErrorItem implements TestItem {
+        private final Class<? extends Throwable> exceptionClass;
+        private final String exceptionMessage;
+
+        public ValidationErrorItem(String exceptionMessage) {
+            this.exceptionClass = ValidationException.class;

Review Comment:
   We can parameterize this `exceptionClass` and change `ValidationErrorItem` 
to `ErrorTestItem` for a more general purpose, otherwise a constant is enough.



##########
flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/functions/BuiltInAggregateFunctionTestBase.java:
##########
@@ -362,6 +387,70 @@ public void execute(TableEnvironment tEnv, Table 
sourceTable) {
         protected abstract TableResult getResult(TableEnvironment tEnv, Table 
sourceTable);
     }
 
+    private abstract static class ValidationErrorItem implements TestItem {
+        private final Class<? extends Throwable> exceptionClass;
+        private final String exceptionMessage;
+
+        public ValidationErrorItem(String exceptionMessage) {
+            this.exceptionClass = ValidationException.class;
+            this.exceptionMessage = exceptionMessage;
+        }
+
+        @Override
+        public void execute(TableEnvironment tEnv, Table sourceTable) {
+            Throwable t = catchThrowable(() -> getResult(tEnv, sourceTable));
+            assertThat(t)
+                    .as("Expected a validation exception")
+                    .isNotNull()
+                    .satisfies(
+                            exceptionMessage == null
+                                    ? anyCauseMatches(exceptionClass)
+                                    : anyCauseMatches(exceptionClass, 
exceptionMessage));
+        }
+
+        protected abstract void getResult(TableEnvironment tEnv, Table 
sourceTable);
+    }
+
+    private static final class SqlValidationErrorItem extends 
ValidationErrorItem {

Review Comment:
   `SqlValidationErrorItem` -> `SqlErrorTestItem`



##########
flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/functions/BuiltInAggregateFunctionTestBase.java:
##########
@@ -362,6 +387,70 @@ public void execute(TableEnvironment tEnv, Table 
sourceTable) {
         protected abstract TableResult getResult(TableEnvironment tEnv, Table 
sourceTable);
     }
 
+    private abstract static class ValidationErrorItem implements TestItem {
+        private final Class<? extends Throwable> exceptionClass;
+        private final String exceptionMessage;
+
+        public ValidationErrorItem(String exceptionMessage) {
+            this.exceptionClass = ValidationException.class;
+            this.exceptionMessage = exceptionMessage;
+        }
+
+        @Override
+        public void execute(TableEnvironment tEnv, Table sourceTable) {
+            Throwable t = catchThrowable(() -> getResult(tEnv, sourceTable));
+            assertThat(t)
+                    .as("Expected a validation exception")
+                    .isNotNull()
+                    .satisfies(
+                            exceptionMessage == null
+                                    ? anyCauseMatches(exceptionClass)
+                                    : anyCauseMatches(exceptionClass, 
exceptionMessage));
+        }
+
+        protected abstract void getResult(TableEnvironment tEnv, Table 
sourceTable);
+    }
+
+    private static final class SqlValidationErrorItem extends 
ValidationErrorItem {
+        private final Function<Table, String> spec;
+
+        public SqlValidationErrorItem(Function<Table, String> spec, String 
exceptionMessage) {
+            super(exceptionMessage);
+            this.spec = spec;
+        }
+
+        @Override
+        protected void getResult(TableEnvironment tEnv, Table sourceTable) {
+            tEnv.sqlQuery(spec.apply(sourceTable)).execute();
+        }
+    }
+
+    private static final class TableApiValidationErrorItem extends 
ValidationErrorItem {

Review Comment:
   `TableApiValidationErrorItem` -> `TableApiErrorTestItem`



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to