use sqlparser::ast::{
Assignment, AssignmentTarget, CreateTableOptions, DuplicateTreatment, Expr, FromTable,
Function, FunctionArg, FunctionArguments, GroupByExpr, LimitClause, ObjectName, OrderBy,
OrderByExpr, OrderByKind, Query, SqlOption, TableObject, TableWithJoins,
};
use crate::error::{SqawkError, SqawkResult};
pub(crate) fn func_args(func: &Function) -> &[FunctionArg] {
match &func.args {
FunctionArguments::List(list) => &list.args,
FunctionArguments::None | FunctionArguments::Subquery(_) => &[],
}
}
pub(crate) fn func_is_distinct(func: &Function) -> bool {
match &func.args {
FunctionArguments::List(list) => {
matches!(list.duplicate_treatment, Some(DuplicateTreatment::Distinct))
}
FunctionArguments::None | FunctionArguments::Subquery(_) => false,
}
}
pub(crate) fn group_by_exprs(group_by: &GroupByExpr) -> &[sqlparser::ast::Expr] {
match group_by {
GroupByExpr::Expressions(exprs, _) => exprs,
GroupByExpr::All(_) => &[],
}
}
pub(crate) fn is_group_by_all(group_by: &GroupByExpr) -> bool {
matches!(group_by, GroupByExpr::All(_))
}
pub(crate) fn query_order_by(query: &Query) -> &[OrderByExpr] {
match &query.order_by {
Some(OrderBy {
kind: OrderByKind::Expressions(exprs),
..
}) => exprs,
_ => &[],
}
}
pub(crate) fn is_order_by_all(query: &Query) -> bool {
matches!(
&query.order_by,
Some(OrderBy {
kind: OrderByKind::All(_),
..
})
)
}
pub(crate) fn order_by_is_asc(expr: &OrderByExpr) -> bool {
expr.options.asc.unwrap_or(true)
}
pub(crate) fn query_limit(query: &Query) -> Option<&Expr> {
match &query.limit_clause {
Some(LimitClause::LimitOffset { limit, .. }) => limit.as_ref(),
Some(LimitClause::OffsetCommaLimit { limit, .. }) => Some(limit),
None => None,
}
}
pub(crate) fn query_offset(query: &Query) -> Option<&Expr> {
match &query.limit_clause {
Some(LimitClause::LimitOffset { offset, .. }) => offset.as_ref().map(|o| &o.value),
Some(LimitClause::OffsetCommaLimit { offset, .. }) => Some(offset),
None => None,
}
}
pub(crate) fn insert_target(table: &TableObject) -> SqawkResult<&ObjectName> {
match table {
TableObject::TableName(name) => Ok(name),
TableObject::TableFunction(_) | TableObject::TableQuery(_) => Err(
SqawkError::UnsupportedSqlFeature("INSERT target must be a plain table name".into()),
),
}
}
pub(crate) fn delete_from(from: &FromTable) -> &[TableWithJoins] {
match from {
FromTable::WithFromKeyword(t) | FromTable::WithoutKeyword(t) => t,
}
}
pub(crate) fn assignment_column(assignment: &Assignment) -> SqawkResult<String> {
match &assignment.target {
AssignmentTarget::ColumnName(name) => Ok(object_name_last(name)),
AssignmentTarget::Tuple(_) => Err(SqawkError::UnsupportedSqlFeature(
"Tuple assignment in UPDATE is not supported".into(),
)),
}
}
pub(crate) fn create_table_options(options: &CreateTableOptions) -> &[SqlOption] {
match options {
CreateTableOptions::With(o)
| CreateTableOptions::Options(o)
| CreateTableOptions::Plain(o)
| CreateTableOptions::TableProperties(o) => o,
_ => &[],
}
}
pub(crate) fn sql_option_key_value(option: &SqlOption) -> Option<(String, String)> {
match option {
SqlOption::KeyValue { key, value } => {
let text = match value {
Expr::Value(v) => match &v.value {
sqlparser::ast::Value::SingleQuotedString(s)
| sqlparser::ast::Value::DoubleQuotedString(s)
| sqlparser::ast::Value::Number(s, _) => s.clone(),
other => other.to_string(),
},
Expr::Identifier(ident) => ident.value.clone(),
other => other.to_string(),
};
Some((key.value.clone(), text))
}
_ => None,
}
}
pub(crate) fn object_name_last(name: &ObjectName) -> String {
match name.0.last() {
Some(part) => match part.as_ident() {
Some(ident) => ident.value.clone(),
None => part.to_string(),
},
None => String::new(),
}
}