mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-21 22:44:08 +00:00
feat: comment and alter column support (#381)
* feat: add support for postgresql comment keyword * feat: add alter column and rename constraint
This commit is contained in:
parent
823635d2fc
commit
9569d1b215
6 changed files with 355 additions and 3 deletions
|
@ -67,6 +67,15 @@ pub enum AlterTableOperation {
|
||||||
data_type: DataType,
|
data_type: DataType,
|
||||||
options: Vec<ColumnOption>,
|
options: Vec<ColumnOption>,
|
||||||
},
|
},
|
||||||
|
/// `RENAME CONSTRAINT <old_constraint_name> TO <new_constraint_name>`
|
||||||
|
///
|
||||||
|
/// Note: this is a PostgreSQL-specific operation.
|
||||||
|
RenameConstraint { old_name: Ident, new_name: Ident },
|
||||||
|
/// `ALTER [ COLUMN ]`
|
||||||
|
AlterColumn {
|
||||||
|
column_name: Ident,
|
||||||
|
op: AlterColumnOperation,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for AlterTableOperation {
|
impl fmt::Display for AlterTableOperation {
|
||||||
|
@ -85,6 +94,9 @@ impl fmt::Display for AlterTableOperation {
|
||||||
AlterTableOperation::AddColumn { column_def } => {
|
AlterTableOperation::AddColumn { column_def } => {
|
||||||
write!(f, "ADD COLUMN {}", column_def.to_string())
|
write!(f, "ADD COLUMN {}", column_def.to_string())
|
||||||
}
|
}
|
||||||
|
AlterTableOperation::AlterColumn { column_name, op } => {
|
||||||
|
write!(f, "ALTER COLUMN {} {}", column_name, op)
|
||||||
|
}
|
||||||
AlterTableOperation::DropPartitions {
|
AlterTableOperation::DropPartitions {
|
||||||
partitions,
|
partitions,
|
||||||
if_exists,
|
if_exists,
|
||||||
|
@ -139,6 +151,51 @@ impl fmt::Display for AlterTableOperation {
|
||||||
write!(f, " {}", display_separated(options, " "))
|
write!(f, " {}", display_separated(options, " "))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
AlterTableOperation::RenameConstraint { old_name, new_name } => {
|
||||||
|
write!(f, "RENAME CONSTRAINT {} TO {}", old_name, new_name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An `ALTER COLUMN` (`Statement::AlterTable`) operation
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
pub enum AlterColumnOperation {
|
||||||
|
/// `SET NOT NULL`
|
||||||
|
SetNotNull,
|
||||||
|
/// `DROP NOT NULL`
|
||||||
|
DropNotNull,
|
||||||
|
/// `SET DEFAULT <expr>`
|
||||||
|
SetDefault { value: Expr },
|
||||||
|
/// `DROP DEFAULT`
|
||||||
|
DropDefault,
|
||||||
|
/// `[SET DATA] TYPE <data_type> [USING <expr>]`
|
||||||
|
SetDataType {
|
||||||
|
data_type: DataType,
|
||||||
|
/// PostgreSQL specific
|
||||||
|
using: Option<Expr>,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for AlterColumnOperation {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
AlterColumnOperation::SetNotNull => write!(f, "SET NOT NULL",),
|
||||||
|
AlterColumnOperation::DropNotNull => write!(f, "DROP NOT NULL",),
|
||||||
|
AlterColumnOperation::SetDefault { value } => {
|
||||||
|
write!(f, "SET DEFAULT {}", value)
|
||||||
|
}
|
||||||
|
AlterColumnOperation::DropDefault {} => {
|
||||||
|
write!(f, "DROP DEFAULT")
|
||||||
|
}
|
||||||
|
AlterColumnOperation::SetDataType { data_type, using } => {
|
||||||
|
if let Some(expr) = using {
|
||||||
|
write!(f, "SET DATA TYPE {} USING {}", data_type, expr)
|
||||||
|
} else {
|
||||||
|
write!(f, "SET DATA TYPE {}", data_type)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,8 +31,8 @@ use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
pub use self::data_type::DataType;
|
pub use self::data_type::DataType;
|
||||||
pub use self::ddl::{
|
pub use self::ddl::{
|
||||||
AlterTableOperation, ColumnDef, ColumnOption, ColumnOptionDef, ReferentialAction,
|
AlterColumnOperation, AlterTableOperation, ColumnDef, ColumnOption, ColumnOptionDef,
|
||||||
TableConstraint,
|
ReferentialAction, TableConstraint,
|
||||||
};
|
};
|
||||||
pub use self::operator::{BinaryOperator, UnaryOperator};
|
pub use self::operator::{BinaryOperator, UnaryOperator};
|
||||||
pub use self::query::{
|
pub use self::query::{
|
||||||
|
@ -592,6 +592,22 @@ impl fmt::Display for ShowCreateObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
pub enum CommentObject {
|
||||||
|
Column,
|
||||||
|
Table,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for CommentObject {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
CommentObject::Column => f.write_str("COLUMN"),
|
||||||
|
CommentObject::Table => f.write_str("TABLE"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A top-level statement (SELECT, INSERT, CREATE, etc.)
|
/// A top-level statement (SELECT, INSERT, CREATE, etc.)
|
||||||
#[allow(clippy::large_enum_variant)]
|
#[allow(clippy::large_enum_variant)]
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
@ -779,6 +795,14 @@ pub enum Statement {
|
||||||
snapshot: Option<Value>,
|
snapshot: Option<Value>,
|
||||||
session: bool,
|
session: bool,
|
||||||
},
|
},
|
||||||
|
/// `COMMENT ON ...`
|
||||||
|
///
|
||||||
|
/// Note: this is a PostgreSQL-specific statement.
|
||||||
|
Comment {
|
||||||
|
object_type: CommentObject,
|
||||||
|
object_name: ObjectName,
|
||||||
|
comment: Option<String>,
|
||||||
|
},
|
||||||
/// `COMMIT [ TRANSACTION | WORK ] [ AND [ NO ] CHAIN ]`
|
/// `COMMIT [ TRANSACTION | WORK ] [ AND [ NO ] CHAIN ]`
|
||||||
Commit { chain: bool },
|
Commit { chain: bool },
|
||||||
/// `ROLLBACK [ TRANSACTION | WORK ] [ AND [ NO ] CHAIN ]`
|
/// `ROLLBACK [ TRANSACTION | WORK ] [ AND [ NO ] CHAIN ]`
|
||||||
|
@ -1459,6 +1483,18 @@ impl fmt::Display for Statement {
|
||||||
}
|
}
|
||||||
write!(f, "AS {}", statement)
|
write!(f, "AS {}", statement)
|
||||||
}
|
}
|
||||||
|
Statement::Comment {
|
||||||
|
object_type,
|
||||||
|
object_name,
|
||||||
|
comment,
|
||||||
|
} => {
|
||||||
|
write!(f, "COMMENT ON {} {} IS ", object_type, object_name)?;
|
||||||
|
if let Some(c) = comment {
|
||||||
|
write!(f, "'{}'", c)
|
||||||
|
} else {
|
||||||
|
write!(f, "NULL")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,6 +128,7 @@ define_keywords!(
|
||||||
COLLECT,
|
COLLECT,
|
||||||
COLUMN,
|
COLUMN,
|
||||||
COLUMNS,
|
COLUMNS,
|
||||||
|
COMMENT,
|
||||||
COMMIT,
|
COMMIT,
|
||||||
COMMITTED,
|
COMMITTED,
|
||||||
COMPUTE,
|
COMPUTE,
|
||||||
|
@ -161,6 +162,7 @@ define_keywords!(
|
||||||
CURRENT_USER,
|
CURRENT_USER,
|
||||||
CURSOR,
|
CURSOR,
|
||||||
CYCLE,
|
CYCLE,
|
||||||
|
DATA,
|
||||||
DATABASE,
|
DATABASE,
|
||||||
DATE,
|
DATE,
|
||||||
DAY,
|
DAY,
|
||||||
|
@ -469,6 +471,7 @@ define_keywords!(
|
||||||
TRUE,
|
TRUE,
|
||||||
TRUNCATE,
|
TRUNCATE,
|
||||||
TRY_CAST,
|
TRY_CAST,
|
||||||
|
TYPE,
|
||||||
UESCAPE,
|
UESCAPE,
|
||||||
UNBOUNDED,
|
UNBOUNDED,
|
||||||
UNCOMMITTED,
|
UNCOMMITTED,
|
||||||
|
|
|
@ -191,6 +191,9 @@ impl<'a> Parser<'a> {
|
||||||
self.prev_token();
|
self.prev_token();
|
||||||
Ok(self.parse_insert()?)
|
Ok(self.parse_insert()?)
|
||||||
}
|
}
|
||||||
|
Keyword::COMMENT if dialect_of!(self is PostgreSqlDialect) => {
|
||||||
|
Ok(self.parse_comment()?)
|
||||||
|
}
|
||||||
_ => self.expected("an SQL statement", Token::Word(w)),
|
_ => self.expected("an SQL statement", Token::Word(w)),
|
||||||
},
|
},
|
||||||
Token::LParen => {
|
Token::LParen => {
|
||||||
|
@ -1944,7 +1947,12 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if self.parse_keyword(Keyword::RENAME) {
|
} else if self.parse_keyword(Keyword::RENAME) {
|
||||||
if self.parse_keyword(Keyword::TO) {
|
if dialect_of!(self is PostgreSqlDialect) && self.parse_keyword(Keyword::CONSTRAINT) {
|
||||||
|
let old_name = self.parse_identifier()?;
|
||||||
|
self.expect_keyword(Keyword::TO)?;
|
||||||
|
let new_name = self.parse_identifier()?;
|
||||||
|
AlterTableOperation::RenameConstraint { old_name, new_name }
|
||||||
|
} else if self.parse_keyword(Keyword::TO) {
|
||||||
let table_name = self.parse_object_name()?;
|
let table_name = self.parse_object_name()?;
|
||||||
AlterTableOperation::RenameTable { table_name }
|
AlterTableOperation::RenameTable { table_name }
|
||||||
} else {
|
} else {
|
||||||
|
@ -2014,6 +2022,38 @@ impl<'a> Parser<'a> {
|
||||||
data_type,
|
data_type,
|
||||||
options,
|
options,
|
||||||
}
|
}
|
||||||
|
} else if self.parse_keyword(Keyword::ALTER) {
|
||||||
|
let _ = self.parse_keyword(Keyword::COLUMN);
|
||||||
|
let column_name = self.parse_identifier()?;
|
||||||
|
let is_postgresql = dialect_of!(self is PostgreSqlDialect);
|
||||||
|
|
||||||
|
let op = if self.parse_keywords(&[Keyword::SET, Keyword::NOT, Keyword::NULL]) {
|
||||||
|
AlterColumnOperation::SetNotNull {}
|
||||||
|
} else if self.parse_keywords(&[Keyword::DROP, Keyword::NOT, Keyword::NULL]) {
|
||||||
|
AlterColumnOperation::DropNotNull {}
|
||||||
|
} else if self.parse_keywords(&[Keyword::SET, Keyword::DEFAULT]) {
|
||||||
|
AlterColumnOperation::SetDefault {
|
||||||
|
value: self.parse_expr()?,
|
||||||
|
}
|
||||||
|
} else if self.parse_keywords(&[Keyword::DROP, Keyword::DEFAULT]) {
|
||||||
|
AlterColumnOperation::DropDefault {}
|
||||||
|
} else if self.parse_keywords(&[Keyword::SET, Keyword::DATA, Keyword::TYPE])
|
||||||
|
|| (is_postgresql && self.parse_keyword(Keyword::TYPE))
|
||||||
|
{
|
||||||
|
let data_type = self.parse_data_type()?;
|
||||||
|
let using = if is_postgresql && self.parse_keyword(Keyword::USING) {
|
||||||
|
Some(self.parse_expr()?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
AlterColumnOperation::SetDataType { data_type, using }
|
||||||
|
} else {
|
||||||
|
return self.expected(
|
||||||
|
"SET/DROP NOT NULL, SET DEFAULT, SET DATA TYPE after ALTER COLUMN",
|
||||||
|
self.peek_token(),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
AlterTableOperation::AlterColumn { column_name, op }
|
||||||
} else {
|
} else {
|
||||||
return self.expected(
|
return self.expected(
|
||||||
"ADD, RENAME, PARTITION or DROP after ALTER TABLE",
|
"ADD, RENAME, PARTITION or DROP after ALTER TABLE",
|
||||||
|
@ -3547,6 +3587,35 @@ impl<'a> Parser<'a> {
|
||||||
statement,
|
statement,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_comment(&mut self) -> Result<Statement, ParserError> {
|
||||||
|
self.expect_keyword(Keyword::ON)?;
|
||||||
|
let token = self.next_token();
|
||||||
|
|
||||||
|
let (object_type, object_name) = match token {
|
||||||
|
Token::Word(w) if w.keyword == Keyword::COLUMN => {
|
||||||
|
let object_name = self.parse_object_name()?;
|
||||||
|
(CommentObject::Column, object_name)
|
||||||
|
}
|
||||||
|
Token::Word(w) if w.keyword == Keyword::TABLE => {
|
||||||
|
let object_name = self.parse_object_name()?;
|
||||||
|
(CommentObject::Table, object_name)
|
||||||
|
}
|
||||||
|
_ => self.expected("comment object_type", token)?,
|
||||||
|
};
|
||||||
|
|
||||||
|
self.expect_keyword(Keyword::IS)?;
|
||||||
|
let comment = if self.parse_keyword(Keyword::NULL) {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(self.parse_literal_string()?)
|
||||||
|
};
|
||||||
|
Ok(Statement::Comment {
|
||||||
|
object_type,
|
||||||
|
object_name,
|
||||||
|
comment,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Word {
|
impl Word {
|
||||||
|
|
|
@ -1950,6 +1950,108 @@ fn parse_alter_table_drop_column() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_alter_table_alter_column() {
|
||||||
|
let alter_stmt = "ALTER TABLE tab";
|
||||||
|
match verified_stmt(&format!(
|
||||||
|
"{} ALTER COLUMN is_active SET NOT NULL",
|
||||||
|
alter_stmt
|
||||||
|
)) {
|
||||||
|
Statement::AlterTable {
|
||||||
|
name,
|
||||||
|
operation: AlterTableOperation::AlterColumn { column_name, op },
|
||||||
|
} => {
|
||||||
|
assert_eq!("tab", name.to_string());
|
||||||
|
assert_eq!("is_active", column_name.to_string());
|
||||||
|
assert_eq!(op, AlterColumnOperation::SetNotNull {});
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
one_statement_parses_to(
|
||||||
|
"ALTER TABLE tab ALTER is_active DROP NOT NULL",
|
||||||
|
"ALTER TABLE tab ALTER COLUMN is_active DROP NOT NULL",
|
||||||
|
);
|
||||||
|
|
||||||
|
match verified_stmt(&format!(
|
||||||
|
"{} ALTER COLUMN is_active SET DEFAULT false",
|
||||||
|
alter_stmt
|
||||||
|
)) {
|
||||||
|
Statement::AlterTable {
|
||||||
|
name,
|
||||||
|
operation: AlterTableOperation::AlterColumn { column_name, op },
|
||||||
|
} => {
|
||||||
|
assert_eq!("tab", name.to_string());
|
||||||
|
assert_eq!("is_active", column_name.to_string());
|
||||||
|
assert_eq!(
|
||||||
|
op,
|
||||||
|
AlterColumnOperation::SetDefault {
|
||||||
|
value: Expr::Value(Value::Boolean(false))
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
match verified_stmt(&format!(
|
||||||
|
"{} ALTER COLUMN is_active DROP DEFAULT",
|
||||||
|
alter_stmt
|
||||||
|
)) {
|
||||||
|
Statement::AlterTable {
|
||||||
|
name,
|
||||||
|
operation: AlterTableOperation::AlterColumn { column_name, op },
|
||||||
|
} => {
|
||||||
|
assert_eq!("tab", name.to_string());
|
||||||
|
assert_eq!("is_active", column_name.to_string());
|
||||||
|
assert_eq!(op, AlterColumnOperation::DropDefault {});
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_alter_table_alter_column_type() {
|
||||||
|
let alter_stmt = "ALTER TABLE tab";
|
||||||
|
match verified_stmt("ALTER TABLE tab ALTER COLUMN is_active SET DATA TYPE TEXT") {
|
||||||
|
Statement::AlterTable {
|
||||||
|
name,
|
||||||
|
operation: AlterTableOperation::AlterColumn { column_name, op },
|
||||||
|
} => {
|
||||||
|
assert_eq!("tab", name.to_string());
|
||||||
|
assert_eq!("is_active", column_name.to_string());
|
||||||
|
assert_eq!(
|
||||||
|
op,
|
||||||
|
AlterColumnOperation::SetDataType {
|
||||||
|
data_type: DataType::Text,
|
||||||
|
using: None,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = Parser::parse_sql(
|
||||||
|
&GenericDialect {},
|
||||||
|
&format!("{} ALTER COLUMN is_active TYPE TEXT", alter_stmt),
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
ParserError::ParserError("Expected SET/DROP NOT NULL, SET DEFAULT, SET DATA TYPE after ALTER COLUMN, found: TYPE".to_string()),
|
||||||
|
res.unwrap_err()
|
||||||
|
);
|
||||||
|
|
||||||
|
let res = Parser::parse_sql(
|
||||||
|
&GenericDialect {},
|
||||||
|
&format!(
|
||||||
|
"{} ALTER COLUMN is_active SET DATA TYPE TEXT USING 'text'",
|
||||||
|
alter_stmt
|
||||||
|
),
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
ParserError::ParserError("Expected end of statement, found: USING".to_string()),
|
||||||
|
res.unwrap_err()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_bad_constraint() {
|
fn parse_bad_constraint() {
|
||||||
let res = parse_sql_statements("ALTER TABLE tab ADD");
|
let res = parse_sql_statements("ALTER TABLE tab ADD");
|
||||||
|
|
|
@ -263,6 +263,50 @@ fn parse_create_table_constraints_only() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_alter_table_constraints_rename() {
|
||||||
|
match pg().verified_stmt("ALTER TABLE tab RENAME CONSTRAINT old_name TO new_name") {
|
||||||
|
Statement::AlterTable {
|
||||||
|
name,
|
||||||
|
operation: AlterTableOperation::RenameConstraint { old_name, new_name },
|
||||||
|
} => {
|
||||||
|
assert_eq!("tab", name.to_string());
|
||||||
|
assert_eq!(old_name.to_string(), "old_name");
|
||||||
|
assert_eq!(new_name.to_string(), "new_name");
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_alter_table_alter_column() {
|
||||||
|
pg().one_statement_parses_to(
|
||||||
|
"ALTER TABLE tab ALTER COLUMN is_active TYPE TEXT USING 'text'",
|
||||||
|
"ALTER TABLE tab ALTER COLUMN is_active SET DATA TYPE TEXT USING 'text'",
|
||||||
|
);
|
||||||
|
|
||||||
|
match pg()
|
||||||
|
.verified_stmt("ALTER TABLE tab ALTER COLUMN is_active SET DATA TYPE TEXT USING 'text'")
|
||||||
|
{
|
||||||
|
Statement::AlterTable {
|
||||||
|
name,
|
||||||
|
operation: AlterTableOperation::AlterColumn { column_name, op },
|
||||||
|
} => {
|
||||||
|
assert_eq!("tab", name.to_string());
|
||||||
|
assert_eq!("is_active", column_name.to_string());
|
||||||
|
let using_expr = Expr::Value(Value::SingleQuotedString("text".to_string()));
|
||||||
|
assert_eq!(
|
||||||
|
op,
|
||||||
|
AlterColumnOperation::SetDataType {
|
||||||
|
data_type: DataType::Text,
|
||||||
|
using: Some(using_expr),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_create_table_if_not_exists() {
|
fn parse_create_table_if_not_exists() {
|
||||||
let sql = "CREATE TABLE IF NOT EXISTS uk_cities ()";
|
let sql = "CREATE TABLE IF NOT EXISTS uk_cities ()";
|
||||||
|
@ -749,6 +793,47 @@ fn test_transaction_statement() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_comments() {
|
||||||
|
match pg().verified_stmt("COMMENT ON COLUMN tab.name IS 'comment'") {
|
||||||
|
Statement::Comment {
|
||||||
|
object_type,
|
||||||
|
object_name,
|
||||||
|
comment: Some(comment),
|
||||||
|
} => {
|
||||||
|
assert_eq!("comment", comment);
|
||||||
|
assert_eq!("tab.name", object_name.to_string());
|
||||||
|
assert_eq!(CommentObject::Column, object_type);
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
match pg().verified_stmt("COMMENT ON TABLE public.tab IS 'comment'") {
|
||||||
|
Statement::Comment {
|
||||||
|
object_type,
|
||||||
|
object_name,
|
||||||
|
comment: Some(comment),
|
||||||
|
} => {
|
||||||
|
assert_eq!("comment", comment);
|
||||||
|
assert_eq!("public.tab", object_name.to_string());
|
||||||
|
assert_eq!(CommentObject::Table, object_type);
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
match pg().verified_stmt("COMMENT ON TABLE public.tab IS NULL") {
|
||||||
|
Statement::Comment {
|
||||||
|
object_type,
|
||||||
|
object_name,
|
||||||
|
comment: None,
|
||||||
|
} => {
|
||||||
|
assert_eq!("public.tab", object_name.to_string());
|
||||||
|
assert_eq!(CommentObject::Table, object_type);
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn pg() -> TestedDialects {
|
fn pg() -> TestedDialects {
|
||||||
TestedDialects {
|
TestedDialects {
|
||||||
dialects: vec![Box::new(PostgreSqlDialect {})],
|
dialects: vec![Box::new(PostgreSqlDialect {})],
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue