diff --git a/src/backend/index_builder.rs b/src/backend/index_builder.rs index 1bcce8c2c..9217638db 100644 --- a/src/backend/index_builder.rs +++ b/src/backend/index_builder.rs @@ -16,6 +16,8 @@ pub trait IndexBuilder: QuotedBuilder + TableRefBuilder { self.prepare_index_prefix(create, sql); self.prepare_index_columns(&create.index.columns, sql); + + self.prepare_filter(&create.r#where, sql); } /// Translate [`IndexCreateStatement`] into SQL statement. @@ -67,4 +69,8 @@ pub trait IndexBuilder: QuotedBuilder + TableRefBuilder { }); write!(sql, ")").unwrap(); } + + #[doc(hidden)] + // Write WHERE clause for partial index. This function is not available in MySQL. + fn prepare_filter(&self, _condition: &ConditionHolder, _sql: &mut dyn SqlWriter) {} } diff --git a/src/backend/postgres/index.rs b/src/backend/postgres/index.rs index 5eb33aa40..b10c17b2b 100644 --- a/src/backend/postgres/index.rs +++ b/src/backend/postgres/index.rs @@ -26,6 +26,7 @@ impl IndexBuilder for PostgresQueryBuilder { self.prepare_index_type(&create.index_type, sql); write!(sql, " ").unwrap(); self.prepare_index_columns(&create.index.columns, sql); + self.prepare_filter(&create.r#where, sql); } fn prepare_table_ref_index_stmt(&self, table_ref: &TableRef, sql: &mut dyn SqlWriter) { @@ -78,4 +79,8 @@ impl IndexBuilder for PostgresQueryBuilder { write!(sql, "UNIQUE ").unwrap(); } } + + fn prepare_filter(&self, condition: &ConditionHolder, sql: &mut dyn SqlWriter) { + self.prepare_condition(condition, "WHERE", sql); + } } diff --git a/src/backend/sqlite/index.rs b/src/backend/sqlite/index.rs index 1a29ebca0..a7b241aa4 100644 --- a/src/backend/sqlite/index.rs +++ b/src/backend/sqlite/index.rs @@ -25,6 +25,7 @@ impl IndexBuilder for SqliteQueryBuilder { write!(sql, " ").unwrap(); self.prepare_index_columns(&create.index.columns, sql); + self.prepare_filter(&create.r#where, sql); } fn prepare_table_ref_index_stmt(&self, table_ref: &TableRef, sql: &mut dyn SqlWriter) { @@ -51,4 +52,8 @@ impl IndexBuilder for SqliteQueryBuilder { } fn write_column_index_prefix(&self, _col_prefix: &Option, _sql: &mut dyn SqlWriter) {} + + fn prepare_filter(&self, condition: &ConditionHolder, sql: &mut dyn SqlWriter) { + self.prepare_condition(condition, "WHERE", sql); + } } diff --git a/src/index/create.rs b/src/index/create.rs index 7db1a9321..08bccff15 100644 --- a/src/index/create.rs +++ b/src/index/create.rs @@ -1,5 +1,7 @@ use super::common::*; +use crate::query::IntoCondition; use crate::{backend::SchemaBuilder, types::*, SchemaStatementBuilder}; +use crate::{ConditionHolder, ConditionalStatement}; /// Create an index for an existing table /// @@ -120,6 +122,27 @@ use crate::{backend::SchemaBuilder, types::*, SchemaStatementBuilder}; /// r#"CREATE INDEX "idx-glyph-aspect" ON "glyph" ("aspect" ASC)"# /// ); /// ``` +/// +/// Partial Index with prefix and order +/// ``` +/// use sea_query::{tests_cfg::*, *}; +/// +/// let index = Index::create() +/// .name("idx-glyph-aspect") +/// .table(Glyph::Table) +/// .col((Glyph::Aspect, 64, IndexOrder::Asc)) +/// .and_where(Expr::tbl(Glyph::Table, Glyph::Aspect).is_in(vec![3, 4])) +/// .to_owned(); +/// +/// assert_eq!( +/// index.to_string(PostgresQueryBuilder), +/// r#"CREATE INDEX "idx-glyph-aspect" ON "glyph" ("aspect" (64) ASC) WHERE "glyph"."aspect" IN (3, 4)"# +/// ); +/// assert_eq!( +/// index.to_string(SqliteQueryBuilder), +/// r#"CREATE INDEX "idx-glyph-aspect" ON "glyph" ("aspect" ASC) WHERE "glyph"."aspect" IN (3, 4)"# +/// ); +/// ``` #[derive(Debug, Clone)] pub struct IndexCreateStatement { pub(crate) table: Option, @@ -128,6 +151,7 @@ pub struct IndexCreateStatement { pub(crate) unique: bool, pub(crate) index_type: Option, pub(crate) if_not_exists: bool, + pub(crate) r#where: ConditionHolder, } /// Specification of a table index @@ -155,6 +179,7 @@ impl IndexCreateStatement { unique: false, index_type: None, if_not_exists: false, + r#where: ConditionHolder::new(), } } @@ -233,6 +258,7 @@ impl IndexCreateStatement { unique: self.unique, index_type: self.index_type.take(), if_not_exists: self.if_not_exists, + r#where: self.r#where.clone(), } } } @@ -250,3 +276,18 @@ impl SchemaStatementBuilder for IndexCreateStatement { sql } } + +impl ConditionalStatement for IndexCreateStatement { + fn and_or_where(&mut self, condition: LogicalChainOper) -> &mut Self { + self.r#where.add_and_or(condition); + self + } + + fn cond_where(&mut self, condition: C) -> &mut Self + where + C: IntoCondition, + { + self.r#where.add_condition(condition.into_condition()); + self + } +} diff --git a/src/query/shim.rs b/src/query/shim.rs index f9d21ead9..c4b0309b6 100644 --- a/src/query/shim.rs +++ b/src/query/shim.rs @@ -12,3 +12,4 @@ impl_ordered_statement!(delete_statement_ordered, DeleteStatement); impl_conditional_statement!(select_statement_conditional, SelectStatement); impl_conditional_statement!(update_statement_conditional, UpdateStatement); impl_conditional_statement!(delete_statement_conditional, DeleteStatement); +impl_conditional_statement!(index_create_conditional, IndexCreateStatement);