Skip to main content

uqa_sql/semantics/parameters/
arguments.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! The value text of `SET name TO argument, ...`, flattened as `PostgreSQL`'s `flatten_set_variable_args` does: only a list parameter takes several arguments, which are joined with `, `, and a string of a quoted list is quoted as an identifier needs.
8
9use super::catalog::find_parameter;
10use super::definition::ParameterFlags;
11use crate::SQLError;
12
13/// One argument of `SET`, as the grammar delivers it.
14#[derive(Clone, Debug, PartialEq)]
15pub enum SetArgument {
16    /// An integer constant, written in decimal.
17    Integer(i64),
18    /// A numeric constant that is not an integer, kept as written.
19    Number(String),
20    /// A string constant, an identifier or a keyword.
21    Text(String),
22}
23
24/// The value text that `SET name TO arguments` assigns.
25pub fn flatten_set_arguments(name: &str, arguments: &[SetArgument]) -> Result<String, SQLError> {
26    let flags = find_parameter(name).map_or(ParameterFlags::NONE, |definition| definition.flags);
27    if !flags.contains(ParameterFlags::LIST_INPUT) && arguments.len() != 1 {
28        return Err(SQLError::Routine {
29            sqlstate: "22023".into(),
30            message: format!("SET {name} takes only one argument"),
31        });
32    }
33    let quote = flags.contains(ParameterFlags::LIST_QUOTE);
34    Ok(arguments
35        .iter()
36        .map(|argument| match argument {
37            SetArgument::Integer(value) => value.to_string(),
38            SetArgument::Number(text) => text.clone(),
39            SetArgument::Text(text) if quote => crate::expr::quote_ident(text),
40            SetArgument::Text(text) => text.clone(),
41        })
42        .collect::<Vec<_>>()
43        .join(", "))
44}
45
46#[cfg(test)]
47mod tests;