use super::{Duplicates, Expr, Ident, Identifier, Node, OrderBy, WindowSpec};
#[derive(Debug)]
pub struct Function<'s, ID> {
pub name: Identifier<'s, ID>,
pub params: FunctionParams<'s, ID>,
}
#[derive(Debug)]
pub struct FunctionParams<'s, ID> {
pub args: Node<FunctionArgs<'s, ID>, ID>,
pub within_group: Option<WithinGroup<'s, ID>>,
pub from_row: Option<FromRow<ID>>,
pub respect_nulls: Option<RespectNulls<ID>>,
pub over: Option<FunctionWindow<'s, ID>>,
}
#[derive(Debug)]
pub enum FunctionArgs<'s, ID> {
None(Node<(), ID>),
List(FunctionArgsList<'s, ID>),
}
impl<'s, ID> FunctionArgs<'s, ID> {
pub(crate) fn is_empty(&self) -> bool {
match self {
FunctionArgs::None(_) => true,
FunctionArgs::List(FunctionArgsList {
duplicates: _,
args,
}) => args.is_empty(),
}
}
pub(crate) fn len(&self) -> usize {
match self {
FunctionArgs::None(_) => 0,
FunctionArgs::List(FunctionArgsList {
duplicates: _,
args,
}) => args.len(),
}
}
}
impl<'s, ID> FunctionArgs<'s, ID> {
pub fn duplicates(&self) -> Option<&Node<Duplicates, ID>> {
match self {
FunctionArgs::None(_) => None,
FunctionArgs::List(FunctionArgsList {
duplicates,
args: _,
}) => duplicates.as_ref(),
}
}
pub fn iter(&self) -> impl Iterator<Item = &FunctionArg<'s, ID>> {
match self {
FunctionArgs::None(_) => MaybeIter(None),
FunctionArgs::List(FunctionArgsList {
duplicates: _,
args,
}) => MaybeIter(Some(args.iter())),
}
}
}
struct MaybeIter<I>(Option<I>);
impl<I> Iterator for MaybeIter<I>
where
I: Iterator,
{
type Item = I::Item;
fn next(&mut self) -> Option<Self::Item> {
match self.0.as_mut() {
None => None,
Some(inner) => inner.next(),
}
}
}
#[derive(Debug)]
pub struct FunctionArgsList<'s, ID> {
pub duplicates: Option<Node<Duplicates, ID>>,
pub args: Vec<FunctionArg<'s, ID>>,
}
#[derive(Debug)]
pub struct FunctionArg<'s, ID> {
pub arg: FunctionArgType<'s, ID>,
pub clause: Option<FunctionArgClause<'s, ID>>,
}
impl<'s, ID, T> From<T> for FunctionArg<'s, ID>
where
T: Into<FunctionArgType<'s, ID>>,
{
fn from(value: T) -> Self {
Self {
arg: value.into(),
clause: None,
}
}
}
#[derive(Debug)]
pub enum FunctionArgType<'s, ID> {
Wildcard(Node<(), ID>),
ExtractExpr(ExtractExpr<'s, ID>),
Named(NamedFunctionArg<'s, ID>),
Expr(Expr<'s, ID>),
}
impl<'s, ID> From<Expr<'s, ID>> for FunctionArgType<'s, ID> {
fn from(value: Expr<'s, ID>) -> Self {
Self::Expr(value)
}
}
impl<'s, ID> From<ExtractExpr<'s, ID>> for FunctionArgType<'s, ID> {
fn from(value: ExtractExpr<'s, ID>) -> Self {
Self::ExtractExpr(value)
}
}
impl<'s, ID> From<NamedFunctionArg<'s, ID>> for FunctionArgType<'s, ID> {
fn from(value: NamedFunctionArg<'s, ID>) -> Self {
Self::Named(value)
}
}
#[derive(Debug)]
pub enum FunctionArgClause<'s, ID> {
UsingCharset(UsingCharset<ID>),
RespectNulls(RespectNulls<ID>),
OnOverflow(OnOverflow<'s, ID>),
}
impl<'s, ID> From<UsingCharset<ID>> for FunctionArgClause<'s, ID> {
fn from(value: UsingCharset<ID>) -> Self {
Self::UsingCharset(value)
}
}
impl<'s, ID> From<RespectNulls<ID>> for FunctionArgClause<'s, ID> {
fn from(value: RespectNulls<ID>) -> Self {
Self::RespectNulls(value)
}
}
impl<'s, ID> From<OnOverflow<'s, ID>> for FunctionArgClause<'s, ID> {
fn from(value: OnOverflow<'s, ID>) -> Self {
Self::OnOverflow(value)
}
}
#[derive(Debug)]
pub struct NamedFunctionArg<'s, ID> {
pub name: Node<Ident<'s>, ID>,
pub operator_token: Node<(), ID>,
pub arg: Expr<'s, ID>,
}
#[derive(Debug)]
pub struct FunctionWindow<'s, ID> {
pub over_token: Node<(), ID>,
pub window: FunctionWindowType<'s, ID>,
}
#[derive(Debug)]
pub enum FunctionWindowType<'s, ID> {
Named(Node<Ident<'s>, ID>),
Specified(Node<WindowSpec<'s, ID>, ID>),
}
#[derive(Debug)]
pub struct WithinGroup<'s, ID> {
pub within_token: Node<(), ID>,
pub group_token: Node<(), ID>,
pub order_by: Node<OrderBy<'s, ID>, ID>,
}
#[derive(Debug)]
pub struct UsingCharset<ID> {
pub using_token: Node<(), ID>,
pub charset_token: Node<Charset, ID>,
}
#[derive(Debug, Copy, Clone)]
pub enum Charset {
Database,
National,
}
#[derive(Debug)]
pub struct ExtractExpr<'s, ID> {
pub datetime_token: Node<ExtractDatetime, ID>,
pub from_token: Node<(), ID>,
pub expr: Expr<'s, ID>,
}
#[derive(Debug, Copy, Clone)]
pub enum ExtractDatetime {
Year,
Month,
Day,
Hour,
Minute,
Second,
TimezoneHour,
TimezoneMinute,
TimezoneRegion,
TimezoneAbbreviation,
}
#[derive(Debug)]
pub struct FromRow<ID> {
pub from_token: Node<(), ID>,
pub type_token: Node<FromRowType, ID>,
}
#[derive(Debug, Copy, Clone)]
pub enum FromRowType {
First,
Last,
}
#[derive(Debug)]
pub struct RespectNulls<ID> {
pub type_token: Node<RespectNullsType, ID>,
pub nulls_token: Node<(), ID>,
}
#[derive(Debug, Copy, Clone)]
pub enum RespectNullsType {
Respect,
Ignore,
}
#[derive(Debug)]
pub struct OnOverflow<'s, ID> {
pub on_token: Node<(), ID>,
pub overflow_token: Node<(), ID>,
pub action: OnOverflowAction<'s, ID>,
}
#[derive(Debug)]
pub enum OnOverflowAction<'s, ID> {
Error { error_token: Node<(), ID> },
Truncate {
truncate_token: Node<(), ID>,
indicator: Option<Expr<'s, ID>>,
with_count: Option<OnOverflowCount<ID>>,
},
}
#[derive(Debug)]
pub struct OnOverflowCount<ID> {
pub count_option: Node<OnOverflowCountOption, ID>,
pub count_token: Node<(), ID>,
}
#[derive(Debug, Copy, Clone)]
pub enum OnOverflowCountOption {
With,
Without,
}