0
0
mirror of https://github.com/rbock/sqlpp11.git synced 2024-11-16 04:47:18 +08:00

Added "real" cross join

This commit is contained in:
rbock 2016-03-06 10:36:42 +01:00
parent 20b74206ae
commit d15cb2a410
13 changed files with 227 additions and 184 deletions

View File

@ -27,36 +27,36 @@
#ifndef SQLPP_DYNAMIC_JOIN_H #ifndef SQLPP_DYNAMIC_JOIN_H
#define SQLPP_DYNAMIC_JOIN_H #define SQLPP_DYNAMIC_JOIN_H
#include <sqlpp11/dynamic_cross_join.h> #include <sqlpp11/dynamic_pre_join.h>
namespace sqlpp namespace sqlpp
{ {
template <typename CrossJoin, typename On> template <typename PreJoin, typename On>
struct dynamic_join_t struct dynamic_join_t
{ {
using _traits = make_traits<no_value_t, tag::is_table, tag::is_dynamic_join>; using _traits = make_traits<no_value_t, tag::is_table, tag::is_dynamic_join>;
using _nodes = detail::type_vector<CrossJoin, On>; using _nodes = detail::type_vector<PreJoin, On>;
using _can_be_null = std::false_type; using _can_be_null = std::false_type;
using _provided_tables = provided_tables_of<CrossJoin>; using _provided_tables = provided_tables_of<PreJoin>;
using _required_tables = detail::type_set<>; using _required_tables = detail::type_set<>;
static_assert(is_dynamic_cross_join_t<CrossJoin>::value, "lhs argument for on() has to be a cross join"); static_assert(is_dynamic_pre_join_t<PreJoin>::value, "lhs argument for on() has to be a pre join");
static_assert(required_tables_of<CrossJoin>::size::value == 0, "joined tables must not depend on other tables"); static_assert(required_tables_of<PreJoin>::size::value == 0, "joined tables must not depend on other tables");
static_assert(is_on_t<On>::value, "invalid on expression in join().on()"); static_assert(is_on_t<On>::value, "invalid on expression in join().on()");
CrossJoin _cross_join; PreJoin _pre_join;
On _on; On _on;
}; };
template <typename Context, typename CrossJoin, typename On> template <typename Context, typename PreJoin, typename On>
struct serializer_t<Context, dynamic_join_t<CrossJoin, On>> struct serializer_t<Context, dynamic_join_t<PreJoin, On>>
{ {
using _serialize_check = serialize_check_of<Context, CrossJoin, On>; using _serialize_check = serialize_check_of<Context, PreJoin, On>;
using T = dynamic_join_t<CrossJoin, On>; using T = dynamic_join_t<PreJoin, On>;
static Context& _(const T& t, Context& context) static Context& _(const T& t, Context& context)
{ {
serialize(t._cross_join, context); serialize(t._pre_join, context);
serialize(t._on, context); serialize(t._on, context);
return context; return context;
} }

View File

@ -24,93 +24,88 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef SQLPP_DYNAMIC_CROSS_JOIN_H #ifndef SQLPP_DYNAMIC_PRE_JOIN_H
#define SQLPP_DYNAMIC_CROSS_JOIN_H #define SQLPP_DYNAMIC_PRE_JOIN_H
#include <sqlpp11/join_types.h> #include <sqlpp11/join_types.h>
#include <sqlpp11/on.h> #include <sqlpp11/on.h>
namespace sqlpp namespace sqlpp
{ {
SQLPP_PORTABLE_STATIC_ASSERT(assert_dynamic_cross_join_table_t, "argument of dynamic_join() has to be a table"); SQLPP_PORTABLE_STATIC_ASSERT(assert_dynamic_pre_join_table_t, "argument of dynamic_join() has to be a table");
SQLPP_PORTABLE_STATIC_ASSERT(assert_dynamic_cross_join_no_join_t, "argument of dynamic_join() must not be a table"); SQLPP_PORTABLE_STATIC_ASSERT(assert_dynamic_pre_join_no_join_t, "argument of dynamic_join() must not be a table");
template <typename Table> template <typename Table>
struct check_dynamic_cross_join struct check_dynamic_pre_join
{ {
using type = using type =
static_combined_check_t<static_check_t<is_table_t<Table>::value, assert_dynamic_cross_join_table_t>, static_combined_check_t<static_check_t<is_table_t<Table>::value, assert_dynamic_pre_join_table_t>,
static_check_t<not is_join_t<Table>::value, assert_dynamic_cross_join_no_join_t>>; static_check_t<not is_join_t<Table>::value, assert_dynamic_pre_join_no_join_t>>;
}; };
template <typename Table> template <typename Table>
using check_dynamic_cross_join_t = typename check_dynamic_cross_join<Table>::type; using check_dynamic_pre_join_t = typename check_dynamic_pre_join<Table>::type;
SQLPP_PORTABLE_STATIC_ASSERT(assert_dynamic_join_consist_of_cross_join_and_on_t, SQLPP_PORTABLE_STATIC_ASSERT(assert_dynamic_join_consist_of_pre_join_and_on_t,
"dynamic join has to consist of a dynamic cross_join and a join condition"); "dynamic join has to consist of a dynamic pre_join and a join condition");
SQLPP_PORTABLE_STATIC_ASSERT(assert_dynamic_join_no_table_dependencies_t, SQLPP_PORTABLE_STATIC_ASSERT(assert_dynamic_join_no_table_dependencies_t,
"dynamically joined tables must not depend on other tables"); "dynamically joined tables must not depend on other tables");
template <typename CrossJoin, typename On> template <typename PreJoin, typename On>
struct check_dynamic_join struct check_dynamic_join
{ {
using type = static_combined_check_t< using type = static_combined_check_t<
static_check_t<is_dynamic_cross_join_t<CrossJoin>::value, assert_dynamic_join_consist_of_cross_join_and_on_t>, static_check_t<is_dynamic_pre_join_t<PreJoin>::value, assert_dynamic_join_consist_of_pre_join_and_on_t>,
static_check_t<is_on_t<On>::value, assert_dynamic_join_consist_of_cross_join_and_on_t>, static_check_t<is_on_t<On>::value, assert_dynamic_join_consist_of_pre_join_and_on_t>,
static_check_t<required_tables_of<CrossJoin>::size::value == 0, assert_dynamic_join_no_table_dependencies_t>>; static_check_t<required_tables_of<PreJoin>::size::value == 0, assert_dynamic_join_no_table_dependencies_t>>;
}; };
template <typename CrossJoin, typename On> template <typename PreJoin, typename On>
using check_dynamic_join_t = typename check_dynamic_join<CrossJoin, On>::type; using check_dynamic_join_t = typename check_dynamic_join<PreJoin, On>::type;
template <typename CrossJoin, typename Expr> template <typename PreJoin, typename Expr>
struct check_dynamic_join_on struct check_dynamic_join_on
{ {
using type = static_combined_check_t<check_on_t<Expr>, check_dynamic_join_t<CrossJoin, on_t<Expr>>>; using type = static_combined_check_t<check_on_t<Expr>, check_dynamic_join_t<PreJoin, on_t<Expr>>>;
}; };
template <typename CrossJoin, typename Expr> template <typename PreJoin, typename Expr>
using check_dynamic_join_on_t = typename check_dynamic_join_on<CrossJoin, Expr>::type; using check_dynamic_join_on_t = typename check_dynamic_join_on<PreJoin, Expr>::type;
template <typename CrossJoin, typename On> template <typename PreJoin, typename On>
struct dynamic_join_t; struct dynamic_join_t;
template <typename JoinType, typename Rhs> template <typename JoinType, typename Rhs>
struct dynamic_cross_join_t struct dynamic_pre_join_t
{ {
using _traits = make_traits<no_value_t, tag::is_table, tag::is_dynamic_cross_join>; using _traits = make_traits<no_value_t, tag::is_table, tag::is_dynamic_pre_join>;
using _nodes = detail::type_vector<Rhs>; using _nodes = detail::type_vector<Rhs>;
using _can_be_null = std::false_type; using _can_be_null = std::false_type;
static_assert(is_table_t<Rhs>::value, "rhs argument for dynamic_join() has to be a table"); static_assert(is_table_t<Rhs>::value, "rhs argument for dynamic_join() has to be a table");
static_assert(not is_join_t<Rhs>::value, "rhs argument for dynamic_join must not be a join"); static_assert(not is_join_t<Rhs>::value, "rhs argument for dynamic_join must not be a join");
static_assert(required_tables_of<dynamic_cross_join_t>::size::value == 0, static_assert(required_tables_of<dynamic_pre_join_t>::size::value == 0,
"joined tables must not depend on other tables"); "joined tables must not depend on other tables");
template <typename Expr> template <typename Expr>
auto on(Expr expr) const -> typename std::conditional<check_dynamic_join_on_t<dynamic_cross_join_t, Expr>::value, auto on(Expr expr) const -> typename std::conditional<check_dynamic_join_on_t<dynamic_pre_join_t, Expr>::value,
dynamic_join_t<dynamic_cross_join_t, on_t<Expr>>, dynamic_join_t<dynamic_pre_join_t, on_t<Expr>>,
bad_statement>::type bad_statement>::type
{ {
check_dynamic_join_on_t<dynamic_cross_join_t, Expr>::_(); check_dynamic_join_on_t<dynamic_pre_join_t, Expr>::_();
return {*this, {expr}}; return {*this, {expr}};
} }
auto unconditionally() -> dynamic_join_t<dynamic_cross_join_t, on_t<unconditional_t>>
{
return {*this, {}};
}
Rhs _rhs; Rhs _rhs;
}; };
template <typename Context, typename JoinType, typename Rhs> template <typename Context, typename JoinType, typename Rhs>
struct serializer_t<Context, dynamic_cross_join_t<JoinType, Rhs>> struct serializer_t<Context, dynamic_pre_join_t<JoinType, Rhs>>
{ {
using _serialize_check = serialize_check_of<Context, Rhs>; using _serialize_check = serialize_check_of<Context, Rhs>;
using T = dynamic_cross_join_t<JoinType, Rhs>; using T = dynamic_pre_join_t<JoinType, Rhs>;
static Context& _(const T& t, Context& context) static Context& _(const T& t, Context& context)
{ {
@ -121,44 +116,54 @@ namespace sqlpp
}; };
template <typename JoinType, typename Table> template <typename JoinType, typename Table>
using make_dynamic_cross_join_t = typename std::conditional<check_dynamic_cross_join_t<Table>::value, using make_dynamic_pre_join_t = typename std::conditional<check_dynamic_pre_join_t<Table>::value,
dynamic_cross_join_t<JoinType, Table>, dynamic_pre_join_t<JoinType, Table>,
bad_statement>::type; bad_statement>::type;
template <typename Table> template <typename Table>
auto dynamic_join(Table table) -> make_dynamic_cross_join_t<inner_join_t, Table> auto dynamic_join(Table table) -> make_dynamic_pre_join_t<inner_join_t, Table>
{ {
check_dynamic_cross_join_t<Table>::_(); check_dynamic_pre_join_t<Table>::_();
return {table}; return {table};
} }
template <typename Table> template <typename Table>
auto dynamic_inner_join(Table table) -> make_dynamic_cross_join_t<inner_join_t, Table> auto dynamic_inner_join(Table table) -> make_dynamic_pre_join_t<inner_join_t, Table>
{ {
check_dynamic_cross_join_t<Table>::_(); check_dynamic_pre_join_t<Table>::_();
return {table}; return {table};
} }
template <typename Table> template <typename Table>
auto dynamic_left_outer_join(Table table) -> make_dynamic_cross_join_t<left_outer_join_t, Table> auto dynamic_left_outer_join(Table table) -> make_dynamic_pre_join_t<left_outer_join_t, Table>
{ {
check_dynamic_cross_join_t<Table>::_(); check_dynamic_pre_join_t<Table>::_();
return {table}; return {table};
} }
template <typename Table> template <typename Table>
auto dynamic_right_outer_join(Table table) -> make_dynamic_cross_join_t<right_outer_join_t, Table> auto dynamic_right_outer_join(Table table) -> make_dynamic_pre_join_t<right_outer_join_t, Table>
{ {
check_dynamic_cross_join_t<Table>::_(); check_dynamic_pre_join_t<Table>::_();
return {table}; return {table};
} }
template <typename Table> template <typename Table>
auto dynamic_outer_join(Table table) -> make_dynamic_cross_join_t<outer_join_t, Table> auto dynamic_outer_join(Table table) -> make_dynamic_pre_join_t<outer_join_t, Table>
{ {
check_dynamic_cross_join_t<Table>::_(); check_dynamic_pre_join_t<Table>::_();
return {table}; return {table};
} }
template <typename Table>
auto dynamic_cross_join(Table table) ->
typename std::conditional<check_dynamic_pre_join_t<Table>::value,
dynamic_join_t<dynamic_pre_join_t<cross_join_t, Table>, on_t<unconditional_t>>,
bad_statement>::type
{
check_dynamic_pre_join_t<Table>::_();
return {dynamic_pre_join_t<cross_join_t, Table>{table}, {}};
}
} }
#endif #endif

View File

@ -148,8 +148,8 @@ namespace sqlpp
}; };
SQLPP_PORTABLE_STATIC_ASSERT( SQLPP_PORTABLE_STATIC_ASSERT(
assert_from_not_cross_join_t, assert_from_not_pre_join_t,
"from() argument is a cross join, please use an explicit on() condition or unconditionally()"); "from() argument is a pre join, please use an explicit on() condition or unconditionally()");
SQLPP_PORTABLE_STATIC_ASSERT(assert_from_table_t, "from() argument has to be a table or join expression"); SQLPP_PORTABLE_STATIC_ASSERT(assert_from_table_t, "from() argument has to be a table or join expression");
SQLPP_PORTABLE_STATIC_ASSERT(assert_from_dependency_free_t, "at least one table depends on another table in from()"); SQLPP_PORTABLE_STATIC_ASSERT(assert_from_dependency_free_t, "at least one table depends on another table in from()");
SQLPP_PORTABLE_STATIC_ASSERT(assert_from_no_duplicates_t, "at least one duplicate table name detected in from()"); SQLPP_PORTABLE_STATIC_ASSERT(assert_from_no_duplicates_t, "at least one duplicate table name detected in from()");
@ -161,7 +161,7 @@ namespace sqlpp
struct check_from struct check_from
{ {
using type = static_combined_check_t< using type = static_combined_check_t<
static_check_t<not is_cross_join_t<Table>::value, assert_from_not_cross_join_t>, static_check_t<not is_pre_join_t<Table>::value, assert_from_not_pre_join_t>,
static_check_t<is_table_t<Table>::value, assert_from_table_t>, static_check_t<is_table_t<Table>::value, assert_from_table_t>,
static_check_t<required_tables_of<Table>::size::value == 0, assert_from_dependency_free_t>, static_check_t<required_tables_of<Table>::size::value == 0, assert_from_dependency_free_t>,
static_check_t<provided_tables_of<Table>::size::value == static_check_t<provided_tables_of<Table>::size::value ==

View File

@ -28,18 +28,18 @@
#define SQLPP_JOIN_H #define SQLPP_JOIN_H
#include <sqlpp11/join_types.h> #include <sqlpp11/join_types.h>
#include <sqlpp11/cross_join.h> #include <sqlpp11/pre_join.h>
#include <sqlpp11/on.h> #include <sqlpp11/on.h>
namespace sqlpp namespace sqlpp
{ {
template <typename CrossJoin, typename On> template <typename PreJoin, typename On>
struct join_t struct join_t
{ {
using _traits = make_traits<no_value_t, tag::is_table, tag::is_join>; using _traits = make_traits<no_value_t, tag::is_table, tag::is_join>;
using _nodes = detail::type_vector<CrossJoin, On>; using _nodes = detail::type_vector<PreJoin, On>;
using _can_be_null = std::false_type; using _can_be_null = std::false_type;
using _provided_tables = provided_tables_of<CrossJoin>; using _provided_tables = provided_tables_of<PreJoin>;
using _required_tables = detail::make_difference_set_t<required_tables_of<On>, _provided_tables>; using _required_tables = detail::make_difference_set_t<required_tables_of<On>, _provided_tables>;
template <typename T> template <typename T>
@ -72,19 +72,25 @@ namespace sqlpp
return ::sqlpp::outer_join(*this, t); return ::sqlpp::outer_join(*this, t);
} }
CrossJoin _cross_join; template <typename T>
auto cross_join(T t) const -> decltype(::sqlpp::cross_join(*this, t))
{
return ::sqlpp::cross_join(*this, t);
}
PreJoin _pre_join;
On _on; On _on;
}; };
template <typename Context, typename CrossJoin, typename On> template <typename Context, typename PreJoin, typename On>
struct serializer_t<Context, join_t<CrossJoin, On>> struct serializer_t<Context, join_t<PreJoin, On>>
{ {
using _serialize_check = serialize_check_of<Context, CrossJoin, On>; using _serialize_check = serialize_check_of<Context, PreJoin, On>;
using T = join_t<CrossJoin, On>; using T = join_t<PreJoin, On>;
static Context& _(const T& t, Context& context) static Context& _(const T& t, Context& context)
{ {
serialize(t._cross_join, context); serialize(t._pre_join, context);
serialize(t._on, context); serialize(t._on, context);
return context; return context;
} }

View File

@ -60,6 +60,14 @@ namespace sqlpp
static constexpr const char* _name = " RIGHT OUTER "; static constexpr const char* _name = " RIGHT OUTER ";
}; };
struct cross_join_t
{
template <typename Lhs, typename Rhs>
using _provided_outer_tables =
detail::make_joined_set_t<provided_outer_tables_of<Lhs>, provided_outer_tables_of<Rhs>>;
static constexpr const char* _name = " CROSS ";
};
} }
#endif #endif

View File

@ -24,8 +24,8 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef SQLPP_CROSS_JOIN_H #ifndef SQLPP_PRE_JOIN_H
#define SQLPP_CROSS_JOIN_H #define SQLPP_PRE_JOIN_H
#include <sqlpp11/join_types.h> #include <sqlpp11/join_types.h>
#include <sqlpp11/on.h> #include <sqlpp11/on.h>
@ -33,62 +33,62 @@
namespace sqlpp namespace sqlpp
{ {
SQLPP_PORTABLE_STATIC_ASSERT(assert_cross_join_lhs_table_t, "lhs argument of join() has to be a table or a join"); SQLPP_PORTABLE_STATIC_ASSERT(assert_pre_join_lhs_table_t, "lhs argument of join() has to be a table or a join");
SQLPP_PORTABLE_STATIC_ASSERT(assert_cross_join_rhs_table_t, "rhs argument of join() has to be a table"); SQLPP_PORTABLE_STATIC_ASSERT(assert_pre_join_rhs_table_t, "rhs argument of join() has to be a table");
SQLPP_PORTABLE_STATIC_ASSERT(assert_cross_join_rhs_no_join_t, "rhs argument of join() must not be a join"); SQLPP_PORTABLE_STATIC_ASSERT(assert_pre_join_rhs_no_join_t, "rhs argument of join() must not be a join");
SQLPP_PORTABLE_STATIC_ASSERT(assert_cross_join_unique_names_t, "joined table names have to be unique"); SQLPP_PORTABLE_STATIC_ASSERT(assert_pre_join_unique_names_t, "joined table names have to be unique");
template <typename Lhs, typename Rhs> template <typename Lhs, typename Rhs>
struct check_cross_join struct check_pre_join
{ {
using type = static_combined_check_t< using type = static_combined_check_t<
static_check_t<is_table_t<Lhs>::value, assert_cross_join_lhs_table_t>, static_check_t<is_table_t<Lhs>::value, assert_pre_join_lhs_table_t>,
static_check_t<is_table_t<Rhs>::value, assert_cross_join_rhs_table_t>, static_check_t<is_table_t<Rhs>::value, assert_pre_join_rhs_table_t>,
static_check_t<not is_join_t<Rhs>::value, assert_cross_join_rhs_no_join_t>, static_check_t<not is_join_t<Rhs>::value, assert_pre_join_rhs_no_join_t>,
static_check_t<detail::is_disjunct_from<detail::make_name_of_set_t<provided_tables_of<Lhs>>, static_check_t<detail::is_disjunct_from<detail::make_name_of_set_t<provided_tables_of<Lhs>>,
detail::make_name_of_set_t<provided_tables_of<Rhs>>>::value, detail::make_name_of_set_t<provided_tables_of<Rhs>>>::value,
assert_cross_join_unique_names_t>>; assert_pre_join_unique_names_t>>;
}; };
template <typename Lhs, typename Rhs> template <typename Lhs, typename Rhs>
using check_cross_join_t = typename check_cross_join<Lhs, Rhs>::type; using check_pre_join_t = typename check_pre_join<Lhs, Rhs>::type;
SQLPP_PORTABLE_STATIC_ASSERT(assert_join_consist_of_cross_join_and_on_t, SQLPP_PORTABLE_STATIC_ASSERT(assert_join_consist_of_pre_join_and_on_t,
"join has to consist of a cross_join and a join condition"); "join has to consist of a pre_join and a join condition");
SQLPP_PORTABLE_STATIC_ASSERT(assert_join_no_table_dependencies_t, "joined tables must not depend on other tables"); SQLPP_PORTABLE_STATIC_ASSERT(assert_join_no_table_dependencies_t, "joined tables must not depend on other tables");
SQLPP_PORTABLE_STATIC_ASSERT(assert_join_on_no_foreign_table_dependencies_t, SQLPP_PORTABLE_STATIC_ASSERT(assert_join_on_no_foreign_table_dependencies_t,
"on() condition must not depend on other tables"); "on() condition must not depend on other tables");
template <typename CrossJoin, typename On> template <typename PreJoin, typename On>
struct check_join struct check_join
{ {
using type = static_combined_check_t< using type = static_combined_check_t<
static_check_t<is_cross_join_t<CrossJoin>::value, assert_join_consist_of_cross_join_and_on_t>, static_check_t<is_pre_join_t<PreJoin>::value, assert_join_consist_of_pre_join_and_on_t>,
static_check_t<is_on_t<On>::value, assert_join_consist_of_cross_join_and_on_t>, static_check_t<is_on_t<On>::value, assert_join_consist_of_pre_join_and_on_t>,
static_check_t<required_tables_of<CrossJoin>::size::value == 0, assert_join_no_table_dependencies_t>, static_check_t<required_tables_of<PreJoin>::size::value == 0, assert_join_no_table_dependencies_t>,
static_check_t<detail::is_subset_of<required_tables_of<On>, provided_tables_of<CrossJoin>>::value, static_check_t<detail::is_subset_of<required_tables_of<On>, provided_tables_of<PreJoin>>::value,
assert_join_on_no_foreign_table_dependencies_t>>; assert_join_on_no_foreign_table_dependencies_t>>;
}; };
template <typename CrossJoin, typename On> template <typename PreJoin, typename On>
using check_join_t = typename check_join<CrossJoin, On>::type; using check_join_t = typename check_join<PreJoin, On>::type;
template <typename CrossJoin, typename Expr> template <typename PreJoin, typename Expr>
struct check_join_on struct check_join_on
{ {
using type = static_combined_check_t<check_on_t<Expr>, check_join_t<CrossJoin, on_t<Expr>>>; using type = static_combined_check_t<check_on_t<Expr>, check_join_t<PreJoin, on_t<Expr>>>;
}; };
template <typename CrossJoin, typename Expr> template <typename PreJoin, typename Expr>
using check_join_on_t = typename check_join_on<CrossJoin, Expr>::type; using check_join_on_t = typename check_join_on<PreJoin, Expr>::type;
template <typename CrossJoin, typename On> template <typename PreJoin, typename On>
struct join_t; struct join_t;
template <typename JoinType, typename Lhs, typename Rhs> template <typename JoinType, typename Lhs, typename Rhs>
struct cross_join_t struct pre_join_t
{ {
using _traits = make_traits<no_value_t, tag::is_cross_join>; using _traits = make_traits<no_value_t, tag::is_pre_join>;
using _nodes = detail::type_vector<Lhs, Rhs>; using _nodes = detail::type_vector<Lhs, Rhs>;
using _can_be_null = std::false_type; using _can_be_null = std::false_type;
@ -99,32 +99,27 @@ namespace sqlpp
static_assert(detail::is_disjunct_from<provided_tables_of<Lhs>, provided_tables_of<Rhs>>::value, static_assert(detail::is_disjunct_from<provided_tables_of<Lhs>, provided_tables_of<Rhs>>::value,
"joined tables must not be identical"); "joined tables must not be identical");
static_assert(required_tables_of<cross_join_t>::size::value == 0, "joined tables must not depend on other tables"); static_assert(required_tables_of<pre_join_t>::size::value == 0, "joined tables must not depend on other tables");
template <typename Expr> template <typename Expr>
auto on(Expr expr) const -> typename std::conditional<check_join_on_t<cross_join_t, Expr>::value, auto on(Expr expr) const -> typename std::conditional<check_join_on_t<pre_join_t, Expr>::value,
join_t<cross_join_t, on_t<Expr>>, join_t<pre_join_t, on_t<Expr>>,
bad_statement>::type bad_statement>::type
{ {
check_join_on_t<cross_join_t, Expr>::_(); check_join_on_t<pre_join_t, Expr>::_();
return {*this, {expr}}; return {*this, {expr}};
} }
auto unconditionally() -> join_t<cross_join_t, on_t<unconditional_t>>
{
return {*this, {}};
}
Lhs _lhs; Lhs _lhs;
Rhs _rhs; Rhs _rhs;
}; };
template <typename Context, typename JoinType, typename Lhs, typename Rhs> template <typename Context, typename JoinType, typename Lhs, typename Rhs>
struct serializer_t<Context, cross_join_t<JoinType, Lhs, Rhs>> struct serializer_t<Context, pre_join_t<JoinType, Lhs, Rhs>>
{ {
using _serialize_check = serialize_check_of<Context, Lhs, Rhs>; using _serialize_check = serialize_check_of<Context, Lhs, Rhs>;
using T = cross_join_t<JoinType, Lhs, Rhs>; using T = pre_join_t<JoinType, Lhs, Rhs>;
static Context& _(const T& t, Context& context) static Context& _(const T& t, Context& context)
{ {
@ -137,54 +132,65 @@ namespace sqlpp
}; };
template <typename Lhs, typename Rhs> template <typename Lhs, typename Rhs>
auto join(Lhs lhs, Rhs rhs) -> typename std::conditional<check_cross_join_t<Lhs, Rhs>::value, auto join(Lhs lhs, Rhs rhs) -> typename std::conditional<check_pre_join_t<Lhs, Rhs>::value,
cross_join_t<inner_join_t, Lhs, Rhs>, pre_join_t<inner_join_t, Lhs, Rhs>,
bad_statement>::type bad_statement>::type
{ {
check_cross_join_t<Lhs, Rhs>::_(); check_pre_join_t<Lhs, Rhs>::_();
return {lhs, rhs}; return {lhs, rhs};
} }
template <typename Lhs, typename Rhs> template <typename Lhs, typename Rhs>
auto inner_join(Lhs lhs, Rhs rhs) -> typename std::conditional<check_cross_join_t<Lhs, Rhs>::value, auto inner_join(Lhs lhs, Rhs rhs) -> typename std::conditional<check_pre_join_t<Lhs, Rhs>::value,
cross_join_t<inner_join_t, Lhs, Rhs>, pre_join_t<inner_join_t, Lhs, Rhs>,
bad_statement>::type bad_statement>::type
{ {
check_cross_join_t<Lhs, Rhs>::_(); check_pre_join_t<Lhs, Rhs>::_();
return {lhs, rhs}; return {lhs, rhs};
} }
template <typename Lhs, typename Rhs> template <typename Lhs, typename Rhs>
auto left_outer_join(Lhs lhs, Rhs rhs) -> typename std::conditional<check_cross_join_t<Lhs, Rhs>::value, auto left_outer_join(Lhs lhs, Rhs rhs) -> typename std::conditional<check_pre_join_t<Lhs, Rhs>::value,
cross_join_t<left_outer_join_t, Lhs, Rhs>, pre_join_t<left_outer_join_t, Lhs, Rhs>,
bad_statement>::type bad_statement>::type
{ {
check_cross_join_t<Lhs, Rhs>::_(); check_pre_join_t<Lhs, Rhs>::_();
return {lhs, rhs}; return {lhs, rhs};
} }
template <typename Lhs, typename Rhs> template <typename Lhs, typename Rhs>
auto right_outer_join(Lhs lhs, Rhs rhs) -> typename std::conditional<check_cross_join_t<Lhs, Rhs>::value, auto right_outer_join(Lhs lhs, Rhs rhs) -> typename std::conditional<check_pre_join_t<Lhs, Rhs>::value,
cross_join_t<right_outer_join_t, Lhs, Rhs>, pre_join_t<right_outer_join_t, Lhs, Rhs>,
bad_statement>::type bad_statement>::type
{ {
check_cross_join_t<Lhs, Rhs>::_(); check_pre_join_t<Lhs, Rhs>::_();
return {lhs, rhs}; return {lhs, rhs};
} }
template <typename Lhs, typename Rhs> template <typename Lhs, typename Rhs>
auto outer_join(Lhs lhs, Rhs rhs) -> typename std::conditional<check_cross_join_t<Lhs, Rhs>::value, auto outer_join(Lhs lhs, Rhs rhs) -> typename std::conditional<check_pre_join_t<Lhs, Rhs>::value,
cross_join_t<right_outer_join_t, Lhs, Rhs>, pre_join_t<right_outer_join_t, Lhs, Rhs>,
bad_statement>::type bad_statement>::type
{ {
check_cross_join_t<Lhs, Rhs>::_(); check_pre_join_t<Lhs, Rhs>::_();
return {lhs, rhs}; return {lhs, rhs};
} }
template <typename Lhs, typename Rhs>
auto cross_join(Lhs lhs, Rhs rhs) ->
typename std::conditional<check_pre_join_t<Lhs, Rhs>::value,
join_t<pre_join_t<cross_join_t, Lhs, Rhs>, on_t<unconditional_t>>,
bad_statement>::type
{
check_pre_join_t<Lhs, Rhs>::_();
return {pre_join_t<cross_join_t, Lhs, Rhs>{lhs, rhs}, {}};
}
} }
#endif #endif

View File

@ -97,6 +97,12 @@ namespace sqlpp
return {*static_cast<const Table*>(this)}; return {*static_cast<const Table*>(this)};
} }
template <typename T>
auto cross_join(T t) const -> decltype(::sqlpp::cross_join(std::declval<Table>(), t))
{
return ::sqlpp::cross_join(*static_cast<const Table*>(this), t);
}
const Table& ref() const const Table& ref() const
{ {
return *static_cast<const Table*>(this); return *static_cast<const Table*>(this);

View File

@ -90,6 +90,12 @@ namespace sqlpp
return ::sqlpp::outer_join(*this, t); return ::sqlpp::outer_join(*this, t);
} }
template <typename T>
auto cross_join(T t) const -> decltype(::sqlpp::cross_join(*this, t))
{
return ::sqlpp::cross_join(*this, t);
}
Table _table; Table _table;
}; };

View File

@ -169,9 +169,9 @@ namespace sqlpp
SQLPP_VALUE_TRAIT_GENERATOR(is_return_value) SQLPP_VALUE_TRAIT_GENERATOR(is_return_value)
SQLPP_VALUE_TRAIT_GENERATOR(is_table) SQLPP_VALUE_TRAIT_GENERATOR(is_table)
SQLPP_VALUE_TRAIT_GENERATOR(is_raw_table) SQLPP_VALUE_TRAIT_GENERATOR(is_raw_table)
SQLPP_VALUE_TRAIT_GENERATOR(is_cross_join) SQLPP_VALUE_TRAIT_GENERATOR(is_pre_join)
SQLPP_VALUE_TRAIT_GENERATOR(is_join) SQLPP_VALUE_TRAIT_GENERATOR(is_join)
SQLPP_VALUE_TRAIT_GENERATOR(is_dynamic_cross_join) SQLPP_VALUE_TRAIT_GENERATOR(is_dynamic_pre_join)
SQLPP_VALUE_TRAIT_GENERATOR(is_dynamic_join) SQLPP_VALUE_TRAIT_GENERATOR(is_dynamic_join)
SQLPP_VALUE_TRAIT_GENERATOR(is_pseudo_table) SQLPP_VALUE_TRAIT_GENERATOR(is_pseudo_table)
SQLPP_VALUE_TRAIT_GENERATOR(is_column) SQLPP_VALUE_TRAIT_GENERATOR(is_column)

View File

@ -79,7 +79,7 @@ namespace
{ {
// OK // OK
from_static_check<sqlpp::consistent_t>(t); from_static_check<sqlpp::consistent_t>(t);
from_static_check<sqlpp::consistent_t>(t.join(f).unconditionally()); from_static_check<sqlpp::consistent_t>(t.cross_join(f));
from_static_check<sqlpp::consistent_t>(t.join(f).on(t.alpha > f.omega)); from_static_check<sqlpp::consistent_t>(t.join(f).on(t.alpha > f.omega));
// Try a bunch of non-tables // Try a bunch of non-tables
@ -90,14 +90,14 @@ namespace
from_static_check<sqlpp::assert_from_table_t>(t.delta); from_static_check<sqlpp::assert_from_table_t>(t.delta);
// Try cross joins (missing condition) // Try cross joins (missing condition)
from_static_check<sqlpp::assert_from_not_cross_join_t>(t.join(f)); from_static_check<sqlpp::assert_from_not_pre_join_t>(t.join(f));
} }
void dynamic_from() void dynamic_from()
{ {
// OK // OK
from_dynamic_check<sqlpp::consistent_t>(t); from_dynamic_check<sqlpp::consistent_t>(t);
from_dynamic_check<sqlpp::consistent_t>(t.join(f).unconditionally()); from_dynamic_check<sqlpp::consistent_t>(t.cross_join(f));
from_dynamic_check<sqlpp::consistent_t>(t.join(f).on(t.alpha > f.omega)); from_dynamic_check<sqlpp::consistent_t>(t.join(f).on(t.alpha > f.omega));
// Try a bunch of non-tables // Try a bunch of non-tables
@ -108,7 +108,7 @@ namespace
from_dynamic_check<sqlpp::assert_from_table_t>(t.delta); from_dynamic_check<sqlpp::assert_from_table_t>(t.delta);
// Try cross joins (missing condition) // Try cross joins (missing condition)
from_dynamic_check<sqlpp::assert_from_not_cross_join_t>(t.join(f)); from_dynamic_check<sqlpp::assert_from_not_pre_join_t>(t.join(f));
} }
} }

View File

@ -47,7 +47,7 @@ namespace
template <typename Assert, typename Lhs, typename Rhs> template <typename Assert, typename Lhs, typename Rhs>
void join_static_check(const Lhs& lhs, const Rhs& rhs) void join_static_check(const Lhs& lhs, const Rhs& rhs)
{ {
using CheckResult = sqlpp::check_cross_join_t<Lhs, Rhs>; using CheckResult = sqlpp::check_pre_join_t<Lhs, Rhs>;
using ExpectedCheckResult = std::is_same<CheckResult, Assert>; using ExpectedCheckResult = std::is_same<CheckResult, Assert>;
print_type_on_error<CheckResult>(ExpectedCheckResult{}); print_type_on_error<CheckResult>(ExpectedCheckResult{});
static_assert(ExpectedCheckResult::value, "Unexpected check result"); static_assert(ExpectedCheckResult::value, "Unexpected check result");
@ -57,20 +57,23 @@ namespace
using LeftOuterJoinType = decltype(sqlpp::left_outer_join(lhs, rhs)); using LeftOuterJoinType = decltype(sqlpp::left_outer_join(lhs, rhs));
using RightOuterJoinType = decltype(sqlpp::right_outer_join(lhs, rhs)); using RightOuterJoinType = decltype(sqlpp::right_outer_join(lhs, rhs));
using OuterJoinType = decltype(sqlpp::outer_join(lhs, rhs)); using OuterJoinType = decltype(sqlpp::outer_join(lhs, rhs));
using CrossJoinType = decltype(sqlpp::cross_join(lhs, rhs));
using ExpectedReturnType = sqlpp::logic::all_t< using ExpectedReturnType = sqlpp::logic::all_t<
(Assert::value and sqlpp::is_cross_join_t<JoinType>::value and sqlpp::is_cross_join_t<InnerJoinType>::value and (Assert::value and sqlpp::is_pre_join_t<JoinType>::value and sqlpp::is_pre_join_t<InnerJoinType>::value and
sqlpp::is_cross_join_t<LeftOuterJoinType>::value and sqlpp::is_cross_join_t<RightOuterJoinType>::value and sqlpp::is_pre_join_t<LeftOuterJoinType>::value and sqlpp::is_pre_join_t<RightOuterJoinType>::value and
sqlpp::is_cross_join_t<OuterJoinType>::value) xor sqlpp::is_pre_join_t<OuterJoinType>::value and sqlpp::is_join_t<CrossJoinType>::value) xor
(std::is_same<JoinType, sqlpp::bad_statement>::value and (std::is_same<JoinType, sqlpp::bad_statement>::value and
std::is_same<InnerJoinType, sqlpp::bad_statement>::value and std::is_same<InnerJoinType, sqlpp::bad_statement>::value and
std::is_same<LeftOuterJoinType, sqlpp::bad_statement>::value and std::is_same<LeftOuterJoinType, sqlpp::bad_statement>::value and
std::is_same<RightOuterJoinType, sqlpp::bad_statement>::value and std::is_same<RightOuterJoinType, sqlpp::bad_statement>::value and
std::is_same<OuterJoinType, sqlpp::bad_statement>::value)>; std::is_same<OuterJoinType, sqlpp::bad_statement>::value and
std::is_same<CrossJoinType, sqlpp::bad_statement>::value)>;
print_type_on_error<JoinType>(ExpectedReturnType{}); print_type_on_error<JoinType>(ExpectedReturnType{});
print_type_on_error<InnerJoinType>(ExpectedReturnType{}); print_type_on_error<InnerJoinType>(ExpectedReturnType{});
print_type_on_error<LeftOuterJoinType>(ExpectedReturnType{}); print_type_on_error<LeftOuterJoinType>(ExpectedReturnType{});
print_type_on_error<RightOuterJoinType>(ExpectedReturnType{}); print_type_on_error<RightOuterJoinType>(ExpectedReturnType{});
print_type_on_error<OuterJoinType>(ExpectedReturnType{}); print_type_on_error<OuterJoinType>(ExpectedReturnType{});
print_type_on_error<CrossJoinType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type"); static_assert(ExpectedReturnType::value, "Unexpected return type");
} }
@ -108,7 +111,7 @@ namespace
join_static_check<sqlpp::consistent_t>(ta, t); join_static_check<sqlpp::consistent_t>(ta, t);
// Prepare a join for tests: // Prepare a join for tests:
const auto j = join(ta, tb).unconditionally(); const auto j = cross_join(ta, tb);
// OK: Add a third table // OK: Add a third table
join_static_check<sqlpp::consistent_t>(j, f); join_static_check<sqlpp::consistent_t>(j, f);
@ -116,35 +119,35 @@ namespace
join_static_check<sqlpp::consistent_t>(j, t); join_static_check<sqlpp::consistent_t>(j, t);
// Try a bunch of non-tables // Try a bunch of non-tables
join_static_check<sqlpp::assert_cross_join_rhs_table_t>(t, 7); join_static_check<sqlpp::assert_pre_join_rhs_table_t>(t, 7);
join_static_check<sqlpp::assert_cross_join_rhs_table_t>(t, t.alpha); join_static_check<sqlpp::assert_pre_join_rhs_table_t>(t, t.alpha);
join_static_check<sqlpp::assert_cross_join_rhs_table_t>(t, t.beta); join_static_check<sqlpp::assert_pre_join_rhs_table_t>(t, t.beta);
join_static_check<sqlpp::assert_cross_join_rhs_table_t>(t, t.gamma); join_static_check<sqlpp::assert_pre_join_rhs_table_t>(t, t.gamma);
join_static_check<sqlpp::assert_cross_join_rhs_table_t>(t, t.delta); join_static_check<sqlpp::assert_pre_join_rhs_table_t>(t, t.delta);
join_static_check<sqlpp::assert_cross_join_lhs_table_t>(7, t); join_static_check<sqlpp::assert_pre_join_lhs_table_t>(7, t);
join_static_check<sqlpp::assert_cross_join_lhs_table_t>(t.alpha, t); join_static_check<sqlpp::assert_pre_join_lhs_table_t>(t.alpha, t);
join_static_check<sqlpp::assert_cross_join_lhs_table_t>(t.beta, t); join_static_check<sqlpp::assert_pre_join_lhs_table_t>(t.beta, t);
join_static_check<sqlpp::assert_cross_join_lhs_table_t>(t.gamma, t); join_static_check<sqlpp::assert_pre_join_lhs_table_t>(t.gamma, t);
join_static_check<sqlpp::assert_cross_join_lhs_table_t>(t.delta, t); join_static_check<sqlpp::assert_pre_join_lhs_table_t>(t.delta, t);
// Try to join with join (rhs) // Try to join with join (rhs)
join_static_check<sqlpp::assert_cross_join_rhs_no_join_t>(t, j); join_static_check<sqlpp::assert_pre_join_rhs_no_join_t>(t, j);
join_static_check<sqlpp::assert_cross_join_rhs_no_join_t>(f, j); join_static_check<sqlpp::assert_pre_join_rhs_no_join_t>(f, j);
join_static_check<sqlpp::assert_cross_join_rhs_no_join_t>(t.as(sqlpp::alias::left), j); join_static_check<sqlpp::assert_pre_join_rhs_no_join_t>(t.as(sqlpp::alias::left), j);
// Try to join identical table names // Try to join identical table names
join_static_check<sqlpp::assert_cross_join_unique_names_t>(t, t); join_static_check<sqlpp::assert_pre_join_unique_names_t>(t, t);
join_static_check<sqlpp::assert_cross_join_unique_names_t>(f, f); join_static_check<sqlpp::assert_pre_join_unique_names_t>(f, f);
join_static_check<sqlpp::assert_cross_join_unique_names_t>(t.as(f), f); join_static_check<sqlpp::assert_pre_join_unique_names_t>(t.as(f), f);
join_static_check<sqlpp::assert_cross_join_unique_names_t>(t, f.as(t)); join_static_check<sqlpp::assert_pre_join_unique_names_t>(t, f.as(t));
join_static_check<sqlpp::assert_cross_join_unique_names_t>(ta, fa); join_static_check<sqlpp::assert_pre_join_unique_names_t>(ta, fa);
join_static_check<sqlpp::assert_cross_join_unique_names_t>(j, fa); join_static_check<sqlpp::assert_pre_join_unique_names_t>(j, fa);
join_static_check<sqlpp::assert_cross_join_unique_names_t>(j, fb); join_static_check<sqlpp::assert_pre_join_unique_names_t>(j, fb);
join_static_check<sqlpp::assert_cross_join_unique_names_t>(j, ta); join_static_check<sqlpp::assert_pre_join_unique_names_t>(j, ta);
join_static_check<sqlpp::assert_cross_join_unique_names_t>(j, tb); join_static_check<sqlpp::assert_pre_join_unique_names_t>(j, tb);
// Prepare a cross_joins for tests: // Prepare a pre_joins for tests:
const auto t_f = join(t, f); const auto t_f = join(t, f);
const auto f_t = join(f, t); const auto f_t = join(f, t);
const auto t_t = join(ta, tb); const auto t_t = join(ta, tb);
@ -176,7 +179,7 @@ namespace
template <typename Assert, typename Table> template <typename Assert, typename Table>
void join_dynamic_check(const Table& table) void join_dynamic_check(const Table& table)
{ {
using CheckResult = sqlpp::check_dynamic_cross_join_t<Table>; using CheckResult = sqlpp::check_dynamic_pre_join_t<Table>;
using ExpectedCheckResult = std::is_same<CheckResult, Assert>; using ExpectedCheckResult = std::is_same<CheckResult, Assert>;
print_type_on_error<CheckResult>(ExpectedCheckResult{}); print_type_on_error<CheckResult>(ExpectedCheckResult{});
static_assert(ExpectedCheckResult::value, "Unexpected check result"); static_assert(ExpectedCheckResult::value, "Unexpected check result");
@ -186,22 +189,25 @@ namespace
using LeftOuterJoinType = decltype(sqlpp::dynamic_left_outer_join(table)); using LeftOuterJoinType = decltype(sqlpp::dynamic_left_outer_join(table));
using RightOuterJoinType = decltype(sqlpp::dynamic_right_outer_join(table)); using RightOuterJoinType = decltype(sqlpp::dynamic_right_outer_join(table));
using OuterJoinType = decltype(sqlpp::dynamic_outer_join(table)); using OuterJoinType = decltype(sqlpp::dynamic_outer_join(table));
using ExpectedReturnType = using CrossJoinType = decltype(sqlpp::dynamic_cross_join(table));
sqlpp::logic::all_t<(Assert::value and sqlpp::is_dynamic_cross_join_t<JoinType>::value and using ExpectedReturnType = sqlpp::logic::all_t<(Assert::value and sqlpp::is_dynamic_pre_join_t<JoinType>::value and
sqlpp::is_dynamic_cross_join_t<InnerJoinType>::value and sqlpp::is_dynamic_pre_join_t<InnerJoinType>::value and
sqlpp::is_dynamic_cross_join_t<LeftOuterJoinType>::value and sqlpp::is_dynamic_pre_join_t<LeftOuterJoinType>::value and
sqlpp::is_dynamic_cross_join_t<RightOuterJoinType>::value and sqlpp::is_dynamic_pre_join_t<RightOuterJoinType>::value and
sqlpp::is_dynamic_cross_join_t<OuterJoinType>::value) xor sqlpp::is_dynamic_pre_join_t<OuterJoinType>::value and
(std::is_same<JoinType, sqlpp::bad_statement>::value and sqlpp::is_dynamic_join_t<CrossJoinType>::value) xor
std::is_same<InnerJoinType, sqlpp::bad_statement>::value and (std::is_same<JoinType, sqlpp::bad_statement>::value and
std::is_same<LeftOuterJoinType, sqlpp::bad_statement>::value and std::is_same<InnerJoinType, sqlpp::bad_statement>::value and
std::is_same<RightOuterJoinType, sqlpp::bad_statement>::value and std::is_same<LeftOuterJoinType, sqlpp::bad_statement>::value and
std::is_same<OuterJoinType, sqlpp::bad_statement>::value)>; std::is_same<RightOuterJoinType, sqlpp::bad_statement>::value and
std::is_same<OuterJoinType, sqlpp::bad_statement>::value and
std::is_same<CrossJoinType, sqlpp::bad_statement>::value)>;
print_type_on_error<JoinType>(ExpectedReturnType{}); print_type_on_error<JoinType>(ExpectedReturnType{});
print_type_on_error<InnerJoinType>(ExpectedReturnType{}); print_type_on_error<InnerJoinType>(ExpectedReturnType{});
print_type_on_error<LeftOuterJoinType>(ExpectedReturnType{}); print_type_on_error<LeftOuterJoinType>(ExpectedReturnType{});
print_type_on_error<RightOuterJoinType>(ExpectedReturnType{}); print_type_on_error<RightOuterJoinType>(ExpectedReturnType{});
print_type_on_error<OuterJoinType>(ExpectedReturnType{}); print_type_on_error<OuterJoinType>(ExpectedReturnType{});
print_type_on_error<CrossJoinType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type"); static_assert(ExpectedReturnType::value, "Unexpected return type");
} }
@ -233,17 +239,17 @@ namespace
join_dynamic_check<sqlpp::consistent_t>(fa); join_dynamic_check<sqlpp::consistent_t>(fa);
// Try a bunch of non-tables // Try a bunch of non-tables
join_dynamic_check<sqlpp::assert_dynamic_cross_join_table_t>(7); join_dynamic_check<sqlpp::assert_dynamic_pre_join_table_t>(7);
join_dynamic_check<sqlpp::assert_dynamic_cross_join_table_t>(t.alpha); join_dynamic_check<sqlpp::assert_dynamic_pre_join_table_t>(t.alpha);
join_dynamic_check<sqlpp::assert_dynamic_cross_join_table_t>(t.beta); join_dynamic_check<sqlpp::assert_dynamic_pre_join_table_t>(t.beta);
join_dynamic_check<sqlpp::assert_dynamic_cross_join_table_t>(t.gamma); join_dynamic_check<sqlpp::assert_dynamic_pre_join_table_t>(t.gamma);
join_dynamic_check<sqlpp::assert_dynamic_cross_join_table_t>(t.delta); join_dynamic_check<sqlpp::assert_dynamic_pre_join_table_t>(t.delta);
// Try (cross) joins // Try (pre) joins
join_dynamic_check<sqlpp::assert_dynamic_cross_join_table_t>(t.join(f)); join_dynamic_check<sqlpp::assert_dynamic_pre_join_table_t>(t.join(f));
join_dynamic_check<sqlpp::assert_dynamic_cross_join_no_join_t>(t.join(f).unconditionally()); join_dynamic_check<sqlpp::assert_dynamic_pre_join_no_join_t>(t.cross_join(f));
// Prepare a dynamic_cross_joins for tests: // Prepare a dynamic_pre_joins for tests:
const auto tj = dynamic_join(t); const auto tj = dynamic_join(t);
const auto fj = dynamic_join(f); const auto fj = dynamic_join(f);

View File

@ -146,7 +146,7 @@ int Select(int, char* [])
.dynamic_offset(); .dynamic_offset();
s.select_flags.add(sqlpp::distinct); s.select_flags.add(sqlpp::distinct);
s.selected_columns.add(f.omega); s.selected_columns.add(f.omega);
s.from.add(dynamic_join(f).unconditionally()); s.from.add(dynamic_cross_join(f));
s.where.add(t.alpha > 7); s.where.add(t.alpha > 7);
s.having.add(t.alpha > 7); s.having.add(t.alpha > 7);
s.limit.set(3); s.limit.set(3);

View File

@ -376,7 +376,7 @@ int SelectType(int, char* [])
auto s1 = sqlpp::select() auto s1 = sqlpp::select()
.flags(sqlpp::distinct, sqlpp::straight_join) .flags(sqlpp::distinct, sqlpp::straight_join)
.columns(l.gamma, r.a) .columns(l.gamma, r.a)
.from(r.join(t).unconditionally().join(l).unconditionally()) .from(r.cross_join(t).cross_join(l))
.where(t.beta == "hello world" and select(t.gamma).from(t)) // .as(alias::right)) .where(t.beta == "hello world" and select(t.gamma).from(t)) // .as(alias::right))
.group_by(l.gamma, r.a) .group_by(l.gamma, r.a)
.having(r.a != true) .having(r.a != true)