mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-07-07 17:04:59 +00:00
Postgres: support ADD CONSTRAINT NOT VALID
and VALIDATE CONSTRAINT
(#1908)
This commit is contained in:
parent
015caca611
commit
418b94227a
7 changed files with 99 additions and 22 deletions
|
@ -67,8 +67,11 @@ impl fmt::Display for ReplicaIdentity {
|
|||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
|
||||
pub enum AlterTableOperation {
|
||||
/// `ADD <table_constraint>`
|
||||
AddConstraint(TableConstraint),
|
||||
/// `ADD <table_constraint> [NOT VALID]`
|
||||
AddConstraint {
|
||||
constraint: TableConstraint,
|
||||
not_valid: bool,
|
||||
},
|
||||
/// `ADD [COLUMN] [IF NOT EXISTS] <column_def>`
|
||||
AddColumn {
|
||||
/// `[COLUMN]`.
|
||||
|
@ -344,6 +347,10 @@ pub enum AlterTableOperation {
|
|||
equals: bool,
|
||||
value: ValueWithSpan,
|
||||
},
|
||||
/// `VALIDATE CONSTRAINT <name>`
|
||||
ValidateConstraint {
|
||||
name: Ident,
|
||||
},
|
||||
}
|
||||
|
||||
/// An `ALTER Policy` (`Statement::AlterPolicy`) operation
|
||||
|
@ -494,7 +501,16 @@ impl fmt::Display for AlterTableOperation {
|
|||
display_separated(new_partitions, " "),
|
||||
ine = if *if_not_exists { " IF NOT EXISTS" } else { "" }
|
||||
),
|
||||
AlterTableOperation::AddConstraint(c) => write!(f, "ADD {c}"),
|
||||
AlterTableOperation::AddConstraint {
|
||||
not_valid,
|
||||
constraint,
|
||||
} => {
|
||||
write!(f, "ADD {constraint}")?;
|
||||
if *not_valid {
|
||||
write!(f, " NOT VALID")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
AlterTableOperation::AddColumn {
|
||||
column_keyword,
|
||||
if_not_exists,
|
||||
|
@ -772,6 +788,9 @@ impl fmt::Display for AlterTableOperation {
|
|||
AlterTableOperation::ReplicaIdentity { identity } => {
|
||||
write!(f, "REPLICA IDENTITY {identity}")
|
||||
}
|
||||
AlterTableOperation::ValidateConstraint { name } => {
|
||||
write!(f, "VALIDATE CONSTRAINT {name}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1075,7 +1075,10 @@ impl Spanned for CreateTableOptions {
|
|||
impl Spanned for AlterTableOperation {
|
||||
fn span(&self) -> Span {
|
||||
match self {
|
||||
AlterTableOperation::AddConstraint(table_constraint) => table_constraint.span(),
|
||||
AlterTableOperation::AddConstraint {
|
||||
constraint,
|
||||
not_valid: _,
|
||||
} => constraint.span(),
|
||||
AlterTableOperation::AddColumn {
|
||||
column_keyword: _,
|
||||
if_not_exists: _,
|
||||
|
@ -1196,6 +1199,7 @@ impl Spanned for AlterTableOperation {
|
|||
AlterTableOperation::AutoIncrement { value, .. } => value.span(),
|
||||
AlterTableOperation::Lock { .. } => Span::empty(),
|
||||
AlterTableOperation::ReplicaIdentity { .. } => Span::empty(),
|
||||
AlterTableOperation::ValidateConstraint { name } => name.span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -981,6 +981,7 @@ define_keywords!(
|
|||
UUID,
|
||||
VACUUM,
|
||||
VALID,
|
||||
VALIDATE,
|
||||
VALIDATION_MODE,
|
||||
VALUE,
|
||||
VALUES,
|
||||
|
|
|
@ -8477,7 +8477,11 @@ impl<'a> Parser<'a> {
|
|||
pub fn parse_alter_table_operation(&mut self) -> Result<AlterTableOperation, ParserError> {
|
||||
let operation = if self.parse_keyword(Keyword::ADD) {
|
||||
if let Some(constraint) = self.parse_optional_table_constraint()? {
|
||||
AlterTableOperation::AddConstraint(constraint)
|
||||
let not_valid = self.parse_keywords(&[Keyword::NOT, Keyword::VALID]);
|
||||
AlterTableOperation::AddConstraint {
|
||||
constraint,
|
||||
not_valid,
|
||||
}
|
||||
} else if dialect_of!(self is ClickHouseDialect|GenericDialect)
|
||||
&& self.parse_keyword(Keyword::PROJECTION)
|
||||
{
|
||||
|
@ -8886,6 +8890,9 @@ impl<'a> Parser<'a> {
|
|||
};
|
||||
|
||||
AlterTableOperation::ReplicaIdentity { identity }
|
||||
} else if self.parse_keywords(&[Keyword::VALIDATE, Keyword::CONSTRAINT]) {
|
||||
let name = self.parse_identifier()?;
|
||||
AlterTableOperation::ValidateConstraint { name }
|
||||
} else {
|
||||
let options: Vec<SqlOption> =
|
||||
self.parse_options_with_keywords(&[Keyword::SET, Keyword::TBLPROPERTIES])?;
|
||||
|
|
|
@ -479,20 +479,25 @@ pub fn index_column(stmt: Statement) -> Expr {
|
|||
}
|
||||
}
|
||||
Statement::AlterTable { operations, .. } => match operations.first().unwrap() {
|
||||
AlterTableOperation::AddConstraint(TableConstraint::Index { columns, .. }) => {
|
||||
columns.first().unwrap().column.expr.clone()
|
||||
AlterTableOperation::AddConstraint { constraint, .. } => {
|
||||
match constraint {
|
||||
TableConstraint::Index { columns, .. } => {
|
||||
columns.first().unwrap().column.expr.clone()
|
||||
}
|
||||
TableConstraint::Unique { columns, .. } => {
|
||||
columns.first().unwrap().column.expr.clone()
|
||||
}
|
||||
TableConstraint::PrimaryKey { columns, .. } => {
|
||||
columns.first().unwrap().column.expr.clone()
|
||||
}
|
||||
TableConstraint::FulltextOrSpatial {
|
||||
columns,
|
||||
..
|
||||
} => columns.first().unwrap().column.expr.clone(),
|
||||
_ => panic!("Expected an index, unique, primary, full text, or spatial constraint (foreign key does not support general key part expressions)"),
|
||||
}
|
||||
}
|
||||
AlterTableOperation::AddConstraint(TableConstraint::Unique { columns, .. }) => {
|
||||
columns.first().unwrap().column.expr.clone()
|
||||
}
|
||||
AlterTableOperation::AddConstraint(TableConstraint::PrimaryKey { columns, .. }) => {
|
||||
columns.first().unwrap().column.expr.clone()
|
||||
}
|
||||
AlterTableOperation::AddConstraint(TableConstraint::FulltextOrSpatial {
|
||||
columns,
|
||||
..
|
||||
}) => columns.first().unwrap().column.expr.clone(),
|
||||
_ => panic!("Expected an index, unique, primary, full text, or spatial constraint (foreign key does not support general key part expressions)"),
|
||||
_ => panic!("Expected a constraint"),
|
||||
},
|
||||
_ => panic!("Expected CREATE INDEX, ALTER TABLE, or CREATE TABLE, got: {stmt:?}"),
|
||||
}
|
||||
|
|
|
@ -4956,7 +4956,7 @@ fn parse_alter_table_constraints() {
|
|||
match alter_table_op(verified_stmt(&format!(
|
||||
"ALTER TABLE tab ADD {constraint_text}"
|
||||
))) {
|
||||
AlterTableOperation::AddConstraint(constraint) => {
|
||||
AlterTableOperation::AddConstraint { constraint, .. } => {
|
||||
assert_eq!(constraint_text, constraint.to_string());
|
||||
}
|
||||
_ => unreachable!(),
|
||||
|
|
|
@ -606,9 +606,10 @@ fn parse_alter_table_constraints_unique_nulls_distinct() {
|
|||
.verified_stmt("ALTER TABLE t ADD CONSTRAINT b UNIQUE NULLS NOT DISTINCT (c)")
|
||||
{
|
||||
Statement::AlterTable { operations, .. } => match &operations[0] {
|
||||
AlterTableOperation::AddConstraint(TableConstraint::Unique {
|
||||
nulls_distinct, ..
|
||||
}) => {
|
||||
AlterTableOperation::AddConstraint {
|
||||
constraint: TableConstraint::Unique { nulls_distinct, .. },
|
||||
..
|
||||
} => {
|
||||
assert_eq!(nulls_distinct, &NullsDistinctOption::NotDistinct)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
|
@ -6229,3 +6230,43 @@ fn parse_ts_datatypes() {
|
|||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_alter_table_constraint_not_valid() {
|
||||
match pg_and_generic().verified_stmt(
|
||||
"ALTER TABLE foo ADD CONSTRAINT bar FOREIGN KEY (baz) REFERENCES other(ref) NOT VALID",
|
||||
) {
|
||||
Statement::AlterTable { operations, .. } => {
|
||||
assert_eq!(
|
||||
operations,
|
||||
vec![AlterTableOperation::AddConstraint {
|
||||
constraint: TableConstraint::ForeignKey {
|
||||
name: Some("bar".into()),
|
||||
index_name: None,
|
||||
columns: vec!["baz".into()],
|
||||
foreign_table: ObjectName::from(vec!["other".into()]),
|
||||
referred_columns: vec!["ref".into()],
|
||||
on_delete: None,
|
||||
on_update: None,
|
||||
characteristics: None,
|
||||
},
|
||||
not_valid: true,
|
||||
}]
|
||||
);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_alter_table_validate_constraint() {
|
||||
match pg_and_generic().verified_stmt("ALTER TABLE foo VALIDATE CONSTRAINT bar") {
|
||||
Statement::AlterTable { operations, .. } => {
|
||||
assert_eq!(
|
||||
operations,
|
||||
vec![AlterTableOperation::ValidateConstraint { name: "bar".into() }]
|
||||
);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue