risingwave_frontend/catalog/
mod.rs1use risingwave_common::catalog::{
22 ROW_ID_COLUMN_NAME, RW_RESERVED_COLUMN_NAME_PREFIX, is_system_schema,
23};
24use risingwave_common::error::code::PostgresErrorCode;
25use risingwave_connector::sink::catalog::SinkCatalog;
26use risingwave_pb::user::grant_privilege::Object as PbGrantObject;
27use thiserror::Error;
28
29use crate::error::{ErrorCode, Result, RwError};
30pub(crate) mod catalog_service;
31pub mod purify;
32
33pub(crate) mod connection_catalog;
34pub(crate) mod database_catalog;
35pub(crate) mod function_catalog;
36pub(crate) mod index_catalog;
37pub(crate) mod root_catalog;
38pub(crate) mod schema_catalog;
39pub(crate) mod source_catalog;
40pub(crate) mod subscription_catalog;
41pub(crate) mod system_catalog;
42pub(crate) mod table_catalog;
43pub(crate) mod view_catalog;
44
45pub(crate) mod secret_catalog;
46
47pub(crate) use catalog_service::CatalogReader;
48pub use index_catalog::IndexCatalog;
49pub use table_catalog::TableCatalog;
50
51use crate::user::UserId;
52
53pub(crate) type ConnectionId = u32;
54pub(crate) type SourceId = u32;
55pub(crate) type SinkId = u32;
56pub(crate) type SubscriptionId = u32;
57pub(crate) type ViewId = u32;
58pub(crate) type DatabaseId = u32;
59pub(crate) type SchemaId = u32;
60pub(crate) type TableId = risingwave_common::catalog::TableId;
61pub(crate) type ColumnId = risingwave_common::catalog::ColumnId;
62pub(crate) type FragmentId = u32;
63pub(crate) type SecretId = risingwave_common::catalog::SecretId;
64
65pub fn check_column_name_not_reserved(column_name: &str) -> Result<()> {
67 if column_name.starts_with(ROW_ID_COLUMN_NAME) {
68 return Err(ErrorCode::InternalError(format!(
69 "column name prefixed with {:?} are reserved word.",
70 ROW_ID_COLUMN_NAME
71 ))
72 .into());
73 }
74
75 if column_name.starts_with(RW_RESERVED_COLUMN_NAME_PREFIX) {
76 return Err(ErrorCode::InternalError(format!(
77 "column name prefixed with {:?} are reserved word.",
78 RW_RESERVED_COLUMN_NAME_PREFIX
79 ))
80 .into());
81 }
82
83 if ["tableoid", "xmin", "cmin", "xmax", "cmax", "ctid"].contains(&column_name) {
84 return Err(ErrorCode::InvalidInputSyntax(format!(
85 "column name \"{column_name}\" conflicts with a system column name"
86 ))
87 .into());
88 }
89
90 Ok(())
91}
92
93pub fn check_schema_writable(schema: &str) -> Result<()> {
95 if is_system_schema(schema) {
96 Err(ErrorCode::ProtocolError(format!(
97 "permission denied to write on \"{}\", System catalog modifications are currently disallowed.",
98 schema
99 )).into())
100 } else {
101 Ok(())
102 }
103}
104
105pub type CatalogResult<T> = std::result::Result<T, CatalogError>;
106
107#[derive(Error, Debug)]
109pub enum CatalogError {
110 #[provide(PostgresErrorCode => PostgresErrorCode::UndefinedObject)]
111 #[error("{0} not found: {1}")]
112 NotFound(&'static str, String),
113
114 #[provide(PostgresErrorCode => PostgresErrorCode::DuplicateObject)]
115 #[error(
116 "{0} with name {1} exists{under_creation}", under_creation = (.2).then_some(" but under creation").unwrap_or("")
117 )]
118 Duplicated(
119 &'static str,
120 String,
121 bool,
123 ),
124}
125
126impl CatalogError {
127 pub fn duplicated(object_type: &'static str, name: String) -> Self {
128 Self::Duplicated(object_type, name, false)
129 }
130}
131
132impl From<CatalogError> for RwError {
133 fn from(e: CatalogError) -> Self {
134 ErrorCode::CatalogError(Box::new(e)).into()
135 }
136}
137
138pub trait OwnedByUserCatalog {
143 fn owner(&self) -> UserId;
145}
146
147impl OwnedByUserCatalog for SinkCatalog {
148 fn owner(&self) -> UserId {
149 self.owner.user_id
150 }
151}
152
153pub struct OwnedGrantObject {
154 pub owner: UserId,
155 pub object: PbGrantObject,
156}