use crate::query::ast::*;
pub(crate) fn get_root_alias(query: &SqlQuery) -> Option<String> {
match &query.from {
Some(from) => get_alias_from_collection(&from.collection),
None => None,
}
}
fn get_alias_from_collection(coll: &SqlCollectionExpression) -> Option<String> {
match coll {
SqlCollectionExpression::Aliased { collection, alias } => {
alias.clone().or_else(|| match collection {
SqlCollection::Path { root, .. } => Some(root.clone()),
_ => None,
})
}
SqlCollectionExpression::Join { left, .. } => get_alias_from_collection(left),
SqlCollectionExpression::ArrayIterator { .. } => None,
}
}
pub(crate) type Params = [(String, serde_json::Value)];
pub(crate) fn normalize_parameter_name(name: &str) -> &str {
name.trim_start_matches('@')
}
pub(crate) fn resolve_parameter_value<'a>(
parameters: &'a Params,
name: &str,
) -> Option<&'a serde_json::Value> {
let needle = normalize_parameter_name(name);
parameters
.iter()
.find(|(param_name, _)| normalize_parameter_name(param_name) == needle)
.map(|(_, value)| value)
}
pub(crate) fn resolve_non_negative_integer_parameter(
parameters: &Params,
name: &str,
) -> Result<i64, String> {
let needle = normalize_parameter_name(name);
let Some(value) = resolve_parameter_value(parameters, name) else {
return Err(format!(
"query references parameter @{needle} but no value was supplied"
));
};
match value {
serde_json::Value::Number(n) => match n.as_i64() {
Some(i) if i < 0 => Err(format!("parameter @{needle} must be non-negative; got {i}")),
Some(i) => Ok(i),
None => Err(format!("parameter @{needle} must be an integer; got {n}")),
},
other => Err(format!(
"parameter @{needle} must be an integer; got {other}"
)),
}
}