@@ -14,18 +14,17 @@ use crate::{
1414} ;
1515use datafusion:: {
1616 arrow:: datatypes:: { DataType , Schema as ArrowSchema } ,
17- catalog:: CatalogProvider ,
18- common:: { tree_node:: Transformed , SchemaReference } ,
17+ catalog:: { CatalogProvider , Session } ,
18+ common:: { tree_node:: Transformed , SchemaReference , TableReference } ,
1919 error:: DataFusionError ,
20- execution:: context:: { QueryPlanner , SessionState } ,
20+ execution:: context:: QueryPlanner ,
2121 logical_expr:: {
22- CreateExternalTable , DdlStatement , Extension , InvariantLevel , LogicalPlan ,
23- UserDefinedLogicalNode ,
22+ physical_planning_context :: PhysicalPlanningContext , CreateExternalTable , DdlStatement ,
23+ Extension , InvariantLevel , LogicalPlan , UserDefinedLogicalNode ,
2424 } ,
2525 physical_plan:: { empty:: EmptyExec , ExecutionPlan } ,
2626 physical_planner:: { DefaultPhysicalPlanner , ExtensionPlanner , PhysicalPlanner } ,
2727 scalar:: ScalarValue ,
28- sql:: TableReference ,
2928} ;
3029use iceberg_rust:: {
3130 catalog:: { tabular:: Tabular , CatalogList } ,
@@ -72,11 +71,9 @@ impl QueryPlanner for IcebergQueryPlanner {
7271 async fn create_physical_plan (
7372 & self ,
7473 logical_plan : & LogicalPlan ,
75- session_state : & SessionState ,
74+ session : & dyn Session ,
7675 ) -> Result < Arc < dyn ExecutionPlan > , DataFusionError > {
77- self . 0
78- . create_physical_plan ( logical_plan, session_state)
79- . await
76+ self . 0 . create_physical_plan ( logical_plan, session) . await
8077 }
8178}
8279
@@ -85,7 +82,7 @@ pub fn iceberg_transform(node: LogicalPlan) -> Result<Transformed<LogicalPlan>,
8582 LogicalPlan :: Ddl ( DdlStatement :: CreateExternalTable ( table) ) => {
8683 if table. file_type . to_lowercase ( ) == "iceberg" {
8784 Ok ( Transformed :: yes ( LogicalPlan :: Extension ( Extension {
88- node : Arc :: new ( CreateIcebergTable ( table) ) ,
85+ node : Arc :: new ( CreateIcebergTable ( * table) ) ,
8986 } ) ) )
9087 } else {
9188 Ok ( Transformed :: no ( LogicalPlan :: Ddl (
@@ -127,18 +124,19 @@ impl ExtensionPlanner for IcebergExtensionPlanner {
127124 node : & dyn UserDefinedLogicalNode ,
128125 _logical_inputs : & [ & LogicalPlan ] ,
129126 _physical_inputs : & [ Arc < dyn ExecutionPlan > ] ,
130- session_state : & SessionState ,
127+ session : & dyn Session ,
128+ _planning_ctx : & PhysicalPlanningContext ,
131129 ) -> Result < Option < Arc < dyn ExecutionPlan > > , DataFusionError > {
132130 if let Some ( node) = node. as_any ( ) . downcast_ref :: < CreateIcebergTable > ( ) {
133- plan_create_table ( node, session_state ) . await
131+ plan_create_table ( node, session ) . await
134132 } else if let Some ( node) = node. as_any ( ) . downcast_ref :: < CreateIcebergView > ( ) {
135- plan_create_view ( node, session_state ) . await
133+ plan_create_view ( node, session ) . await
136134 } else if let Some ( node) = node. as_any ( ) . downcast_ref :: < CreateIcebergNamespace > ( ) {
137- plan_create_namespace ( node, session_state ) . await
135+ plan_create_namespace ( node, session ) . await
138136 } else if let Some ( node) = node. as_any ( ) . downcast_ref :: < DropIcebergTable > ( ) {
139- plan_drop_table ( node, session_state ) . await
137+ plan_drop_table ( node, session ) . await
140138 } else if let Some ( node) = node. as_any ( ) . downcast_ref :: < DropIcebergNamespace > ( ) {
141- plan_drop_namespace ( node, session_state ) . await
139+ plan_drop_namespace ( node, session ) . await
142140 } else {
143141 return Ok ( None ) ;
144142 }
@@ -147,13 +145,13 @@ impl ExtensionPlanner for IcebergExtensionPlanner {
147145
148146async fn plan_create_table (
149147 node : & CreateIcebergTable ,
150- session_state : & SessionState ,
148+ session : & dyn Session ,
151149) -> Result < Option < Arc < dyn ExecutionPlan > > , DataFusionError > {
152150 let table_ref = & node. 0 . name . to_string ( ) ;
153151
154152 let identifier = TableReference :: parse_str ( table_ref) . resolve ( "datafusion" , "public" ) ;
155153
156- let catalog_list = session_state . catalog_list ( ) ;
154+ let catalog_list = session . catalog_list ( ) ;
157155 let catalog_name = & identifier. catalog ;
158156 let namespace_name = & identifier. schema ;
159157 let table_name: & str = & identifier. table ;
@@ -206,9 +204,15 @@ async fn plan_create_table(
206204 . build ( )
207205 . map_err ( |err| DataFusionError :: External ( Box :: new ( err) ) ) ?;
208206
207+ let [ location] = node. 0 . locations . as_slice ( ) else {
208+ return Err ( DataFusionError :: Plan (
209+ "Iceberg tables must be created with exactly one LOCATION." . to_owned ( ) ,
210+ ) ) ;
211+ } ;
212+
209213 Table :: builder ( )
210214 . with_name ( table_name)
211- . with_location ( & node . 0 . location )
215+ . with_location ( location)
212216 . with_schema ( Schema :: from_struct_type ( schema, DEFAULT_SCHEMA_ID , None ) )
213217 . with_partition_spec ( partition_spec)
214218 . with_properties ( node. 0 . options . clone ( ) )
@@ -223,13 +227,13 @@ async fn plan_create_table(
223227
224228async fn plan_create_view (
225229 node : & CreateIcebergView ,
226- session_state : & SessionState ,
230+ session : & dyn Session ,
227231) -> Result < Option < Arc < dyn ExecutionPlan > > , DataFusionError > {
228232 let table_ref = & node. 0 . name . to_string ( ) ;
229233
230234 let identifier = TableReference :: parse_str ( table_ref) . resolve ( "datafusion" , "public" ) ;
231235
232- let catalog_list = session_state . catalog_list ( ) ;
236+ let catalog_list = session . catalog_list ( ) ;
233237 let catalog_name = & identifier. catalog ;
234238 let namespace_name = & identifier. schema ;
235239 let table_name: & str = & identifier. table ;
@@ -347,7 +351,7 @@ async fn plan_create_view(
347351
348352async fn plan_create_namespace (
349353 node : & CreateIcebergNamespace ,
350- session_state : & SessionState ,
354+ session : & dyn Session ,
351355) -> Result < Option < Arc < dyn ExecutionPlan > > , DataFusionError > {
352356 let ( catalog_name, namespace_name) =
353357 node. 0
@@ -359,7 +363,7 @@ async fn plan_create_namespace(
359363 & node. 0 . schema_name
360364 ) ) ) ?;
361365
362- let catalog_list = session_state . catalog_list ( ) ;
366+ let catalog_list = session . catalog_list ( ) ;
363367 let datafusion_catalog = catalog_list
364368 . catalog ( catalog_name)
365369 . ok_or ( DataFusionError :: Plan ( format ! (
@@ -393,13 +397,13 @@ async fn plan_create_namespace(
393397
394398async fn plan_drop_table (
395399 node : & DropIcebergTable ,
396- session_state : & SessionState ,
400+ session : & dyn Session ,
397401) -> Result < Option < Arc < dyn ExecutionPlan > > , DataFusionError > {
398402 let table_ref = & node. 0 . name . to_string ( ) ;
399403
400404 let identifier = TableReference :: parse_str ( table_ref) . resolve ( "datafusion" , "public" ) ;
401405
402- let catalog_list = session_state . catalog_list ( ) ;
406+ let catalog_list = session . catalog_list ( ) ;
403407 let catalog_name = & identifier. catalog ;
404408 let namespace_name = & identifier. schema ;
405409 let table_name: & str = & identifier. table ;
@@ -431,14 +435,14 @@ async fn plan_drop_table(
431435
432436async fn plan_drop_namespace (
433437 node : & DropIcebergNamespace ,
434- session_state : & SessionState ,
438+ session : & dyn Session ,
435439) -> Result < Option < Arc < dyn ExecutionPlan > > , DataFusionError > {
436440 let ( catalog_name, namespace_name) = match & node. 0 . name {
437441 SchemaReference :: Bare { schema } => ( "datafusion" . to_owned ( ) , schema. to_string ( ) ) ,
438442 SchemaReference :: Full { schema, catalog } => ( catalog. to_string ( ) , schema. to_string ( ) ) ,
439443 } ;
440444
441- let catalog_list = session_state . catalog_list ( ) ;
445+ let catalog_list = session . catalog_list ( ) ;
442446 let datafusion_catalog = catalog_list
443447 . catalog ( & catalog_name)
444448 . ok_or ( DataFusionError :: Plan ( format ! (
0 commit comments