Skip to content

Commit 39c18f5

Browse files
LucaCappelletti94ayman-sigma
authored andcommitted
Refactored ColumnOption::Unique to reuse UniqueConstraint and PrimaryKeyConstraint (apache#2064)
1 parent ef28b7e commit 39c18f5

File tree

7 files changed

+152
-54
lines changed

7 files changed

+152
-54
lines changed

src/ast/ddl.rs

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ use sqlparser_derive::{Visit, VisitMut};
3131
use crate::ast::value::escape_single_quote_string;
3232
use crate::ast::{
3333
display_comma_separated, display_separated,
34-
table_constraints::{CheckConstraint, ForeignKeyConstraint, TableConstraint},
34+
table_constraints::{
35+
CheckConstraint, ForeignKeyConstraint, PrimaryKeyConstraint, TableConstraint,
36+
UniqueConstraint,
37+
},
3538
ArgMode, AttachedToken, CommentDef, ConditionalStatements, CreateFunctionBody,
3639
CreateFunctionUsing, CreateTableLikeKind, CreateTableOptions, CreateViewParams, DataType, Expr,
3740
FileFormat, FunctionBehavior, FunctionCalledOnNull, FunctionDesc, FunctionDeterminismSpecifier,
@@ -55,6 +58,22 @@ pub struct IndexColumn {
5558
pub operator_class: Option<Ident>,
5659
}
5760

61+
impl From<Ident> for IndexColumn {
62+
fn from(c: Ident) -> Self {
63+
Self {
64+
column: OrderByExpr::from(c),
65+
operator_class: None,
66+
}
67+
}
68+
}
69+
70+
impl<'a> From<&'a str> for IndexColumn {
71+
fn from(c: &'a str) -> Self {
72+
let ident = Ident::new(c);
73+
ident.into()
74+
}
75+
}
76+
5877
impl fmt::Display for IndexColumn {
5978
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6079
write!(f, "{}", self.column)?;
@@ -1555,11 +1574,10 @@ pub enum ColumnOption {
15551574
/// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/statements/create/table#default_values)
15561575
Alias(Expr),
15571576

1558-
/// `{ PRIMARY KEY | UNIQUE } [<constraint_characteristics>]`
1559-
Unique {
1560-
is_primary: bool,
1561-
characteristics: Option<ConstraintCharacteristics>,
1562-
},
1577+
/// `PRIMARY KEY [<constraint_characteristics>]`
1578+
PrimaryKey(PrimaryKeyConstraint),
1579+
/// `UNIQUE [<constraint_characteristics>]`
1580+
Unique(UniqueConstraint),
15631581
/// A referential integrity constraint (`REFERENCES <foreign_table> (<referred_columns>)
15641582
/// [ MATCH { FULL | PARTIAL | SIMPLE } ]
15651583
/// { [ON DELETE <referential_action>] [ON UPDATE <referential_action>] |
@@ -1638,6 +1656,18 @@ pub enum ColumnOption {
16381656
Invisible,
16391657
}
16401658

1659+
impl From<UniqueConstraint> for ColumnOption {
1660+
fn from(c: UniqueConstraint) -> Self {
1661+
ColumnOption::Unique(c)
1662+
}
1663+
}
1664+
1665+
impl From<PrimaryKeyConstraint> for ColumnOption {
1666+
fn from(c: PrimaryKeyConstraint) -> Self {
1667+
ColumnOption::PrimaryKey(c)
1668+
}
1669+
}
1670+
16411671
impl From<CheckConstraint> for ColumnOption {
16421672
fn from(c: CheckConstraint) -> Self {
16431673
ColumnOption::Check(c)
@@ -1665,12 +1695,16 @@ impl fmt::Display for ColumnOption {
16651695
}
16661696
}
16671697
Alias(expr) => write!(f, "ALIAS {expr}"),
1668-
Unique {
1669-
is_primary,
1670-
characteristics,
1671-
} => {
1672-
write!(f, "{}", if *is_primary { "PRIMARY KEY" } else { "UNIQUE" })?;
1673-
if let Some(characteristics) = characteristics {
1698+
PrimaryKey(constraint) => {
1699+
write!(f, "PRIMARY KEY")?;
1700+
if let Some(characteristics) = &constraint.characteristics {
1701+
write!(f, " {characteristics}")?;
1702+
}
1703+
Ok(())
1704+
}
1705+
Unique(constraint) => {
1706+
write!(f, "UNIQUE")?;
1707+
if let Some(characteristics) = &constraint.characteristics {
16741708
write!(f, " {characteristics}")?;
16751709
}
16761710
Ok(())

src/ast/query.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2519,6 +2519,16 @@ pub struct OrderByExpr {
25192519
pub with_fill: Option<WithFill>,
25202520
}
25212521

2522+
impl From<Ident> for OrderByExpr {
2523+
fn from(ident: Ident) -> Self {
2524+
OrderByExpr {
2525+
expr: Expr::Identifier(ident),
2526+
options: OrderByOptions::default(),
2527+
with_fill: None,
2528+
}
2529+
}
2530+
}
2531+
25222532
impl fmt::Display for OrderByExpr {
25232533
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
25242534
write!(f, "{}{}", self.expr, self.options)?;
@@ -2587,7 +2597,7 @@ impl fmt::Display for InterpolateExpr {
25872597
}
25882598
}
25892599

2590-
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2600+
#[derive(Default, Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
25912601
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
25922602
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
25932603
pub struct OrderByOptions {

src/ast/spans.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,8 @@ impl Spanned for RaiseStatementValue {
728728
/// - [ColumnOption::Null]
729729
/// - [ColumnOption::NotNull]
730730
/// - [ColumnOption::Comment]
731-
/// - [ColumnOption::Unique]¨
731+
/// - [ColumnOption::PrimaryKey]
732+
/// - [ColumnOption::Unique]
732733
/// - [ColumnOption::DialectSpecific]
733734
/// - [ColumnOption::Generated]
734735
impl Spanned for ColumnOption {
@@ -740,7 +741,8 @@ impl Spanned for ColumnOption {
740741
ColumnOption::Materialized(expr) => expr.span(),
741742
ColumnOption::Ephemeral(expr) => expr.as_ref().map_or(Span::empty(), |e| e.span()),
742743
ColumnOption::Alias(expr) => expr.span(),
743-
ColumnOption::Unique { .. } => Span::empty(),
744+
ColumnOption::PrimaryKey(constraint) => constraint.span(),
745+
ColumnOption::Unique(constraint) => constraint.span(),
744746
ColumnOption::Check(constraint) => constraint.span(),
745747
ColumnOption::ForeignKey(constraint) => constraint.span(),
746748
ColumnOption::DialectSpecific(_) => Span::empty(),

src/parser/mod.rs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8081,16 +8081,32 @@ impl<'a> Parser<'a> {
80818081
}
80828082
} else if self.parse_keywords(&[Keyword::PRIMARY, Keyword::KEY]) {
80838083
let characteristics = self.parse_constraint_characteristics()?;
8084-
Ok(Some(ColumnOption::Unique {
8085-
is_primary: true,
8086-
characteristics,
8087-
}))
8084+
Ok(Some(
8085+
PrimaryKeyConstraint {
8086+
name: None,
8087+
index_name: None,
8088+
index_type: None,
8089+
columns: vec![],
8090+
index_options: vec![],
8091+
characteristics,
8092+
}
8093+
.into(),
8094+
))
80888095
} else if self.parse_keyword(Keyword::UNIQUE) {
80898096
let characteristics = self.parse_constraint_characteristics()?;
8090-
Ok(Some(ColumnOption::Unique {
8091-
is_primary: false,
8092-
characteristics,
8093-
}))
8097+
Ok(Some(
8098+
UniqueConstraint {
8099+
name: None,
8100+
index_name: None,
8101+
index_type_display: KeyOrIndexDisplay::None,
8102+
index_type: None,
8103+
columns: vec![],
8104+
index_options: vec![],
8105+
characteristics,
8106+
nulls_distinct: NullsDistinctOption::None,
8107+
}
8108+
.into(),
8109+
))
80948110
} else if self.parse_keyword(Keyword::REFERENCES) {
80958111
let foreign_table = self.parse_object_name(false)?;
80968112
// PostgreSQL allows omitting the column list and

tests/sqlparser_common.rs

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3764,21 +3764,31 @@ fn parse_create_table() {
37643764
},
37653765
ColumnOptionDef {
37663766
name: Some("pkey".into()),
3767-
option: ColumnOption::Unique {
3768-
is_primary: true,
3769-
characteristics: None
3770-
},
3767+
option: ColumnOption::PrimaryKey(PrimaryKeyConstraint {
3768+
name: None,
3769+
index_name: None,
3770+
index_type: None,
3771+
columns: vec![],
3772+
index_options: vec![],
3773+
characteristics: None,
3774+
}),
37713775
},
37723776
ColumnOptionDef {
37733777
name: None,
37743778
option: ColumnOption::NotNull,
37753779
},
37763780
ColumnOptionDef {
37773781
name: None,
3778-
option: ColumnOption::Unique {
3779-
is_primary: false,
3780-
characteristics: None
3781-
},
3782+
option: ColumnOption::Unique(UniqueConstraint {
3783+
name: None,
3784+
index_name: None,
3785+
index_type_display: KeyOrIndexDisplay::None,
3786+
index_type: None,
3787+
columns: vec![],
3788+
index_options: vec![],
3789+
characteristics: None,
3790+
nulls_distinct: NullsDistinctOption::None,
3791+
}),
37823792
},
37833793
ColumnOptionDef {
37843794
name: None,
@@ -4107,10 +4117,16 @@ fn parse_create_table_column_constraint_characteristics() {
41074117
data_type: DataType::Int(None),
41084118
options: vec![ColumnOptionDef {
41094119
name: None,
4110-
option: ColumnOption::Unique {
4111-
is_primary: false,
4112-
characteristics: expected_value
4113-
}
4120+
option: ColumnOption::Unique(UniqueConstraint {
4121+
name: None,
4122+
index_name: None,
4123+
index_type_display: KeyOrIndexDisplay::None,
4124+
index_type: None,
4125+
columns: vec![],
4126+
index_options: vec![],
4127+
characteristics: expected_value,
4128+
nulls_distinct: NullsDistinctOption::None,
4129+
})
41144130
}]
41154131
}],
41164132
"{message}"

tests/sqlparser_mysql.rs

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -638,10 +638,14 @@ fn parse_create_table_auto_increment() {
638638
options: vec![
639639
ColumnOptionDef {
640640
name: None,
641-
option: ColumnOption::Unique {
642-
is_primary: true,
643-
characteristics: None
644-
},
641+
option: ColumnOption::PrimaryKey(PrimaryKeyConstraint {
642+
name: None,
643+
index_name: None,
644+
index_type: None,
645+
columns: vec![],
646+
index_options: vec![],
647+
characteristics: None,
648+
}),
645649
},
646650
ColumnOptionDef {
647651
name: None,
@@ -743,10 +747,14 @@ fn parse_create_table_primary_and_unique_key() {
743747
options: vec![
744748
ColumnOptionDef {
745749
name: None,
746-
option: ColumnOption::Unique {
747-
is_primary: true,
748-
characteristics: None
749-
},
750+
option: ColumnOption::PrimaryKey(PrimaryKeyConstraint {
751+
name: None,
752+
index_name: None,
753+
index_type: None,
754+
columns: vec![],
755+
index_options: vec![],
756+
characteristics: None,
757+
}),
750758
},
751759
ColumnOptionDef {
752760
name: None,
@@ -1382,10 +1390,14 @@ fn parse_quote_identifiers() {
13821390
data_type: DataType::Int(None),
13831391
options: vec![ColumnOptionDef {
13841392
name: None,
1385-
option: ColumnOption::Unique {
1386-
is_primary: true,
1387-
characteristics: None
1388-
},
1393+
option: ColumnOption::PrimaryKey(PrimaryKeyConstraint {
1394+
name: None,
1395+
index_name: None,
1396+
index_type: None,
1397+
columns: vec![],
1398+
index_options: vec![],
1399+
characteristics: None,
1400+
}),
13891401
}],
13901402
}],
13911403
columns

tests/sqlparser_sqlite.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -217,10 +217,14 @@ fn parse_create_table_auto_increment() {
217217
options: vec![
218218
ColumnOptionDef {
219219
name: None,
220-
option: ColumnOption::Unique {
221-
is_primary: true,
222-
characteristics: None
223-
},
220+
option: ColumnOption::PrimaryKey(PrimaryKeyConstraint {
221+
name: None,
222+
index_name: None,
223+
index_type: None,
224+
columns: vec![],
225+
index_options: vec![],
226+
characteristics: None,
227+
}),
224228
},
225229
ColumnOptionDef {
226230
name: None,
@@ -245,10 +249,14 @@ fn parse_create_table_primary_key_asc_desc() {
245249
options: vec![
246250
ColumnOptionDef {
247251
name: None,
248-
option: ColumnOption::Unique {
249-
is_primary: true,
252+
option: ColumnOption::PrimaryKey(PrimaryKeyConstraint {
253+
name: None,
254+
index_name: None,
255+
index_type: None,
256+
columns: vec![],
257+
index_options: vec![],
250258
characteristics: None,
251-
},
259+
}),
252260
},
253261
ColumnOptionDef {
254262
name: None,

0 commit comments

Comments
 (0)