Skip to content

Commit 96ff27f

Browse files
authored
feat: support alter rename relations including table/mview/view/sink/index (risingwavelabs#7745)
1 parent 0069678 commit 96ff27f

27 files changed

+1651
-176
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
statement ok
2+
SET RW_IMPLICIT_FLUSH TO true;
3+
4+
statement ok
5+
CREATE TABLE t (v1 INT primary key, v2 STRUCT<v1 INT, v2 STRUCT<v1 INT, v2 INT>>);
6+
7+
statement ok
8+
CREATE TABLE t_as AS ( WITH source_data AS ( SELECT 1 AS id) SELECT * FROM source_data);
9+
10+
statement ok
11+
CREATE MATERIALIZED VIEW mv AS SELECT v1, (t.v2).v1 AS v21 FROM t;
12+
13+
statement ok
14+
CREATE SINK sink AS SELECT mv3.v1 AS v1, mv3.v21 AS v2 FROM mv AS mv3 WITH (
15+
connector = 'blackhole'
16+
);
17+
18+
statement ok
19+
CREATE VIEW v1 AS ( SELECT * FROM t_as WHERE id = 1);
20+
21+
statement ok
22+
CREATE VIEW v2 AS (SELECT COUNT(*) FROM t, t AS t2 WHERE t.v1 = t2.v1);
23+
24+
statement ok
25+
CREATE VIEW v3 AS (SELECT MAX((t.v2).v1) FROM t AS t);
26+
27+
statement ok
28+
CREATE VIEW v4 AS (SELECT * FROM t join t as t2 on (t.v1 = t2.v1) ORDER BY t.v1, t2.v1);
29+
30+
statement ok
31+
CREATE index idx ON t(v1);
32+
33+
query TT
34+
SHOW CREATE TABLE t;
35+
----
36+
public.t CREATE TABLE t (v1 INT PRIMARY KEY, v2 STRUCT<v1 INT, v2 STRUCT<v1 INT, v2 INT>>)
37+
38+
# alter table rename with alias conflict
39+
statement ok
40+
ALTER TABLE t RENAME TO t2;
41+
42+
query TT
43+
SHOW CREATE TABLE t2;
44+
----
45+
public.t2 CREATE TABLE t2 (v1 INT PRIMARY KEY, v2 STRUCT<v1 INT, v2 STRUCT<v1 INT, v2 INT>>)
46+
47+
query TT
48+
SHOW CREATE VIEW v2;
49+
----
50+
public.v2 CREATE VIEW v2 AS (SELECT COUNT(*) FROM t2 AS t, t2 AS t2 WHERE t.v1 = t2.v1)
51+
52+
query TT
53+
SHOW CREATE VIEW v3;
54+
----
55+
public.v3 CREATE VIEW v3 AS (SELECT MAX((t.v2).v1) FROM t2 AS t)
56+
57+
query TT
58+
SHOW CREATE VIEW v4;
59+
----
60+
public.v4 CREATE VIEW v4 AS (SELECT * FROM t2 AS t JOIN t2 AS t2 ON (t.v1 = t2.v1) ORDER BY t.v1, t2.v1)
61+
62+
query TT
63+
SHOW CREATE MATERIALIZED VIEW mv;
64+
----
65+
public.mv CREATE MATERIALIZED VIEW mv AS SELECT v1, (t.v2).v1 AS v21 FROM t2 AS t
66+
67+
# alter mview rename
68+
statement ok
69+
ALTER MATERIALIZED VIEW mv RENAME TO mv2;
70+
71+
query TT
72+
SHOW CREATE MATERIALIZED VIEW mv2;
73+
----
74+
public.mv2 CREATE MATERIALIZED VIEW mv2 AS SELECT v1, (t.v2).v1 AS v21 FROM t2 AS t
75+
76+
statement ok
77+
ALTER SINK sink RENAME TO sink1;
78+
79+
# alter mview rename with alias conflict, used by sink1
80+
statement ok
81+
ALTER MATERIALIZED VIEW mv2 RENAME TO mv3;
82+
83+
statement ok
84+
ALTER TABLE t_as RENAME TO t_as_1;
85+
86+
# alter view rename
87+
statement ok
88+
ALTER VIEW v1 RENAME TO v5;
89+
90+
query TT
91+
SHOW CREATE VIEW v5;
92+
----
93+
public.v5 CREATE VIEW v5 AS (SELECT * FROM t_as_1 AS t_as WHERE id = 1)
94+
95+
statement ok
96+
ALTER INDEX idx RENAME TO idx1;
97+
98+
statement ok
99+
INSERT INTO t2 VALUES(1,(1,(1,2)));
100+
101+
statement ok
102+
INSERT INTO t2 VALUES(2,(2,(2,4)));
103+
104+
query II rowsort
105+
SELECT * from mv3
106+
----
107+
1 1
108+
2 2
109+
110+
query I
111+
SELECT * from v2
112+
----
113+
2
114+
115+
query I
116+
SELECT * from v3
117+
----
118+
2
119+
120+
query IIII rowsort
121+
SELECT * from v4
122+
----
123+
1 (1,(1,2)) 1 (1,(1,2))
124+
2 (2,(2,4)) 2 (2,(2,4))
125+
126+
statement ok
127+
DROP SINK sink1;
128+
129+
statement ok
130+
DROP VIEW v5;
131+
132+
statement ok
133+
DROP VIEW v4;
134+
135+
statement ok
136+
DROP VIEW v3;
137+
138+
statement ok
139+
DROP VIEW v2;
140+
141+
statement ok
142+
DROP MATERIALIZED VIEW mv3;
143+
144+
statement ok
145+
DROP TABLE t2;
146+
147+
statement ok
148+
DROP TABLE t_as_1;

proto/ddl_service.proto

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,21 @@ message CreateTableResponse {
139139
uint64 version = 3;
140140
}
141141

142+
message AlterRelationNameRequest {
143+
oneof relation {
144+
uint32 table_id = 1;
145+
uint32 view_id = 2;
146+
uint32 index_id = 3;
147+
uint32 sink_id = 4;
148+
}
149+
string new_name = 20;
150+
}
151+
152+
message AlterRelationNameResponse {
153+
common.Status status = 1;
154+
uint64 version = 2;
155+
}
156+
142157
message CreateFunctionRequest {
143158
catalog.Function function = 1;
144159
}
@@ -279,6 +294,7 @@ service DdlService {
279294
rpc CreateMaterializedView(CreateMaterializedViewRequest) returns (CreateMaterializedViewResponse);
280295
rpc DropMaterializedView(DropMaterializedViewRequest) returns (DropMaterializedViewResponse);
281296
rpc CreateTable(CreateTableRequest) returns (CreateTableResponse);
297+
rpc AlterRelationName(AlterRelationNameRequest) returns (AlterRelationNameResponse);
282298
rpc DropTable(DropTableRequest) returns (DropTableResponse);
283299
rpc RisectlListStateTables(RisectlListStateTablesRequest) returns (RisectlListStateTablesResponse);
284300
rpc CreateView(CreateViewRequest) returns (CreateViewResponse);

src/frontend/src/binder/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,10 @@ impl Binder {
227227
self.param_types.export()
228228
}
229229

230+
pub fn shared_views(&self) -> &HashMap<ViewId, ShareId> {
231+
&self.shared_views
232+
}
233+
230234
fn push_context(&mut self) {
231235
let new_context = std::mem::take(&mut self.context);
232236
self.context.cte_to_relation = new_context.cte_to_relation.clone();

src/frontend/src/binder/relation/mod.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,21 @@ impl Binder {
203203
Self::resolve_single_name(name.0, "index name")
204204
}
205205

206+
/// return the `view_name`
207+
pub fn resolve_view_name(name: ObjectName) -> Result<String> {
208+
Self::resolve_single_name(name.0, "view name")
209+
}
210+
211+
/// return the `sink_name`
212+
pub fn resolve_sink_name(name: ObjectName) -> Result<String> {
213+
Self::resolve_single_name(name.0, "sink name")
214+
}
215+
216+
/// return the `table_name`
217+
pub fn resolve_table_name(name: ObjectName) -> Result<String> {
218+
Self::resolve_single_name(name.0, "table name")
219+
}
220+
206221
/// return the `user_name`
207222
pub fn resolve_user_name(name: ObjectName) -> Result<String> {
208223
Self::resolve_single_name(name.0, "user name")

src/frontend/src/catalog/catalog_service.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use risingwave_common::util::column_index_mapping::ColIndexMapping;
2323
use risingwave_pb::catalog::{
2424
PbDatabase, PbFunction, PbIndex, PbSchema, PbSink, PbSource, PbTable, PbView,
2525
};
26+
use risingwave_pb::ddl_service::alter_relation_name_request::Relation;
2627
use risingwave_pb::stream_plan::StreamFragmentGraph;
2728
use risingwave_rpc_client::MetaClient;
2829
use tokio::sync::watch::Receiver;
@@ -114,6 +115,14 @@ pub trait CatalogWriter: Send + Sync {
114115
async fn drop_index(&self, index_id: IndexId) -> Result<()>;
115116

116117
async fn drop_function(&self, function_id: FunctionId) -> Result<()>;
118+
119+
async fn alter_table_name(&self, table_id: u32, table_name: &str) -> Result<()>;
120+
121+
async fn alter_view_name(&self, view_id: u32, view_name: &str) -> Result<()>;
122+
123+
async fn alter_index_name(&self, index_id: u32, index_name: &str) -> Result<()>;
124+
125+
async fn alter_sink_name(&self, sink_id: u32, sink_name: &str) -> Result<()>;
117126
}
118127

119128
#[derive(Clone)]
@@ -264,6 +273,38 @@ impl CatalogWriter for CatalogWriterImpl {
264273
let version = self.meta_client.drop_database(database_id).await?;
265274
self.wait_version(version).await
266275
}
276+
277+
async fn alter_table_name(&self, table_id: u32, table_name: &str) -> Result<()> {
278+
let version = self
279+
.meta_client
280+
.alter_relation_name(Relation::TableId(table_id), table_name)
281+
.await?;
282+
self.wait_version(version).await
283+
}
284+
285+
async fn alter_view_name(&self, view_id: u32, view_name: &str) -> Result<()> {
286+
let version = self
287+
.meta_client
288+
.alter_relation_name(Relation::ViewId(view_id), view_name)
289+
.await?;
290+
self.wait_version(version).await
291+
}
292+
293+
async fn alter_index_name(&self, index_id: u32, index_name: &str) -> Result<()> {
294+
let version = self
295+
.meta_client
296+
.alter_relation_name(Relation::IndexId(index_id), index_name)
297+
.await?;
298+
self.wait_version(version).await
299+
}
300+
301+
async fn alter_sink_name(&self, sink_id: u32, sink_name: &str) -> Result<()> {
302+
let version = self
303+
.meta_client
304+
.alter_relation_name(Relation::SinkId(sink_id), sink_name)
305+
.await?;
306+
self.wait_version(version).await
307+
}
267308
}
268309

269310
impl CatalogWriterImpl {

src/frontend/src/catalog/index_catalog.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ use risingwave_pb::catalog::PbIndex;
2323
use risingwave_pb::expr::expr_node::RexNode;
2424

2525
use super::ColumnId;
26-
use crate::catalog::{DatabaseId, SchemaId, TableCatalog};
26+
use crate::catalog::{DatabaseId, RelationCatalog, SchemaId, TableCatalog};
2727
use crate::expr::{Expr, InputRef};
28+
use crate::user::UserId;
2829

2930
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
3031
pub struct IndexCatalog {
@@ -152,3 +153,9 @@ impl IndexCatalog {
152153
}
153154
}
154155
}
156+
157+
impl RelationCatalog for IndexCatalog {
158+
fn owner(&self) -> UserId {
159+
self.index_table.owner
160+
}
161+
}

src/frontend/src/catalog/root_catalog.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,14 @@ impl Catalog {
238238
.drop_source(source_id);
239239
}
240240

241+
pub fn update_source(&mut self, proto: &PbSource) {
242+
self.get_database_mut(proto.database_id)
243+
.unwrap()
244+
.get_schema_mut(proto.schema_id)
245+
.unwrap()
246+
.update_source(proto);
247+
}
248+
241249
pub fn drop_sink(&mut self, db_id: DatabaseId, schema_id: SchemaId, sink_id: SinkId) {
242250
self.get_database_mut(db_id)
243251
.unwrap()
@@ -246,6 +254,14 @@ impl Catalog {
246254
.drop_sink(sink_id);
247255
}
248256

257+
pub fn update_sink(&mut self, proto: &PbSink) {
258+
self.get_database_mut(proto.database_id)
259+
.unwrap()
260+
.get_schema_mut(proto.schema_id)
261+
.unwrap()
262+
.update_sink(proto);
263+
}
264+
249265
pub fn drop_index(&mut self, db_id: DatabaseId, schema_id: SchemaId, index_id: IndexId) {
250266
self.get_database_mut(db_id)
251267
.unwrap()
@@ -262,6 +278,14 @@ impl Catalog {
262278
.drop_view(view_id);
263279
}
264280

281+
pub fn update_view(&mut self, proto: &PbView) {
282+
self.get_database_mut(proto.database_id)
283+
.unwrap()
284+
.get_schema_mut(proto.schema_id)
285+
.unwrap()
286+
.update_view(proto);
287+
}
288+
265289
pub fn drop_function(
266290
&mut self,
267291
db_id: DatabaseId,
@@ -379,6 +403,30 @@ impl Catalog {
379403
.ok_or_else(|| CatalogError::NotFound("table id", table_id.to_string()))
380404
}
381405

406+
// Used by test_utils only.
407+
pub fn alter_table_name_by_id(&mut self, table_id: &TableId, table_name: &str) {
408+
let (mut database_id, mut schema_id) = (0, 0);
409+
let mut found = false;
410+
for database in self.database_by_name.values() {
411+
if !found {
412+
for schema in database.iter_schemas() {
413+
if schema.iter_table().any(|t| t.id() == *table_id) {
414+
found = true;
415+
database_id = database.id();
416+
schema_id = schema.id();
417+
break;
418+
}
419+
}
420+
}
421+
}
422+
423+
if found {
424+
let mut table = self.get_table_by_id(table_id).unwrap();
425+
table.name = table_name.to_string();
426+
self.update_table(&table.to_prost(schema_id, database_id));
427+
}
428+
}
429+
382430
#[cfg(test)]
383431
pub fn insert_table_id_mapping(&mut self, table_id: TableId, fragment_id: super::FragmentId) {
384432
self.table_by_id.insert(

0 commit comments

Comments
 (0)