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::metadata::TableId;
28use table::TableRef;
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 table_source;
44
45#[async_trait::async_trait]
46pub trait CatalogManager: Send + Sync {
47    fn as_any(&self) -> &dyn Any;
48
49    async fn catalog_names(&self) -> Result<Vec<String>>;
50
51    async fn schema_names(
52        &self,
53        catalog: &str,
54        query_ctx: Option<&QueryContext>,
55    ) -> Result<Vec<String>>;
56
57    async fn table_names(
58        &self,
59        catalog: &str,
60        schema: &str,
61        query_ctx: Option<&QueryContext>,
62    ) -> Result<Vec<String>>;
63
64    async fn catalog_exists(&self, catalog: &str) -> Result<bool>;
65
66    async fn schema_exists(
67        &self,
68        catalog: &str,
69        schema: &str,
70        query_ctx: Option<&QueryContext>,
71    ) -> Result<bool>;
72
73    async fn table_exists(
74        &self,
75        catalog: &str,
76        schema: &str,
77        table: &str,
78        query_ctx: Option<&QueryContext>,
79    ) -> Result<bool>;
80
81    /// Returns the table by catalog, schema and table name.
82    async fn table(
83        &self,
84        catalog: &str,
85        schema: &str,
86        table_name: &str,
87        query_ctx: Option<&QueryContext>,
88    ) -> Result<Option<TableRef>>;
89
90    /// Returns the tables by table ids.
91    async fn tables_by_ids(
92        &self,
93        catalog: &str,
94        schema: &str,
95        table_ids: &[TableId],
96    ) -> Result<Vec<TableRef>>;
97
98    /// Returns all tables with a stream by catalog and schema.
99    fn tables<'a>(
100        &'a self,
101        catalog: &'a str,
102        schema: &'a str,
103        query_ctx: Option<&'a QueryContext>,
104    ) -> BoxStream<'a, Result<TableRef>>;
105
106    /// Check if `schema` is a reserved schema name
107    fn is_reserved_schema_name(&self, schema: &str) -> bool {
108        // We have to check whether a schema name is reserved before create schema.
109        // We need this rather than use schema_exists directly because `pg_catalog` is
110        // only visible via postgres protocol. So if we don't check, a mysql client may
111        // create a schema named `pg_catalog` which is somehow malformed.
112        schema == INFORMATION_SCHEMA_NAME || schema == PG_CATALOG_NAME
113    }
114}
115
116pub type CatalogManagerRef = Arc<dyn CatalogManager>;
117
118/// Hook called after system table opening.
119pub type OpenSystemTableHook =
120    Box<dyn Fn(TableRef) -> BoxFuture<'static, Result<()>> + Send + Sync>;
121
122/// Register system table request:
123/// - When system table is already created and registered, the hook will be called
124///     with table ref after opening the system table
125/// - When system table is not exists, create and register the table by `create_table_expr` and calls `open_hook` with the created table.
126pub struct RegisterSystemTableRequest {
127    pub create_table_expr: CreateTableExpr,
128    pub open_hook: Option<OpenSystemTableHook>,
129}
130
131#[derive(Clone)]
132pub struct RegisterTableRequest {
133    pub catalog: String,
134    pub schema: String,
135    pub table_name: String,
136    pub table_id: TableId,
137    pub table: TableRef,
138}
139
140impl Debug for RegisterTableRequest {
141    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
142        f.debug_struct("RegisterTableRequest")
143            .field("catalog", &self.catalog)
144            .field("schema", &self.schema)
145            .field("table_name", &self.table_name)
146            .field("table_id", &self.table_id)
147            .field("table", &self.table.table_info())
148            .finish()
149    }
150}
151
152#[derive(Debug, Clone)]
153pub struct RenameTableRequest {
154    pub catalog: String,
155    pub schema: String,
156    pub table_name: String,
157    pub new_table_name: String,
158    pub table_id: TableId,
159}
160
161#[derive(Debug, Clone)]
162pub struct DeregisterTableRequest {
163    pub catalog: String,
164    pub schema: String,
165    pub table_name: String,
166}
167
168#[derive(Debug, Clone)]
169pub struct DeregisterSchemaRequest {
170    pub catalog: String,
171    pub schema: String,
172}
173
174#[derive(Debug, Clone)]
175pub struct RegisterSchemaRequest {
176    pub catalog: String,
177    pub schema: String,
178}