use crate::Dialect;
pub fn skip_args_for_function(dialect: Dialect, func_name: &str) -> &'static [usize] {
let func_normalized: String = func_name
.chars()
.filter(|c| *c != '_')
.map(|c| c.to_ascii_lowercase())
.collect();
match func_normalized.as_str() {
"datediff" => match dialect {
Dialect::Bigquery => &[],
Dialect::Databricks => &[],
Dialect::Duckdb => &[],
Dialect::Hive => &[],
Dialect::Mssql => &[0],
Dialect::Mysql => &[],
Dialect::Redshift => &[0],
Dialect::Snowflake => &[0],
_ => &[],
},
"dateadd" => match dialect {
Dialect::Bigquery => &[],
Dialect::Hive => &[],
Dialect::Mssql => &[0],
Dialect::Mysql => &[],
Dialect::Postgres => &[],
Dialect::Snowflake => &[0],
_ => &[],
},
"datepart" => match dialect {
Dialect::Postgres => &[0],
Dialect::Redshift => &[0],
Dialect::Snowflake => &[0],
_ => &[],
},
"datetrunc" => match dialect {
Dialect::Bigquery => &[1],
Dialect::Databricks => &[0],
Dialect::Duckdb => &[0],
Dialect::Postgres => &[0],
Dialect::Redshift => &[0],
Dialect::Snowflake => &[0],
_ => &[],
},
"extract" => &[0],
"timestampadd" => match dialect {
Dialect::Bigquery => &[1],
Dialect::Snowflake => &[0],
_ => &[],
},
"timestampsub" => match dialect {
Dialect::Bigquery => &[1],
_ => &[],
},
_ => &[],
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum NullOrdering {
NullsAreLarge,
NullsAreSmall,
NullsAreLast,
}
impl Dialect {
pub const fn null_ordering(&self) -> NullOrdering {
match self {
Dialect::Bigquery => NullOrdering::NullsAreSmall,
Dialect::Clickhouse => NullOrdering::NullsAreLast,
Dialect::Databricks => NullOrdering::NullsAreSmall,
Dialect::Duckdb => NullOrdering::NullsAreLast,
Dialect::Hive => NullOrdering::NullsAreSmall,
Dialect::Mssql => NullOrdering::NullsAreSmall,
Dialect::Mysql => NullOrdering::NullsAreSmall,
Dialect::Oracle => NullOrdering::NullsAreLarge,
Dialect::Postgres => NullOrdering::NullsAreLarge,
Dialect::Redshift => NullOrdering::NullsAreLarge,
Dialect::Snowflake => NullOrdering::NullsAreLarge,
Dialect::Sqlite => NullOrdering::NullsAreSmall,
_ => NullOrdering::NullsAreLast,
}
}
pub const fn supports_implicit_unnest(&self) -> bool {
matches!(self, Dialect::Bigquery | Dialect::Redshift)
}
}
pub fn is_value_table_function(dialect: Dialect, func_name: &str) -> bool {
let name = func_name.to_ascii_uppercase();
if matches!(name.as_str(), "UNNEST" | "GENERATE_SERIES" | "JSON_TABLE") {
return true;
}
match dialect {
Dialect::Postgres => matches!(name.as_str(), "GENERATE_SUBSCRIPTS" | "REGEXP_MATCHES"),
Dialect::Snowflake => matches!(
name.as_str(),
"FLATTEN" | "SPLIT_TO_TABLE" | "STRTOK_SPLIT_TO_TABLE"
),
Dialect::Mssql => matches!(name.as_str(), "OPENJSON" | "STRING_SPLIT"),
Dialect::Duckdb => matches!(name.as_str(), "RANGE"),
Dialect::Clickhouse => matches!(name.as_str(), "ARRAY_JOIN"),
Dialect::Databricks => matches!(
name.as_str(),
"EXPLODE"
| "EXPLODE_OUTER"
| "POSEXPLODE"
| "POSEXPLODE_OUTER"
| "INLINE"
| "INLINE_OUTER"
),
Dialect::Hive => matches!(
name.as_str(),
"EXPLODE" | "POSEXPLODE" | "INLINE" | "JSON_TUPLE" | "PARSE_URL_TUPLE"
),
_ => false,
}
}