@@ -45,8 +45,8 @@ use datafusion_expr::{
45
45
use sqlparser:: ast;
46
46
use sqlparser:: ast:: {
47
47
Assignment , Expr as SQLExpr , Expr , Ident , ObjectName , ObjectType , OrderByExpr , Query ,
48
- SchemaName , SetExpr , ShowCreateObject , ShowStatementFilter , Statement , TableFactor ,
49
- TableWithJoins , TransactionMode , UnaryOperator , Value ,
48
+ SchemaName , SetExpr , ShowCreateObject , ShowStatementFilter , Statement ,
49
+ TableConstraint , TableFactor , TableWithJoins , TransactionMode , UnaryOperator , Value ,
50
50
} ;
51
51
52
52
use sqlparser:: parser:: ParserError :: ParserError ;
@@ -128,69 +128,67 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
128
128
if_not_exists,
129
129
or_replace,
130
130
..
131
- } if constraints. is_empty ( )
132
- && table_properties. is_empty ( )
133
- && with_options. is_empty ( ) =>
134
- {
135
- match query {
136
- Some ( query) => {
137
- let plan = self . query_to_plan ( * query, planner_context) ?;
138
- let input_schema = plan. schema ( ) ;
139
-
140
- let plan = if !columns. is_empty ( ) {
141
- let schema = self . build_schema ( columns) ?. to_dfschema_ref ( ) ?;
142
- if schema. fields ( ) . len ( ) != input_schema. fields ( ) . len ( ) {
143
- return Err ( DataFusionError :: Plan ( format ! (
131
+ } if table_properties. is_empty ( ) && with_options. is_empty ( ) => match query {
132
+ Some ( query) => {
133
+ let primary_key = Self :: primary_key_from_constraints ( & constraints) ?;
134
+
135
+ let plan = self . query_to_plan ( * query, planner_context) ?;
136
+ let input_schema = plan. schema ( ) ;
137
+
138
+ let plan = if !columns. is_empty ( ) {
139
+ let schema = self . build_schema ( columns) ?. to_dfschema_ref ( ) ?;
140
+ if schema. fields ( ) . len ( ) != input_schema. fields ( ) . len ( ) {
141
+ return Err ( DataFusionError :: Plan ( format ! (
144
142
"Mismatch: {} columns specified, but result has {} columns" ,
145
143
schema. fields( ) . len( ) ,
146
144
input_schema. fields( ) . len( )
147
145
) ) ) ;
148
- }
149
- let input_fields = input_schema. fields ( ) ;
150
- let project_exprs = schema
151
- . fields ( )
152
- . iter ( )
153
- . zip ( input_fields)
154
- . map ( |( field, input_field) | {
155
- cast (
156
- col ( input_field. name ( ) ) ,
157
- field. data_type ( ) . clone ( ) ,
158
- )
146
+ }
147
+ let input_fields = input_schema. fields ( ) ;
148
+ let project_exprs = schema
149
+ . fields ( )
150
+ . iter ( )
151
+ . zip ( input_fields)
152
+ . map ( |( field, input_field) | {
153
+ cast ( col ( input_field. name ( ) ) , field. data_type ( ) . clone ( ) )
159
154
. alias ( field. name ( ) )
160
- } )
161
- . collect :: < Vec < _ > > ( ) ;
162
- LogicalPlanBuilder :: from ( plan. clone ( ) )
163
- . project ( project_exprs) ?
164
- . build ( ) ?
165
- } else {
166
- plan
167
- } ;
168
-
169
- Ok ( LogicalPlan :: CreateMemoryTable ( CreateMemoryTable {
170
- name : self . object_name_to_table_reference ( name) ?,
171
- input : Arc :: new ( plan) ,
172
- if_not_exists,
173
- or_replace,
174
- } ) )
175
- }
155
+ } )
156
+ . collect :: < Vec < _ > > ( ) ;
157
+ LogicalPlanBuilder :: from ( plan. clone ( ) )
158
+ . project ( project_exprs) ?
159
+ . build ( ) ?
160
+ } else {
161
+ plan
162
+ } ;
163
+
164
+ Ok ( LogicalPlan :: CreateMemoryTable ( CreateMemoryTable {
165
+ name : self . object_name_to_table_reference ( name) ?,
166
+ primary_key,
167
+ input : Arc :: new ( plan) ,
168
+ if_not_exists,
169
+ or_replace,
170
+ } ) )
171
+ }
176
172
177
- None => {
178
- let schema = self . build_schema ( columns) ?. to_dfschema_ref ( ) ?;
179
- let plan = EmptyRelation {
180
- produce_one_row : false ,
181
- schema,
182
- } ;
183
- let plan = LogicalPlan :: EmptyRelation ( plan) ;
184
-
185
- Ok ( LogicalPlan :: CreateMemoryTable ( CreateMemoryTable {
186
- name : self . object_name_to_table_reference ( name) ?,
187
- input : Arc :: new ( plan) ,
188
- if_not_exists,
189
- or_replace,
190
- } ) )
191
- }
173
+ None => {
174
+ let primary_key = Self :: primary_key_from_constraints ( & constraints) ?;
175
+
176
+ let schema = self . build_schema ( columns) ?. to_dfschema_ref ( ) ?;
177
+ let plan = EmptyRelation {
178
+ produce_one_row : false ,
179
+ schema,
180
+ } ;
181
+ let plan = LogicalPlan :: EmptyRelation ( plan) ;
182
+
183
+ Ok ( LogicalPlan :: CreateMemoryTable ( CreateMemoryTable {
184
+ name : self . object_name_to_table_reference ( name) ?,
185
+ primary_key,
186
+ input : Arc :: new ( plan) ,
187
+ if_not_exists,
188
+ or_replace,
189
+ } ) )
192
190
}
193
- }
191
+ } ,
194
192
195
193
Statement :: CreateView {
196
194
or_replace,
@@ -1076,4 +1074,54 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
1076
1074
. get_table_provider ( tables_reference)
1077
1075
. is_ok ( )
1078
1076
}
1077
+
1078
+ fn primary_key_from_constraints (
1079
+ constraints : & [ TableConstraint ] ,
1080
+ ) -> Result < Vec < Column > > {
1081
+ let pk: Result < Vec < & Vec < Ident > > > = constraints
1082
+ . iter ( )
1083
+ . map ( |c : & TableConstraint | match c {
1084
+ TableConstraint :: Unique {
1085
+ columns,
1086
+ is_primary,
1087
+ ..
1088
+ } => match is_primary {
1089
+ true => Ok ( columns) ,
1090
+ false => Err ( DataFusionError :: Plan (
1091
+ "Non-primary unique constraints are not supported" . to_string ( ) ,
1092
+ ) ) ,
1093
+ } ,
1094
+ TableConstraint :: ForeignKey { .. } => Err ( DataFusionError :: Plan (
1095
+ "Foreign key constraints are not currently supported" . to_string ( ) ,
1096
+ ) ) ,
1097
+ TableConstraint :: Check { .. } => Err ( DataFusionError :: Plan (
1098
+ "Check constraints are not currently supported" . to_string ( ) ,
1099
+ ) ) ,
1100
+ TableConstraint :: Index { .. } => Err ( DataFusionError :: Plan (
1101
+ "Indexes are not currently supported" . to_string ( ) ,
1102
+ ) ) ,
1103
+ TableConstraint :: FulltextOrSpatial { .. } => Err ( DataFusionError :: Plan (
1104
+ "Indexes are not currently supported" . to_string ( ) ,
1105
+ ) ) ,
1106
+ } )
1107
+ . collect ( ) ;
1108
+ let pk = pk?;
1109
+ let pk = match pk. as_slice ( ) {
1110
+ [ ] => return Ok ( vec ! [ ] ) ,
1111
+ [ pk] => pk,
1112
+ _ => {
1113
+ return Err ( DataFusionError :: Plan (
1114
+ "Only one primary key is supported!" . to_string ( ) ,
1115
+ ) ) ?
1116
+ }
1117
+ } ;
1118
+ let primary_key: Vec < Column > = pk
1119
+ . iter ( )
1120
+ . map ( |c| Column {
1121
+ relation : None ,
1122
+ name : c. value . clone ( ) ,
1123
+ } )
1124
+ . collect ( ) ;
1125
+ Ok ( primary_key)
1126
+ }
1079
1127
}
0 commit comments