datafusion_functions_window/
utils.rs

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
18use datafusion_common::arrow::datatypes::DataType;
19use datafusion_common::{exec_err, DataFusionError, Result, ScalarValue};
20use datafusion_physical_expr::expressions::Literal;
21use datafusion_physical_expr_common::physical_expr::PhysicalExpr;
22use std::sync::Arc;
23
24pub(crate) fn get_signed_integer(value: ScalarValue) -> Result<i64> {
25    if value.is_null() {
26        return Ok(0);
27    }
28
29    if !value.data_type().is_integer() {
30        return exec_err!("Expected an integer value");
31    }
32
33    value.cast_to(&DataType::Int64)?.try_into()
34}
35
36pub(crate) fn get_scalar_value_from_args(
37    args: &[Arc<dyn PhysicalExpr>],
38    index: usize,
39) -> Result<Option<ScalarValue>> {
40    Ok(if let Some(field) = args.get(index) {
41        let tmp = field
42            .as_any()
43            .downcast_ref::<Literal>()
44            .ok_or_else(|| DataFusionError::NotImplemented(
45                format!("There is only support Literal types for field at idx: {index} in Window Function"),
46            ))?
47            .value()
48            .clone();
49        Some(tmp)
50    } else {
51        None
52    })
53}
54
55pub(crate) fn get_unsigned_integer(value: ScalarValue) -> Result<u64> {
56    if value.is_null() {
57        return Ok(0);
58    }
59
60    if !value.data_type().is_integer() {
61        return exec_err!("Expected an integer value");
62    }
63
64    value.cast_to(&DataType::UInt64)?.try_into()
65}