rudb_catalog/view.rs
1//! A view: a name, the query it stands for, and the names its columns answer to.
2//!
3//! The body is text rather than anything bound. A view in DuckDB follows the tables underneath it,
4//! which was measured: a view over `SELECT * FROM t` picks up a column that `ALTER TABLE t ADD
5//! COLUMN` added after the view was created, and a view over a table that was then dropped is an
6//! error when it is selected from rather than when the table went. Neither of those is possible if
7//! what the catalog keeps is a plan, because a plan has the columns of the day it was built baked
8//! into it. So the catalog keeps the query and the binder binds it again at every reference.
9
10use crate::name::QualifiedName;
11
12/// One view.
13#[derive(Debug, Clone)]
14pub struct View {
15 name: QualifiedName,
16 sql: String,
17 aliases: Vec<String>,
18}
19
20impl View {
21 /// A view over `sql`, whose columns answer to `aliases` as far as that list goes.
22 #[must_use]
23 pub fn new(name: QualifiedName, sql: String, aliases: Vec<String>) -> Self {
24 Self { name, sql, aliases }
25 }
26
27 /// The three part name.
28 #[must_use]
29 pub fn name(&self) -> &QualifiedName {
30 &self.name
31 }
32
33 /// The body, as the text that was written.
34 #[must_use]
35 pub fn sql(&self) -> &str {
36 &self.sql
37 }
38
39 /// The column names the statement gave, which rename a prefix of what the body produces.
40 ///
41 /// Shorter than the body's output, or empty, is the ordinary case. `CREATE VIEW v (a) AS SELECT
42 /// 1, 2` answers under `a` and `2`, which was measured, so a short list is a rename of the front
43 /// of the list and not a projection down to it. Longer is refused by the binder before a view
44 /// is ever made.
45 #[must_use]
46 pub fn aliases(&self) -> &[String] {
47 &self.aliases
48 }
49}