Skip to content

Commit

Permalink
support partial index
Browse files Browse the repository at this point in the history
  • Loading branch information
kyoto7250 committed Oct 16, 2022
1 parent 9c2a6b2 commit 7f3dfef
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/backend/index_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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) {}
}
5 changes: 5 additions & 0 deletions src/backend/postgres/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
}
}
5 changes: 5 additions & 0 deletions src/backend/sqlite/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -51,4 +52,8 @@ impl IndexBuilder for SqliteQueryBuilder {
}

fn write_column_index_prefix(&self, _col_prefix: &Option<u32>, _sql: &mut dyn SqlWriter) {}

fn prepare_filter(&self, condition: &ConditionHolder, sql: &mut dyn SqlWriter) {
self.prepare_condition(condition, "WHERE", sql);
}
}
41 changes: 41 additions & 0 deletions src/index/create.rs
Original file line number Diff line number Diff line change
@@ -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
///
Expand Down Expand Up @@ -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<TableRef>,
Expand All @@ -128,6 +151,7 @@ pub struct IndexCreateStatement {
pub(crate) unique: bool,
pub(crate) index_type: Option<IndexType>,
pub(crate) if_not_exists: bool,
pub(crate) r#where: ConditionHolder,
}

/// Specification of a table index
Expand Down Expand Up @@ -155,6 +179,7 @@ impl IndexCreateStatement {
unique: false,
index_type: None,
if_not_exists: false,
r#where: ConditionHolder::new(),
}
}

Expand Down Expand Up @@ -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(),
}
}
}
Expand All @@ -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<C>(&mut self, condition: C) -> &mut Self
where
C: IntoCondition,
{
self.r#where.add_condition(condition.into_condition());
self
}
}
1 change: 1 addition & 0 deletions src/query/shim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

0 comments on commit 7f3dfef

Please sign in to comment.