uqa_sql/catalog/
sequence_functions.rs1use crate::{
10 schema::sequences::ownership::{SequenceOwnerCatalog, SequenceOwnerColumnIdentity},
11 SQLError,
12};
13use uqa_core::Value;
14
15pub fn strict_sequence_oid(function: &str, arguments: &[Value]) -> Result<Option<i64>, SQLError> {
16 let [argument] = arguments else {
17 return Err(SQLError::BadArity {
18 name: function.into(),
19 expected: "1".into(),
20 actual: arguments.len(),
21 });
22 };
23 match argument {
24 Value::Null => Ok(None),
25 Value::Int(oid) => Ok(Some(*oid)),
26 value => Err(SQLError::TypeMismatch(format!(
27 "{function} requires oid or regclass, got {value:?}"
28 ))),
29 }
30}
31
32pub fn strict_sequence_regclass_oid(
33 function: &str,
34 arguments: &[Value],
35 resolve: &mut dyn FnMut(&str) -> Result<Option<i64>, SQLError>,
36) -> Result<Option<i64>, SQLError> {
37 let [argument] = arguments else {
38 return Err(SQLError::BadArity {
39 name: function.into(),
40 expected: "1".into(),
41 actual: arguments.len(),
42 });
43 };
44 match argument {
45 Value::Null => Ok(None),
46 Value::Int(oid) => Ok(Some(*oid)),
47 Value::Str(name) | Value::FixedChar(name) => {
48 resolve(name)?.map(Some).ok_or_else(|| SQLError::Routine {
49 sqlstate: "42P01".into(),
50 message: format!("relation \"{name}\" does not exist"),
51 })
52 }
53 value => Err(SQLError::TypeMismatch(format!(
54 "{function} requires regclass, got {value:?}"
55 ))),
56 }
57}
58
59pub fn serial_sequence_owner(
60 catalog: &dyn SequenceOwnerCatalog,
61 arguments: &[Value],
62) -> Result<Option<SequenceOwnerColumnIdentity>, SQLError> {
63 if arguments.len() != 2 {
64 return Err(SQLError::BadArity {
65 name: "pg_get_serial_sequence".into(),
66 expected: "2".into(),
67 actual: arguments.len(),
68 });
69 }
70 if arguments
71 .iter()
72 .any(|argument| matches!(argument, Value::Null))
73 {
74 return Ok(None);
75 }
76 let relation_name = match &arguments[0] {
77 Value::Str(value) | Value::FixedChar(value) => value,
78 other => {
79 return Err(SQLError::TypeMismatch(format!(
80 "pg_get_serial_sequence table name must be text, got {other:?}"
81 )))
82 }
83 };
84 let column_name = match &arguments[1] {
85 Value::Str(value) | Value::FixedChar(value) => value,
86 other => {
87 return Err(SQLError::TypeMismatch(format!(
88 "pg_get_serial_sequence column name must be text, got {other:?}"
89 )))
90 }
91 };
92 let Some((canonical, kind)) = catalog.resolve_owner_relation(relation_name)? else {
93 return Err(SQLError::Routine {
94 sqlstate: "42P01".into(),
95 message: format!("relation \"{relation_name}\" does not exist"),
96 });
97 };
98 let Some(owner_column) = crate::schema::sequences::ownership::sequence_owner_column_identity(
99 catalog,
100 &canonical,
101 kind,
102 column_name,
103 )?
104 else {
105 return Ok(None);
106 };
107 Ok(Some(owner_column))
108}
109
110pub mod value_error;