Skip to content

Commit 228c1b7

Browse files
committed
add missing file
1 parent cc2e14f commit 228c1b7

File tree

1 file changed

+74
-0
lines changed
  • datafusion/functions-aggregate/src

1 file changed

+74
-0
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
use std::sync::Arc;
19+
20+
use arrow::array::RecordBatch;
21+
use arrow::datatypes::Schema;
22+
use datafusion_common::{internal_err, plan_err, DataFusionError, Result, ScalarValue};
23+
use datafusion_expr::ColumnarValue;
24+
use datafusion_physical_expr_common::physical_expr::PhysicalExpr;
25+
26+
/// Evaluates a physical expression to extract its scalar value.
27+
///
28+
/// This is used to extract constant values from expressions (like percentile parameters)
29+
/// by evaluating them against an empty record batch.
30+
pub(crate) fn get_percentile_scalar_value(
31+
expr: &Arc<dyn PhysicalExpr>,
32+
) -> Result<ScalarValue> {
33+
let empty_schema = Arc::new(Schema::empty());
34+
let batch = RecordBatch::new_empty(Arc::clone(&empty_schema));
35+
if let ColumnarValue::Scalar(s) = expr.evaluate(&batch)? {
36+
Ok(s)
37+
} else {
38+
internal_err!("Didn't expect ColumnarValue::Array")
39+
}
40+
}
41+
42+
/// Validates that a percentile expression is a literal float value between 0.0 and 1.0.
43+
///
44+
/// Used by both `percentile_cont` and `approx_percentile_cont` to validate their
45+
/// percentile parameters.
46+
pub(crate) fn validate_percentile_expr(
47+
expr: &Arc<dyn PhysicalExpr>,
48+
fn_name: &str,
49+
) -> Result<f64> {
50+
let scalar_value = get_percentile_scalar_value(expr).map_err(|_e| {
51+
DataFusionError::Plan(format!(
52+
"Percentile value for '{fn_name}' must be a literal"
53+
))
54+
})?;
55+
56+
let percentile = match scalar_value {
57+
ScalarValue::Float32(Some(value)) => value as f64,
58+
ScalarValue::Float64(Some(value)) => value,
59+
sv => {
60+
return plan_err!(
61+
"Percentile value for '{fn_name}' must be Float32 or Float64 literal (got data type {})",
62+
sv.data_type()
63+
)
64+
}
65+
};
66+
67+
// Ensure the percentile is between 0 and 1.
68+
if !(0.0..=1.0).contains(&percentile) {
69+
return plan_err!(
70+
"Percentile value must be between 0.0 and 1.0 inclusive, {percentile} is invalid"
71+
);
72+
}
73+
Ok(percentile)
74+
}

0 commit comments

Comments
 (0)