1212// See the License for the specific language governing permissions and
1313// limitations under the License.
1414
15- use super :: { is_valid_identifier, Binder } ;
15+ use super :: { attach_span_if_absent , is_valid_identifier, Binder } ;
1616use crate :: binder:: lower_case_name;
1717use crate :: catalog:: { ColumnCatalog , ColumnDesc } ;
1818use crate :: errors:: DatabaseError ;
@@ -24,7 +24,7 @@ use crate::storage::Transaction;
2424use crate :: types:: value:: DataValue ;
2525use crate :: types:: LogicalType ;
2626use itertools:: Itertools ;
27- use sqlparser:: ast:: { ColumnDef , ColumnOption , ObjectName , TableConstraint } ;
27+ use sqlparser:: ast:: { ColumnDef , ColumnOption , Expr , IndexColumn , ObjectName , TableConstraint } ;
2828use std:: collections:: HashSet ;
2929use std:: sync:: Arc ;
3030
@@ -40,8 +40,9 @@ impl<T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'_, '_, T, A>
4040 let table_name: Arc < str > = lower_case_name ( name) ?. into ( ) ;
4141
4242 if !is_valid_identifier ( & table_name) {
43- return Err ( DatabaseError :: InvalidTable (
44- "illegal table naming" . to_string ( ) ,
43+ return Err ( attach_span_if_absent (
44+ DatabaseError :: invalid_table ( "illegal table naming" . to_string ( ) ) ,
45+ name,
4546 ) ) ;
4647 }
4748 {
@@ -53,8 +54,9 @@ impl<T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'_, '_, T, A>
5354 return Err ( DatabaseError :: DuplicateColumn ( col_name. clone ( ) ) ) ;
5455 }
5556 if !is_valid_identifier ( col_name) {
56- return Err ( DatabaseError :: InvalidColumn (
57- "illegal column naming" . to_string ( ) ,
57+ return Err ( attach_span_if_absent (
58+ DatabaseError :: invalid_column ( "illegal column naming" . to_string ( ) ) ,
59+ col,
5860 ) ) ;
5961 }
6062 }
@@ -66,27 +68,15 @@ impl<T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'_, '_, T, A>
6668 . try_collect ( ) ?;
6769 for constraint in constraints {
6870 match constraint {
69- TableConstraint :: Unique {
70- columns : column_names,
71- is_primary,
72- ..
73- } => {
74- for ( i, column_name) in column_names
75- . iter ( )
76- . map ( |ident| ident. value . to_lowercase ( ) )
77- . enumerate ( )
78- {
79- if let Some ( column) = columns
80- . iter_mut ( )
81- . find ( |column| column. name ( ) == column_name)
82- {
83- if * is_primary {
84- column. desc_mut ( ) . set_primary ( Some ( i) ) ;
85- } else {
86- column. desc_mut ( ) . set_unique ( true ) ;
87- }
88- }
89- }
71+ TableConstraint :: PrimaryKey ( primary) => {
72+ Self :: bind_constraint ( & mut columns, & primary. columns , |i, desc| {
73+ desc. set_primary ( Some ( i) )
74+ } ) ?;
75+ }
76+ TableConstraint :: Unique ( unique) => {
77+ Self :: bind_constraint ( & mut columns, & unique. columns , |_, desc| {
78+ desc. set_unique ( )
79+ } ) ?;
9080 }
9181 constraint => {
9282 return Err ( DatabaseError :: UnsupportedStmt ( format ! (
@@ -97,8 +87,11 @@ impl<T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'_, '_, T, A>
9787 }
9888
9989 if columns. iter ( ) . filter ( |col| col. desc ( ) . is_primary ( ) ) . count ( ) == 0 {
100- return Err ( DatabaseError :: InvalidTable (
101- "the primary key field must exist and have at least one" . to_string ( ) ,
90+ return Err ( attach_span_if_absent (
91+ DatabaseError :: invalid_table (
92+ "the primary key field must exist and have at least one" . to_string ( ) ,
93+ ) ,
94+ name,
10295 ) ) ;
10396 }
10497
@@ -112,6 +105,29 @@ impl<T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'_, '_, T, A>
112105 ) )
113106 }
114107
108+ fn bind_constraint < F : Fn ( usize , & mut ColumnDesc ) > (
109+ table_columns : & mut [ ColumnCatalog ] ,
110+ exprs : & [ IndexColumn ] ,
111+ fn_constraint : F ,
112+ ) -> Result < ( ) , DatabaseError > {
113+ for ( i, index_column) in exprs. iter ( ) . enumerate ( ) {
114+ let Expr :: Identifier ( ident) = & index_column. column . expr else {
115+ return Err ( DatabaseError :: UnsupportedStmt (
116+ "only identifier columns are supported in `PRIMARY KEY/UNIQUE`" . to_string ( ) ,
117+ ) ) ;
118+ } ;
119+ let column_name = ident. value . to_lowercase ( ) ;
120+
121+ if let Some ( column) = table_columns
122+ . iter_mut ( )
123+ . find ( |column| column. name ( ) == column_name)
124+ {
125+ fn_constraint ( i, column. desc_mut ( ) )
126+ }
127+ }
128+ Ok ( ( ) )
129+ }
130+
115131 pub fn bind_column (
116132 & mut self ,
117133 column_def : & ColumnDef ,
@@ -130,16 +146,13 @@ impl<T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'_, '_, T, A>
130146 match & option_def. option {
131147 ColumnOption :: Null => nullable = true ,
132148 ColumnOption :: NotNull => nullable = false ,
133- ColumnOption :: Unique { is_primary, .. } => {
134- if * is_primary {
135- column_desc. set_primary ( column_index) ;
136- nullable = false ;
137- // Skip other options when using primary key
138- break ;
139- } else {
140- column_desc. set_unique ( true ) ;
141- }
149+ ColumnOption :: PrimaryKey ( _) => {
150+ column_desc. set_primary ( column_index) ;
151+ nullable = false ;
152+ // Skip other options when using primary key
153+ break ;
142154 }
155+ ColumnOption :: Unique ( _) => column_desc. set_unique ( ) ,
143156 ColumnOption :: Default ( expr) => {
144157 let mut expr = self . bind_expr ( expr) ?;
145158
0 commit comments