uqa_sql/catalog/
foreign_relations.rs1use super::VirtualRelation;
10use crate::ColumnType;
11
12pub struct ForeignCatalogDescriptor {
13 pub relation: VirtualRelation,
14 pub row_type: u32,
15 pub array_type: u32,
16 pub required_columns: usize,
17}
18
19pub const FOREIGN_CATALOGS: &[ForeignCatalogDescriptor] = &[
20 ForeignCatalogDescriptor {
21 relation: VirtualRelation::PgForeignServer,
22 row_type: 10_078,
23 array_type: 10_077,
24 required_columns: 4,
25 },
26 ForeignCatalogDescriptor {
27 relation: VirtualRelation::PgForeignDataWrapper,
28 row_type: 10_076,
29 array_type: 10_075,
30 required_columns: 5,
31 },
32 ForeignCatalogDescriptor {
33 relation: VirtualRelation::PgForeignTable,
34 row_type: 10_082,
35 array_type: 10_081,
36 required_columns: 2,
37 },
38];
39
40pub(super) fn schema(relation: VirtualRelation) -> Vec<(String, ColumnType)> {
41 use ColumnType::{AclItem, Name, Oid, Text};
42 let array = |ty| ColumnType::Array(Box::new(ty));
43 let columns = match relation {
44 VirtualRelation::PgForeignDataWrapper => vec![
45 ("oid", Oid),
46 ("fdwname", Name),
47 ("fdwowner", Oid),
48 ("fdwhandler", Oid),
49 ("fdwvalidator", Oid),
50 ("fdwacl", array(AclItem)),
51 ("fdwoptions", array(Text)),
52 ],
53 VirtualRelation::PgForeignServer => vec![
54 ("oid", Oid),
55 ("srvname", Name),
56 ("srvowner", Oid),
57 ("srvfdw", Oid),
58 ("srvtype", Text),
59 ("srvversion", Text),
60 ("srvacl", array(AclItem)),
61 ("srvoptions", array(Text)),
62 ],
63 VirtualRelation::PgForeignTable => vec![
64 ("ftrelid", Oid),
65 ("ftserver", Oid),
66 ("ftoptions", array(Text)),
67 ],
68 _ => unreachable!("foreign catalog descriptor"),
69 };
70 columns
71 .into_iter()
72 .map(|(name, ty)| (name.into(), ty))
73 .collect()
74}
75
76#[cfg(test)]
77mod tests {
78 use super::*;
79
80 #[test]
81 fn foreign_catalog_descriptors_match_postgresql() {
82 let reference: serde_json::Value = serde_json::from_str(include_str!(concat!(
83 env!("CARGO_MANIFEST_DIR"),
84 "/../../tests/parity/pg18/foreign_catalog_oracle.expected.json"
85 )))
86 .unwrap();
87 let expected = reference["cases"]
88 .as_array()
89 .unwrap()
90 .iter()
91 .find(|case| case["id"] == "column_types")
92 .unwrap()["results"][0]["rows"]
93 .clone();
94 let mut rows = Vec::new();
95 for descriptor in FOREIGN_CATALOGS {
96 assert!(descriptor.relation.accepts_row_lock());
97 for (index, (name, ty)) in descriptor.relation.schema().into_iter().enumerate() {
98 rows.push(vec![
99 descriptor.relation.oid().to_string(),
100 (index + 1).to_string(),
101 name,
102 crate::catalog::type_metadata::pg_type_oid(&ty).to_string(),
103 if index < descriptor.required_columns {
104 "t"
105 } else {
106 "f"
107 }
108 .to_owned(),
109 "f".into(),
110 ]);
111 }
112 }
113 assert_eq!(serde_json::json!(rows), expected);
114 }
115}