@@ -130,7 +130,7 @@ use crate::catalog::{
130130use crate :: iceberg:: IcebergSinkConfigOptionExtracted ;
131131use crate :: kafka_util:: { KafkaSinkConfigOptionExtracted , KafkaSourceConfigOptionExtracted } ;
132132use crate :: names:: {
133- Aug , CommentObjectId , DatabaseId , ObjectId , PartialItemName , QualifiedItemName ,
133+ Aug , CommentObjectId , DatabaseId , DependencyIds , ObjectId , PartialItemName , QualifiedItemName ,
134134 ResolvedClusterName , ResolvedColumnReference , ResolvedDataType , ResolvedDatabaseSpecifier ,
135135 ResolvedItemName , ResolvedNetworkPolicyName , SchemaSpecifier , SystemObjectId ,
136136} ;
@@ -2720,6 +2720,27 @@ pub fn plan_create_materialized_view(
27202720 scx : & StatementContext ,
27212721 mut stmt : CreateMaterializedViewStatement < Aug > ,
27222722) -> Result < Plan , PlanError > {
2723+ // Validate the replacement target, if one is given.
2724+ let replacement_target = if let Some ( target_name) = & stmt. replacing {
2725+ let target = scx. get_item_by_resolved_name ( target_name) ?;
2726+ if target. item_type ( ) != CatalogItemType :: MaterializedView {
2727+ sql_bail ! (
2728+ "cannot replace {} {} because it is not a materialized view" ,
2729+ target. item_type( ) ,
2730+ scx. catalog. minimal_qualification( target. name( ) ) ,
2731+ ) ;
2732+ }
2733+ if target. id ( ) . is_system ( ) {
2734+ sql_bail ! (
2735+ "cannot replace {} because it is required by the database system" ,
2736+ scx. catalog. minimal_qualification( target. name( ) ) ,
2737+ ) ;
2738+ }
2739+ Some ( target. id ( ) )
2740+ } else {
2741+ None
2742+ } ;
2743+
27232744 let cluster_id =
27242745 crate :: plan:: statement:: resolve_cluster_for_materialized_view ( scx. catalog , & stmt) ?;
27252746 stmt. in_cluster = Some ( ResolvedClusterName {
@@ -2962,12 +2983,16 @@ pub fn plan_create_materialized_view(
29622983 . collect ( )
29632984 } )
29642985 . unwrap_or_default ( ) ;
2965- let dependencies = expr
2986+ let mut dependencies: BTreeSet < _ > = expr
29662987 . depends_on ( )
29672988 . into_iter ( )
29682989 . map ( |gid| scx. catalog . resolve_item_id ( & gid) )
29692990 . collect ( ) ;
29702991
2992+ if let Some ( id) = replacement_target {
2993+ dependencies. insert ( id) ;
2994+ }
2995+
29712996 // Check for an object in the catalog with this same name
29722997 let full_name = scx. catalog . resolve_full_name ( & name) ;
29732998 let partial_name = PartialItemName :: from ( full_name. clone ( ) ) ;
@@ -2987,8 +3012,9 @@ pub fn plan_create_materialized_view(
29873012 materialized_view : MaterializedView {
29883013 create_sql,
29893014 expr,
2990- dependencies,
3015+ dependencies : DependencyIds ( dependencies ) ,
29913016 column_names,
3017+ replacement_target,
29923018 cluster_id,
29933019 non_null_assertions,
29943020 compaction_window,
@@ -3238,6 +3264,7 @@ pub fn plan_create_continual_task(
32383264 expr,
32393265 dependencies,
32403266 column_names,
3267+ replacement_target : None ,
32413268 cluster_id,
32423269 non_null_assertions : Vec :: new ( ) ,
32433270 compaction_window : None ,
0 commit comments