Skip to content

Commit d0eeadc

Browse files
committed
Make sure we only use RETURNING on backends that support it
SQLite does not support RETURNING clauses. To my knowledge it is the only backend that does not support it (though the syntax is different on SQL Server). Of course at the moment the only backend supported on master is PG, which *does* support it. However, this was an extraction from the SQLite branch that is able to live on its own. I've removed most uses of `get_result` and `get_results` in tests, except for one explicit test that returning clauses work (which is currently in a cfg attr which is always true, but won't be once SQLite is merged). There are still some places that it's being used which I need to track down, but right now I've got those modules set to only run on PG anyway, as they have other issues that require detangling from PG.
1 parent 8a33029 commit d0eeadc

9 files changed

Lines changed: 61 additions & 40 deletions

File tree

diesel/src/backend.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ pub trait TypeMetadata {
2626
type TypeMetadata;
2727
}
2828

29+
pub trait SupportsReturningClause {}
30+
2931
pub struct Debug;
3032

3133
impl Backend for Debug {
@@ -37,6 +39,8 @@ impl TypeMetadata for Debug {
3739
type TypeMetadata = ();
3840
}
3941

42+
impl SupportsReturningClause for Debug {}
43+
4044
pub struct Pg;
4145

4246
#[derive(Debug, Clone, Copy, Default)]
@@ -53,3 +57,5 @@ impl Backend for Pg {
5357
impl TypeMetadata for Pg {
5458
type TypeMetadata = PgTypeMetadata;
5559
}
60+
61+
impl SupportsReturningClause for Pg {}

diesel/src/query_builder/insert_statement.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use backend::Backend;
1+
use backend::{Backend, SupportsReturningClause};
22
use persistable::{Insertable, InsertableColumns};
33
use expression::Expression;
44
use query_builder::*;
@@ -83,7 +83,7 @@ impl<T, U> Query for InsertQuery<T, U> where
8383
}
8484

8585
impl<T, U, DB> QueryFragment<DB> for InsertQuery<T, U> where
86-
DB: Backend,
86+
DB: Backend + SupportsReturningClause,
8787
T: QueryFragment<DB>,
8888
U: QueryFragment<DB>,
8989
{

diesel/src/query_builder/update_statement/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ pub mod target;
44
pub use self::changeset::{Changeset, AsChangeset};
55
pub use self::target::UpdateTarget;
66

7-
use backend::Backend;
7+
use backend::{Backend, SupportsReturningClause};
88
use expression::Expression;
99
use query_builder::{Query, AsQuery, QueryFragment, QueryBuilder, BuildQueryResult, Context};
1010
use query_source::Table;
@@ -75,7 +75,7 @@ impl<T, U> AsQuery for UpdateStatement<T, U> where
7575
pub struct UpdateQuery<T, U>(UpdateStatement<T, U>);
7676

7777
impl<T, U, DB> QueryFragment<DB> for UpdateQuery<T, U> where
78-
DB: Backend,
78+
DB: Backend + SupportsReturningClause,
7979
T: UpdateTarget,
8080
<T::Table as Table>::AllColumns: QueryFragment<DB>,
8181
UpdateStatement<T, U>: QueryFragment<DB>,

diesel_codegen/src/update.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ fn save_changes_impl(
141141
$_pub fn save_changes<'update, T, Conn>(&'update self, connection: &Conn)
142142
-> ::diesel::QueryResult<T> where
143143
Conn::Backend: ::diesel::types::HasSqlType<$sql_type> +
144+
::diesel::backend::SupportsReturningClause +
144145
::diesel::types::HasSqlType<
145146
<<$table as ::diesel::query_source::Table>::PrimaryKey
146147
as ::diesel::expression::Expression>::SqlType>,

diesel_tests/tests/filter.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ fn filter_by_equality_on_nullable_columns() {
4141
NewUser::new("Tess", Some("brown")),
4242
NewUser::new("Jim", Some("black")),
4343
];
44-
let data: Vec<User> = insert(&data).into(users)
45-
.get_results(&connection).unwrap().collect();;
44+
insert(&data).into(users).execute(&connection).unwrap();
45+
let data = users.load(&connection).unwrap().collect::<Vec<User>>();
4646
let sean = data[0].clone();
4747
let tess = data[1].clone();
4848
let jim = data[2].clone();
@@ -62,8 +62,8 @@ fn filter_by_is_not_null_on_nullable_columns() {
6262
NewUser::new("Derek", Some("red")),
6363
NewUser::new("Gordon", None),
6464
];
65-
let data: Vec<User> = insert(&data).into(users)
66-
.get_results(&connection).unwrap().collect();
65+
insert(&data).into(users).execute(&connection).unwrap();
66+
let data = users.load(&connection).unwrap().collect::<Vec<User>>();
6767
let derek = data[0].clone();
6868

6969
let source = users.filter(hair_color.is_not_null());
@@ -79,8 +79,8 @@ fn filter_by_is_null_on_nullable_columns() {
7979
NewUser::new("Derek", Some("red")),
8080
NewUser::new("Gordon", None),
8181
];
82-
let data: Vec<User> = insert(&data).into(users)
83-
.get_results(&connection).unwrap().collect();
82+
insert(&data).into(users).execute(&connection).unwrap();
83+
let data = users.load(&connection).unwrap().collect::<Vec<User>>();
8484
let gordon = data[1].clone();
8585

8686
let source = users.filter(hair_color.is_null());
@@ -151,8 +151,8 @@ fn filter_on_multiple_columns() {
151151
NewUser::new("Tess", Some("black")),
152152
NewUser::new("Tess", Some("brown")),
153153
];
154-
let data: Vec<User> = insert(data).into(users)
155-
.get_results(&connection).unwrap().collect();
154+
insert(data).into(users).execute(&connection).unwrap();
155+
let data = users.load(&connection).unwrap().collect::<Vec<User>>();
156156
let black_haired_sean = data[0].clone();
157157
let brown_haired_sean = data[1].clone();
158158
let black_haired_tess = data[3].clone();
@@ -187,8 +187,8 @@ fn filter_called_twice_means_same_thing_as_and() {
187187
NewUser::new("Tess", Some("black")),
188188
NewUser::new("Tess", Some("brown")),
189189
];
190-
let data: Vec<User> = insert(data).into(users)
191-
.get_results(&connection).unwrap().collect();
190+
insert(data).into(users).execute(&connection).unwrap();
191+
let data = users.load(&connection).unwrap().collect::<Vec<User>>();
192192
let black_haired_sean = data[0].clone();
193193
let brown_haired_sean = data[1].clone();
194194
let black_haired_tess = data[3].clone();

diesel_tests/tests/filter_operators.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ fn filter_by_like() {
9191
NewUser::new("Tess Griffin", None),
9292
NewUser::new("Jim", None),
9393
];
94-
let data: Vec<User> = insert(&data).into(users)
95-
.get_results(&connection).unwrap().collect();;
94+
insert(&data).into(users).execute(&connection).unwrap();
95+
let data = users.load(&connection).unwrap().collect::<Vec<User>>();
9696
let sean = data[0].clone();
9797
let tess = data[1].clone();
9898
let jim = data[2].clone();

diesel_tests/tests/insert.rs

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,37 @@ use diesel::*;
55
fn insert_records() {
66
use schema::users::table as users;
77
let connection = connection();
8+
let new_users: &[_] = &[
9+
NewUser::new("Sean", Some("Black")),
10+
NewUser::new("Tess", None),
11+
];
12+
13+
insert(new_users).into(users).execute(&connection).unwrap();
14+
let actual_users = users.load(&connection).unwrap().collect::<Vec<User>>();
815

16+
let expected_users = vec![
17+
User { id: actual_users[0].id, name: "Sean".to_string(), hair_color: Some("Black".to_string()) },
18+
User { id: actual_users[1].id, name: "Tess".to_string(), hair_color: None },
19+
];
20+
assert_eq!(expected_users, actual_users);
21+
}
22+
23+
#[test]
24+
#[cfg(not(feature = "sqlite"))]
25+
fn insert_records_using_returning_clause() {
26+
use schema::users::table as users;
27+
let connection = connection();
928
let new_users: &[_] = &[
1029
NewUser::new("Sean", Some("Black")),
1130
NewUser::new("Tess", None),
1231
];
13-
let inserted_users: Vec<User> = insert(new_users).into(users).get_results(&connection).unwrap().collect();
1432

33+
let inserted_users: Vec<User> = insert(new_users).into(users).get_results(&connection).unwrap().collect();
1534
let expected_users = vec![
1635
User { id: inserted_users[0].id, name: "Sean".to_string(), hair_color: Some("Black".to_string()) },
1736
User { id: inserted_users[1].id, name: "Tess".to_string(), hair_color: None },
1837
];
19-
let actual_users: Vec<_> = users.load(&connection).unwrap().collect();
2038

21-
assert_eq!(expected_users, actual_users);
2239
assert_eq!(expected_users, inserted_users);
2340
}
2441

@@ -36,7 +53,7 @@ fn insert_with_defaults() {
3653
NewUser::new("Sean", Some("Black")),
3754
NewUser::new("Tess", None),
3855
];
39-
let inserted_users: Vec<_> = insert(new_users).into(users).get_results(&connection).unwrap().collect();
56+
insert(new_users).into(users).execute(&connection).unwrap();
4057

4158
let expected_users = vec![
4259
User { id: 1, name: "Sean".to_string(), hair_color: Some("Black".to_string()) },
@@ -45,7 +62,6 @@ fn insert_with_defaults() {
4562
let actual_users: Vec<_> = users.load(&connection).unwrap().collect();
4663

4764
assert_eq!(expected_users, actual_users);
48-
assert_eq!(expected_users, inserted_users);
4965
}
5066

5167
#[test]
@@ -62,7 +78,7 @@ fn insert_with_defaults_not_provided() {
6278
BaldUser { name: "Sean".to_string() },
6379
BaldUser { name: "Tess".to_string() },
6480
];
65-
let inserted_users: Vec<_> = insert(new_users).into(users).get_results(&connection).unwrap().collect();
81+
insert(new_users).into(users).execute(&connection).unwrap();
6682

6783
let expected_users = vec![
6884
User { id: 1, name: "Sean".to_string(), hair_color: Some("Green".to_string()) },
@@ -71,7 +87,6 @@ fn insert_with_defaults_not_provided() {
7187
let actual_users: Vec<_> = users.load(&connection).unwrap().collect();
7288

7389
assert_eq!(expected_users, actual_users);
74-
assert_eq!(expected_users, inserted_users);
7590
}
7691

7792
#[test]
@@ -113,17 +128,15 @@ fn insert_borrowed_content() {
113128
BorrowedUser { name: "Sean" },
114129
BorrowedUser { name: "Tess" },
115130
];
116-
let inserted_users: Vec<User> = insert(new_users).into(users).get_results(&connection)
117-
.unwrap().collect();
131+
insert(new_users).into(users).execute(&connection).unwrap();
118132

133+
let actual_users: Vec<User> = users.load(&connection).unwrap().collect();
119134
let expected_users = vec![
120-
User::new(inserted_users[0].id, "Sean"),
121-
User::new(inserted_users[1].id, "Tess"),
135+
User::new(actual_users[0].id, "Sean"),
136+
User::new(actual_users[1].id, "Tess"),
122137
];
123-
let actual_users: Vec<_> = users.load(&connection).unwrap().collect();
124138

125139
assert_eq!(expected_users, actual_users);
126-
assert_eq!(expected_users, inserted_users);
127140
}
128141

129142
#[test]

diesel_tests/tests/order.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ fn order_by_column() {
1111
NewUser::new("Tess", None),
1212
NewUser::new("Jim", None),
1313
];
14-
let data: Vec<User> =
15-
insert(&data).into(users).get_results(&conn).unwrap().collect();
14+
insert(&data).into(users).execute(&conn).unwrap();
15+
let data = users.load(&conn).unwrap().collect::<Vec<User>>();
1616
let sean = &data[0];
1717
let tess = &data[1];
1818
let jim = &data[2];
@@ -25,8 +25,9 @@ fn order_by_column() {
2525
let data: Vec<_> = users.order(name).load(&conn).unwrap().collect();
2626
assert_eq!(expected_data, data);
2727

28-
let aaron = insert(&NewUser::new("Aaron", None)).into(users)
29-
.get_result::<User>(&conn).unwrap();
28+
insert(&NewUser::new("Aaron", None)).into(users)
29+
.execute(&conn).unwrap();
30+
let aaron = users.order(id.desc()).first::<User>(&conn).unwrap();
3031
let expected_data = vec![
3132
User::new(aaron.id, "Aaron"),
3233
User::new(jim.id, "Jim"),
@@ -47,8 +48,8 @@ fn order_by_descending_column() {
4748
NewUser::new("Tess", None),
4849
NewUser::new("Jim", None),
4950
];
50-
let data: Vec<User> = insert(&data).into(users)
51-
.get_results(&conn).unwrap().collect();
51+
insert(&data).into(users).execute(&conn).unwrap();
52+
let data = users.load(&conn).unwrap().collect::<Vec<User>>();
5253
let sean = &data[0];
5354
let tess = &data[1];
5455
let jim = &data[2];
@@ -61,8 +62,9 @@ fn order_by_descending_column() {
6162
let data: Vec<_> = users.order(name.desc()).load(&conn).unwrap().collect();
6263
assert_eq!(expected_data, data);
6364

64-
let aaron = insert(&NewUser::new("Aaron", None)).into(users)
65-
.get_result::<User>(&conn).unwrap();
65+
insert(&NewUser::new("Aaron", None)).into(users)
66+
.execute(&conn).unwrap();
67+
let aaron = users.order(id.desc()).first::<User>(&conn).unwrap();
6668
let expected_data = vec![
6769
User::new(tess.id, "Tess"),
6870
User::new(sean.id, "Sean"),

diesel_tests/tests/select.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,10 @@ fn selecting_columns_with_different_definition_order() {
137137
connection.execute("CREATE TABLE users (id SERIAL PRIMARY KEY, hair_color VARCHAR, name VARCHAR NOT NULL)")
138138
.unwrap();
139139
let expected_user = User::with_hair_color(1, "Sean", "black");
140-
let user_from_insert = insert(&NewUser::new("Sean", Some("black"))).into(users::table)
141-
.get_result(&connection);
140+
insert(&NewUser::new("Sean", Some("black"))).into(users::table)
141+
.execute(&connection).unwrap();
142142
let user_from_select = users::table.first(&connection);
143143

144-
assert_eq!(Ok(&expected_user), user_from_insert.as_ref());
145144
assert_eq!(Ok(&expected_user), user_from_select.as_ref());
146145
}
147146

0 commit comments

Comments
 (0)