Skip to content

Commit ee234f1

Browse files
kyoto7250tyt2y3
andauthored
support partial index (#478)
* support partial index * add tests for partial index * update examples for partial index * import once in src/index/create.rs * fix an output in examples/postgres/Readme.md * cargo fmt for examples * use bigdecimal:0.4.5 --------- Co-authored-by: Chris Tsang <[email protected]>
1 parent 9c1318f commit ee234f1

File tree

15 files changed

+162
-10
lines changed

15 files changed

+162
-10
lines changed

examples/diesel_postgres/Readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# SeaQuery Diesel Postgres example
22

33
> WARN: If you enable `with-bigdecimal`, you HAVE to update the version used by default by `diesel`
4-
> otherwise it will fail to build. Use `cargo update -p bigdecimal:0.4.2 --precise 0.3.1`.
4+
> otherwise it will fail to build. Use `cargo update -p bigdecimal:0.4.5 --precise 0.3.1`.
55
66
Running:
77

examples/diesel_sqlite/src/main.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ use diesel::deserialize::{self, FromSql};
55
use diesel::sql_types::BigInt;
66
use diesel::sql_types::{Blob, Text};
77
use diesel::{Connection, QueryableByName, RunQueryDsl, SqliteConnection};
8-
use sea_query::{Alias, ColumnDef, Expr, Func, Iden, Order, Query, SqliteQueryBuilder, Table};
8+
use sea_query::{
9+
Alias, ColumnDef, ConditionalStatement, Expr, Func, Iden, Index, Order, Query,
10+
SqliteQueryBuilder, Table,
11+
};
912
use sea_query_diesel::DieselBinder;
1013
use serde_json::json;
1114
use time::macros::{date, time};
@@ -40,6 +43,13 @@ fn main() {
4043
.col(ColumnDef::new(Character::Meta).json().not_null())
4144
.col(ColumnDef::new(Character::Created).date_time())
4245
.build(SqliteQueryBuilder),
46+
Index::create()
47+
.name("partial_index_small_font")
48+
.if_not_exists()
49+
.table(Character::Table)
50+
.col(Character::FontSize)
51+
.and_where(Expr::col(Character::FontSize).lt(11).not())
52+
.build(SqliteQueryBuilder),
4353
]
4454
.join("; ");
4555

examples/postgres/Readme.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ cargo run
77

88
Example output:
99
```
10-
DROP TABLE IF EXISTS "document"; CREATE TABLE IF NOT EXISTS "document" ( "id" serial NOT NULL PRIMARY KEY, "json_field" jsonb, "timestamp" timestamp )
11-
Create table document: ()
10+
DROP TABLE IF EXISTS "document"; CREATE TABLE IF NOT EXISTS "document" ( "id" serial NOT NULL PRIMARY KEY, "uuid" uuid, "json_field" jsonb, "timestamp" timestamp, "timestamp_with_time_zone" timestamp with time zone, "decimal" decimal, "array" integer[] ); CREATE INDEX "partial_index_small_decimal" ON "document" ("decimal") WHERE NOT "decimal" < 11
11+
Create table document: Ok(())
1212
1313
Insert into document: Ok(1)
1414

examples/postgres/src/main.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ use chrono::{DateTime, FixedOffset, NaiveDate, NaiveDateTime};
22

33
use postgres::{Client, NoTls, Row};
44
use rust_decimal::Decimal;
5-
use sea_query::{ColumnDef, ColumnType, Iden, Order, PostgresQueryBuilder, Query, Table};
5+
use sea_query::{
6+
ColumnDef, ColumnType, ConditionalStatement, Expr, Iden, Index, Order, PostgresQueryBuilder,
7+
Query, Table,
8+
};
69
use sea_query_postgres::PostgresBinder;
710
use time::{
811
macros::{date, offset, time},
@@ -37,6 +40,12 @@ fn main() {
3740
.col(ColumnDef::new(Document::Decimal).decimal())
3841
.col(ColumnDef::new(Document::Array).array(ColumnType::Integer))
3942
.build(PostgresQueryBuilder),
43+
Index::create()
44+
.name("partial_index_small_decimal")
45+
.table(Document::Table)
46+
.col(Document::Decimal)
47+
.and_where(Expr::col(Document::Decimal).lt(11).not())
48+
.build(PostgresQueryBuilder),
4049
]
4150
.join("; ");
4251

examples/rusqlite/src/main.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use chrono::{NaiveDate, NaiveDateTime};
22
use rusqlite::{Connection, Result, Row};
3-
use sea_query::{ColumnDef, Expr, Func, Iden, Order, Query, SqliteQueryBuilder, Table};
4-
3+
use sea_query::{
4+
ColumnDef, ConditionalStatement, Expr, Func, Iden, Index, Order, Query, SqliteQueryBuilder,
5+
Table,
6+
};
57
use sea_query_rusqlite::RusqliteBinder;
68
use serde_json::{json, Value as Json};
79
use time::{
@@ -37,6 +39,12 @@ fn main() -> Result<()> {
3739
.col(ColumnDef::new(Character::Meta).json())
3840
.col(ColumnDef::new(Character::Created).date_time())
3941
.build(SqliteQueryBuilder),
42+
Index::create()
43+
.name("partial_index_small_font")
44+
.table(Character::Table)
45+
.col(Character::FontSize)
46+
.and_where(Expr::col(Character::FontSize).lt(11).not())
47+
.build(SqliteQueryBuilder),
4048
]
4149
.join("; ");
4250

examples/sqlx_postgres/Readme.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ Example output:
99
```
1010
Create table character: Ok(PgQueryResult { rows_affected: 0 })
1111
12+
Create partial index: Ok(PgQueryResult { rows_affected: 0 })
13+
1214
Insert into character: Ok(PgQueryResult { rows_affected: 1 })
1315
1416
Select one from character:

examples/sqlx_postgres/src/main.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ use bigdecimal::{BigDecimal, FromPrimitive};
22
use chrono::{NaiveDate, NaiveDateTime};
33
use rust_decimal::Decimal;
44
use sea_query::{
5-
ColumnDef, Expr, Func, Iden, OnConflict, Order, PostgresQueryBuilder, Query, Table,
5+
ColumnDef, ConditionalStatement, Expr, Func, Iden, Index, OnConflict, Order,
6+
PostgresQueryBuilder, Query, Table,
67
};
78
use sea_query_binder::SqlxBinder;
89
use sqlx::{PgPool, Row};
@@ -50,6 +51,18 @@ async fn main() {
5051
let result = sqlx::query(&sql).execute(&mut *pool).await;
5152
println!("Create table character: {result:?}\n");
5253

54+
// Partial Index
55+
let partial_index = Index::create()
56+
.if_not_exists()
57+
.name("partial_index_small_font")
58+
.table(Character::Table)
59+
.col(Character::FontSize)
60+
.and_where(Expr::col(Character::FontSize).lt(11).not())
61+
.build(PostgresQueryBuilder);
62+
63+
let index = sqlx::query(&partial_index).execute(&mut *pool).await;
64+
println!("Create partial index: {index:?}\n");
65+
5366
// Create
5467

5568
let (sql, values) = Query::insert()

examples/sqlx_sqlite/Readme.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ Example output:
99
```
1010
Create table character: Ok(SqliteQueryResult { changes: 0, last_insert_rowid: 0 })
1111
12+
Create partial index: Ok(SqliteQueryResult { changes: 0, last_insert_rowid: 0 })
13+
1214
Insert into character: last_insert_id = 1
1315
1416
Select one from character:

examples/sqlx_sqlite/src/main.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
use chrono::{NaiveDate, NaiveDateTime};
2-
use sea_query::{ColumnDef, Expr, Func, Iden, OnConflict, Order, Query, SqliteQueryBuilder, Table};
2+
use sea_query::{
3+
ColumnDef, ConditionalStatement, Expr, Func, Iden, Index, OnConflict, Order, Query,
4+
SqliteQueryBuilder, Table,
5+
};
36
use sea_query_binder::SqlxBinder;
47
use serde_json::{json, Value as Json};
58
use sqlx::{Row, SqlitePool};
@@ -34,6 +37,17 @@ async fn main() {
3437
let result = sqlx::query(&sql).execute(&pool).await;
3538
println!("Create table character: {result:?}\n");
3639

40+
// Partial Index
41+
let partial_index = Index::create()
42+
.name("partial_index_small_font")
43+
.table(Character::Table)
44+
.col(Character::FontSize)
45+
.and_where(Expr::col(Character::FontSize).lt(11).not())
46+
.build(SqliteQueryBuilder);
47+
48+
let index = sqlx::query(&partial_index).execute(&pool).await;
49+
println!("Create partial index: {index:?}\n");
50+
3751
// Create
3852
let (sql, values) = Query::insert()
3953
.into_table(Character::Table)

src/backend/index_builder.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ pub trait IndexBuilder: QuotedBuilder + TableRefBuilder {
2323
self.prepare_index_prefix(create, sql);
2424

2525
self.prepare_index_columns(&create.index.columns, sql);
26+
27+
self.prepare_filter(&create.r#where, sql);
2628
}
2729

2830
/// Translate [`IndexCreateStatement`] into SQL statement.
@@ -74,4 +76,8 @@ pub trait IndexBuilder: QuotedBuilder + TableRefBuilder {
7476
});
7577
write!(sql, ")").unwrap();
7678
}
79+
80+
#[doc(hidden)]
81+
// Write WHERE clause for partial index. This function is not available in MySQL.
82+
fn prepare_filter(&self, _condition: &ConditionHolder, _sql: &mut dyn SqlWriter) {}
7783
}

0 commit comments

Comments
 (0)