catalog/
lib.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#![feature(assert_matches)]
16#![feature(try_blocks)]
17#![feature(let_chains)]
18
19use std::any::Any;
20use std::fmt::{Debug, Formatter};
21use std::sync::Arc;
22
23use api::v1::CreateTableExpr;
24use common_catalog::consts::{INFORMATION_SCHEMA_NAME, PG_CATALOG_NAME};
25use futures::future::BoxFuture;
26use futures_util::stream::BoxStream;
27use session::context::QueryContext;
28use table::metadata::{TableId, TableInfoRef};
29use table::TableRef;
30
31use crate::error::Result;
32
33pub mod error;
34pub mod information_extension;
35pub mod kvbackend;
36pub mod memory;
37mod metrics;
38pub mod system_schema;
39pub mod information_schema {
40    // TODO(j0hn50n133): re-export to make it compatible with the legacy code, migrate to the new path later
41    pub use crate::system_schema::information_schema::*;
42}
43
44pub mod process_manager;
45pub mod table_source;
46
47#[async_trait::async_trait]
48pub trait CatalogManager: Send + Sync {
49    fn as_any(&self) -> &dyn Any;
50
51    async fn catalog_names(&self) -> Result<Vec<String>>;
52
53    async fn schema_names(
54        &self,
55        catalog: &str,
56        query_ctx: Option<&QueryContext>,
57    ) -> Result<Vec<String>>;
58
59    async fn table_names(
60        &self,
61        catalog: &str,
62        schema: &str,
63        query_ctx: Option<&QueryContext>,
64    ) -> Result<Vec<String>>;
65
66    async fn catalog_exists(&self, catalog: &str) -> Result<bool>;
67
68    async fn schema_exists(
69        &self,
70        catalog: &str,
71        schema: &str,
72        query_ctx: Option<&QueryContext>,
73    ) -> Result<bool>;
74
75    async fn table_exists(
76        &self,
77        catalog: &str,
78        schema: &str,
79        table: &str,
80        query_ctx: Option<&QueryContext>,
81    ) -> Result<bool>;
82
83    /// Returns the table by catalog, schema and table name.
84    async fn table(
85        &self,
86        catalog: &str,
87        schema: &str,
88        table_name: &str,
89        query_ctx: Option<&QueryContext>,
90    ) -> Result<Option<TableRef>>;
91
92    /// Returns the table id of provided table ident.
93    async fn table_id(
94        &self,
95        catalog: &str,
96        schema: &str,
97        table_name: &str,
98        query_ctx: Option<&QueryContext>,
99    ) -> Result<Option<TableId>> {
100        Ok(self
101            .table(catalog, schema, table_name, query_ctx)
102            .await?
103            .map(|t| t.table_info().ident.table_id))
104    }
105
106    /// Returns the table of provided id.
107    async fn table_info_by_id(&self, table_id: TableId) -> Result<Option<TableInfoRef>>;
108
109    /// Returns the tables by table ids.
110    async fn tables_by_ids(
111        &self,
112        catalog: &str,
113        schema: &str,
114        table_ids: &[TableId],
115    ) -> Result<Vec<TableRef>>;
116
117    /// Returns all tables with a stream by catalog and schema.
118    fn tables<'a>(
119        &'a self,
120        catalog: &'a str,
121        schema: &'a str,
122        query_ctx: Option<&'a QueryContext>,
123    ) -> BoxStream<'a, Result<TableRef>>;
124
125    /// Check if `schema` is a reserved schema name
126    fn is_reserved_schema_name(&self, schema: &str) -> bool {
127        // We have to check whether a schema name is reserved before create schema.
128        // We need this rather than use schema_exists directly because `pg_catalog` is
129        // only visible via postgres protocol. So if we don't check, a mysql client may
130        // create a schema named `pg_catalog` which is somehow malformed.
131        schema == INFORMATION_SCHEMA_NAME || schema == PG_CATALOG_NAME
132    }
133}
134
135pub type CatalogManagerRef = Arc<dyn CatalogManager>;
136
137/// Hook called after system table opening.
138pub type OpenSystemTableHook =
139    Box<dyn Fn(TableRef) -> BoxFuture<'static, Result<()>> + Send + Sync>;
140
141/// Register system table request:
142/// - When system table is already created and registered, the hook will be called
143///     with table ref after opening the system table
144/// - When system table is not exists, create and register the table by `create_table_expr` and calls `open_hook` with the created table.
145pub struct RegisterSystemTableRequest {
146    pub create_table_expr: CreateTableExpr,
147    pub open_hook: Option<OpenSystemTableHook>,
148}
149
150#[derive(Clone)]
151pub struct RegisterTableRequest {
152    pub catalog: String,
153    pub schema: String,
154    pub table_name: String,
155    pub table_id: TableId,
156    pub table: TableRef,
157}
158
159impl Debug for RegisterTableRequest {
160    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
161        f.debug_struct("RegisterTableRequest")
162            .field("catalog", &self.catalog)
163            .field("schema", &self.schema)
164            .field("table_name", &self.table_name)
165            .field("table_id", &self.table_id)
166            .field("table", &self.table.table_info())
167            .finish()
168    }
169}
170
171#[derive(Debug, Clone)]
172pub struct RenameTableRequest {
173    pub catalog: String,
174    pub schema: String,
175    pub table_name: String,
176    pub new_table_name: String,
177    pub table_id: TableId,
178}
179
180#[derive(Debug, Clone)]
181pub struct DeregisterTableRequest {
182    pub catalog: String,
183    pub schema: String,
184    pub table_name: String,
185}
186
187#[derive(Debug, Clone)]
188pub struct DeregisterSchemaRequest {
189    pub catalog: String,
190    pub schema: String,
191}
192
193#[derive(Debug, Clone)]
194pub struct RegisterSchemaRequest {
195    pub catalog: String,
196    pub schema: String,
197}