risingwave_frontend/catalog/
view_catalog.rs

1// Copyright 2025 RisingWave Labs
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 risingwave_common::catalog::{Field, SYS_CATALOG_START_ID};
16use risingwave_pb::catalog::PbView;
17use risingwave_sqlparser::ast::Statement;
18use risingwave_sqlparser::parser::Parser;
19
20use super::{DatabaseId, OwnedByUserCatalog, SchemaId, ViewId};
21use crate::WithOptions;
22use crate::user::UserId;
23
24#[derive(Clone, Debug)]
25pub struct ViewCatalog {
26    pub id: ViewId,
27    pub name: String,
28    pub schema_id: SchemaId,
29    pub database_id: DatabaseId,
30
31    pub owner: UserId,
32    pub properties: WithOptions,
33    pub sql: String,
34    pub columns: Vec<Field>,
35}
36
37impl From<&PbView> for ViewCatalog {
38    fn from(view: &PbView) -> Self {
39        ViewCatalog {
40            id: view.id,
41            name: view.name.clone(),
42            schema_id: view.schema_id,
43            database_id: view.database_id,
44            owner: view.owner,
45            properties: WithOptions::new_with_options(view.properties.clone()),
46            sql: view.sql.clone(),
47            columns: view.columns.iter().map(|f| f.into()).collect(),
48        }
49    }
50}
51
52impl ViewCatalog {
53    pub fn name(&self) -> &str {
54        &self.name
55    }
56
57    pub fn with_id(mut self, id: ViewId) -> Self {
58        self.id = id;
59        self
60    }
61
62    /// Returns the SQL statement that can be used to create this view.
63    pub fn create_sql(&self, schema: String) -> String {
64        if schema == "public" {
65            format!("CREATE VIEW {} AS {}", self.name, self.sql)
66        } else {
67            format!("CREATE VIEW {}.{} AS {}", schema, self.name, self.sql)
68        }
69    }
70
71    /// Returns the parsed SQL definition when the view was created (`CREATE VIEW` not included).
72    ///
73    /// Returns error if it's invalid.
74    pub fn sql_ast(&self) -> crate::error::Result<Statement> {
75        Ok(Parser::parse_exactly_one(&self.sql)?)
76    }
77
78    /// Returns true if this view is a system view.
79    pub fn is_system_view(&self) -> bool {
80        self.id >= SYS_CATALOG_START_ID as u32
81    }
82}
83
84impl OwnedByUserCatalog for ViewCatalog {
85    fn owner(&self) -> UserId {
86        self.owner
87    }
88}