Skip to content

Commit c59b518

Browse files
test(postgres): add collation DDL coverage
Add parser tests for PostgreSQL collation statements and comment targets.\n\n- validate AST shape for CREATE/ALTER COLLATION variants\n- validate DROP COLLATION and COMMENT ON COLLATION AST mapping\n- round-trip the full statement set used for regression investigation\n- include COLLATION in shared COMMENT object-type coverage
1 parent 90d6578 commit c59b518

File tree

3 files changed

+188
-23
lines changed

3 files changed

+188
-23
lines changed

src/ast/mod.rs

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -60,29 +60,28 @@ pub use self::dcl::{
6060
SetConfigValue, Use,
6161
};
6262
pub use self::ddl::{
63-
Alignment, AlterColumnOperation, AlterConnectorOwner, AlterFunction, AlterFunctionAction,
64-
AlterFunctionKind, AlterFunctionOperation, AlterIndexOperation, AlterOperator,
65-
AlterOperatorClass, AlterOperatorClassOperation, AlterOperatorFamily,
66-
AlterOperatorFamilyOperation, AlterOperatorOperation, AlterPolicy, AlterPolicyOperation,
67-
AlterSchema, AlterSchemaOperation, AlterTable, AlterTableAlgorithm, AlterTableLock,
68-
AlterTableOperation, AlterTableType, AlterType, AlterTypeAddValue, AlterTypeAddValuePosition,
69-
AlterTypeOperation, AlterTypeRename, AlterTypeRenameValue, ClusteredBy, ColumnDef,
70-
ColumnOption, ColumnOptionDef, ColumnOptions, ColumnPolicy, ColumnPolicyProperty,
71-
ConstraintCharacteristics, CreateConnector, CreateDomain, CreateExtension, CreateFunction,
72-
CreateIndex, CreateOperator, CreateOperatorClass, CreateOperatorFamily, CreatePolicy,
73-
CreatePolicyCommand, CreatePolicyType, CreateTable, CreateTrigger, CreateView, Deduplicate,
74-
DeferrableInitial, DistStyle, DropBehavior, DropExtension, DropFunction, DropOperator,
75-
DropOperatorClass, DropOperatorFamily, DropOperatorSignature, DropPolicy, DropTrigger,
76-
ForValues, FunctionReturnType, GeneratedAs, GeneratedExpressionMode, IdentityParameters,
77-
IdentityProperty, IdentityPropertyFormatKind, IdentityPropertyKind, IdentityPropertyOrder,
78-
IndexColumn, IndexOption, IndexType, KeyOrIndexDisplay, Msck, NullsDistinctOption,
79-
OperatorArgTypes, OperatorClassItem, OperatorFamilyDropItem, OperatorFamilyItem,
80-
OperatorOption, OperatorPurpose, Owner, Partition, PartitionBoundValue, ProcedureParam,
81-
ReferentialAction, RenameTableNameKind, ReplicaIdentity, TagsColumnOption, TriggerObjectKind,
82-
Truncate, UserDefinedTypeCompositeAttributeDef, UserDefinedTypeInternalLength,
83-
UserDefinedTypeRangeOption, UserDefinedTypeRepresentation, UserDefinedTypeSqlDefinitionOption,
84-
UserDefinedTypeStorage, ViewColumnDef,
85-
AlterCollation, AlterCollationOperation, CreateCollation, CreateCollationDefinition,
63+
Alignment, AlterCollation, AlterCollationOperation, AlterColumnOperation, AlterConnectorOwner,
64+
AlterFunction, AlterFunctionAction, AlterFunctionKind, AlterFunctionOperation,
65+
AlterIndexOperation, AlterOperator, AlterOperatorClass, AlterOperatorClassOperation,
66+
AlterOperatorFamily, AlterOperatorFamilyOperation, AlterOperatorOperation, AlterPolicy,
67+
AlterPolicyOperation, AlterSchema, AlterSchemaOperation, AlterTable, AlterTableAlgorithm,
68+
AlterTableLock, AlterTableOperation, AlterTableType, AlterType, AlterTypeAddValue,
69+
AlterTypeAddValuePosition, AlterTypeOperation, AlterTypeRename, AlterTypeRenameValue,
70+
ClusteredBy, ColumnDef, ColumnOption, ColumnOptionDef, ColumnOptions, ColumnPolicy,
71+
ColumnPolicyProperty, ConstraintCharacteristics, CreateCollation, CreateCollationDefinition,
72+
CreateConnector, CreateDomain, CreateExtension, CreateFunction, CreateIndex, CreateOperator,
73+
CreateOperatorClass, CreateOperatorFamily, CreatePolicy, CreatePolicyCommand, CreatePolicyType,
74+
CreateTable, CreateTrigger, CreateView, Deduplicate, DeferrableInitial, DistStyle,
75+
DropBehavior, DropExtension, DropFunction, DropOperator, DropOperatorClass, DropOperatorFamily,
76+
DropOperatorSignature, DropPolicy, DropTrigger, ForValues, FunctionReturnType, GeneratedAs,
77+
GeneratedExpressionMode, IdentityParameters, IdentityProperty, IdentityPropertyFormatKind,
78+
IdentityPropertyKind, IdentityPropertyOrder, IndexColumn, IndexOption, IndexType,
79+
KeyOrIndexDisplay, Msck, NullsDistinctOption, OperatorArgTypes, OperatorClassItem,
80+
OperatorFamilyDropItem, OperatorFamilyItem, OperatorOption, OperatorPurpose, Owner, Partition,
81+
PartitionBoundValue, ProcedureParam, ReferentialAction, RenameTableNameKind, ReplicaIdentity,
82+
TagsColumnOption, TriggerObjectKind, Truncate, UserDefinedTypeCompositeAttributeDef,
83+
UserDefinedTypeInternalLength, UserDefinedTypeRangeOption, UserDefinedTypeRepresentation,
84+
UserDefinedTypeSqlDefinitionOption, UserDefinedTypeStorage, ViewColumnDef,
8685
};
8786
pub use self::dml::{
8887
Delete, Insert, Merge, MergeAction, MergeClause, MergeClauseKind, MergeInsertExpr,

tests/sqlparser_common.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15294,6 +15294,7 @@ fn parse_comments() {
1529415294

1529515295
// https://www.postgresql.org/docs/current/sql-comment.html
1529615296
let object_types = [
15297+
("COLLATION", CommentObject::Collation),
1529715298
("COLUMN", CommentObject::Column),
1529815299
("DATABASE", CommentObject::Database),
1529915300
("DOMAIN", CommentObject::Domain),

tests/sqlparser_postgres.rs

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,171 @@ fn parse_drop_extension() {
850850
);
851851
}
852852

853+
#[test]
854+
fn parse_create_collation() {
855+
assert_eq!(
856+
pg_and_generic()
857+
.verified_stmt("CREATE COLLATION test3 (provider = icu, lc_collate = 'en_US.utf8')",),
858+
Statement::CreateCollation(CreateCollation {
859+
if_not_exists: false,
860+
name: ObjectName::from(vec![Ident::new("test3")]),
861+
definition: CreateCollationDefinition::Options(vec![
862+
SqlOption::KeyValue {
863+
key: Ident::new("provider"),
864+
value: Expr::Identifier(Ident::new("icu")),
865+
},
866+
SqlOption::KeyValue {
867+
key: Ident::new("lc_collate"),
868+
value: Expr::Value(
869+
Value::SingleQuotedString("en_US.utf8".to_string()).with_empty_span(),
870+
),
871+
},
872+
]),
873+
})
874+
);
875+
876+
assert_eq!(
877+
pg_and_generic().verified_stmt("CREATE COLLATION test4 FROM nonsense"),
878+
Statement::CreateCollation(CreateCollation {
879+
if_not_exists: false,
880+
name: ObjectName::from(vec![Ident::new("test4")]),
881+
definition: CreateCollationDefinition::From(ObjectName::from(vec![Ident::new(
882+
"nonsense",
883+
)])),
884+
})
885+
);
886+
887+
assert_eq!(
888+
pg_and_generic()
889+
.verified_stmt("CREATE COLLATION testx (provider = icu, locale = 'nonsense-nowhere')"),
890+
Statement::CreateCollation(CreateCollation {
891+
if_not_exists: false,
892+
name: ObjectName::from(vec![Ident::new("testx")]),
893+
definition: CreateCollationDefinition::Options(vec![
894+
SqlOption::KeyValue {
895+
key: Ident::new("provider"),
896+
value: Expr::Identifier(Ident::new("icu")),
897+
},
898+
SqlOption::KeyValue {
899+
key: Ident::new("locale"),
900+
value: Expr::Value(
901+
Value::SingleQuotedString("nonsense-nowhere".to_string()).with_empty_span(),
902+
),
903+
},
904+
]),
905+
})
906+
);
907+
}
908+
909+
#[test]
910+
fn parse_alter_collation() {
911+
assert_eq!(
912+
pg_and_generic().verified_stmt("ALTER COLLATION test1 RENAME TO test11"),
913+
Statement::AlterCollation(AlterCollation {
914+
name: ObjectName::from(vec![Ident::new("test1")]),
915+
operation: AlterCollationOperation::RenameTo {
916+
new_name: Ident::new("test11"),
917+
},
918+
})
919+
);
920+
921+
assert_eq!(
922+
pg_and_generic().verified_stmt("ALTER COLLATION test11 OWNER TO regress_test_role"),
923+
Statement::AlterCollation(AlterCollation {
924+
name: ObjectName::from(vec![Ident::new("test11")]),
925+
operation: AlterCollationOperation::OwnerTo(Owner::Ident(Ident::new(
926+
"regress_test_role",
927+
))),
928+
})
929+
);
930+
931+
assert_eq!(
932+
pg_and_generic().verified_stmt("ALTER COLLATION test11 SET SCHEMA test_schema"),
933+
Statement::AlterCollation(AlterCollation {
934+
name: ObjectName::from(vec![Ident::new("test11")]),
935+
operation: AlterCollationOperation::SetSchema {
936+
schema_name: ObjectName::from(vec![Ident::new("test_schema")]),
937+
},
938+
})
939+
);
940+
941+
assert_eq!(
942+
pg_and_generic().verified_stmt("ALTER COLLATION \"en-x-icu\" REFRESH VERSION"),
943+
Statement::AlterCollation(AlterCollation {
944+
name: ObjectName::from(vec![Ident::with_quote('"', "en-x-icu")]),
945+
operation: AlterCollationOperation::RefreshVersion,
946+
})
947+
);
948+
}
949+
950+
#[test]
951+
fn parse_drop_and_comment_collation_ast() {
952+
assert_eq!(
953+
pg_and_generic().verified_stmt("DROP COLLATION test0"),
954+
Statement::Drop {
955+
object_type: ObjectType::Collation,
956+
if_exists: false,
957+
names: vec![ObjectName::from(vec![Ident::new("test0")])],
958+
cascade: false,
959+
restrict: false,
960+
purge: false,
961+
temporary: false,
962+
table: None,
963+
}
964+
);
965+
966+
assert_eq!(
967+
pg_and_generic().verified_stmt("DROP COLLATION IF EXISTS test0"),
968+
Statement::Drop {
969+
object_type: ObjectType::Collation,
970+
if_exists: true,
971+
names: vec![ObjectName::from(vec![Ident::new("test0")])],
972+
cascade: false,
973+
restrict: false,
974+
purge: false,
975+
temporary: false,
976+
table: None,
977+
}
978+
);
979+
980+
assert_eq!(
981+
pg_and_generic().verified_stmt("COMMENT ON COLLATION test0 IS 'US English'"),
982+
Statement::Comment {
983+
object_type: CommentObject::Collation,
984+
object_name: ObjectName::from(vec![Ident::new("test0")]),
985+
comment: Some("US English".to_string()),
986+
if_exists: false,
987+
}
988+
);
989+
}
990+
991+
#[test]
992+
fn parse_collation_statements_roundtrip() {
993+
let statements = [
994+
"CREATE COLLATION test3 (provider = icu, lc_collate = 'en_US.utf8')",
995+
"CREATE COLLATION testx (provider = icu, locale = 'nonsense-nowhere')",
996+
"CREATE COLLATION testx (provider = icu, locale = '@colStrength=primary;nonsense=yes')",
997+
"DROP COLLATION testx",
998+
"CREATE COLLATION test4 FROM nonsense",
999+
"CREATE COLLATION test5 FROM test0",
1000+
"ALTER COLLATION test1 RENAME TO test11",
1001+
"ALTER COLLATION test0 RENAME TO test11",
1002+
"ALTER COLLATION test1 RENAME TO test22",
1003+
"ALTER COLLATION test11 OWNER TO regress_test_role",
1004+
"ALTER COLLATION test11 OWNER TO nonsense",
1005+
"ALTER COLLATION test11 SET SCHEMA test_schema",
1006+
"COMMENT ON COLLATION test0 IS 'US English'",
1007+
"DROP COLLATION test0, test_schema.test11, test5",
1008+
"DROP COLLATION test0",
1009+
"DROP COLLATION IF EXISTS test0",
1010+
"ALTER COLLATION \"en-x-icu\" REFRESH VERSION",
1011+
];
1012+
1013+
for sql in statements {
1014+
pg_and_generic().verified_stmt(sql);
1015+
}
1016+
}
1017+
8531018
#[test]
8541019
fn parse_alter_table_alter_column() {
8551020
pg().verified_stmt("ALTER TABLE tab ALTER COLUMN is_active TYPE TEXT USING 'text'");

0 commit comments

Comments
 (0)