在柴油中显式加入
Explicit JOIN ON in diesel
我有两个表,我想加入、过滤,并且 select 只有 Diesel 中的特定列:
contest_users::dsl::contest_users
.inner_join(
contests::table.on(contest_users::contest_id.eq(contests::contest_id)),
)
.filter(contest_users::user_id.eq(42))
.select((contests::columns::contest_id,))
这里有一个repo with a repro(见代码中的注释)
我找到了一些可以编译的解决方案,但我仍然想知道是否可以在不使用 joinable!
.
的情况下命名此查询的类型
以下内容是可编译的:
pub fn join_and_filter() -> diesel::dsl::Filter<
diesel::dsl::Select<
diesel::dsl::InnerJoin<contest_users::table, contests::table>,
(contests::columns::contest_id,),
>,
diesel::expression::operators::Eq<
contest_users::columns::user_id,
diesel::expression::bound::Bound<diesel::sql_types::Integer, i32>,
>,
> {
joinable!(contest_users -> contests (contest_id));
contest_users::dsl::contest_users
.inner_join(
contests::table.on(contest_users::contest_id.nullable().eq(contests::contest_id.nullable())),
)
.filter(contest_users::user_id.eq(42))
.select((contests::columns::contest_id,))
}
虽然以下(没有 joinable
即使我有显式 .on()
)导致编译错误:
pub fn join_and_filter() -> diesel::dsl::Filter<
diesel::dsl::Select<
diesel::dsl::InnerJoin<contest_users::table, contests::table>,
(contests::columns::contest_id,),
>,
diesel::expression::operators::Eq<
contest_users::columns::user_id,
diesel::expression::bound::Bound<diesel::sql_types::Integer, i32>,
>,
> {
contest_users::dsl::contest_users
.inner_join(
contests::table.on(contest_users::contest_id.eq(contests::contest_id))
)
.filter(contest_users::user_id.eq(42))
.select((contests::columns::contest_id,))
}
error[E0277]: the trait bound `contest_users::table: JoinTo<contests::table>` is not satisfied
--> src/main.rs:69:1
|
69 | / pub fn join_and_filter() -> diesel::dsl::Filter<
70 | | diesel::dsl::Select<
71 | | diesel::dsl::InnerJoin<contest_users::table, contests::table>,
72 | | (contests::columns::contest_id,),
... |
84 | | .select((contests::columns::contest_id,))
85 | | }
| |_^ the trait `JoinTo<contests::table>` is not implemented for `contest_users::table`
|
= help: the following implementations were found:
<contest_users::table as JoinTo<JoinOn<Join, On>>>
<contest_users::table as JoinTo<diesel::query_builder::BoxedSelectStatement<'a, QS, ST, DB>>>
<contest_users::table as JoinTo<diesel::query_builder::SelectStatement<F, S, D, W, O, L, Of, G>>>
<contest_users::table as JoinTo<diesel::query_source::joins::Join<Left, Right, Kind>>>
= note: required because of the requirements on the impl of `JoinWithImplicitOnClause<contests::table, Inner>` for `contest_users::table`
I have found a few solutions that I can make to compile, but I still wonder if I can name a type of this query without using joinable!.
根据文档 diesel::dsl::InnerJoin
定义如下:
type InnerJoin<Source, Rhs> = <Source as JoinWithImplicitOnClause<Rhs, Inner>>::Output;
这个和声明
Represents the return type of .inner_join(rhs)
表示此类型旨在与没有显式 on
子句的 inner_join
语句一起使用。
现在问题是如何正确指定 return 类型,因为柴油 1.4 不会通过 diesel::dsl
导出相应的类型。 diesles master 分支的文档表明那里存在相应的 type,但是构成类型定义的相关类型并未作为 public API 的一部分在 1.4 版本中公开。这表明目前无法使用现有柴油版本命名此类型。
我有两个表,我想加入、过滤,并且 select 只有 Diesel 中的特定列:
contest_users::dsl::contest_users
.inner_join(
contests::table.on(contest_users::contest_id.eq(contests::contest_id)),
)
.filter(contest_users::user_id.eq(42))
.select((contests::columns::contest_id,))
这里有一个repo with a repro(见代码中的注释)
我找到了一些可以编译的解决方案,但我仍然想知道是否可以在不使用 joinable!
.
以下内容是可编译的:
pub fn join_and_filter() -> diesel::dsl::Filter<
diesel::dsl::Select<
diesel::dsl::InnerJoin<contest_users::table, contests::table>,
(contests::columns::contest_id,),
>,
diesel::expression::operators::Eq<
contest_users::columns::user_id,
diesel::expression::bound::Bound<diesel::sql_types::Integer, i32>,
>,
> {
joinable!(contest_users -> contests (contest_id));
contest_users::dsl::contest_users
.inner_join(
contests::table.on(contest_users::contest_id.nullable().eq(contests::contest_id.nullable())),
)
.filter(contest_users::user_id.eq(42))
.select((contests::columns::contest_id,))
}
虽然以下(没有 joinable
即使我有显式 .on()
)导致编译错误:
pub fn join_and_filter() -> diesel::dsl::Filter<
diesel::dsl::Select<
diesel::dsl::InnerJoin<contest_users::table, contests::table>,
(contests::columns::contest_id,),
>,
diesel::expression::operators::Eq<
contest_users::columns::user_id,
diesel::expression::bound::Bound<diesel::sql_types::Integer, i32>,
>,
> {
contest_users::dsl::contest_users
.inner_join(
contests::table.on(contest_users::contest_id.eq(contests::contest_id))
)
.filter(contest_users::user_id.eq(42))
.select((contests::columns::contest_id,))
}
error[E0277]: the trait bound `contest_users::table: JoinTo<contests::table>` is not satisfied
--> src/main.rs:69:1
|
69 | / pub fn join_and_filter() -> diesel::dsl::Filter<
70 | | diesel::dsl::Select<
71 | | diesel::dsl::InnerJoin<contest_users::table, contests::table>,
72 | | (contests::columns::contest_id,),
... |
84 | | .select((contests::columns::contest_id,))
85 | | }
| |_^ the trait `JoinTo<contests::table>` is not implemented for `contest_users::table`
|
= help: the following implementations were found:
<contest_users::table as JoinTo<JoinOn<Join, On>>>
<contest_users::table as JoinTo<diesel::query_builder::BoxedSelectStatement<'a, QS, ST, DB>>>
<contest_users::table as JoinTo<diesel::query_builder::SelectStatement<F, S, D, W, O, L, Of, G>>>
<contest_users::table as JoinTo<diesel::query_source::joins::Join<Left, Right, Kind>>>
= note: required because of the requirements on the impl of `JoinWithImplicitOnClause<contests::table, Inner>` for `contest_users::table`
I have found a few solutions that I can make to compile, but I still wonder if I can name a type of this query without using joinable!.
根据文档 diesel::dsl::InnerJoin
定义如下:
type InnerJoin<Source, Rhs> = <Source as JoinWithImplicitOnClause<Rhs, Inner>>::Output;
这个和声明
Represents the return type of .inner_join(rhs)
表示此类型旨在与没有显式 on
子句的 inner_join
语句一起使用。
现在问题是如何正确指定 return 类型,因为柴油 1.4 不会通过 diesel::dsl
导出相应的类型。 diesles master 分支的文档表明那里存在相应的 type,但是构成类型定义的相关类型并未作为 public API 的一部分在 1.4 版本中公开。这表明目前无法使用现有柴油版本命名此类型。