Skip to content

Commit b67624a

Browse files
viromesgrif
authored andcommitted
Impl sqlord for array (diesel-rs#1449)
* Add DropTable struct for ensured cleanup of one-off tables * Impl SqlOrd for Array<T: SqlOrd>
1 parent a34055c commit b67624a

4 files changed

Lines changed: 72 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ for Rust libraries in [RFC #1105](https://github.com/rust-lang/rfcs/blob/master/
2727
* Added support for SQLite's `INSERT OR IGNORE` and MySQL's `INSERT IGNORE`
2828
via the `insert_or_ignore` function.
2929

30+
* Trait `SqlOrd` is now implemented for `Array`, meaning min/max functions can be used
31+
on Array columns (PostgreSQL only).
32+
3033
### Deprecated
3134

3235
* Deprecated `impl_query_id!` in favor of `#[derive(QueryId)]`

diesel/src/types/ord.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,5 @@ impl SqlOrd for types::Interval {}
1414
impl SqlOrd for types::Time {}
1515
impl SqlOrd for types::Timestamp {}
1616
impl<T: SqlOrd + NotNull> SqlOrd for types::Nullable<T> {}
17+
#[cfg(feature = "postgres")]
18+
impl<T: SqlOrd> SqlOrd for types::Array<T> {}

diesel_tests/tests/expressions/mod.rs

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
mod date_and_time;
22
mod ops;
33

4-
use schema::{connection, NewUser, TestBackend};
4+
use schema::{connection, DropTable, NewUser, TestBackend};
55
use schema::users::dsl::*;
66
use diesel::*;
77
use diesel::backend::Backend;
@@ -67,6 +67,58 @@ fn test_count_max() {
6767
assert_eq!(Ok(None::<i32>), source.first(&connection));
6868
}
6969

70+
#[cfg(feature = "postgres")]
71+
table! {
72+
number_arrays (na) {
73+
na -> Array<Integer>,
74+
}
75+
}
76+
77+
#[test]
78+
#[cfg(feature = "postgres")]
79+
fn test_min_max_of_array() {
80+
use self::number_arrays::dsl::*;
81+
82+
let connection = connection();
83+
connection
84+
.execute("CREATE TABLE number_arrays ( na INTEGER[] PRIMARY KEY )")
85+
.unwrap();
86+
let _bomb = DropTable {
87+
connection: &connection,
88+
table_name: "number_arrays",
89+
};
90+
91+
insert_into(number_arrays)
92+
.values(&vec![
93+
na.eq(vec![1, 1, 100]),
94+
na.eq(vec![1, 5, 5]),
95+
na.eq(vec![5, 0]),
96+
])
97+
.execute(&connection)
98+
.unwrap();
99+
100+
let max_query = number_arrays.select(max(na));
101+
let min_query = number_arrays.select(min(na));
102+
assert_eq!(Ok(Some(vec![5, 0])), max_query.first(&connection));
103+
assert_eq!(Ok(Some(vec![1, 1, 100])), min_query.first(&connection));
104+
105+
delete(number_arrays.filter(na.eq(vec![5, 0])))
106+
.execute(&connection)
107+
.unwrap();
108+
assert_eq!(Ok(Some(vec![1, 5, 5])), max_query.first(&connection));
109+
assert_eq!(Ok(Some(vec![1, 1, 100])), min_query.first(&connection));
110+
111+
delete(number_arrays.filter(na.eq(vec![1, 1, 100])))
112+
.execute(&connection)
113+
.unwrap();
114+
assert_eq!(Ok(Some(vec![1, 5, 5])), max_query.first(&connection));
115+
assert_eq!(Ok(Some(vec![1, 5, 5])), min_query.first(&connection));
116+
117+
delete(number_arrays).execute(&connection).unwrap();
118+
assert_eq!(Ok(None::<Vec<i32>>), max_query.first(&connection));
119+
assert_eq!(Ok(None::<Vec<i32>>), min_query.first(&connection));
120+
}
121+
70122
#[test]
71123
fn max_returns_same_type_as_expression_being_maximized() {
72124
let connection = connection();

diesel_tests/tests/schema.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,20 @@ pub type TestConnection = MysqlConnection;
165165

166166
pub type TestBackend = <TestConnection as Connection>::Backend;
167167

168+
//Used to ensure cleanup of one-off tables, e.g. for a table created for a single test
169+
pub struct DropTable<'a> {
170+
pub connection: &'a TestConnection,
171+
pub table_name: &'static str,
172+
}
173+
174+
impl<'a> Drop for DropTable<'a> {
175+
fn drop(&mut self) {
176+
self.connection
177+
.execute(&format!("DROP TABLE {}", self.table_name))
178+
.unwrap();
179+
}
180+
}
181+
168182
pub fn connection() -> TestConnection {
169183
let result = connection_without_transaction();
170184
#[cfg(feature = "sqlite")]

0 commit comments

Comments
 (0)