Skip to content

Commit 13a38c1

Browse files
committed
sql-parser: support for replacement materialized views
1 parent 8c97419 commit 13a38c1

File tree

13 files changed

+190
-55
lines changed

13 files changed

+190
-55
lines changed

src/adapter/src/coord/command_handler.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -929,6 +929,7 @@ impl Coordinator {
929929
| Statement::AlterConnection(_)
930930
| Statement::AlterDefaultPrivileges(_)
931931
| Statement::AlterIndex(_)
932+
| Statement::AlterMaterializedViewApplyReplacement(_)
932933
| Statement::AlterSetCluster(_)
933934
| Statement::AlterOwner(_)
934935
| Statement::AlterRetainHistory(_)
@@ -1170,6 +1171,7 @@ impl Coordinator {
11701171
if_exists: cmvs.if_exists,
11711172
name: cmvs.name,
11721173
columns: cmvs.columns,
1174+
replacing: cmvs.replacing,
11731175
in_cluster: cmvs.in_cluster,
11741176
query: cmvs.query,
11751177
with_options: cmvs.with_options,

src/sql-lexer/src/keywords.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ Analysis
4040
Analyze
4141
And
4242
Any
43+
Apply
4344
Arity
4445
Arn
4546
Arranged
@@ -390,6 +391,8 @@ Rename
390391
Reoptimize
391392
Repeatable
392393
Replace
394+
Replacement
395+
Replacing
393396
Replan
394397
Replica
395398
Replicas

src/sql-parser/src/ast/defs/statement.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ pub enum Statement<T: AstInfo> {
8282
AlterNetworkPolicy(AlterNetworkPolicyStatement<T>),
8383
AlterRole(AlterRoleStatement<T>),
8484
AlterTableAddColumn(AlterTableAddColumnStatement<T>),
85+
AlterMaterializedViewApplyReplacement(AlterMaterializedViewApplyReplacementStatement),
8586
Discard(DiscardStatement),
8687
DropObjects(DropObjectsStatement),
8788
DropOwned(DropOwnedStatement<T>),
@@ -160,6 +161,7 @@ impl<T: AstInfo> AstDisplay for Statement<T> {
160161
Statement::AlterConnection(stmt) => f.write_node(stmt),
161162
Statement::AlterRole(stmt) => f.write_node(stmt),
162163
Statement::AlterTableAddColumn(stmt) => f.write_node(stmt),
164+
Statement::AlterMaterializedViewApplyReplacement(stmt) => f.write_node(stmt),
163165
Statement::Discard(stmt) => f.write_node(stmt),
164166
Statement::DropObjects(stmt) => f.write_node(stmt),
165167
Statement::DropOwned(stmt) => f.write_node(stmt),
@@ -241,6 +243,9 @@ pub fn statement_kind_label_value(kind: StatementKind) -> &'static str {
241243
StatementKind::AlterOwner => "alter_owner",
242244
StatementKind::AlterConnection => "alter_connection",
243245
StatementKind::AlterTableAddColumn => "alter_table",
246+
StatementKind::AlterMaterializedViewApplyReplacement => {
247+
"alter_materialized_view_apply_replacement"
248+
}
244249
StatementKind::Discard => "discard",
245250
StatementKind::DropObjects => "drop_objects",
246251
StatementKind::DropOwned => "drop_owned",
@@ -1382,6 +1387,7 @@ pub struct CreateMaterializedViewStatement<T: AstInfo> {
13821387
pub if_exists: IfExistsBehavior,
13831388
pub name: UnresolvedItemName,
13841389
pub columns: Vec<Ident>,
1390+
pub replacing: Option<T::ItemName>,
13851391
pub in_cluster: Option<T::ClusterName>,
13861392
pub query: Query<T>,
13871393
pub as_of: Option<u64>,
@@ -1410,6 +1416,11 @@ impl<T: AstInfo> AstDisplay for CreateMaterializedViewStatement<T> {
14101416
f.write_str(")");
14111417
}
14121418

1419+
if let Some(target) = &self.replacing {
1420+
f.write_str(" REPLACING ");
1421+
f.write_node(target);
1422+
}
1423+
14131424
if let Some(cluster) = &self.in_cluster {
14141425
f.write_str(" IN CLUSTER ");
14151426
f.write_node(cluster);
@@ -3199,6 +3210,32 @@ impl<T: AstInfo> AstDisplay for AlterTableAddColumnStatement<T> {
31993210

32003211
impl_display_t!(AlterTableAddColumnStatement);
32013212

3213+
/// `ALTER MATERIALIZED VIEW ... APPLY REPLACEMENT ...`
3214+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3215+
pub struct AlterMaterializedViewApplyReplacementStatement {
3216+
pub if_exists: bool,
3217+
pub name: UnresolvedItemName,
3218+
pub replacement_name: UnresolvedItemName,
3219+
}
3220+
3221+
impl AstDisplay for AlterMaterializedViewApplyReplacementStatement {
3222+
fn fmt<W>(&self, f: &mut AstFormatter<W>)
3223+
where
3224+
W: fmt::Write,
3225+
{
3226+
f.write_str("ALTER MATERIALIZED VIEW ");
3227+
if self.if_exists {
3228+
f.write_str("IF EXISTS ");
3229+
}
3230+
f.write_node(&self.name);
3231+
3232+
f.write_str(" APPLY REPLACEMENT ");
3233+
f.write_node(&self.replacement_name);
3234+
}
3235+
}
3236+
3237+
impl_display!(AlterMaterializedViewApplyReplacementStatement);
3238+
32023239
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
32033240
pub struct DiscardStatement {
32043241
pub target: DiscardTarget,

src/sql-parser/src/parser.rs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3862,6 +3862,10 @@ impl<'a> Parser<'a> {
38623862

38633863
let name = self.parse_item_name()?;
38643864
let columns = self.parse_parenthesized_column_list(Optional)?;
3865+
let replacing = self
3866+
.parse_keyword(REPLACING)
3867+
.then(|| self.parse_raw_name())
3868+
.transpose()?;
38653869
let in_cluster = self.parse_optional_in_cluster()?;
38663870

38673871
let with_options = if self.parse_keyword(WITH) {
@@ -3882,6 +3886,7 @@ impl<'a> Parser<'a> {
38823886
if_exists,
38833887
name,
38843888
columns,
3889+
replacing,
38853890
in_cluster,
38863891
query,
38873892
as_of,
@@ -6432,10 +6437,10 @@ impl<'a> Parser<'a> {
64326437
) -> Result<Statement<Raw>, ParserStatementError> {
64336438
let if_exists = self.parse_if_exists().map_no_statement_parser_err()?;
64346439
let name = self.parse_item_name().map_no_statement_parser_err()?;
6435-
let keywords = if object_type == ObjectType::Table {
6436-
[SET, RENAME, OWNER, RESET, ADD].as_slice()
6437-
} else {
6438-
[SET, RENAME, OWNER, RESET].as_slice()
6440+
let keywords: &[_] = match object_type {
6441+
ObjectType::Table => &[SET, RENAME, OWNER, RESET, ADD],
6442+
ObjectType::MaterializedView => &[SET, RENAME, OWNER, RESET, APPLY],
6443+
_ => &[SET, RENAME, OWNER, RESET],
64396444
};
64406445

64416446
let action = self
@@ -6526,6 +6531,28 @@ impl<'a> Parser<'a> {
65266531
},
65276532
))
65286533
}
6534+
APPLY => {
6535+
assert_eq!(
6536+
object_type,
6537+
ObjectType::MaterializedView,
6538+
"checked object_type above",
6539+
);
6540+
6541+
self.expect_keyword(REPLACEMENT)
6542+
.map_parser_err(StatementKind::AlterMaterializedViewApplyReplacement)?;
6543+
6544+
let replacement_name = self
6545+
.parse_item_name()
6546+
.map_parser_err(StatementKind::AlterMaterializedViewApplyReplacement)?;
6547+
6548+
Ok(Statement::AlterMaterializedViewApplyReplacement(
6549+
AlterMaterializedViewApplyReplacementStatement {
6550+
if_exists,
6551+
name,
6552+
replacement_name,
6553+
},
6554+
))
6555+
}
65296556
_ => unreachable!(),
65306557
}
65316558
}

src/sql-parser/tests/testdata/alter

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,3 +131,17 @@ ALTER TABLE IF EXISTS t1 ADD COLUMN IF NOT EXISTS bar text
131131
ALTER TABLE IF EXISTS t1 ADD COLUMN IF NOT EXISTS bar text
132132
=>
133133
AlterTableAddColumn(AlterTableAddColumnStatement { if_exists: true, name: UnresolvedItemName([Ident("t1")]), if_col_not_exist: true, column_name: Ident("bar"), data_type: Other { name: Name(UnresolvedItemName([Ident("text")])), typ_mod: [] } })
134+
135+
parse-statement
136+
ALTER MATERIALIZED VIEW mv APPLY REPLACEMENT rpl
137+
----
138+
ALTER MATERIALIZED VIEW mv APPLY REPLACEMENT rpl
139+
=>
140+
AlterMaterializedViewApplyReplacement(AlterMaterializedViewApplyReplacementStatement { if_exists: false, name: UnresolvedItemName([Ident("mv")]), replacement_name: UnresolvedItemName([Ident("rpl")]) })
141+
142+
parse-statement
143+
ALTER MATERIALIZED VIEW IF EXISTS mv APPLY REPLACEMENT rpl
144+
----
145+
ALTER MATERIALIZED VIEW IF EXISTS mv APPLY REPLACEMENT rpl
146+
=>
147+
AlterMaterializedViewApplyReplacement(AlterMaterializedViewApplyReplacementStatement { if_exists: true, name: UnresolvedItemName([Ident("mv")]), replacement_name: UnresolvedItemName([Ident("rpl")]) })

0 commit comments

Comments
 (0)