mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-01-07 13:52:59 +00:00
* refactor: check and fix super import Signed-off-by: Ruihang Xia <waynestxia@gmail.com> * add to makefile Signed-off-by: Ruihang Xia <waynestxia@gmail.com> * change dir Signed-off-by: Ruihang Xia <waynestxia@gmail.com> --------- Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
166 lines
5.4 KiB
Rust
166 lines
5.4 KiB
Rust
// Copyright 2023 Greptime Team
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
mod pg_catalog_memory_table;
|
|
mod pg_class;
|
|
mod pg_database;
|
|
mod pg_namespace;
|
|
mod table_names;
|
|
|
|
use std::collections::HashMap;
|
|
use std::sync::{Arc, LazyLock, Weak};
|
|
|
|
use common_catalog::consts::{self, DEFAULT_CATALOG_NAME, DEFAULT_SCHEMA_NAME, PG_CATALOG_NAME};
|
|
use datatypes::schema::ColumnSchema;
|
|
use lazy_static::lazy_static;
|
|
use paste::paste;
|
|
use pg_catalog_memory_table::get_schema_columns;
|
|
use pg_class::PGClass;
|
|
use pg_database::PGDatabase;
|
|
use pg_namespace::PGNamespace;
|
|
use session::context::{Channel, QueryContext};
|
|
use table::TableRef;
|
|
pub use table_names::*;
|
|
|
|
use self::pg_namespace::oid_map::{PGNamespaceOidMap, PGNamespaceOidMapRef};
|
|
use crate::system_schema::memory_table::MemoryTable;
|
|
use crate::system_schema::utils::tables::u32_column;
|
|
use crate::system_schema::{SystemSchemaProvider, SystemSchemaProviderInner, SystemTableRef};
|
|
use crate::CatalogManager;
|
|
|
|
lazy_static! {
|
|
static ref MEMORY_TABLES: &'static [&'static str] = &[table_names::PG_TYPE];
|
|
}
|
|
|
|
/// The column name for the OID column.
|
|
/// The OID column is a unique identifier of type u32 for each object in the database.
|
|
const OID_COLUMN_NAME: &str = "oid";
|
|
|
|
fn oid_column() -> ColumnSchema {
|
|
u32_column(OID_COLUMN_NAME)
|
|
}
|
|
|
|
/// [`PGCatalogProvider`] is the provider for a schema named `pg_catalog`, it is not a catalog.
|
|
pub struct PGCatalogProvider {
|
|
catalog_name: String,
|
|
catalog_manager: Weak<dyn CatalogManager>,
|
|
tables: HashMap<String, TableRef>,
|
|
|
|
// Workaround to store mapping of schema_name to a numeric id
|
|
namespace_oid_map: PGNamespaceOidMapRef,
|
|
}
|
|
|
|
impl SystemSchemaProvider for PGCatalogProvider {
|
|
fn tables(&self) -> &HashMap<String, TableRef> {
|
|
assert!(!self.tables.is_empty());
|
|
|
|
&self.tables
|
|
}
|
|
}
|
|
|
|
// TODO(j0hn50n133): Not sure whether to avoid duplication with `information_schema` or not.
|
|
macro_rules! setup_memory_table {
|
|
($name: expr) => {
|
|
paste! {
|
|
{
|
|
let (schema, columns) = get_schema_columns($name);
|
|
Some(Arc::new(MemoryTable::new(
|
|
consts::[<PG_CATALOG_ $name _TABLE_ID>],
|
|
$name,
|
|
schema,
|
|
columns
|
|
)) as _)
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
impl PGCatalogProvider {
|
|
pub fn new(catalog_name: String, catalog_manager: Weak<dyn CatalogManager>) -> Self {
|
|
let mut provider = Self {
|
|
catalog_name,
|
|
catalog_manager,
|
|
tables: HashMap::new(),
|
|
namespace_oid_map: Arc::new(PGNamespaceOidMap::new()),
|
|
};
|
|
provider.build_tables();
|
|
provider
|
|
}
|
|
|
|
fn build_tables(&mut self) {
|
|
// SECURITY NOTE:
|
|
// Must follow the same security rules as [`InformationSchemaProvider::build_tables`].
|
|
let mut tables = HashMap::new();
|
|
// TODO(J0HN50N133): modeling the table_name as a enum type to get rid of expect/unwrap here
|
|
// It's safe to unwrap here because we are sure that the constants have been handle correctly inside system_table.
|
|
for name in MEMORY_TABLES.iter() {
|
|
tables.insert(name.to_string(), self.build_table(name).expect(name));
|
|
}
|
|
tables.insert(
|
|
PG_NAMESPACE.to_string(),
|
|
self.build_table(PG_NAMESPACE).expect(PG_NAMESPACE),
|
|
);
|
|
tables.insert(
|
|
PG_CLASS.to_string(),
|
|
self.build_table(PG_CLASS).expect(PG_NAMESPACE),
|
|
);
|
|
tables.insert(
|
|
PG_DATABASE.to_string(),
|
|
self.build_table(PG_DATABASE).expect(PG_DATABASE),
|
|
);
|
|
self.tables = tables;
|
|
}
|
|
}
|
|
|
|
impl SystemSchemaProviderInner for PGCatalogProvider {
|
|
fn schema_name() -> &'static str {
|
|
PG_CATALOG_NAME
|
|
}
|
|
|
|
fn system_table(&self, name: &str) -> Option<SystemTableRef> {
|
|
match name {
|
|
table_names::PG_TYPE => setup_memory_table!(PG_TYPE),
|
|
table_names::PG_NAMESPACE => Some(Arc::new(PGNamespace::new(
|
|
self.catalog_name.clone(),
|
|
self.catalog_manager.clone(),
|
|
self.namespace_oid_map.clone(),
|
|
))),
|
|
table_names::PG_CLASS => Some(Arc::new(PGClass::new(
|
|
self.catalog_name.clone(),
|
|
self.catalog_manager.clone(),
|
|
self.namespace_oid_map.clone(),
|
|
))),
|
|
table_names::PG_DATABASE => Some(Arc::new(PGDatabase::new(
|
|
self.catalog_name.clone(),
|
|
self.catalog_manager.clone(),
|
|
self.namespace_oid_map.clone(),
|
|
))),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
fn catalog_name(&self) -> &str {
|
|
&self.catalog_name
|
|
}
|
|
}
|
|
|
|
/// Provide query context to call the [`CatalogManager`]'s method.
|
|
static PG_QUERY_CTX: LazyLock<QueryContext> = LazyLock::new(|| {
|
|
QueryContext::with_channel(DEFAULT_CATALOG_NAME, DEFAULT_SCHEMA_NAME, Channel::Postgres)
|
|
});
|
|
|
|
fn query_ctx() -> Option<&'static QueryContext> {
|
|
Some(&PG_QUERY_CTX)
|
|
}
|