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