Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for NULLS NOT DISTINCT clause #532

Merged
merged 3 commits into from
Dec 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/backend/postgres/index.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,26 @@
use super::*;

impl IndexBuilder for PostgresQueryBuilder {
// Overriden due to different "NULLS NOT UNIQUE" position in table index expression
// (as opposed to the regular index expression)
fn prepare_table_index_expression(
&self,
create: &IndexCreateStatement,
sql: &mut dyn SqlWriter,
) {
if let Some(name) = &create.index.name {
write!(sql, "CONSTRAINT {}{}{} ", self.quote(), name, self.quote()).unwrap();
}

self.prepare_index_prefix(create, sql);

if create.nulls_not_distinct {
write!(sql, "NULLS NOT DISTINCT ").unwrap();
}

self.prepare_index_columns(&create.index.columns, sql);
}

fn prepare_index_create_statement(
&self,
create: &IndexCreateStatement,
Expand All @@ -26,6 +46,10 @@ impl IndexBuilder for PostgresQueryBuilder {
self.prepare_index_type(&create.index_type, sql);
write!(sql, " ").unwrap();
self.prepare_index_columns(&create.index.columns, sql);

if create.nulls_not_distinct {
write!(sql, " NULLS NOT DISTINCT").unwrap();
}
}

fn prepare_table_ref_index_stmt(&self, table_ref: &TableRef, sql: &mut dyn SqlWriter) {
Expand Down
12 changes: 12 additions & 0 deletions src/index/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ pub struct IndexCreateStatement {
pub(crate) index: TableIndex,
pub(crate) primary: bool,
pub(crate) unique: bool,
pub(crate) nulls_not_distinct: bool,
pub(crate) index_type: Option<IndexType>,
pub(crate) if_not_exists: bool,
}
Expand Down Expand Up @@ -187,6 +188,12 @@ impl IndexCreateStatement {
self
}

/// Set nulls to not be treated as distinct values. Only available on Postgres.
pub fn nulls_not_distinct(&mut self) -> &mut Self {
self.nulls_not_distinct = true;
self
}

/// Set index as full text.
/// On MySQL, this is `FULLTEXT`.
/// On PgSQL, this is `GIN`.
Expand All @@ -208,6 +215,10 @@ impl IndexCreateStatement {
self.unique
}

pub fn is_nulls_not_distinct(&self) -> bool {
rstular marked this conversation as resolved.
Show resolved Hide resolved
self.nulls_not_distinct
}

pub fn get_index_spec(&self) -> &TableIndex {
&self.index
}
Expand All @@ -218,6 +229,7 @@ impl IndexCreateStatement {
index: self.index.take(),
primary: self.primary,
unique: self.unique,
nulls_not_distinct: self.nulls_not_distinct,
index_type: self.index_type.take(),
if_not_exists: self.if_not_exists,
}
Expand Down
15 changes: 15 additions & 0 deletions tests/postgres/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,21 @@ fn create_5() {
);
}

#[test]
fn create_6() {
assert_eq!(
Index::create()
.unique()
.nulls_not_distinct()
.name("idx-glyph-aspect-image")
.table(Glyph::Table)
.col(Glyph::Aspect)
.col(Glyph::Image)
.to_string(PostgresQueryBuilder),
r#"CREATE UNIQUE INDEX "idx-glyph-aspect-image" ON "glyph" ("aspect", "image") NULLS NOT DISTINCT"#
);
}

#[test]
fn drop_1() {
assert_eq!(
Expand Down
28 changes: 28 additions & 0 deletions tests/postgres/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,34 @@ fn create_14() {
);
}

#[test]
fn create_15() {
assert_eq!(
Table::create()
.table(Glyph::Table)
.col(ColumnDef::new(Glyph::Image).json())
.col(ColumnDef::new(Glyph::Aspect).json_binary())
.index(
Index::create()
.unique()
.nulls_not_distinct()
.name("idx-glyph-aspect-image")
.table(Glyph::Table)
.col(Glyph::Aspect)
.col(Glyph::Image)
)
.to_string(PostgresQueryBuilder),
[
r#"CREATE TABLE "glyph" ("#,
r#""image" json,"#,
r#""aspect" jsonb,"#,
r#"CONSTRAINT "idx-glyph-aspect-image" UNIQUE NULLS NOT DISTINCT ("aspect", "image")"#,
r#")"#,
]
.join(" ")
);
}

#[test]
fn drop_1() {
assert_eq!(
Expand Down