Jefffrey commented on code in PR #17424:
URL: https://github.com/apache/datafusion/pull/17424#discussion_r2354189234


##########
datafusion/functions/src/datetime/make_interval.rs:
##########
@@ -0,0 +1,621 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use std::any::Any;
+use std::sync::Arc;
+
+use crate::utils::make_scalar_function;
+use arrow::array::{Array, ArrayRef, IntervalMonthDayNanoBuilder, 
PrimitiveArray};
+use arrow::datatypes::DataType::Interval;
+use arrow::datatypes::IntervalUnit::MonthDayNano;
+use arrow::datatypes::{DataType, IntervalMonthDayNano};
+use datafusion_common::{
+    exec_err, plan_datafusion_err, DataFusionError, Result, ScalarValue,
+};
+use datafusion_expr::{
+    ColumnarValue, Documentation, ScalarFunctionArgs, ScalarUDFImpl, Signature,
+    Volatility,
+};
+use datafusion_macros::user_doc;
+
+#[user_doc(
+    doc_section(label = "Time and Date Functions"),
+    description = "Construct an INTERVAL (MonthDayNano) from component parts. 
Missing arguments default to 0; if any provided argument is NULL on a row, the 
result is NULL.",
+    syntax_example = "make_interval([years[, months[, weeks[, days[, hours[, 
mins[, secs]]]]]])",
+    sql_example = r#"```sql
+-- Inline example without creating a table
+> SELECT
+      y, m, w, d, h, mi, s,
+      make_interval(y, m, w, d, h, mi, s) AS interval
+    FROM VALUES
+      (1,   1,   1,   1,   1,   1,   1.0)
+    AS v(y, m, w, d, h, mi, s);
++---+---+---+---+---+---+---+---------------------------------------------------+
+|y  |m  |w  |d  |h  |mi |s  |interval                                          
 |
++---+---+---+---+---+---+---+---------------------------------------------------+
+|1  |1  |1  |1  |1  |1  |1.0|1 years 1 months 8 days 1 hours 1 minutes 1 
seconds|
++---+---+---+---+---+---+---+---------------------------------------------------+
+```"#,
+    argument(
+        name = "years",
+        description = "Years to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "months",
+        description = "Months to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "weeks",
+        description = "Weeks to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "days",
+        description = "Days to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "hours",
+        description = "Hours to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "mins",
+        description = "Minutes to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "secs",
+        description = "Seconds to use when making the interval (may be 
fractional). Optional; defaults to 0. Must be finite (not NaN/±Inf). Can be a 
constant, column or function, and any combination of arithmetic operators."
+    )
+)]
+#[derive(Debug, PartialEq, Eq, Hash)]
+pub struct MakeIntervalFunc {
+    signature: Signature,
+}
+
+impl Default for MakeIntervalFunc {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+impl MakeIntervalFunc {
+    pub fn new() -> Self {
+        Self {
+            signature: Signature::user_defined(Volatility::Immutable),
+        }
+    }
+}
+
+impl ScalarUDFImpl for MakeIntervalFunc {
+    fn as_any(&self) -> &dyn Any {
+        self
+    }
+
+    fn name(&self) -> &str {
+        "make_interval"
+    }
+
+    fn signature(&self) -> &Signature {
+        &self.signature
+    }
+
+    fn return_type(&self, _arg_types: &[DataType]) -> Result<DataType> {
+        Ok(Interval(MonthDayNano))
+    }
+
+    fn invoke_with_args(&self, args: ScalarFunctionArgs) -> 
Result<ColumnarValue> {
+        if args.args.is_empty() {
+            return Ok(ColumnarValue::Scalar(ScalarValue::IntervalMonthDayNano(
+                Some(IntervalMonthDayNano::new(0, 0, 0)),
+            )));
+        }
+        make_scalar_function(make_interval_kernel, vec![])(&args.args)
+    }
+
+    fn coerce_types(&self, arg_types: &[DataType]) -> Result<Vec<DataType>> {
+        let length = arg_types.len();
+        match length {
+            x if x > 7 => {
+                exec_err!(
+                    "make_interval expects between 0 and 7 arguments, got {}",
+                    arg_types.len()
+                )
+            }
+            _ => Ok((0..arg_types.len())
+                .map(|i| {
+                    if i == 6 {
+                        DataType::Float64
+                    } else {
+                        DataType::Int32
+                    }
+                })
+                .collect()),
+        }
+    }
+
+    fn documentation(&self) -> Option<&Documentation> {
+        self.doc()
+    }
+}
+
+fn make_interval_kernel(args: &[ArrayRef]) -> Result<ArrayRef, 
DataFusionError> {
+    use arrow::array::AsArray;
+    use arrow::datatypes::{Float64Type, Int32Type};
+
+    if args.len() > 7 {
+        return exec_err!(
+            "make_interval expects between 0 and 7 arguments, got {}",
+            args.len()
+        );
+    }
+
+    let n_rows = args[0].len();

Review Comment:
   I think either assume this function `make_interval_kernel` has been called 
with the correct arguments and don't do this check, or enhance the check to 
make sure `args` isn't empty since the error message says it accepts 0 
arguments but right after it assumes the first element exists when indexing.



##########
datafusion/sqllogictest/test_files/spark/datetime/make_interval.slt:
##########
@@ -0,0 +1,117 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+
+#   http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# This file was originally created by a porting script from:
+#   
https://github.com/lakehq/sail/tree/43b6ed8221de5c4c4adbedbb267ae1351158b43c/crates/sail-spark-connect/tests/gold_data/function
+# This file is part of the implementation of the datafusion-spark function 
library.
+# For more information, please see:
+#   https://github.com/apache/datafusion/issues/15914
+
+query IIIIIIR?
+SELECT
+  y, m, w, d, h, mi, s,
+  make_interval(y, m, w, d, h, mi, s) AS interval
+FROM VALUES
+  (NULL,2,   3,   4,   5,   6,   7.5),
+  (1,   NULL,3,   4,   5,   6,   7.5),
+  (1,   2,   NULL,4,   5,   6,   7.5),
+  (1,   2,   3,   NULL,5,   6,   7.5),
+  (1,   2,   3,   4,   NULL,6,   7.5),
+  (1,   2,   3,   4,   5,   NULL,7.5),
+  (1,   2,   3,   4,   5,   6,   CAST(NULL AS DOUBLE)),
+  (1,   1,   1,   1,   1,   1,   1.0)
+AS v(y, m, w, d, h, mi, s);
+----
+NULL 2 3 4 5 6 7.5 NULL
+1 NULL 3 4 5 6 7.5 NULL
+1 2 NULL 4 5 6 7.5 NULL
+1 2 3 NULL 5 6 7.5 NULL
+1 2 3 4 NULL 6 7.5 NULL
+1 2 3 4 5 NULL 7.5 NULL
+1 2 3 4 5 6 NULL NULL
+1 1 1 1 1 1 1 13 mons 8 days 1 hours 1 mins 1.000000000 secs
+
+query IIIIIIR?
+SELECT
+  y, m, w, d, h, mi, s,
+  make_interval(y, m, w, d, h, mi, s) AS interval
+FROM VALUES
+  (0,   0,   0,   0,   0,   0,   arrow_cast('NaN','Float64'))
+AS v(y, m, w, d, h, mi, s);
+----
+0 0 0 0 0 0 NaN NULL
+
+query IIIIIIR?
+SELECT
+  y, m, w, d, h, mi, s,
+  make_interval(y, m, w, d, h, mi, s) AS interval
+FROM VALUES
+  (0,   0,   0,   0,   0,   0,   CAST('Infinity' AS DOUBLE))
+AS v(y, m, w, d, h, mi, s);
+----
+0 0 0 0 0 0 Infinity NULL
+
+query IIIIIIR?
+SELECT
+  y, m, w, d, h, mi, s,
+  make_interval(y, m, w, d, h, mi, s) AS interval
+FROM VALUES
+  (0,   0,   0,   0,   0,   0,   CAST('-Infinity' AS DOUBLE))
+AS v(y, m, w, d, h, mi, s);
+----
+0 0 0 0 0 0 -Infinity NULL
+
+query ?
+SELECT make_interval(2147483647, 1, 0, 0, 0, 0, 0.0);
+----
+NULL
+
+query ?
+SELECT make_interval(0, 0, 2147483647, 1, 0, 0, 0.0);
+----
+NULL
+
+query ?
+SELECT make_interval(0, 0, 0, 0, 2147483647, 1, 0.0);
+----
+NULL
+
+# seconds is now blank line
+#query ?
+#SELECT make_interval(0, 0, 0, 0, 0, 0, 0.0);
+#----
+#0.000000000 secs
+
+#query ?
+#SELECT make_interval();
+#----
+#0.000000000 secs
+
+
+query ?
+SELECT INTERVAL '1' SECOND AS iv;
+----
+1.000000000 secs
+
+
+#>>> spark.sql("SELECT make_interval() AS interval FROM VALUES (1), (2) AS 
t(x)").show()
+# +---------+
+# | interval|
+# +---------+
+# |0 seconds|
+# |0 seconds|
+# +---------+

Review Comment:
   Consider removing these unless there's comments explaining why we have them 
here



##########
datafusion/functions/src/datetime/make_interval.rs:
##########
@@ -0,0 +1,621 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use std::any::Any;
+use std::sync::Arc;
+
+use crate::utils::make_scalar_function;
+use arrow::array::{Array, ArrayRef, IntervalMonthDayNanoBuilder, 
PrimitiveArray};
+use arrow::datatypes::DataType::Interval;
+use arrow::datatypes::IntervalUnit::MonthDayNano;
+use arrow::datatypes::{DataType, IntervalMonthDayNano};
+use datafusion_common::{
+    exec_err, plan_datafusion_err, DataFusionError, Result, ScalarValue,
+};
+use datafusion_expr::{
+    ColumnarValue, Documentation, ScalarFunctionArgs, ScalarUDFImpl, Signature,
+    Volatility,
+};
+use datafusion_macros::user_doc;
+
+#[user_doc(
+    doc_section(label = "Time and Date Functions"),
+    description = "Construct an INTERVAL (MonthDayNano) from component parts. 
Missing arguments default to 0; if any provided argument is NULL on a row, the 
result is NULL.",
+    syntax_example = "make_interval([years[, months[, weeks[, days[, hours[, 
mins[, secs]]]]]])",
+    sql_example = r#"```sql
+-- Inline example without creating a table
+> SELECT
+      y, m, w, d, h, mi, s,
+      make_interval(y, m, w, d, h, mi, s) AS interval
+    FROM VALUES
+      (1,   1,   1,   1,   1,   1,   1.0)
+    AS v(y, m, w, d, h, mi, s);
++---+---+---+---+---+---+---+---------------------------------------------------+
+|y  |m  |w  |d  |h  |mi |s  |interval                                          
 |
++---+---+---+---+---+---+---+---------------------------------------------------+
+|1  |1  |1  |1  |1  |1  |1.0|1 years 1 months 8 days 1 hours 1 minutes 1 
seconds|
++---+---+---+---+---+---+---+---------------------------------------------------+
+```"#,
+    argument(
+        name = "years",
+        description = "Years to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "months",
+        description = "Months to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "weeks",
+        description = "Weeks to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "days",
+        description = "Days to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "hours",
+        description = "Hours to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "mins",
+        description = "Minutes to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "secs",
+        description = "Seconds to use when making the interval (may be 
fractional). Optional; defaults to 0. Must be finite (not NaN/±Inf). Can be a 
constant, column or function, and any combination of arithmetic operators."
+    )
+)]
+#[derive(Debug, PartialEq, Eq, Hash)]
+pub struct MakeIntervalFunc {
+    signature: Signature,
+}
+
+impl Default for MakeIntervalFunc {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+impl MakeIntervalFunc {
+    pub fn new() -> Self {
+        Self {
+            signature: Signature::user_defined(Volatility::Immutable),
+        }
+    }
+}
+
+impl ScalarUDFImpl for MakeIntervalFunc {
+    fn as_any(&self) -> &dyn Any {
+        self
+    }
+
+    fn name(&self) -> &str {
+        "make_interval"
+    }
+
+    fn signature(&self) -> &Signature {
+        &self.signature
+    }
+
+    fn return_type(&self, _arg_types: &[DataType]) -> Result<DataType> {
+        Ok(Interval(MonthDayNano))
+    }
+
+    fn invoke_with_args(&self, args: ScalarFunctionArgs) -> 
Result<ColumnarValue> {
+        if args.args.is_empty() {
+            return Ok(ColumnarValue::Scalar(ScalarValue::IntervalMonthDayNano(
+                Some(IntervalMonthDayNano::new(0, 0, 0)),
+            )));
+        }
+        make_scalar_function(make_interval_kernel, vec![])(&args.args)
+    }
+
+    fn coerce_types(&self, arg_types: &[DataType]) -> Result<Vec<DataType>> {
+        let length = arg_types.len();
+        match length {
+            x if x > 7 => {
+                exec_err!(
+                    "make_interval expects between 0 and 7 arguments, got {}",
+                    arg_types.len()
+                )
+            }
+            _ => Ok((0..arg_types.len())
+                .map(|i| {
+                    if i == 6 {
+                        DataType::Float64
+                    } else {
+                        DataType::Int32
+                    }
+                })
+                .collect()),
+        }
+    }
+
+    fn documentation(&self) -> Option<&Documentation> {
+        self.doc()
+    }
+}
+
+fn make_interval_kernel(args: &[ArrayRef]) -> Result<ArrayRef, 
DataFusionError> {
+    use arrow::array::AsArray;
+    use arrow::datatypes::{Float64Type, Int32Type};
+
+    if args.len() > 7 {
+        return exec_err!(
+            "make_interval expects between 0 and 7 arguments, got {}",
+            args.len()
+        );
+    }
+
+    let n_rows = args[0].len();
+
+    let years = args
+        .first()
+        .map(|a| {
+            a.as_primitive_opt::<Int32Type>().ok_or_else(|| {
+                plan_datafusion_err!("make_dt_interval arg[0] must be Int32")
+            })
+        })
+        .transpose()?;
+    let months = args
+        .get(1)
+        .map(|a| {
+            a.as_primitive_opt::<Int32Type>().ok_or_else(|| {
+                plan_datafusion_err!("make_dt_interval arg[1] must be Int32")
+            })
+        })
+        .transpose()?;
+    let weeks = args
+        .get(2)
+        .map(|a| {
+            a.as_primitive_opt::<Int32Type>().ok_or_else(|| {
+                plan_datafusion_err!("make_dt_interval arg[2] must be Int32")
+            })
+        })
+        .transpose()?;
+    let days: Option<&PrimitiveArray<Int32Type>> = args
+        .get(3)
+        .map(|a| {
+            a.as_primitive_opt::<Int32Type>().ok_or_else(|| {
+                plan_datafusion_err!("make_dt_interval arg[3] must be Int32")
+            })
+        })
+        .transpose()?;
+    let hours: Option<&PrimitiveArray<Int32Type>> = args
+        .get(4)
+        .map(|a| {
+            a.as_primitive_opt::<Int32Type>().ok_or_else(|| {
+                plan_datafusion_err!("make_dt_interval arg[4] must be Int32")
+            })
+        })
+        .transpose()?;
+    let mins: Option<&PrimitiveArray<Int32Type>> = args
+        .get(5)
+        .map(|a| {
+            a.as_primitive_opt::<Int32Type>().ok_or_else(|| {
+                plan_datafusion_err!("make_dt_interval arg[5] must be Int32")
+            })
+        })
+        .transpose()?;
+    let secs: Option<&PrimitiveArray<Float64Type>> = args
+        .get(6)
+        .map(|a| {
+            a.as_primitive_opt::<Float64Type>().ok_or_else(|| {
+                plan_datafusion_err!("make_dt_interval arg[6] must be Float64")
+            })
+        })
+        .transpose()?;
+
+    let mut builder = IntervalMonthDayNanoBuilder::with_capacity(n_rows);
+
+    for i in 0..n_rows {
+        // if one column is NULL → result NULL
+        let any_null_present = years.as_ref().is_some_and(|a| a.is_null(i))
+            || months.as_ref().is_some_and(|a| a.is_null(i))
+            || weeks.as_ref().is_some_and(|a| a.is_null(i))
+            || days.as_ref().is_some_and(|a| a.is_null(i))
+            || hours.as_ref().is_some_and(|a| a.is_null(i))
+            || mins.as_ref().is_some_and(|a| a.is_null(i))
+            || secs.as_ref().is_some_and(|a| {
+                a.is_null(i) || a.value(i).is_infinite() || a.value(i).is_nan()
+            });
+
+        if any_null_present {
+            builder.append_null();
+            continue;
+        }
+
+        // default values 0 or 0.0
+        let y = years.as_ref().map_or(0, |a| a.value(i));
+        let mo = months.as_ref().map_or(0, |a| a.value(i));
+        let w = weeks.as_ref().map_or(0, |a| a.value(i));
+        let d = days.as_ref().map_or(0, |a| a.value(i));
+        let h = hours.as_ref().map_or(0, |a| a.value(i));
+        let mi = mins.as_ref().map_or(0, |a| a.value(i));
+        let s = secs.as_ref().map_or(0.0, |a| a.value(i));
+
+        match make_interval_month_day_nano(y, mo, w, d, h, mi, s)? {
+            Some(v) => builder.append_value(v),
+            None => {
+                builder.append_null();
+                continue;
+            }
+        }
+    }
+
+    Ok(Arc::new(builder.finish()))
+}
+
+pub fn make_interval_month_day_nano(
+    year: i32,
+    month: i32,
+    week: i32,
+    day: i32,
+    hour: i32,
+    min: i32,
+    sec: f64,
+) -> Result<Option<IntervalMonthDayNano>> {
+    use datafusion_common::DataFusionError;
+
+    if !sec.is_finite() {
+        return Err(DataFusionError::Execution(
+            "seconds cannot be NaN or Inf".into(),
+        ));
+    }

Review Comment:
   This has been checked earlier in `make_interval_kernel` so I think can omit 
this redundant check here



##########
datafusion/functions/src/datetime/make_interval.rs:
##########
@@ -0,0 +1,621 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use std::any::Any;
+use std::sync::Arc;
+
+use crate::utils::make_scalar_function;
+use arrow::array::{Array, ArrayRef, IntervalMonthDayNanoBuilder, 
PrimitiveArray};
+use arrow::datatypes::DataType::Interval;
+use arrow::datatypes::IntervalUnit::MonthDayNano;
+use arrow::datatypes::{DataType, IntervalMonthDayNano};
+use datafusion_common::{
+    exec_err, plan_datafusion_err, DataFusionError, Result, ScalarValue,
+};
+use datafusion_expr::{
+    ColumnarValue, Documentation, ScalarFunctionArgs, ScalarUDFImpl, Signature,
+    Volatility,
+};
+use datafusion_macros::user_doc;
+
+#[user_doc(
+    doc_section(label = "Time and Date Functions"),
+    description = "Construct an INTERVAL (MonthDayNano) from component parts. 
Missing arguments default to 0; if any provided argument is NULL on a row, the 
result is NULL.",
+    syntax_example = "make_interval([years[, months[, weeks[, days[, hours[, 
mins[, secs]]]]]])",
+    sql_example = r#"```sql
+-- Inline example without creating a table
+> SELECT
+      y, m, w, d, h, mi, s,
+      make_interval(y, m, w, d, h, mi, s) AS interval
+    FROM VALUES
+      (1,   1,   1,   1,   1,   1,   1.0)
+    AS v(y, m, w, d, h, mi, s);
++---+---+---+---+---+---+---+---------------------------------------------------+
+|y  |m  |w  |d  |h  |mi |s  |interval                                          
 |
++---+---+---+---+---+---+---+---------------------------------------------------+
+|1  |1  |1  |1  |1  |1  |1.0|1 years 1 months 8 days 1 hours 1 minutes 1 
seconds|
++---+---+---+---+---+---+---+---------------------------------------------------+
+```"#,
+    argument(
+        name = "years",
+        description = "Years to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "months",
+        description = "Months to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "weeks",
+        description = "Weeks to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "days",
+        description = "Days to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "hours",
+        description = "Hours to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "mins",
+        description = "Minutes to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "secs",
+        description = "Seconds to use when making the interval (may be 
fractional). Optional; defaults to 0. Must be finite (not NaN/±Inf). Can be a 
constant, column or function, and any combination of arithmetic operators."
+    )
+)]
+#[derive(Debug, PartialEq, Eq, Hash)]
+pub struct MakeIntervalFunc {
+    signature: Signature,
+}
+
+impl Default for MakeIntervalFunc {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+impl MakeIntervalFunc {
+    pub fn new() -> Self {
+        Self {
+            signature: Signature::user_defined(Volatility::Immutable),
+        }
+    }
+}
+
+impl ScalarUDFImpl for MakeIntervalFunc {
+    fn as_any(&self) -> &dyn Any {
+        self
+    }
+
+    fn name(&self) -> &str {
+        "make_interval"
+    }
+
+    fn signature(&self) -> &Signature {
+        &self.signature
+    }
+
+    fn return_type(&self, _arg_types: &[DataType]) -> Result<DataType> {
+        Ok(Interval(MonthDayNano))
+    }
+
+    fn invoke_with_args(&self, args: ScalarFunctionArgs) -> 
Result<ColumnarValue> {
+        if args.args.is_empty() {
+            return Ok(ColumnarValue::Scalar(ScalarValue::IntervalMonthDayNano(
+                Some(IntervalMonthDayNano::new(0, 0, 0)),
+            )));
+        }
+        make_scalar_function(make_interval_kernel, vec![])(&args.args)
+    }
+
+    fn coerce_types(&self, arg_types: &[DataType]) -> Result<Vec<DataType>> {
+        let length = arg_types.len();
+        match length {
+            x if x > 7 => {
+                exec_err!(
+                    "make_interval expects between 0 and 7 arguments, got {}",
+                    arg_types.len()
+                )
+            }
+            _ => Ok((0..arg_types.len())
+                .map(|i| {
+                    if i == 6 {
+                        DataType::Float64
+                    } else {
+                        DataType::Int32
+                    }
+                })
+                .collect()),
+        }
+    }
+
+    fn documentation(&self) -> Option<&Documentation> {
+        self.doc()
+    }
+}
+
+fn make_interval_kernel(args: &[ArrayRef]) -> Result<ArrayRef, 
DataFusionError> {
+    use arrow::array::AsArray;
+    use arrow::datatypes::{Float64Type, Int32Type};
+
+    if args.len() > 7 {
+        return exec_err!(
+            "make_interval expects between 0 and 7 arguments, got {}",
+            args.len()
+        );
+    }
+
+    let n_rows = args[0].len();
+
+    let years = args
+        .first()
+        .map(|a| {
+            a.as_primitive_opt::<Int32Type>().ok_or_else(|| {
+                plan_datafusion_err!("make_dt_interval arg[0] must be Int32")
+            })
+        })
+        .transpose()?;
+    let months = args
+        .get(1)
+        .map(|a| {
+            a.as_primitive_opt::<Int32Type>().ok_or_else(|| {
+                plan_datafusion_err!("make_dt_interval arg[1] must be Int32")
+            })
+        })
+        .transpose()?;
+    let weeks = args
+        .get(2)
+        .map(|a| {
+            a.as_primitive_opt::<Int32Type>().ok_or_else(|| {
+                plan_datafusion_err!("make_dt_interval arg[2] must be Int32")
+            })
+        })
+        .transpose()?;
+    let days: Option<&PrimitiveArray<Int32Type>> = args
+        .get(3)
+        .map(|a| {
+            a.as_primitive_opt::<Int32Type>().ok_or_else(|| {
+                plan_datafusion_err!("make_dt_interval arg[3] must be Int32")
+            })
+        })
+        .transpose()?;
+    let hours: Option<&PrimitiveArray<Int32Type>> = args
+        .get(4)
+        .map(|a| {
+            a.as_primitive_opt::<Int32Type>().ok_or_else(|| {
+                plan_datafusion_err!("make_dt_interval arg[4] must be Int32")
+            })
+        })
+        .transpose()?;
+    let mins: Option<&PrimitiveArray<Int32Type>> = args
+        .get(5)
+        .map(|a| {
+            a.as_primitive_opt::<Int32Type>().ok_or_else(|| {
+                plan_datafusion_err!("make_dt_interval arg[5] must be Int32")
+            })
+        })
+        .transpose()?;
+    let secs: Option<&PrimitiveArray<Float64Type>> = args
+        .get(6)
+        .map(|a| {
+            a.as_primitive_opt::<Float64Type>().ok_or_else(|| {
+                plan_datafusion_err!("make_dt_interval arg[6] must be Float64")
+            })
+        })
+        .transpose()?;
+
+    let mut builder = IntervalMonthDayNanoBuilder::with_capacity(n_rows);
+
+    for i in 0..n_rows {
+        // if one column is NULL → result NULL
+        let any_null_present = years.as_ref().is_some_and(|a| a.is_null(i))
+            || months.as_ref().is_some_and(|a| a.is_null(i))
+            || weeks.as_ref().is_some_and(|a| a.is_null(i))
+            || days.as_ref().is_some_and(|a| a.is_null(i))
+            || hours.as_ref().is_some_and(|a| a.is_null(i))
+            || mins.as_ref().is_some_and(|a| a.is_null(i))
+            || secs.as_ref().is_some_and(|a| {
+                a.is_null(i) || a.value(i).is_infinite() || a.value(i).is_nan()
+            });
+
+        if any_null_present {
+            builder.append_null();
+            continue;
+        }
+
+        // default values 0 or 0.0
+        let y = years.as_ref().map_or(0, |a| a.value(i));
+        let mo = months.as_ref().map_or(0, |a| a.value(i));
+        let w = weeks.as_ref().map_or(0, |a| a.value(i));
+        let d = days.as_ref().map_or(0, |a| a.value(i));
+        let h = hours.as_ref().map_or(0, |a| a.value(i));
+        let mi = mins.as_ref().map_or(0, |a| a.value(i));
+        let s = secs.as_ref().map_or(0.0, |a| a.value(i));
+
+        match make_interval_month_day_nano(y, mo, w, d, h, mi, s)? {
+            Some(v) => builder.append_value(v),
+            None => {
+                builder.append_null();
+                continue;
+            }
+        }
+    }
+
+    Ok(Arc::new(builder.finish()))
+}
+
+pub fn make_interval_month_day_nano(
+    year: i32,
+    month: i32,
+    week: i32,
+    day: i32,
+    hour: i32,
+    min: i32,
+    sec: f64,
+) -> Result<Option<IntervalMonthDayNano>> {
+    use datafusion_common::DataFusionError;
+
+    if !sec.is_finite() {
+        return Err(DataFusionError::Execution(
+            "seconds cannot be NaN or Inf".into(),
+        ));
+    }
+
+    // checks if overflow
+    let months = match year.checked_mul(12).and_then(|v| v.checked_add(month)) 
{
+        Some(m) => m,
+        None => return Ok(None),
+    };
+    let total_days = match week.checked_mul(7).and_then(|v| 
v.checked_add(day)) {
+        Some(dy) => dy,
+        None => return Ok(None),
+    };
+
+    let hours_nanos = match (hour as i64).checked_mul(3_600_000_000_000) {
+        Some(n) => n,
+        None => return Ok(None),
+    };
+    let mins_nanos = match (min as i64).checked_mul(60_000_000_000) {
+        Some(n) => n,
+        None => return Ok(None),
+    };
+
+    let sec_int = sec.trunc() as i64;
+    let frac = sec - sec.trunc();
+    let mut frac_nanos = (frac * 1_000_000_000.0).round() as i64;
+
+    if frac_nanos.abs() >= 1_000_000_000 {
+        if frac_nanos > 0 {
+            frac_nanos -= 1_000_000_000;
+        } else {
+            frac_nanos += 1_000_000_000;
+        }
+    }
+
+    let secs_nanos = sec_int
+        .checked_mul(1_000_000_000)
+        .ok_or_else(|| DataFusionError::Execution("overflow summing 
nanoseconds: (hours+mins)={} + secs_nanos={} exceeds i64 range".into()))?;
+
+    let total_nanos = hours_nanos
+        .checked_add(mins_nanos)
+        .and_then(|v| v.checked_add(secs_nanos))
+        .and_then(|v| v.checked_add(frac_nanos))
+        .ok_or_else(|| DataFusionError::Execution("overflow summing 
nanoseconds: (hours+mins+secs)={} + frac_nanos={} exceeds i64 range".into()))?;

Review Comment:
   Could you help me to understand why we throw an error for this overflow 
specifically, but above (for months, total_days, etc.) we instead return null?



##########
datafusion/functions/src/datetime/make_interval.rs:
##########
@@ -0,0 +1,621 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use std::any::Any;
+use std::sync::Arc;
+
+use crate::utils::make_scalar_function;
+use arrow::array::{Array, ArrayRef, IntervalMonthDayNanoBuilder, 
PrimitiveArray};
+use arrow::datatypes::DataType::Interval;
+use arrow::datatypes::IntervalUnit::MonthDayNano;
+use arrow::datatypes::{DataType, IntervalMonthDayNano};
+use datafusion_common::{
+    exec_err, plan_datafusion_err, DataFusionError, Result, ScalarValue,
+};
+use datafusion_expr::{
+    ColumnarValue, Documentation, ScalarFunctionArgs, ScalarUDFImpl, Signature,
+    Volatility,
+};
+use datafusion_macros::user_doc;
+
+#[user_doc(
+    doc_section(label = "Time and Date Functions"),
+    description = "Construct an INTERVAL (MonthDayNano) from component parts. 
Missing arguments default to 0; if any provided argument is NULL on a row, the 
result is NULL.",
+    syntax_example = "make_interval([years[, months[, weeks[, days[, hours[, 
mins[, secs]]]]]])",
+    sql_example = r#"```sql
+-- Inline example without creating a table
+> SELECT
+      y, m, w, d, h, mi, s,
+      make_interval(y, m, w, d, h, mi, s) AS interval
+    FROM VALUES
+      (1,   1,   1,   1,   1,   1,   1.0)
+    AS v(y, m, w, d, h, mi, s);
++---+---+---+---+---+---+---+---------------------------------------------------+
+|y  |m  |w  |d  |h  |mi |s  |interval                                          
 |
++---+---+---+---+---+---+---+---------------------------------------------------+
+|1  |1  |1  |1  |1  |1  |1.0|1 years 1 months 8 days 1 hours 1 minutes 1 
seconds|
++---+---+---+---+---+---+---+---------------------------------------------------+
+```"#,
+    argument(
+        name = "years",
+        description = "Years to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "months",
+        description = "Months to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "weeks",
+        description = "Weeks to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "days",
+        description = "Days to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "hours",
+        description = "Hours to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "mins",
+        description = "Minutes to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "secs",
+        description = "Seconds to use when making the interval (may be 
fractional). Optional; defaults to 0. Must be finite (not NaN/±Inf). Can be a 
constant, column or function, and any combination of arithmetic operators."
+    )
+)]
+#[derive(Debug, PartialEq, Eq, Hash)]
+pub struct MakeIntervalFunc {
+    signature: Signature,
+}
+
+impl Default for MakeIntervalFunc {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+impl MakeIntervalFunc {
+    pub fn new() -> Self {
+        Self {
+            signature: Signature::user_defined(Volatility::Immutable),
+        }
+    }
+}
+
+impl ScalarUDFImpl for MakeIntervalFunc {
+    fn as_any(&self) -> &dyn Any {
+        self
+    }
+
+    fn name(&self) -> &str {
+        "make_interval"
+    }
+
+    fn signature(&self) -> &Signature {
+        &self.signature
+    }
+
+    fn return_type(&self, _arg_types: &[DataType]) -> Result<DataType> {
+        Ok(Interval(MonthDayNano))
+    }
+
+    fn invoke_with_args(&self, args: ScalarFunctionArgs) -> 
Result<ColumnarValue> {
+        if args.args.is_empty() {
+            return Ok(ColumnarValue::Scalar(ScalarValue::IntervalMonthDayNano(
+                Some(IntervalMonthDayNano::new(0, 0, 0)),
+            )));
+        }
+        make_scalar_function(make_interval_kernel, vec![])(&args.args)
+    }
+
+    fn coerce_types(&self, arg_types: &[DataType]) -> Result<Vec<DataType>> {
+        let length = arg_types.len();
+        match length {
+            x if x > 7 => {
+                exec_err!(
+                    "make_interval expects between 0 and 7 arguments, got {}",
+                    arg_types.len()
+                )
+            }
+            _ => Ok((0..arg_types.len())
+                .map(|i| {
+                    if i == 6 {
+                        DataType::Float64
+                    } else {
+                        DataType::Int32
+                    }
+                })
+                .collect()),
+        }
+    }
+
+    fn documentation(&self) -> Option<&Documentation> {
+        self.doc()
+    }
+}
+
+fn make_interval_kernel(args: &[ArrayRef]) -> Result<ArrayRef, 
DataFusionError> {
+    use arrow::array::AsArray;
+    use arrow::datatypes::{Float64Type, Int32Type};
+
+    if args.len() > 7 {
+        return exec_err!(
+            "make_interval expects between 0 and 7 arguments, got {}",
+            args.len()
+        );
+    }
+
+    let n_rows = args[0].len();
+
+    let years = args
+        .first()
+        .map(|a| {
+            a.as_primitive_opt::<Int32Type>().ok_or_else(|| {
+                plan_datafusion_err!("make_dt_interval arg[0] must be Int32")
+            })
+        })
+        .transpose()?;
+    let months = args
+        .get(1)
+        .map(|a| {
+            a.as_primitive_opt::<Int32Type>().ok_or_else(|| {
+                plan_datafusion_err!("make_dt_interval arg[1] must be Int32")
+            })
+        })
+        .transpose()?;
+    let weeks = args
+        .get(2)
+        .map(|a| {
+            a.as_primitive_opt::<Int32Type>().ok_or_else(|| {
+                plan_datafusion_err!("make_dt_interval arg[2] must be Int32")
+            })
+        })
+        .transpose()?;
+    let days: Option<&PrimitiveArray<Int32Type>> = args
+        .get(3)
+        .map(|a| {
+            a.as_primitive_opt::<Int32Type>().ok_or_else(|| {
+                plan_datafusion_err!("make_dt_interval arg[3] must be Int32")
+            })
+        })
+        .transpose()?;
+    let hours: Option<&PrimitiveArray<Int32Type>> = args
+        .get(4)
+        .map(|a| {
+            a.as_primitive_opt::<Int32Type>().ok_or_else(|| {
+                plan_datafusion_err!("make_dt_interval arg[4] must be Int32")
+            })
+        })
+        .transpose()?;
+    let mins: Option<&PrimitiveArray<Int32Type>> = args
+        .get(5)
+        .map(|a| {
+            a.as_primitive_opt::<Int32Type>().ok_or_else(|| {
+                plan_datafusion_err!("make_dt_interval arg[5] must be Int32")
+            })
+        })
+        .transpose()?;
+    let secs: Option<&PrimitiveArray<Float64Type>> = args
+        .get(6)
+        .map(|a| {
+            a.as_primitive_opt::<Float64Type>().ok_or_else(|| {
+                plan_datafusion_err!("make_dt_interval arg[6] must be Float64")
+            })
+        })
+        .transpose()?;
+
+    let mut builder = IntervalMonthDayNanoBuilder::with_capacity(n_rows);
+
+    for i in 0..n_rows {
+        // if one column is NULL → result NULL
+        let any_null_present = years.as_ref().is_some_and(|a| a.is_null(i))
+            || months.as_ref().is_some_and(|a| a.is_null(i))
+            || weeks.as_ref().is_some_and(|a| a.is_null(i))
+            || days.as_ref().is_some_and(|a| a.is_null(i))
+            || hours.as_ref().is_some_and(|a| a.is_null(i))
+            || mins.as_ref().is_some_and(|a| a.is_null(i))
+            || secs.as_ref().is_some_and(|a| {
+                a.is_null(i) || a.value(i).is_infinite() || a.value(i).is_nan()

Review Comment:
   ```suggestion
                   a.is_null(i) || !a.value(i).is_finite()
   ```



##########
datafusion/functions/src/datetime/make_interval.rs:
##########
@@ -0,0 +1,621 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use std::any::Any;
+use std::sync::Arc;
+
+use crate::utils::make_scalar_function;
+use arrow::array::{Array, ArrayRef, IntervalMonthDayNanoBuilder, 
PrimitiveArray};
+use arrow::datatypes::DataType::Interval;
+use arrow::datatypes::IntervalUnit::MonthDayNano;
+use arrow::datatypes::{DataType, IntervalMonthDayNano};
+use datafusion_common::{
+    exec_err, plan_datafusion_err, DataFusionError, Result, ScalarValue,
+};
+use datafusion_expr::{
+    ColumnarValue, Documentation, ScalarFunctionArgs, ScalarUDFImpl, Signature,
+    Volatility,
+};
+use datafusion_macros::user_doc;
+
+#[user_doc(
+    doc_section(label = "Time and Date Functions"),
+    description = "Construct an INTERVAL (MonthDayNano) from component parts. 
Missing arguments default to 0; if any provided argument is NULL on a row, the 
result is NULL.",
+    syntax_example = "make_interval([years[, months[, weeks[, days[, hours[, 
mins[, secs]]]]]])",
+    sql_example = r#"```sql
+-- Inline example without creating a table
+> SELECT
+      y, m, w, d, h, mi, s,
+      make_interval(y, m, w, d, h, mi, s) AS interval
+    FROM VALUES
+      (1,   1,   1,   1,   1,   1,   1.0)
+    AS v(y, m, w, d, h, mi, s);
++---+---+---+---+---+---+---+---------------------------------------------------+
+|y  |m  |w  |d  |h  |mi |s  |interval                                          
 |
++---+---+---+---+---+---+---+---------------------------------------------------+
+|1  |1  |1  |1  |1  |1  |1.0|1 years 1 months 8 days 1 hours 1 minutes 1 
seconds|
++---+---+---+---+---+---+---+---------------------------------------------------+
+```"#,
+    argument(
+        name = "years",
+        description = "Years to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "months",
+        description = "Months to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "weeks",
+        description = "Weeks to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "days",
+        description = "Days to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "hours",
+        description = "Hours to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "mins",
+        description = "Minutes to use when making the interval. Optional; 
defaults to 0. Can be a constant, column or function, and any combination of 
arithmetic operators."
+    ),
+    argument(
+        name = "secs",
+        description = "Seconds to use when making the interval (may be 
fractional). Optional; defaults to 0. Must be finite (not NaN/±Inf). Can be a 
constant, column or function, and any combination of arithmetic operators."
+    )
+)]
+#[derive(Debug, PartialEq, Eq, Hash)]
+pub struct MakeIntervalFunc {
+    signature: Signature,
+}
+
+impl Default for MakeIntervalFunc {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+impl MakeIntervalFunc {
+    pub fn new() -> Self {
+        Self {
+            signature: Signature::user_defined(Volatility::Immutable),
+        }
+    }
+}
+
+impl ScalarUDFImpl for MakeIntervalFunc {
+    fn as_any(&self) -> &dyn Any {
+        self
+    }
+
+    fn name(&self) -> &str {
+        "make_interval"
+    }
+
+    fn signature(&self) -> &Signature {
+        &self.signature
+    }
+
+    fn return_type(&self, _arg_types: &[DataType]) -> Result<DataType> {
+        Ok(Interval(MonthDayNano))
+    }
+
+    fn invoke_with_args(&self, args: ScalarFunctionArgs) -> 
Result<ColumnarValue> {
+        if args.args.is_empty() {
+            return Ok(ColumnarValue::Scalar(ScalarValue::IntervalMonthDayNano(
+                Some(IntervalMonthDayNano::new(0, 0, 0)),
+            )));
+        }
+        make_scalar_function(make_interval_kernel, vec![])(&args.args)
+    }
+
+    fn coerce_types(&self, arg_types: &[DataType]) -> Result<Vec<DataType>> {
+        let length = arg_types.len();
+        match length {
+            x if x > 7 => {
+                exec_err!(
+                    "make_interval expects between 0 and 7 arguments, got {}",
+                    arg_types.len()
+                )
+            }
+            _ => Ok((0..arg_types.len())
+                .map(|i| {
+                    if i == 6 {
+                        DataType::Float64
+                    } else {
+                        DataType::Int32
+                    }
+                })
+                .collect()),
+        }
+    }
+
+    fn documentation(&self) -> Option<&Documentation> {
+        self.doc()
+    }
+}
+
+fn make_interval_kernel(args: &[ArrayRef]) -> Result<ArrayRef, 
DataFusionError> {
+    use arrow::array::AsArray;
+    use arrow::datatypes::{Float64Type, Int32Type};
+
+    if args.len() > 7 {
+        return exec_err!(
+            "make_interval expects between 0 and 7 arguments, got {}",
+            args.len()
+        );
+    }
+
+    let n_rows = args[0].len();
+
+    let years = args
+        .first()
+        .map(|a| {
+            a.as_primitive_opt::<Int32Type>().ok_or_else(|| {
+                plan_datafusion_err!("make_dt_interval arg[0] must be Int32")
+            })
+        })
+        .transpose()?;

Review Comment:
   Similarly here, we already grabbed the first argument for `n_rows` so we can 
assume years array exists (even disregarding that this would be checked before 
invocation of this function)



-- 
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: github-unsubscr...@datafusion.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscr...@datafusion.apache.org
For additional commands, e-mail: github-h...@datafusion.apache.org


Reply via email to