catalog/system_schema/
pg_catalog.rs1mod pg_catalog_memory_table;
16mod pg_class;
17mod pg_database;
18mod pg_namespace;
19mod table_names;
20
21use std::collections::HashMap;
22use std::sync::{Arc, LazyLock, Weak};
23
24use common_catalog::consts::{self, DEFAULT_CATALOG_NAME, DEFAULT_SCHEMA_NAME, PG_CATALOG_NAME};
25use datatypes::schema::ColumnSchema;
26use lazy_static::lazy_static;
27use paste::paste;
28use pg_catalog_memory_table::get_schema_columns;
29use pg_class::PGClass;
30use pg_database::PGDatabase;
31use pg_namespace::PGNamespace;
32use session::context::{Channel, QueryContext};
33use table::TableRef;
34pub use table_names::*;
35
36use self::pg_namespace::oid_map::{PGNamespaceOidMap, PGNamespaceOidMapRef};
37use crate::system_schema::memory_table::MemoryTable;
38use crate::system_schema::utils::tables::u32_column;
39use crate::system_schema::{SystemSchemaProvider, SystemSchemaProviderInner, SystemTableRef};
40use crate::CatalogManager;
41
42lazy_static! {
43 static ref MEMORY_TABLES: &'static [&'static str] = &[table_names::PG_TYPE];
44}
45
46const OID_COLUMN_NAME: &str = "oid";
49
50fn oid_column() -> ColumnSchema {
51 u32_column(OID_COLUMN_NAME)
52}
53
54pub struct PGCatalogProvider {
56 catalog_name: String,
57 catalog_manager: Weak<dyn CatalogManager>,
58 tables: HashMap<String, TableRef>,
59
60 namespace_oid_map: PGNamespaceOidMapRef,
62}
63
64impl SystemSchemaProvider for PGCatalogProvider {
65 fn tables(&self) -> &HashMap<String, TableRef> {
66 assert!(!self.tables.is_empty());
67
68 &self.tables
69 }
70}
71
72macro_rules! setup_memory_table {
74 ($name: expr) => {
75 paste! {
76 {
77 let (schema, columns) = get_schema_columns($name);
78 Some(Arc::new(MemoryTable::new(
79 consts::[<PG_CATALOG_ $name _TABLE_ID>],
80 $name,
81 schema,
82 columns
83 )) as _)
84 }
85 }
86 };
87}
88
89impl PGCatalogProvider {
90 pub fn new(catalog_name: String, catalog_manager: Weak<dyn CatalogManager>) -> Self {
91 let mut provider = Self {
92 catalog_name,
93 catalog_manager,
94 tables: HashMap::new(),
95 namespace_oid_map: Arc::new(PGNamespaceOidMap::new()),
96 };
97 provider.build_tables();
98 provider
99 }
100
101 fn build_tables(&mut self) {
102 let mut tables = HashMap::new();
105 for name in MEMORY_TABLES.iter() {
108 tables.insert(name.to_string(), self.build_table(name).expect(name));
109 }
110 tables.insert(
111 PG_NAMESPACE.to_string(),
112 self.build_table(PG_NAMESPACE).expect(PG_NAMESPACE),
113 );
114 tables.insert(
115 PG_CLASS.to_string(),
116 self.build_table(PG_CLASS).expect(PG_NAMESPACE),
117 );
118 tables.insert(
119 PG_DATABASE.to_string(),
120 self.build_table(PG_DATABASE).expect(PG_DATABASE),
121 );
122 self.tables = tables;
123 }
124}
125
126impl SystemSchemaProviderInner for PGCatalogProvider {
127 fn schema_name() -> &'static str {
128 PG_CATALOG_NAME
129 }
130
131 fn system_table(&self, name: &str) -> Option<SystemTableRef> {
132 match name {
133 table_names::PG_TYPE => setup_memory_table!(PG_TYPE),
134 table_names::PG_NAMESPACE => Some(Arc::new(PGNamespace::new(
135 self.catalog_name.clone(),
136 self.catalog_manager.clone(),
137 self.namespace_oid_map.clone(),
138 ))),
139 table_names::PG_CLASS => Some(Arc::new(PGClass::new(
140 self.catalog_name.clone(),
141 self.catalog_manager.clone(),
142 self.namespace_oid_map.clone(),
143 ))),
144 table_names::PG_DATABASE => Some(Arc::new(PGDatabase::new(
145 self.catalog_name.clone(),
146 self.catalog_manager.clone(),
147 self.namespace_oid_map.clone(),
148 ))),
149 _ => None,
150 }
151 }
152
153 fn catalog_name(&self) -> &str {
154 &self.catalog_name
155 }
156}
157
158static PG_QUERY_CTX: LazyLock<QueryContext> = LazyLock::new(|| {
160 QueryContext::with_channel(DEFAULT_CATALOG_NAME, DEFAULT_SCHEMA_NAME, Channel::Postgres)
161});
162
163fn query_ctx() -> Option<&'static QueryContext> {
164 Some(&PG_QUERY_CTX)
165}