1use rupg_common::{Error, Result, SqlState};
4use rupg_sql::nodes::{List, Node};
5
6use crate::agg::Kind;
7use crate::coerce::{AtOpt, Context};
8use crate::select::{Query, Target};
9use crate::{Analyzer, Env, Params, types};
10
11pub fn param_types(names: &List, env: &dyn Env) -> Result<Vec<u32>> {
17 let mut analyzer = Analyzer::new(env, &Params::default());
18 names
19 .iter()
20 .map(|node| match node {
21 Some(Node::TypeName(name)) => analyzer.type_name(name).map(|(ty, _)| ty),
22 _ => Err(Error::new(SqlState::INTERNAL_ERROR, "a parameter of PREPARE is not a type")),
23 })
24 .collect()
25}
26
27pub fn execute_params(exprs: &List, types: &[u32], env: &dyn Env) -> Result<Query> {
33 let mut analyzer = Analyzer::new(env, &Params::default());
34 let mut targets = Vec::with_capacity(exprs.len());
35 for (i, (node, &ty)) in exprs.iter().zip(types).enumerate() {
36 let expr = analyzer.with_kind(Kind::ExecuteParameter, |an| an.transform(node.as_ref()))?;
37 let (given, at) = (expr.ty, expr.location);
38 let Some(expr) = analyzer.coerce_to_target(expr, ty, -1, Context::Assignment, at)? else {
39 return Err(Error::new(
40 SqlState::DATATYPE_MISMATCH,
41 format!(
42 "parameter ${} of type {} cannot be coerced to the expected type {}",
43 i + 1,
44 types::name(given),
45 types::name(ty)
46 ),
47 )
48 .with_hint("You will need to rewrite or cast the expression.")
49 .at_opt(at));
50 };
51 targets.push(Target { name: "?column?".into(), expr, origin: None, junk: false });
52 }
53 Ok(Query {
54 relations: Vec::new(),
55 from: Vec::new(),
56 targets,
57 filter: None,
58 grouped: false,
59 group: Vec::new(),
60 grouping_sets: Vec::new(),
61 group_distinct: false,
62 having: None,
63 sort: Vec::new(),
64 distinct: Vec::new(),
65 distinct_on: false,
66 offset: None,
67 limit: None,
68 with_ties: false,
69 params: Vec::new(),
70 notices: analyzer.notices,
71 set_op: None,
72 windows: Vec::new(),
73 ctes: Vec::new(),
74 recursive: false,
75 row_marks: Vec::new(),
76 write: None,
77 out_args: Vec::new(),
78 pulled: 0,
79 pushed: false,
80 barrier: Vec::new(),
81 minmax: None,
82 constraint_deps: Vec::new(),
83 shown: None,
84 perms: Vec::new(),
85 funcs: Vec::new(),
86 })
87}