Skip to content

Commit d71c186

Browse files
committed
Move PG specific expressions out of the global namespace
We've also changed them to only compile when passed to a `PgConnection`, and added tests to ensure this continues to be true. The `WithQuerySource` is PG specific syntax, but interestingly, I didn't have a good place to mark it as such. We've done a hacky workaround for now. Fixes diesel-rs#153
1 parent e1f618e commit d71c186

18 files changed

Lines changed: 270 additions & 59 deletions

File tree

diesel/src/backend.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ pub trait TypeMetadata {
2626

2727
pub trait SupportsReturningClause {}
2828
pub trait SupportsDefaultKeyword {}
29+
pub trait SupportsNowFunction {}
2930

3031
pub struct Debug;
3132

@@ -40,3 +41,4 @@ impl TypeMetadata for Debug {
4041

4142
impl SupportsReturningClause for Debug {}
4243
impl SupportsDefaultKeyword for Debug {}
44+
impl SupportsNowFunction for Debug {}

diesel/src/expression/expression_methods/global_expression_methods.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,6 @@ pub trait ExpressionMethods: Expression + Sized {
4949
Eq::new(self, other.as_expression())
5050
}
5151

52-
#[doc(hidden)]
53-
fn is_not_distinct_from<T>(self, other: T)
54-
-> IsNotDistinctFrom<Self, T::Expression> where
55-
T: AsExpression<Self::SqlType>,
56-
{
57-
IsNotDistinctFrom::new(self, other.as_expression())
58-
}
59-
6052
/// Creates a SQL `!=` expression.
6153
///
6254
/// # Example

diesel/src/expression/expression_methods/mod.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,10 @@
77
pub mod global_expression_methods;
88
pub mod bool_expression_methods;
99
pub mod text_expression_methods;
10-
#[doc(hidden)]
11-
pub mod timestamp_expression_methods;
1210

1311
pub use self::global_expression_methods::ExpressionMethods;
1412
pub use self::bool_expression_methods::BoolExpressionMethods;
1513
pub use self::text_expression_methods::{TextExpressionMethods, VarCharExpressionMethods};
16-
#[doc(hidden)]
17-
pub use self::timestamp_expression_methods::TimestampExpressionMethods;
14+
15+
#[cfg(feature = "postgres")]
16+
pub use pg::expression::expression_methods::*;

diesel/src/expression/expression_methods/timestamp_expression_methods.rs

Lines changed: 0 additions & 14 deletions
This file was deleted.

diesel/src/expression/functions/date_and_time.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
use backend;
12
use types::*;
23

3-
no_arg_sql_function!(now, Timestamp, "Represents the SQL NOW() function");
4+
no_arg_sql_function!(now, Timestamp, "Represents the SQL NOW() function", backend::SupportsNowFunction);
45
operator_allowed!(now, Add, add);
56
operator_allowed!(now, Sub, sub);
67
sql_function!(date, date_t, (x: Timestamp) -> Date,

diesel/src/expression/functions/mod.rs

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ macro_rules! sql_function {
106106

107107
#[macro_export]
108108
#[doc(hidden)]
109-
macro_rules! no_arg_sql_function_body {
109+
macro_rules! no_arg_sql_function_body_except_to_sql {
110110
($type_name:ident, $return_type:ty, $docs:expr) => {
111111
#[allow(non_camel_case_types)]
112112
#[doc=$docs]
@@ -116,23 +116,48 @@ macro_rules! no_arg_sql_function_body {
116116
type SqlType = $return_type;
117117
}
118118

119+
impl<QS> $crate::expression::SelectableExpression<QS> for $type_name {
120+
}
121+
122+
impl $crate::expression::NonAggregate for $type_name {
123+
}
124+
}
125+
}
126+
127+
#[macro_export]
128+
#[doc(hidden)]
129+
macro_rules! no_arg_sql_function_body {
130+
($type_name:ident, $return_type:ty, $docs:expr, $($constraint:ident)::+) => {
131+
no_arg_sql_function_body_except_to_sql!($type_name, $return_type, $docs);
132+
119133
impl<DB> $crate::query_builder::QueryFragment<DB> for $type_name where
120-
DB: $crate::backend::Backend,
134+
DB: $crate::backend::Backend + $($constraint)::+,
121135
{
122136
fn to_sql(&self, out: &mut DB::QueryBuilder)
123-
-> $crate::query_builder::BuildQueryResult {
124-
use $crate::query_builder::QueryBuilder;
125-
out.push_sql(concat!(stringify!($type_name), "()"));
126-
Ok(())
127-
}
137+
-> $crate::query_builder::BuildQueryResult
138+
{
139+
use $crate::query_builder::QueryBuilder;
140+
out.push_sql(concat!(stringify!($type_name), "()"));
141+
Ok(())
142+
}
128143
}
144+
};
129145

130-
impl<QS> $crate::expression::SelectableExpression<QS> for $type_name {
131-
}
146+
($type_name:ident, $return_type:ty, $docs:expr) => {
147+
no_arg_sql_function_body_except_to_sql!($type_name, $return_type, $docs);
132148

133-
impl $crate::expression::NonAggregate for $type_name {
149+
impl<DB> $crate::query_builder::QueryFragment<DB> for $type_name where
150+
DB: $crate::backend::Backend,
151+
{
152+
fn to_sql(&self, out: &mut DB::QueryBuilder)
153+
-> $crate::query_builder::BuildQueryResult
154+
{
155+
use $crate::query_builder::QueryBuilder;
156+
out.push_sql(concat!(stringify!($type_name), "()"));
157+
Ok(())
158+
}
134159
}
135-
}
160+
};
136161
}
137162

138163
#[macro_export]
@@ -147,14 +172,21 @@ macro_rules! no_arg_sql_function_body {
147172
/// no_arg_sql_function!(now, types::Timestamp, "Represents the SQL NOW() function");
148173
/// # fn main() {}
149174
/// ```
175+
///
176+
/// You can optionally pass the name of a trait, as a constraint for backends which support the
177+
/// function.
150178
macro_rules! no_arg_sql_function {
151179
($type_name:ident, $return_type:ty) => {
152180
no_arg_sql_function!($type_name, $return_type, "");
153181
};
154182

155183
($type_name:ident, $return_type:ty, $docs:expr) => {
156184
no_arg_sql_function_body!($type_name, $return_type, $docs);
157-
}
185+
};
186+
187+
($type_name:ident, $return_type:ty, $docs:expr, $($constraint:ident)::+) => {
188+
no_arg_sql_function_body!($type_name, $return_type, $docs, $($constraint)::+);
189+
};
158190
}
159191

160192
pub mod aggregate_ordering;

diesel/src/expression/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ pub mod aliased;
2323
pub mod bound;
2424
#[doc(hidden)]
2525
pub mod count;
26-
#[doc(hidden)]
27-
pub mod date_and_time;
2826
pub mod expression_methods;
2927
#[doc(hidden)]
3028
pub mod functions;
@@ -34,6 +32,7 @@ pub mod helper_types;
3432
#[doc(hidden)]
3533
pub mod nullable;
3634
#[doc(hidden)]
35+
#[macro_use]
3736
pub mod predicates;
3837
pub mod sql_literal;
3938

diesel/src/expression/predicates.rs

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,24 @@ macro_rules! infix_predicate_body {
2424
type SqlType = $return_type;
2525
}
2626

27+
impl<T, U, QS> $crate::expression::SelectableExpression<QS> for $name<T, U> where
28+
T: $crate::expression::SelectableExpression<QS>,
29+
U: $crate::expression::SelectableExpression<QS>,
30+
{
31+
}
32+
33+
impl<T, U> $crate::expression::NonAggregate for $name<T, U> where
34+
T: $crate::expression::NonAggregate,
35+
U: $crate::expression::NonAggregate,
36+
{
37+
}
38+
}
39+
}
40+
41+
#[macro_export]
42+
#[doc(hidden)]
43+
macro_rules! global_infix_predicate_to_sql {
44+
($name:ident, $operator:expr) => {
2745
impl<T, U, DB> $crate::query_builder::QueryFragment<DB> for $name<T, U> where
2846
DB: $crate::backend::Backend,
2947
T: $crate::query_builder::QueryFragment<DB>,
@@ -35,17 +53,41 @@ macro_rules! infix_predicate_body {
3553
self.right.to_sql(out)
3654
}
3755
}
56+
}
57+
}
3858

39-
impl<T, U, QS> $crate::expression::SelectableExpression<QS> for $name<T, U> where
40-
T: $crate::expression::SelectableExpression<QS>,
41-
U: $crate::expression::SelectableExpression<QS>,
59+
#[macro_export]
60+
#[doc(hidden)]
61+
macro_rules! backend_specific_infix_predicate_to_sql {
62+
($name:ident, $operator:expr, $backend:ty) => {
63+
impl<T, U> $crate::query_builder::QueryFragment<$backend> for $name<T, U> where
64+
T: $crate::query_builder::QueryFragment<$backend>,
65+
U: $crate::query_builder::QueryFragment<$backend>,
4266
{
67+
fn to_sql(&self, out: &mut <$backend as $crate::backend::Backend>::QueryBuilder)
68+
-> $crate::query_builder::BuildQueryResult
69+
{
70+
use $crate::query_builder::QueryBuilder;
71+
try!(self.left.to_sql(out));
72+
out.push_sql($operator);
73+
self.right.to_sql(out)
74+
}
4375
}
4476

45-
impl<T, U> $crate::expression::NonAggregate for $name<T, U> where
46-
T: $crate::expression::NonAggregate,
47-
U: $crate::expression::NonAggregate,
77+
impl<T, U> $crate::query_builder::QueryFragment<$crate::backend::Debug>
78+
for $name<T, U> where
79+
T: $crate::query_builder::QueryFragment<$crate::backend::Debug>,
80+
U: $crate::query_builder::QueryFragment<$crate::backend::Debug>,
4881
{
82+
fn to_sql(
83+
&self,
84+
out: &mut <$crate::backend::Debug as $crate::backend::Backend>::QueryBuilder,
85+
) -> $crate::query_builder::BuildQueryResult {
86+
use $crate::query_builder::QueryBuilder;
87+
try!(self.left.to_sql(out));
88+
out.push_sql($operator);
89+
self.right.to_sql(out)
90+
}
4991
}
5092
}
5193
}
@@ -70,6 +112,16 @@ macro_rules! infix_predicate {
70112
};
71113

72114
($name:ident, $operator:expr, $return_type:ty) => {
115+
global_infix_predicate_to_sql!($name, $operator);
116+
infix_predicate_body!($name, $operator, $return_type);
117+
};
118+
119+
($name:ident, $operator:expr, backend: $backend:ty) => {
120+
infix_predicate!($name, $operator, $backend, $crate::types::Bool);
121+
};
122+
123+
($name:ident, $operator:expr, $backend:ty, $return_type:ty) => {
124+
backend_specific_infix_predicate_to_sql!($name, $operator, $backend);
73125
infix_predicate_body!($name, $operator, $return_type);
74126
};
75127
}
@@ -139,7 +191,6 @@ macro_rules! postfix_expression {
139191
infix_predicate!(And, " AND ");
140192
infix_predicate!(Between, " BETWEEN ");
141193
infix_predicate!(Eq, " = ");
142-
infix_predicate!(IsNotDistinctFrom, " IS NOT DISTINCT FROM ");
143194
infix_predicate!(Gt, " > ");
144195
infix_predicate!(GtEq, " >= ");
145196
infix_predicate!(Like, " LIKE ");

diesel/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#![cfg_attr(all(feature = "unstable", feature = "postgres"), feature(time2))]
66
pub mod backend;
77
pub mod connection;
8+
#[macro_use]
89
pub mod expression;
910
#[doc(hidden)]
1011
pub mod persistable;

diesel/src/pg/backend.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ impl TypeMetadata for Pg {
2020

2121
impl SupportsReturningClause for Pg {}
2222
impl SupportsDefaultKeyword for Pg {}
23+
impl SupportsNowFunction for Pg {}

0 commit comments

Comments
 (0)