This is an automated email from the ASF dual-hosted git repository. github-bot pushed a commit to branch gh-readonly-queue/main/pr-2131-9b8a2d1e226a024758a4dbbaaf47fafe67a9619d in repository https://gitbox.apache.org/repos/asf/datafusion-sqlparser-rs.git
commit cdeed32294609e31779c13b48bd19e505bf65ea8 Author: Denis Goncharenko <[email protected]> AuthorDate: Tue Dec 16 13:07:11 2025 +0100 PostgreSQL: Support schema-qualified operator classes in CREATE INDEX (#2131) --- src/ast/ddl.rs | 2 +- src/parser/mod.rs | 6 +++--- tests/sqlparser_postgres.rs | 44 ++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/ast/ddl.rs b/src/ast/ddl.rs index 8ccd533c..d0aed448 100644 --- a/src/ast/ddl.rs +++ b/src/ast/ddl.rs @@ -61,7 +61,7 @@ use crate::tokenizer::{Span, Token}; #[cfg_attr(feature = "visitor", derive(Visit, VisitMut))] pub struct IndexColumn { pub column: OrderByExpr, - pub operator_class: Option<Ident>, + pub operator_class: Option<ObjectName>, } impl From<Ident> for IndexColumn { diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 2b82d009..3ba4ba57 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -16933,10 +16933,10 @@ impl<'a> Parser<'a> { fn parse_order_by_expr_inner( &mut self, with_operator_class: bool, - ) -> Result<(OrderByExpr, Option<Ident>), ParserError> { + ) -> Result<(OrderByExpr, Option<ObjectName>), ParserError> { let expr = self.parse_expr()?; - let operator_class: Option<Ident> = if with_operator_class { + let operator_class: Option<ObjectName> = if with_operator_class { // We check that if non of the following keywords are present, then we parse an // identifier as operator class. if self @@ -16945,7 +16945,7 @@ impl<'a> Parser<'a> { { None } else { - self.maybe_parse(|parser| parser.parse_identifier())? + self.maybe_parse(|parser| parser.parse_object_name(false))? } } else { None diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs index 11512cf8..d595a0a2 100644 --- a/tests/sqlparser_postgres.rs +++ b/tests/sqlparser_postgres.rs @@ -2572,11 +2572,17 @@ fn parse_create_indices_with_operator_classes() { IndexType::SPGiST, IndexType::Custom("CustomIndexType".into()), ]; - let operator_classes: [Option<Ident>; 4] = [ + let operator_classes: [Option<ObjectName>; 4] = [ None, - Some("gin_trgm_ops".into()), - Some("gist_trgm_ops".into()), - Some("totally_not_valid".into()), + Some(ObjectName(vec![ObjectNamePart::Identifier(Ident::new( + "gin_trgm_ops", + ))])), + Some(ObjectName(vec![ObjectNamePart::Identifier(Ident::new( + "gist_trgm_ops", + ))])), + Some(ObjectName(vec![ObjectNamePart::Identifier(Ident::new( + "totally_not_valid", + ))])), ]; for expected_index_type in indices { @@ -2713,6 +2719,36 @@ fn parse_create_indices_with_operator_classes() { } } +#[test] +fn parse_create_index_with_schema_qualified_operator_class() { + let sql = "CREATE INDEX my_index ON my_table USING HNSW (embedding public.vector_cosine_ops)"; + + match pg().verified_stmt(sql) { + Statement::CreateIndex(CreateIndex { columns, .. }) => { + assert_eq!(1, columns.len()); + let idx_col = &columns[0]; + + // Verify the column name + match &idx_col.column.expr { + Expr::Identifier(ident) => { + assert_eq!("embedding", ident.value); + } + _ => panic!("Expected identifier expression"), + } + + // Verify the schema-qualified operator class + assert_eq!( + Some(ObjectName(vec![ + ObjectNamePart::Identifier(Ident::new("public")), + ObjectNamePart::Identifier(Ident::new("vector_cosine_ops")), + ])), + idx_col.operator_class + ); + } + _ => unreachable!(), + } +} + #[test] fn parse_create_bloom() { let sql = --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
