#[macro_export]
macro_rules! define_pure_function {
(
$struct_name:ident,
$func_name:literal,
() -> $ret:ident,
$impl_path:path
) => {
#[derive(Debug, Clone, Copy, Default)]
pub struct $struct_name;
impl $crate::exec::function::ScalarFunction for $struct_name {
fn name(&self) -> &'static str {
$func_name
}
fn signature(&self) -> $crate::exec::function::Signature {
$crate::exec::function::Signature::new().returns($crate::expr::Kind::$ret)
}
fn invoke(&self, args: Vec<$crate::val::Value>) -> anyhow::Result<$crate::val::Value> {
let args = $crate::fnc::args::FromArgs::from_args($func_name, args)?;
$impl_path(args)
}
}
};
(
$struct_name:ident,
$func_name:literal,
($arg_name:ident : $arg_type:ident) -> $ret:ident,
$impl_path:path
) => {
#[derive(Debug, Clone, Copy, Default)]
pub struct $struct_name;
impl $crate::exec::function::ScalarFunction for $struct_name {
fn name(&self) -> &'static str {
$func_name
}
fn signature(&self) -> $crate::exec::function::Signature {
$crate::exec::function::Signature::new()
.arg(stringify!($arg_name), $crate::expr::Kind::$arg_type)
.returns($crate::expr::Kind::$ret)
}
fn invoke(&self, args: Vec<$crate::val::Value>) -> anyhow::Result<$crate::val::Value> {
let args = $crate::fnc::args::FromArgs::from_args($func_name, args)?;
$impl_path(args)
}
}
};
(
$struct_name:ident,
$func_name:literal,
($arg1_name:ident : $arg1_type:ident, $arg2_name:ident : $arg2_type:ident) -> $ret:ident,
$impl_path:path
) => {
#[derive(Debug, Clone, Copy, Default)]
pub struct $struct_name;
impl $crate::exec::function::ScalarFunction for $struct_name {
fn name(&self) -> &'static str {
$func_name
}
fn signature(&self) -> $crate::exec::function::Signature {
$crate::exec::function::Signature::new()
.arg(stringify!($arg1_name), $crate::expr::Kind::$arg1_type)
.arg(stringify!($arg2_name), $crate::expr::Kind::$arg2_type)
.returns($crate::expr::Kind::$ret)
}
fn invoke(&self, args: Vec<$crate::val::Value>) -> anyhow::Result<$crate::val::Value> {
let args = $crate::fnc::args::FromArgs::from_args($func_name, args)?;
$impl_path(args)
}
}
};
(
$struct_name:ident,
$func_name:literal,
($arg1_name:ident : $arg1_type:ident, $arg2_name:ident : $arg2_type:ident, $arg3_name:ident : $arg3_type:ident) -> $ret:ident,
$impl_path:path
) => {
#[derive(Debug, Clone, Copy, Default)]
pub struct $struct_name;
impl $crate::exec::function::ScalarFunction for $struct_name {
fn name(&self) -> &'static str {
$func_name
}
fn signature(&self) -> $crate::exec::function::Signature {
$crate::exec::function::Signature::new()
.arg(stringify!($arg1_name), $crate::expr::Kind::$arg1_type)
.arg(stringify!($arg2_name), $crate::expr::Kind::$arg2_type)
.arg(stringify!($arg3_name), $crate::expr::Kind::$arg3_type)
.returns($crate::expr::Kind::$ret)
}
fn invoke(&self, args: Vec<$crate::val::Value>) -> anyhow::Result<$crate::val::Value> {
let args = $crate::fnc::args::FromArgs::from_args($func_name, args)?;
$impl_path(args)
}
}
};
(
$struct_name:ident,
$func_name:literal,
(... $arg_name:ident : $arg_type:ident) -> $ret:ident,
$impl_path:path
) => {
#[derive(Debug, Clone, Copy, Default)]
pub struct $struct_name;
impl $crate::exec::function::ScalarFunction for $struct_name {
fn name(&self) -> &'static str {
$func_name
}
fn signature(&self) -> $crate::exec::function::Signature {
$crate::exec::function::Signature::new()
.variadic($crate::expr::Kind::$arg_type)
.returns($crate::expr::Kind::$ret)
}
fn invoke(&self, args: Vec<$crate::val::Value>) -> anyhow::Result<$crate::val::Value> {
let args = $crate::fnc::args::FromArgs::from_args($func_name, args)?;
$impl_path(args)
}
}
};
(
$struct_name:ident,
$func_name:literal,
($arg1_name:ident : $arg1_type:ident, ... $rest_name:ident : $rest_type:ident) -> $ret:ident,
$impl_path:path
) => {
#[derive(Debug, Clone, Copy, Default)]
pub struct $struct_name;
impl $crate::exec::function::ScalarFunction for $struct_name {
fn name(&self) -> &'static str {
$func_name
}
fn signature(&self) -> $crate::exec::function::Signature {
$crate::exec::function::Signature::new()
.arg(stringify!($arg1_name), $crate::expr::Kind::$arg1_type)
.variadic($crate::expr::Kind::$rest_type)
.returns($crate::expr::Kind::$ret)
}
fn invoke(&self, args: Vec<$crate::val::Value>) -> anyhow::Result<$crate::val::Value> {
let args = $crate::fnc::args::FromArgs::from_args($func_name, args)?;
$impl_path(args)
}
}
};
(
$struct_name:ident,
$func_name:literal,
($arg1_name:ident : $arg1_type:ident, ? $arg2_name:ident : $arg2_type:ident) -> $ret:ident,
$impl_path:path
) => {
#[derive(Debug, Clone, Copy, Default)]
pub struct $struct_name;
impl $crate::exec::function::ScalarFunction for $struct_name {
fn name(&self) -> &'static str {
$func_name
}
fn signature(&self) -> $crate::exec::function::Signature {
$crate::exec::function::Signature::new()
.arg(stringify!($arg1_name), $crate::expr::Kind::$arg1_type)
.optional(stringify!($arg2_name), $crate::expr::Kind::$arg2_type)
.returns($crate::expr::Kind::$ret)
}
fn invoke(&self, args: Vec<$crate::val::Value>) -> anyhow::Result<$crate::val::Value> {
let args = $crate::fnc::args::FromArgs::from_args($func_name, args)?;
$impl_path(args)
}
}
};
(
$struct_name:ident,
$func_name:literal,
($arg1_name:ident : $arg1_type:ident, $arg2_name:ident : $arg2_type:ident, ? $arg3_name:ident : $arg3_type:ident) -> $ret:ident,
$impl_path:path
) => {
#[derive(Debug, Clone, Copy, Default)]
pub struct $struct_name;
impl $crate::exec::function::ScalarFunction for $struct_name {
fn name(&self) -> &'static str {
$func_name
}
fn signature(&self) -> $crate::exec::function::Signature {
$crate::exec::function::Signature::new()
.arg(stringify!($arg1_name), $crate::expr::Kind::$arg1_type)
.arg(stringify!($arg2_name), $crate::expr::Kind::$arg2_type)
.optional(stringify!($arg3_name), $crate::expr::Kind::$arg3_type)
.returns($crate::expr::Kind::$ret)
}
fn invoke(&self, args: Vec<$crate::val::Value>) -> anyhow::Result<$crate::val::Value> {
let args = $crate::fnc::args::FromArgs::from_args($func_name, args)?;
$impl_path(args)
}
}
};
(
$struct_name:ident,
$func_name:literal,
(? $arg1_name:ident : $arg1_type:ident, ? $arg2_name:ident : $arg2_type:ident) -> $ret:ident,
$impl_path:path
) => {
#[derive(Debug, Clone, Copy, Default)]
pub struct $struct_name;
impl $crate::exec::function::ScalarFunction for $struct_name {
fn name(&self) -> &'static str {
$func_name
}
fn signature(&self) -> $crate::exec::function::Signature {
$crate::exec::function::Signature::new()
.optional(stringify!($arg1_name), $crate::expr::Kind::$arg1_type)
.optional(stringify!($arg2_name), $crate::expr::Kind::$arg2_type)
.returns($crate::expr::Kind::$ret)
}
fn invoke(&self, args: Vec<$crate::val::Value>) -> anyhow::Result<$crate::val::Value> {
let args = $crate::fnc::args::FromArgs::from_args($func_name, args)?;
$impl_path(args)
}
}
};
}
#[macro_export]
macro_rules! register_functions {
($registry:expr, $($func:ty),* $(,)?) => {
$(
$registry.register(<$func>::default());
)*
};
}
#[macro_export]
macro_rules! define_context_function {
(
$struct_name:ident,
$func_name:literal,
() -> $ret:ident,
$impl_fn:expr
) => {
#[derive(Debug, Clone, Copy, Default)]
pub struct $struct_name;
impl $crate::exec::function::ScalarFunction for $struct_name {
fn name(&self) -> &'static str {
$func_name
}
fn signature(&self) -> $crate::exec::function::Signature {
$crate::exec::function::Signature::new().returns($crate::expr::Kind::$ret)
}
fn is_pure(&self) -> bool {
false
}
fn invoke(&self, _args: Vec<$crate::val::Value>) -> anyhow::Result<$crate::val::Value> {
Err(anyhow::anyhow!("Function '{}' requires context", self.name()))
}
fn invoke_async<'a>(
&'a self,
ctx: &'a $crate::exec::physical_expr::EvalContext<'_>,
_args: Vec<$crate::val::Value>,
) -> $crate::exec::BoxFut<'a, anyhow::Result<$crate::val::Value>> {
Box::pin(async move { $impl_fn(ctx) })
}
}
};
}
#[macro_export]
macro_rules! define_async_function {
(
$struct_name:ident,
$func_name:literal,
() -> $ret:ident,
$impl_fn:expr
) => {
#[derive(Debug, Clone, Copy, Default)]
pub struct $struct_name;
impl $crate::exec::function::ScalarFunction for $struct_name {
fn name(&self) -> &'static str {
$func_name
}
fn signature(&self) -> $crate::exec::function::Signature {
$crate::exec::function::Signature::new().returns($crate::expr::Kind::$ret)
}
fn is_pure(&self) -> bool {
false
}
fn is_async(&self) -> bool {
true
}
fn invoke(&self, _args: Vec<$crate::val::Value>) -> anyhow::Result<$crate::val::Value> {
Err(anyhow::anyhow!("Function '{}' requires async execution", self.name()))
}
fn invoke_async<'a>(
&'a self,
ctx: &'a $crate::exec::physical_expr::EvalContext<'_>,
_args: Vec<$crate::val::Value>,
) -> $crate::exec::BoxFut<'a, anyhow::Result<$crate::val::Value>> {
Box::pin(async move { $impl_fn(ctx).await })
}
}
};
(
$struct_name:ident,
$func_name:literal,
($arg_name:ident : $arg_type:ident) -> $ret:ident,
$impl_fn:expr
) => {
#[derive(Debug, Clone, Copy, Default)]
pub struct $struct_name;
impl $crate::exec::function::ScalarFunction for $struct_name {
fn name(&self) -> &'static str {
$func_name
}
fn signature(&self) -> $crate::exec::function::Signature {
$crate::exec::function::Signature::new()
.arg(stringify!($arg_name), $crate::expr::Kind::$arg_type)
.returns($crate::expr::Kind::$ret)
}
fn is_pure(&self) -> bool {
false
}
fn is_async(&self) -> bool {
true
}
fn invoke(&self, _args: Vec<$crate::val::Value>) -> anyhow::Result<$crate::val::Value> {
Err(anyhow::anyhow!("Function '{}' requires async execution", self.name()))
}
fn invoke_async<'a>(
&'a self,
ctx: &'a $crate::exec::physical_expr::EvalContext<'_>,
args: Vec<$crate::val::Value>,
) -> $crate::exec::BoxFut<'a, anyhow::Result<$crate::val::Value>> {
Box::pin(async move { $impl_fn(ctx, args).await })
}
}
};
(
$struct_name:ident,
$func_name:literal,
($arg1_name:ident : $arg1_type:ident, $arg2_name:ident : $arg2_type:ident) -> $ret:ident,
$impl_fn:expr
) => {
#[derive(Debug, Clone, Copy, Default)]
pub struct $struct_name;
impl $crate::exec::function::ScalarFunction for $struct_name {
fn name(&self) -> &'static str {
$func_name
}
fn signature(&self) -> $crate::exec::function::Signature {
$crate::exec::function::Signature::new()
.arg(stringify!($arg1_name), $crate::expr::Kind::$arg1_type)
.arg(stringify!($arg2_name), $crate::expr::Kind::$arg2_type)
.returns($crate::expr::Kind::$ret)
}
fn is_pure(&self) -> bool {
false
}
fn is_async(&self) -> bool {
true
}
fn invoke(&self, _args: Vec<$crate::val::Value>) -> anyhow::Result<$crate::val::Value> {
Err(anyhow::anyhow!("Function '{}' requires async execution", self.name()))
}
fn invoke_async<'a>(
&'a self,
ctx: &'a $crate::exec::physical_expr::EvalContext<'_>,
args: Vec<$crate::val::Value>,
) -> $crate::exec::BoxFut<'a, anyhow::Result<$crate::val::Value>> {
Box::pin(async move { $impl_fn(ctx, args).await })
}
}
};
(
$struct_name:ident,
$func_name:literal,
($arg1_name:ident : $arg1_type:ident, ? $arg2_name:ident : $arg2_type:ident) -> $ret:ident,
$impl_fn:expr
) => {
#[derive(Debug, Clone, Copy, Default)]
pub struct $struct_name;
impl $crate::exec::function::ScalarFunction for $struct_name {
fn name(&self) -> &'static str {
$func_name
}
fn signature(&self) -> $crate::exec::function::Signature {
$crate::exec::function::Signature::new()
.arg(stringify!($arg1_name), $crate::expr::Kind::$arg1_type)
.optional(stringify!($arg2_name), $crate::expr::Kind::$arg2_type)
.returns($crate::expr::Kind::$ret)
}
fn is_pure(&self) -> bool {
false
}
fn is_async(&self) -> bool {
true
}
fn invoke(&self, _args: Vec<$crate::val::Value>) -> anyhow::Result<$crate::val::Value> {
Err(anyhow::anyhow!("Function '{}' requires async execution", self.name()))
}
fn invoke_async<'a>(
&'a self,
ctx: &'a $crate::exec::physical_expr::EvalContext<'_>,
args: Vec<$crate::val::Value>,
) -> $crate::exec::BoxFut<'a, anyhow::Result<$crate::val::Value>> {
Box::pin(async move { $impl_fn(ctx, args).await })
}
}
};
(
$struct_name:ident,
$func_name:literal,
($arg1_name:ident : $arg1_type:ident, ? $arg2_name:ident : $arg2_type:ident, ? $arg3_name:ident : $arg3_type:ident) -> $ret:ident,
$impl_fn:expr
) => {
#[derive(Debug, Clone, Copy, Default)]
pub struct $struct_name;
impl $crate::exec::function::ScalarFunction for $struct_name {
fn name(&self) -> &'static str {
$func_name
}
fn signature(&self) -> $crate::exec::function::Signature {
$crate::exec::function::Signature::new()
.arg(stringify!($arg1_name), $crate::expr::Kind::$arg1_type)
.optional(stringify!($arg2_name), $crate::expr::Kind::$arg2_type)
.optional(stringify!($arg3_name), $crate::expr::Kind::$arg3_type)
.returns($crate::expr::Kind::$ret)
}
fn is_pure(&self) -> bool {
false
}
fn is_async(&self) -> bool {
true
}
fn invoke(&self, _args: Vec<$crate::val::Value>) -> anyhow::Result<$crate::val::Value> {
Err(anyhow::anyhow!("Function '{}' requires async execution", self.name()))
}
fn invoke_async<'a>(
&'a self,
ctx: &'a $crate::exec::physical_expr::EvalContext<'_>,
args: Vec<$crate::val::Value>,
) -> $crate::exec::BoxFut<'a, anyhow::Result<$crate::val::Value>> {
Box::pin(async move { $impl_fn(ctx, args).await })
}
}
};
}