From d4863ca9dc52623efc18f3d96923e58ff7aa202f Mon Sep 17 00:00:00 2001 From: daniel Date: Wed, 30 Jul 2025 10:43:07 -0400 Subject: [PATCH] feat(index columns): operator classes (#2) --- src/backend/postgres/index.rs | 3 +++ src/index/common.rs | 30 ++++++++++++++++++++++++++++++ tests/postgres/index.rs | 21 +++++++++++++++++---- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/src/backend/postgres/index.rs b/src/backend/postgres/index.rs index 020e2a070..193d8ca4a 100644 --- a/src/backend/postgres/index.rs +++ b/src/backend/postgres/index.rs @@ -162,6 +162,9 @@ impl IndexBuilder for PostgresQueryBuilder { } } } + if let Some(operator_class) = col.operator_class() { + write!(sql, " {}", operator_class.to_string()).unwrap(); + } false }); write!(sql, ")").unwrap(); diff --git a/src/index/common.rs b/src/index/common.rs index 4a76e3018..31e11c887 100644 --- a/src/index/common.rs +++ b/src/index/common.rs @@ -20,12 +20,14 @@ pub struct IndexColumnTableColumn { pub(crate) name: DynIden, pub(crate) prefix: Option, pub(crate) order: Option, + pub(crate) operator_class: Option, } #[derive(Debug, Clone)] pub struct IndexColumnExpr { pub(crate) expr: Expr, pub(crate) order: Option, + pub(crate) operator_class: Option, } impl IndexColumn { @@ -35,6 +37,26 @@ impl IndexColumn { IndexColumn::Expr(_) => None, } } + + pub(crate) fn operator_class(&self) -> &Option { + match self { + IndexColumn::TableColumn(IndexColumnTableColumn { operator_class, .. }) => operator_class, + IndexColumn::Expr(IndexColumnExpr { operator_class, .. }) => operator_class, + } + } + + /// Set index operator class. Only available on Postgres. + pub fn with_operator_class(mut self, operator_class: I) -> Self { + match self { + IndexColumn::TableColumn(ref mut index_column_table_column) => { + index_column_table_column.operator_class = Some(operator_class.into_iden()); + }, + IndexColumn::Expr(ref mut index_column_expr) => { + index_column_expr.operator_class = Some(operator_class.into_iden()) + }, + }; + self + } } #[derive(Debug, Clone)] @@ -63,6 +85,7 @@ where name: self.into_iden(), prefix: None, order: None, + operator_class: None, }) } } @@ -76,6 +99,7 @@ where name: self.0.into_iden(), prefix: Some(self.1), order: None, + operator_class: None, }) } } @@ -89,6 +113,7 @@ where name: self.0.into_iden(), prefix: None, order: Some(self.1), + operator_class: None, }) } } @@ -102,6 +127,7 @@ where name: self.0.into_iden(), prefix: Some(self.1), order: Some(self.2), + operator_class: None, }) } } @@ -111,6 +137,7 @@ impl IntoIndexColumn for FunctionCall { IndexColumn::Expr(IndexColumnExpr { expr: self.into(), order: None, + operator_class: None, }) } } @@ -120,6 +147,7 @@ impl IntoIndexColumn for (FunctionCall, IndexOrder) { IndexColumn::Expr(IndexColumnExpr { expr: self.0.into(), order: Some(self.1), + operator_class: None, }) } } @@ -129,6 +157,7 @@ impl IntoIndexColumn for Expr { IndexColumn::Expr(IndexColumnExpr { expr: self, order: None, + operator_class: None, }) } } @@ -138,6 +167,7 @@ impl IntoIndexColumn for (Expr, IndexOrder) { IndexColumn::Expr(IndexColumnExpr { expr: self.0, order: Some(self.1), + operator_class: None, }) } } diff --git a/tests/postgres/index.rs b/tests/postgres/index.rs index bb75a26ee..5f1dcdb37 100644 --- a/tests/postgres/index.rs +++ b/tests/postgres/index.rs @@ -70,6 +70,19 @@ fn create_5() { #[test] fn create_6() { + assert_eq!( + Index::create() + .if_not_exists() + .name("idx-glyph-image") + .table(Glyph::Table) + .col(Glyph::Image.into_index_column().with_operator_class("text_pattern_ops")) + .to_string(PostgresQueryBuilder), + r#"CREATE INDEX IF NOT EXISTS "idx-glyph-image" ON "glyph" ("image" text_pattern_ops)"# + ); +} + +#[test] +fn create_7() { assert_eq!( Index::create() .unique() @@ -84,7 +97,7 @@ fn create_6() { } #[test] -fn create_7() { +fn create_8() { assert_eq!( Index::create() .unique() @@ -99,7 +112,7 @@ fn create_7() { } #[test] -fn create_8() { +fn create_9() { assert_eq!( Index::create() .name("idx-font-name-include-id-language") @@ -115,7 +128,7 @@ fn create_8() { } #[test] -fn create_9() { +fn create_10() { assert_eq!( Index::create() .name("idx-character-area") @@ -127,7 +140,7 @@ fn create_9() { } #[test] -fn create_10() { +fn create_11() { assert_eq!( Index::create() .name("idx-character-character-area-desc-created_at")