Skip to main content

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