0
0
mirror of https://github.com/rbock/sqlpp11.git synced 2024-11-15 20:31:16 +08:00

Replaced recursive traits with local traits which are evaluated recursively

Ok, that sounds weird...

Earlier, each node in the SQL tree had a struct containing all recursive
traits. This is now gone. It only contains a reference to all sub nodes
and its own specific traits.
This commit is contained in:
rbock 2015-02-17 07:05:41 +01:00
parent 97de6fad7f
commit 436ef67072
69 changed files with 208 additions and 325 deletions

View File

@ -36,7 +36,7 @@ namespace sqlpp
struct expression_alias_t struct expression_alias_t
{ {
using _traits = make_traits<value_type_of<Expression>, tag::is_selectable, tag::is_alias>; using _traits = make_traits<value_type_of<Expression>, tag::is_selectable, tag::is_alias>;
using _recursive_traits = make_recursive_traits<Expression>; using _nodes = std::tuple<Expression>;
static_assert(is_expression_t<Expression>::value, "invalid argument for an expression alias"); static_assert(is_expression_t<Expression>::value, "invalid argument for an expression alias");
static_assert(not is_alias_t<Expression>::value, "cannot create an alias of an alias"); static_assert(not is_alias_t<Expression>::value, "cannot create an alias of an alias");

View File

@ -37,7 +37,7 @@ namespace sqlpp
struct any_t struct any_t
{ {
using _traits = make_traits<value_type_of<Select>, tag::is_multi_expression>; using _traits = make_traits<value_type_of<Select>, tag::is_multi_expression>;
using _recursive_traits = make_recursive_traits<Select>; using _nodes = std::tuple<Select>;
struct _alias_t struct _alias_t
{ {

View File

@ -41,7 +41,7 @@ namespace sqlpp
struct assignment_t struct assignment_t
{ {
using _traits = make_traits<no_value_t, tag::is_assignment>; using _traits = make_traits<no_value_t, tag::is_assignment>;
using _recursive_traits = make_recursive_traits<Lhs, Rhs>; using _nodes = std::tuple<Lhs, Rhs>;
using _lhs_t = Lhs; using _lhs_t = Lhs;
using _rhs_t = rhs_wrap_t<allow_tvin_t<Rhs>, trivial_value_is_null_t<_lhs_t>::value>; using _rhs_t = rhs_wrap_t<allow_tvin_t<Rhs>, trivial_value_is_null_t<_lhs_t>::value>;

View File

@ -38,7 +38,7 @@ namespace sqlpp
public alias_operators<avg_t<Flag, Expr>> public alias_operators<avg_t<Flag, Expr>>
{ {
using _traits = make_traits<floating_point, tag::is_expression, tag::is_selectable>; using _traits = make_traits<floating_point, tag::is_expression, tag::is_selectable>;
using _recursive_traits = make_recursive_traits<Expr, aggregate_function>; using _nodes = std::tuple<Expr, aggregate_function>;
static_assert(is_noop<Flag>::value or std::is_same<distinct_t, Flag>::value, "avg() used with flag other than 'distinct'"); static_assert(is_noop<Flag>::value or std::is_same<distinct_t, Flag>::value, "avg() used with flag other than 'distinct'");
static_assert(is_numeric_t<Expr>::value, "avg() requires a value expression as argument"); static_assert(is_numeric_t<Expr>::value, "avg() requires a value expression as argument");

View File

@ -36,7 +36,7 @@ namespace sqlpp
struct boolean_expression_t: public expression_operators<boolean_expression_t<Database>, boolean> struct boolean_expression_t: public expression_operators<boolean_expression_t<Database>, boolean>
{ {
using _traits = make_traits<boolean, tag::is_expression>; using _traits = make_traits<boolean, tag::is_expression>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
template<typename Expr> template<typename Expr>
boolean_expression_t(Expr expr): boolean_expression_t(Expr expr):

View File

@ -52,19 +52,9 @@ namespace sqlpp
using _tags = detail::make_joined_set_t<detail::type_set<tag::is_column, tag::is_expression, tag::is_selectable>, typename ColumnSpec::_traits::_tags>; using _tags = detail::make_joined_set_t<detail::type_set<tag::is_column, tag::is_expression, tag::is_selectable>, typename ColumnSpec::_traits::_tags>;
}; };
struct _recursive_traits using _nodes = std::tuple<>;
{ using _required_tables = detail::type_set<Table>;
using _required_ctes = detail::type_set<>; using _can_be_null = column_spec_can_be_null_t<ColumnSpec>;
using _provided_ctes = detail::type_set<>;
using _required_tables = detail::type_set<Table>;
using _provided_tables = detail::type_set<>;
using _provided_outer_tables = detail::type_set<>;
using _extra_tables = detail::type_set<>;
using _parameters = std::tuple<>;
using _tags = typename std::conditional<column_spec_can_be_null_t<ColumnSpec>::value,
detail::type_set<tag::can_be_null>,
detail::type_set<>>::type;
};
using _spec_t = ColumnSpec; using _spec_t = ColumnSpec;
using _table = Table; using _table = Table;

View File

@ -42,7 +42,7 @@ namespace sqlpp
public alias_operators<concat_t<First, Args...>> public alias_operators<concat_t<First, Args...>>
{ {
using _traits = make_traits<value_type_of<First>, tag::is_expression, tag::is_selectable>; using _traits = make_traits<value_type_of<First>, tag::is_expression, tag::is_selectable>;
using _recursive_traits = make_recursive_traits<First, Args...>; using _nodes = std::tuple<First, Args...>;
static_assert(sizeof...(Args) > 0, "concat requires two arguments at least"); static_assert(sizeof...(Args) > 0, "concat requires two arguments at least");
static_assert(logic::all_t<is_text_t<First>::value, is_text_t<Args>::value...>::value, "at least one non-text argument detected in concat()"); static_assert(logic::all_t<is_text_t<First>::value, is_text_t<Args>::value...>::value, "at least one non-text argument detected in concat()");

View File

@ -39,19 +39,9 @@ namespace sqlpp
public alias_operators<count_t<Flag, Expr>> public alias_operators<count_t<Flag, Expr>>
{ {
using _traits = make_traits<integral, tag::is_expression, tag::is_selectable>; using _traits = make_traits<integral, tag::is_expression, tag::is_selectable>;
struct _recursive_traits
{
using _required_ctes = required_ctes_of<Expr>;
using _provided_ctes = detail::type_set<>;
using _required_tables = required_tables_of<Expr>;
using _provided_tables = provided_tables_of<Expr>;
using _provided_outer_tables = provided_outer_tables_of<Expr>;
using _extra_tables = extra_tables_of<Expr>;
using _parameters = parameters_of<Expr>;
using _tags = detail::make_difference_set_t<detail::joined_set_t<recursive_tags_of<Expr>, recursive_tags_of<aggregate_function>>,
detail::type_set<tag::can_be_null>>;
};
using _nodes = std::tuple<Expr>;
using _can_be_null = std::false_type;
static_assert(is_noop<Flag>::value or std::is_same<distinct_t, Flag>::value, "count() used with flag other than 'distinct'"); static_assert(is_noop<Flag>::value or std::is_same<distinct_t, Flag>::value, "count() used with flag other than 'distinct'");

View File

@ -43,17 +43,9 @@ namespace sqlpp
template<typename Flag, typename Lhs, typename Rhs> template<typename Flag, typename Lhs, typename Rhs>
struct cte_union_t struct cte_union_t
{ {
struct _recursive_traits using _nodes = std::tuple<>;
{ using _required_ctes = detail::make_joined_set_t<required_ctes_of<Lhs>, required_ctes_of<Rhs>>;
using _required_ctes = detail::make_joined_set_t<required_ctes_of<Lhs>, required_ctes_of<Rhs>>; using _parameters = detail::make_parameter_tuple_t<parameters_of<Lhs>, parameters_of<Rhs>>;
using _provided_ctes = detail::type_set<>;
using _required_tables = detail::type_set<>;
using _provided_tables = detail::type_set<>;
using _provided_outer_tables = detail::type_set<>;
using _extra_tables = detail::type_set<>;
using _parameters = detail::make_parameter_tuple_t<parameters_of<Lhs>, parameters_of<Rhs>>;
using _tags = detail::type_set<>;
};
cte_union_t(Lhs lhs, Rhs rhs): cte_union_t(Lhs lhs, Rhs rhs):
_lhs(lhs), _lhs(lhs),
@ -140,17 +132,10 @@ namespace sqlpp
struct cte_t: public member_t<cte_column_spec_t<FieldSpecs>, column_t<AliasProvider, cte_column_spec_t<FieldSpecs>>>... struct cte_t: public member_t<cte_column_spec_t<FieldSpecs>, column_t<AliasProvider, cte_column_spec_t<FieldSpecs>>>...
{ {
using _traits = make_traits<no_value_t, tag::is_cte, tag::is_table>; // FIXME: is table? really? using _traits = make_traits<no_value_t, tag::is_cte, tag::is_table>; // FIXME: is table? really?
struct _recursive_traits using _nodes = std::tuple<>;
{ using _required_ctes = detail::make_joined_set_t<required_ctes_of<Statement>, detail::type_set<AliasProvider>>;
using _required_ctes = detail::make_joined_set_t<required_ctes_of<Statement>, detail::type_set<AliasProvider>>; using _parameters = parameters_of<Statement>;
using _provided_ctes = detail::type_set<>;
using _required_tables = detail::type_set<>;
using _provided_tables = detail::type_set<>;
using _provided_outer_tables = detail::type_set<>;
using _extra_tables = detail::type_set<>;
using _parameters = parameters_of<Statement>;
using _tags = detail::type_set<>;
};
using _alias_t = typename AliasProvider::_alias_t; using _alias_t = typename AliasProvider::_alias_t;
constexpr static bool _is_recursive = detail::is_element_of<AliasProvider, required_ctes_of<Statement>>::value; constexpr static bool _is_recursive = detail::is_element_of<AliasProvider, required_ctes_of<Statement>>::value;
@ -235,17 +220,9 @@ namespace sqlpp
struct cte_ref_t struct cte_ref_t
{ {
using _traits = make_traits<no_value_t, tag::is_alias, tag::is_cte, tag::is_table>; // FIXME: is table? really? using _traits = make_traits<no_value_t, tag::is_alias, tag::is_cte, tag::is_table>; // FIXME: is table? really?
struct _recursive_traits using _nodes = std::tuple<>;
{ using _required_ctes = detail::make_type_set_t<AliasProvider>;
using _required_ctes = detail::make_type_set_t<AliasProvider>; using _provided_tables = detail::type_set<AliasProvider>;
using _provided_ctes = detail::type_set<>;
using _required_tables = detail::type_set<>;
using _provided_tables = detail::type_set<AliasProvider>;
using _provided_outer_tables = detail::type_set<>;
using _extra_tables = detail::type_set<>;
using _parameters = std::tuple<>;
using _tags = detail::type_set<>;
};
using _alias_t = typename AliasProvider::_alias_t; using _alias_t = typename AliasProvider::_alias_t;

View File

@ -54,9 +54,9 @@ namespace sqlpp
{ {
using _methods_t = typename detail::custom_parts_t<Database, Parts...>::_result_methods_t; using _methods_t = typename detail::custom_parts_t<Database, Parts...>::_result_methods_t;
using _traits = make_traits<no_value_t, tag::is_statement>; using _traits = make_traits<no_value_t, tag::is_statement>;
using _recursive_traits = make_recursive_traits<Parts...>; using _nodes = std::tuple<Parts...>;
using _parameter_check = typename std::conditional<std::tuple_size<typename _recursive_traits::_parameters>::value == 0, using _parameter_check = typename std::conditional<std::tuple_size<parameters_of<custom_query_t>>::value == 0,
consistent_t, assert_no_parameters_t>::type; consistent_t, assert_no_parameters_t>::type;
using _run_check = detail::get_first_if<is_inconsistent_t, consistent_t, using _run_check = detail::get_first_if<is_inconsistent_t, consistent_t,
_parameter_check>; _parameter_check>;

View File

@ -34,7 +34,7 @@ namespace sqlpp
struct default_value_t struct default_value_t
{ {
using _traits = make_traits<no_value_t, tag::is_expression>; using _traits = make_traits<no_value_t, tag::is_expression>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
static constexpr bool _is_trivial() { return false; } static constexpr bool _is_trivial() { return false; }
}; };

View File

@ -38,7 +38,7 @@ namespace sqlpp
public alias_operators<exists_t<Select>> public alias_operators<exists_t<Select>>
{ {
using _traits = make_traits<boolean, tag::is_expression, tag::is_selectable>; using _traits = make_traits<boolean, tag::is_expression, tag::is_selectable>;
using _recursive_traits = make_recursive_traits<Select>; using _nodes = std::tuple<Select>;
static_assert(is_select_t<Select>::value, "exists() requires a select expression as argument"); static_assert(is_select_t<Select>::value, "exists() requires a select expression as argument");

View File

@ -44,7 +44,7 @@ namespace sqlpp
public alias_operators<binary_expression_t<Lhs, op::equal_to, Rhs>> public alias_operators<binary_expression_t<Lhs, op::equal_to, Rhs>>
{ {
using _traits = make_traits<boolean, tag::is_expression>; using _traits = make_traits<boolean, tag::is_expression>;
using _recursive_traits = make_recursive_traits<Lhs, Rhs>; using _nodes = std::tuple<Lhs, Rhs>;
using _lhs_t = Lhs; using _lhs_t = Lhs;
using _rhs_t = rhs_wrap_t<allow_tvin_t<Rhs>, trivial_value_is_null_t<_lhs_t>::value>; using _rhs_t = rhs_wrap_t<allow_tvin_t<Rhs>, trivial_value_is_null_t<_lhs_t>::value>;
@ -93,7 +93,7 @@ namespace sqlpp
public alias_operators<binary_expression_t<Lhs, op::not_equal_to, Rhs>> public alias_operators<binary_expression_t<Lhs, op::not_equal_to, Rhs>>
{ {
using _traits = make_traits<boolean, tag::is_expression>; using _traits = make_traits<boolean, tag::is_expression>;
using _recursive_traits = make_recursive_traits<Lhs, Rhs>; using _nodes = std::tuple<Lhs, Rhs>;
using _lhs_t = Lhs; using _lhs_t = Lhs;
using _rhs_t = rhs_wrap_t<allow_tvin_t<Rhs>, trivial_value_is_null_t<_lhs_t>::value>; using _rhs_t = rhs_wrap_t<allow_tvin_t<Rhs>, trivial_value_is_null_t<_lhs_t>::value>;
@ -142,7 +142,7 @@ namespace sqlpp
public alias_operators<unary_expression_t<op::logical_not, Rhs>> public alias_operators<unary_expression_t<op::logical_not, Rhs>>
{ {
using _traits = make_traits<boolean, tag::is_expression>; using _traits = make_traits<boolean, tag::is_expression>;
using _recursive_traits = make_recursive_traits<Rhs>; using _nodes = std::tuple<Rhs>;
unary_expression_t(Rhs rhs): unary_expression_t(Rhs rhs):
_rhs(rhs) _rhs(rhs)
@ -188,7 +188,7 @@ namespace sqlpp
public alias_operators<binary_expression_t<Lhs, O, Rhs>> public alias_operators<binary_expression_t<Lhs, O, Rhs>>
{ {
using _traits = make_traits<value_type_of<O>, tag::is_expression>; using _traits = make_traits<value_type_of<O>, tag::is_expression>;
using _recursive_traits = make_recursive_traits<Lhs, Rhs>; using _nodes = std::tuple<Lhs, Rhs>;
binary_expression_t(Lhs lhs, Rhs rhs): binary_expression_t(Lhs lhs, Rhs rhs):
_lhs(lhs), _lhs(lhs),
@ -228,7 +228,7 @@ namespace sqlpp
public alias_operators<unary_expression_t<O, Rhs>> public alias_operators<unary_expression_t<O, Rhs>>
{ {
using _traits = make_traits<value_type_of<O>, tag::is_expression>; using _traits = make_traits<value_type_of<O>, tag::is_expression>;
using _recursive_traits = make_recursive_traits<Rhs>; using _nodes = std::tuple<Rhs>;
unary_expression_t(Rhs rhs): unary_expression_t(Rhs rhs):
_rhs(rhs) _rhs(rhs)

View File

@ -52,17 +52,9 @@ namespace sqlpp
struct extra_tables_t struct extra_tables_t
{ {
using _traits = make_traits<no_value_t, tag::is_extra_tables>; using _traits = make_traits<no_value_t, tag::is_extra_tables>;
struct _recursive_traits using _nodes = std::tuple<>;
{ using _required_ctes = detail::make_joined_set_t<required_ctes_of<Tables>...>;
using _required_ctes = detail::make_joined_set_t<required_ctes_of<Tables>...>; using _extra_tables = detail::type_set<Tables...>;
using _provided_ctes = detail::type_set<>;
using _required_tables = detail::type_set<>;
using _provided_outer_tables = detail::type_set<>;
using _provided_tables = detail::type_set<>;
using _extra_tables = detail::type_set<Tables...>;
using _parameters = std::tuple<>;
using _tags = detail::type_set<>;
};
// Data // Data
using _data_t = extra_tables_data_t<Tables...>; using _data_t = extra_tables_data_t<Tables...>;
@ -98,7 +90,7 @@ namespace sqlpp
struct no_extra_tables_t struct no_extra_tables_t
{ {
using _traits = make_traits<no_value_t, tag::is_noop>; using _traits = make_traits<no_value_t, tag::is_noop>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
// Data // Data
using _data_t = no_data_t; using _data_t = no_data_t;

View File

@ -38,7 +38,7 @@ namespace sqlpp
tag_if<tag::can_be_null, CanBeNull>, tag_if<tag::can_be_null, CanBeNull>,
tag_if<tag::null_is_trivial_value, NullIsTrivialValue> tag_if<tag::null_is_trivial_value, NullIsTrivialValue>
>; >;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
using _alias_t = NameType; using _alias_t = NameType;
}; };

View File

@ -61,7 +61,7 @@ namespace sqlpp
struct from_t struct from_t
{ {
using _traits = make_traits<no_value_t, tag::is_from>; using _traits = make_traits<no_value_t, tag::is_from>;
using _recursive_traits = make_recursive_traits<Tables...>; using _nodes = std::tuple<Tables...>;
using _is_dynamic = is_database<Database>; using _is_dynamic = is_database<Database>;
// Data // Data
@ -125,7 +125,7 @@ namespace sqlpp
struct no_from_t struct no_from_t
{ {
using _traits = make_traits<no_value_t, tag::is_noop>; using _traits = make_traits<no_value_t, tag::is_noop>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
// Data // Data
using _data_t = no_data_t; using _data_t = no_data_t;

View File

@ -82,7 +82,7 @@ namespace sqlpp
struct value_list_t // to be used in .in() method struct value_list_t // to be used in .in() method
{ {
using _traits = make_traits<value_type_t<typename Container::value_type>, tag::is_expression>; using _traits = make_traits<value_type_t<typename Container::value_type>, tag::is_expression>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
using _container_t = Container; using _container_t = Container;

View File

@ -71,7 +71,7 @@ namespace sqlpp
struct group_by_t struct group_by_t
{ {
using _traits = make_traits<no_value_t, tag::is_group_by>; using _traits = make_traits<no_value_t, tag::is_group_by>;
using _recursive_traits = make_recursive_traits<Expressions...>; using _nodes = std::tuple<Expressions...>;
using _is_dynamic = is_database<Database>; using _is_dynamic = is_database<Database>;
@ -141,7 +141,7 @@ namespace sqlpp
struct no_group_by_t struct no_group_by_t
{ {
using _traits = make_traits<no_value_t, tag::is_noop>; using _traits = make_traits<no_value_t, tag::is_noop>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
// Data // Data
using _data_t = no_data_t; using _data_t = no_data_t;

View File

@ -70,7 +70,7 @@ namespace sqlpp
struct having_t struct having_t
{ {
using _traits = make_traits<no_value_t, tag::is_having>; using _traits = make_traits<no_value_t, tag::is_having>;
using _recursive_traits = make_recursive_traits<Expressions...>; using _nodes = std::tuple<Expressions...>;
using _is_dynamic = is_database<Database>; using _is_dynamic = is_database<Database>;
@ -141,7 +141,7 @@ namespace sqlpp
struct no_having_t struct no_having_t
{ {
using _traits = make_traits<no_value_t, tag::is_noop>; using _traits = make_traits<no_value_t, tag::is_noop>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
// Data // Data
using _data_t = no_data_t; using _data_t = no_data_t;

View File

@ -41,7 +41,7 @@ namespace sqlpp
public alias_operators<in_t<Operand, Args...>> public alias_operators<in_t<Operand, Args...>>
{ {
using _traits = make_traits<boolean, tag::is_expression, tag::is_selectable>; using _traits = make_traits<boolean, tag::is_expression, tag::is_selectable>;
using _recursive_traits = make_recursive_traits<Operand, Args...>; using _nodes = std::tuple<Operand, Args...>;
static_assert(sizeof...(Args) > 0, "in() requires at least one argument"); static_assert(sizeof...(Args) > 0, "in() requires at least one argument");

View File

@ -50,7 +50,7 @@ namespace sqlpp
struct type struct type
{ {
using _traits = make_traits<no_value_t, tag::is_noop>; using _traits = make_traits<no_value_t, tag::is_noop>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
}; };
}; };
} }

View File

@ -64,7 +64,7 @@ namespace sqlpp
struct insert_default_values_t struct insert_default_values_t
{ {
using _traits = make_traits<no_value_t>; using _traits = make_traits<no_value_t>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
// Data // Data
using _data_t = insert_default_values_data_t; using _data_t = insert_default_values_data_t;
@ -133,7 +133,7 @@ namespace sqlpp
struct insert_list_t struct insert_list_t
{ {
using _traits = make_traits<no_value_t, tag::is_insert_list>; using _traits = make_traits<no_value_t, tag::is_insert_list>;
using _recursive_traits = make_recursive_traits<lhs_t<Assignments>..., rhs_t<Assignments>...>; using _nodes = std::tuple<lhs_t<Assignments>..., rhs_t<Assignments>...>;
using _is_dynamic = is_database<Database>; using _is_dynamic = is_database<Database>;
@ -245,7 +245,7 @@ namespace sqlpp
struct column_list_t struct column_list_t
{ {
using _traits = make_traits<no_value_t, tag::is_column_list>; using _traits = make_traits<no_value_t, tag::is_column_list>;
using _recursive_traits = make_recursive_traits<Columns...>; using _nodes = std::tuple<Columns...>;
using _value_tuple_t = typename column_list_data_t<Columns...>::_value_tuple_t; using _value_tuple_t = typename column_list_data_t<Columns...>::_value_tuple_t;
@ -322,7 +322,7 @@ namespace sqlpp
struct no_insert_value_list_t struct no_insert_value_list_t
{ {
using _traits = make_traits<no_value_t, tag::is_noop>; using _traits = make_traits<no_value_t, tag::is_noop>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
// Data // Data
using _data_t = no_data_t; using _data_t = no_data_t;

View File

@ -59,7 +59,7 @@ namespace sqlpp
struct into_t struct into_t
{ {
using _traits = make_traits<no_value_t, tag::is_into>; using _traits = make_traits<no_value_t, tag::is_into>;
using _recursive_traits = make_recursive_traits<Table>; using _nodes = std::tuple<Table>;
using _data_t = into_data_t<Database, Table>; using _data_t = into_data_t<Database, Table>;
@ -108,7 +108,7 @@ namespace sqlpp
struct no_into_t struct no_into_t
{ {
using _traits = make_traits<no_value_t, tag::is_noop>; using _traits = make_traits<no_value_t, tag::is_noop>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
// Data // Data
using _data_t = no_data_t; using _data_t = no_data_t;

View File

@ -40,7 +40,7 @@ namespace sqlpp
public alias_operators<is_not_null_t<Operand>> public alias_operators<is_not_null_t<Operand>>
{ {
using _traits = make_traits<boolean, tag::is_expression, tag::is_selectable>; using _traits = make_traits<boolean, tag::is_expression, tag::is_selectable>;
using _recursive_traits = make_recursive_traits<Operand>; using _nodes = std::tuple<Operand>;
struct _alias_t struct _alias_t
{ {

View File

@ -40,7 +40,7 @@ namespace sqlpp
public alias_operators<is_null_t<Operand>> public alias_operators<is_null_t<Operand>>
{ {
using _traits = make_traits<boolean, tag::is_expression, tag::is_selectable>; using _traits = make_traits<boolean, tag::is_expression, tag::is_selectable>;
using _recursive_traits = make_recursive_traits<Operand>; using _nodes = std::tuple<Operand>;
struct _alias_t struct _alias_t
{ {

View File

@ -66,18 +66,8 @@ namespace sqlpp
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>;
struct _recursive_traits using _nodes = std::tuple<Lhs, Rhs>;
{ using _can_be_null = std::false_type;
using _required_ctes = detail::make_joined_set_t<required_ctes_of<Lhs>, required_ctes_of<Rhs>>;
using _provided_ctes = detail::type_set<>;
using _required_tables = detail::make_joined_set_t<required_tables_of<Lhs>, required_tables_of<Rhs>>;
using _provided_tables = detail::make_joined_set_t<provided_tables_of<Lhs>, provided_tables_of<Rhs>>;
using _provided_outer_tables = typename JoinType::template _provided_outer_tables<Lhs, Rhs>;
using _extra_tables = detail::make_joined_set_t<extra_tables_of<Lhs>, extra_tables_of<Rhs>>;
using _parameters = detail::make_parameter_tuple_t<parameters_of<Lhs>, parameters_of<Rhs>>;
using _tags = detail::type_set<>;
};
static_assert(is_table_t<Lhs>::value, "lhs argument for join() has to be a table or join"); static_assert(is_table_t<Lhs>::value, "lhs argument for join() has to be a table or join");
static_assert(is_table_t<Rhs>::value, "rhs argument for join() has to be a table"); static_assert(is_table_t<Rhs>::value, "rhs argument for join() has to be a table");
@ -86,7 +76,7 @@ namespace sqlpp
static_assert(detail::is_disjunct_from<provided_tables_of<Lhs>, provided_tables_of<Rhs>>::value, "joined tables must not be identical"); static_assert(detail::is_disjunct_from<provided_tables_of<Lhs>, provided_tables_of<Rhs>>::value, "joined tables must not be identical");
static_assert(_recursive_traits::_required_tables::size::value == 0, "joined tables must not depend on other tables"); static_assert(required_tables_of<join_t>::size::value == 0, "joined tables must not depend on other tables");
template<typename OnT> template<typename OnT>
using set_on_t = join_t<JoinType, Lhs, Rhs, OnT>; using set_on_t = join_t<JoinType, Lhs, Rhs, OnT>;

View File

@ -40,7 +40,7 @@ namespace sqlpp
public alias_operators<like_t<Operand, Pattern>> public alias_operators<like_t<Operand, Pattern>>
{ {
using _traits = make_traits<boolean, tag::is_expression, tag::is_selectable>; using _traits = make_traits<boolean, tag::is_expression, tag::is_selectable>;
using _recursive_traits = make_recursive_traits<Operand, Pattern>; using _nodes = std::tuple<Operand, Pattern>;
struct _alias_t struct _alias_t
{ {

View File

@ -55,7 +55,7 @@ namespace sqlpp
struct limit_t struct limit_t
{ {
using _traits = make_traits<no_value_t, tag::is_limit>; using _traits = make_traits<no_value_t, tag::is_limit>;
using _recursive_traits = make_recursive_traits<Limit>; using _nodes = std::tuple<Limit>;
// Data // Data
using _data_t = limit_data_t<Limit>; using _data_t = limit_data_t<Limit>;
@ -118,7 +118,7 @@ namespace sqlpp
struct dynamic_limit_t struct dynamic_limit_t
{ {
using _traits = make_traits<no_value_t, tag::is_limit>; using _traits = make_traits<no_value_t, tag::is_limit>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
// Data // Data
using _data_t = dynamic_limit_data_t<Database>; using _data_t = dynamic_limit_data_t<Database>;
@ -163,7 +163,7 @@ namespace sqlpp
struct no_limit_t struct no_limit_t
{ {
using _traits = make_traits<no_value_t, tag::is_noop>; using _traits = make_traits<no_value_t, tag::is_noop>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
// Data // Data
using _data_t = no_data_t; using _data_t = no_data_t;

View File

@ -38,7 +38,7 @@ namespace sqlpp
public alias_operators<max_t<Expr>> public alias_operators<max_t<Expr>>
{ {
using _traits = make_traits<value_type_of<Expr>, tag::is_expression, tag::is_selectable>; using _traits = make_traits<value_type_of<Expr>, tag::is_expression, tag::is_selectable>;
using _recursive_traits = make_recursive_traits<Expr, aggregate_function>; using _nodes = std::tuple<Expr, aggregate_function>;
struct _alias_t struct _alias_t
{ {

View File

@ -38,7 +38,7 @@ namespace sqlpp
public alias_operators<min_t<Expr>> public alias_operators<min_t<Expr>>
{ {
using _traits = make_traits<value_type_of<Expr>, tag::is_expression, tag::is_selectable>; using _traits = make_traits<value_type_of<Expr>, tag::is_expression, tag::is_selectable>;
using _recursive_traits = make_recursive_traits<Expr, aggregate_function>; using _nodes = std::tuple<Expr, aggregate_function>;
struct _alias_t struct _alias_t
{ {

View File

@ -42,7 +42,7 @@ namespace sqlpp
struct multi_column_t struct multi_column_t
{ {
using _traits = make_traits<no_value_t>; using _traits = make_traits<no_value_t>;
using _recursive_traits = make_recursive_traits<Columns...>; using _nodes = std::tuple<Columns...>;
static_assert(logic::all_t<is_selectable_t<Columns>::value...>::value, "multi_column parameters need to be named expressions"); static_assert(logic::all_t<is_selectable_t<Columns>::value...>::value, "multi_column parameters need to be named expressions");
@ -73,7 +73,7 @@ namespace sqlpp
struct multi_column_alias_t struct multi_column_alias_t
{ {
using _traits = make_traits<no_value_t, tag::is_alias, tag::is_multi_column, tag::is_selectable>; using _traits = make_traits<no_value_t, tag::is_alias, tag::is_multi_column, tag::is_selectable>;
using _recursive_traits = make_recursive_traits<Columns...>; using _nodes = std::tuple<Columns...>;
static_assert(logic::all_t<is_selectable_t<Columns>::value...>::value, "multi_column parameters need to be named expressions"); static_assert(logic::all_t<is_selectable_t<Columns>::value...>::value, "multi_column parameters need to be named expressions");

View File

@ -37,7 +37,7 @@ namespace sqlpp
struct noop struct noop
{ {
using _traits = make_traits<no_value_t, tag::is_noop>; using _traits = make_traits<no_value_t, tag::is_noop>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
struct _alias_t {}; struct _alias_t {};

View File

@ -41,7 +41,7 @@ namespace sqlpp
public alias_operators<not_in_t<Operand, Args...>> public alias_operators<not_in_t<Operand, Args...>>
{ {
using _traits = make_traits<boolean, tag::is_expression, tag::is_selectable>; using _traits = make_traits<boolean, tag::is_expression, tag::is_selectable>;
using _recursive_traits = make_recursive_traits<Operand, Args...>; using _nodes = std::tuple<Operand, Args...>;
static_assert(sizeof...(Args) > 0, "not_in() requires at least one argument"); static_assert(sizeof...(Args) > 0, "not_in() requires at least one argument");

View File

@ -34,7 +34,7 @@ namespace sqlpp
struct null_t struct null_t
{ {
using _traits = make_traits<no_value_t, tag::is_expression, tag::is_sql_null>; using _traits = make_traits<no_value_t, tag::is_expression, tag::is_sql_null>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
}; };
template<typename Context> template<typename Context>

View File

@ -55,7 +55,7 @@ namespace sqlpp
struct offset_t struct offset_t
{ {
using _traits = make_traits<no_value_t, tag::is_offset>; using _traits = make_traits<no_value_t, tag::is_offset>;
using _recursive_traits = make_recursive_traits<Offset>; using _nodes = std::tuple<Offset>;
static_assert(is_integral_t<Offset>::value, "offset requires an integral value or integral parameter"); static_assert(is_integral_t<Offset>::value, "offset requires an integral value or integral parameter");
@ -120,7 +120,7 @@ namespace sqlpp
struct dynamic_offset_t struct dynamic_offset_t
{ {
using _traits = make_traits<no_value_t, tag::is_offset>; using _traits = make_traits<no_value_t, tag::is_offset>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
// Data // Data
using _data_t = dynamic_offset_data_t<Database>; using _data_t = dynamic_offset_data_t<Database>;
@ -177,7 +177,7 @@ namespace sqlpp
struct no_offset_t struct no_offset_t
{ {
using _traits = make_traits<no_value_t, tag::is_noop>; using _traits = make_traits<no_value_t, tag::is_noop>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
// Data // Data
using _data_t = no_data_t; using _data_t = no_data_t;

View File

@ -38,7 +38,7 @@ namespace sqlpp
struct on_t struct on_t
{ {
using _traits = make_traits<no_value_t, tag::is_on>; using _traits = make_traits<no_value_t, tag::is_on>;
using _recursive_traits = make_recursive_traits<Expressions...>; using _nodes = std::tuple<Expressions...>;
using _is_dynamic = is_database<Database>; using _is_dynamic = is_database<Database>;

View File

@ -71,7 +71,7 @@ namespace sqlpp
struct order_by_t struct order_by_t
{ {
using _traits = make_traits<no_value_t, tag::is_order_by>; using _traits = make_traits<no_value_t, tag::is_order_by>;
using _recursive_traits = make_recursive_traits<Expressions...>; using _nodes = std::tuple<Expressions...>;
using _is_dynamic = is_database<Database>; using _is_dynamic = is_database<Database>;
@ -141,7 +141,7 @@ namespace sqlpp
struct no_order_by_t struct no_order_by_t
{ {
using _traits = make_traits<no_value_t, tag::is_noop>; using _traits = make_traits<no_value_t, tag::is_noop>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
// Data // Data
using _data_t = no_data_t; using _data_t = no_data_t;

View File

@ -38,17 +38,10 @@ namespace sqlpp
public expression_operators<parameter_t<ValueType, NameType>, ValueType> public expression_operators<parameter_t<ValueType, NameType>, ValueType>
{ {
using _traits = make_traits<ValueType, tag::is_parameter, tag::is_expression>; using _traits = make_traits<ValueType, tag::is_parameter, tag::is_expression>;
struct _recursive_traits
{ using _nodes = std::tuple<>;
using _required_ctes = detail::type_set<>; using _parameters = std::tuple<parameter_t>;
using _provided_ctes = detail::type_set<>; using _can_be_null = std::true_type;
using _required_tables = detail::type_set<>;
using _provided_tables = detail::type_set<>;
using _provided_outer_tables = detail::type_set<>;
using _extra_tables = detail::type_set<>;
using _parameters = std::tuple<parameter_t>;
using _tags = detail::type_set<tag::can_be_null>;
};
using _instance_t = member_t<NameType, parameter_value_t<ValueType>>; using _instance_t = member_t<NameType, parameter_value_t<ValueType>>;

View File

@ -37,7 +37,7 @@ namespace sqlpp
struct prepared_execute_t struct prepared_execute_t
{ {
using _traits = make_traits<no_value_t, tag::is_prepared_statement>; using _traits = make_traits<no_value_t, tag::is_prepared_statement>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
using _parameter_list_t = make_parameter_list_t<Statement>; using _parameter_list_t = make_parameter_list_t<Statement>;
using _prepared_statement_t = typename Db::_prepared_statement_t; using _prepared_statement_t = typename Db::_prepared_statement_t;

View File

@ -37,7 +37,7 @@ namespace sqlpp
struct prepared_insert_t struct prepared_insert_t
{ {
using _traits = make_traits<no_value_t, tag::is_prepared_statement>; using _traits = make_traits<no_value_t, tag::is_prepared_statement>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
using _parameter_list_t = make_parameter_list_t<Insert>; using _parameter_list_t = make_parameter_list_t<Insert>;
using _prepared_statement_t = typename Db::_prepared_statement_t; using _prepared_statement_t = typename Db::_prepared_statement_t;

View File

@ -37,7 +37,7 @@ namespace sqlpp
struct prepared_remove_t struct prepared_remove_t
{ {
using _traits = make_traits<no_value_t, tag::is_prepared_statement>; using _traits = make_traits<no_value_t, tag::is_prepared_statement>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
using _parameter_list_t = make_parameter_list_t<Remove>; using _parameter_list_t = make_parameter_list_t<Remove>;
using _prepared_statement_t = typename Db::_prepared_statement_t; using _prepared_statement_t = typename Db::_prepared_statement_t;

View File

@ -37,7 +37,7 @@ namespace sqlpp
struct prepared_select_t struct prepared_select_t
{ {
using _traits = make_traits<no_value_t, tag::is_prepared_statement>; using _traits = make_traits<no_value_t, tag::is_prepared_statement>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
using _result_row_t = typename Statement::template _result_row_t<Database>; using _result_row_t = typename Statement::template _result_row_t<Database>;
using _parameter_list_t = make_parameter_list_t<Composite>; using _parameter_list_t = make_parameter_list_t<Composite>;

View File

@ -37,7 +37,7 @@ namespace sqlpp
struct prepared_update_t struct prepared_update_t
{ {
using _traits = make_traits<no_value_t, tag::is_prepared_statement>; using _traits = make_traits<no_value_t, tag::is_prepared_statement>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
using _parameter_list_t = make_parameter_list_t<Update>; using _parameter_list_t = make_parameter_list_t<Update>;
using _prepared_statement_t = typename Db::_prepared_statement_t; using _prepared_statement_t = typename Db::_prepared_statement_t;

View File

@ -81,20 +81,8 @@ namespace sqlpp
tag::is_expression, tag::is_expression,
tag_if<tag::null_is_trivial_value, _base_t::_null_is_trivial>>; tag_if<tag::null_is_trivial_value, _base_t::_null_is_trivial>>;
struct _recursive_traits using _nodes = std::tuple<>;
{ using _can_be_null = column_spec_can_be_null_t<_field_spec_t>;
using _required_ctes = detail::type_set<>;
using _provided_ctes = detail::type_set<>;
using _required_tables = detail::type_set<>;
using _provided_tables = detail::type_set<>;
using _provided_outer_tables = detail::type_set<>;
using _extra_tables = detail::type_set<>;
using _parameters = std::tuple<>;
using _tags = typename std::conditional<column_spec_can_be_null_t<_field_spec_t>::value,
detail::type_set<tag::can_be_null>,
detail::type_set<>>::type;
};
}; };
} }

View File

@ -185,7 +185,7 @@ namespace sqlpp
struct _field_spec_t struct _field_spec_t
{ {
using _traits = make_traits<text, tag::is_noop, tag::can_be_null, tag::null_is_trivial_value>; using _traits = make_traits<text, tag::is_noop, tag::can_be_null, tag::null_is_trivial_value>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
struct _alias_t {}; struct _alias_t {};
}; };

View File

@ -118,7 +118,7 @@ namespace sqlpp
struct rhs_wrap_t struct rhs_wrap_t
{ {
using _traits = typename Expr::_traits; using _traits = typename Expr::_traits;
using _recursive_traits = typename Expr::_recursive_traits; using _nodes = std::tuple<Expr>;
rhs_wrap_t(Expr expr): rhs_wrap_t(Expr expr):
_expr(expr) _expr(expr)

View File

@ -164,7 +164,7 @@ namespace sqlpp
struct select_column_list_t struct select_column_list_t
{ {
using _traits = typename detail::select_traits<Columns...>::_traits; using _traits = typename detail::select_traits<Columns...>::_traits;
using _recursive_traits = make_recursive_traits<Columns...>; using _nodes = std::tuple<Columns...>;
using _alias_t = typename detail::select_traits<Columns...>::_alias_t; using _alias_t = typename detail::select_traits<Columns...>::_alias_t;
@ -353,7 +353,7 @@ namespace sqlpp
struct no_select_column_list_t struct no_select_column_list_t
{ {
using _traits = make_traits<no_value_t, tag::is_noop, tag::is_missing>; using _traits = make_traits<no_value_t, tag::is_noop, tag::is_missing>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
struct _alias_t {}; struct _alias_t {};

View File

@ -60,7 +60,7 @@ namespace sqlpp
struct select_flag_list_t struct select_flag_list_t
{ {
using _traits = make_traits<no_value_t, tag::is_select_flag_list>; using _traits = make_traits<no_value_t, tag::is_select_flag_list>;
using _recursive_traits = make_recursive_traits<Flags...>; using _nodes = std::tuple<Flags...>;
using _is_dynamic = is_database<Database>; using _is_dynamic = is_database<Database>;
@ -128,7 +128,7 @@ namespace sqlpp
struct no_select_flag_list_t struct no_select_flag_list_t
{ {
using _traits = make_traits<no_value_t, tag::is_noop>; using _traits = make_traits<no_value_t, tag::is_noop>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
// Data // Data
using _data_t = no_data_t; using _data_t = no_data_t;

View File

@ -38,7 +38,7 @@ namespace sqlpp
struct all_t struct all_t
{ {
using _traits = make_traits<no_value_t, tag::is_select_flag>; using _traits = make_traits<no_value_t, tag::is_select_flag>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
}; };
static constexpr all_t all = {}; static constexpr all_t all = {};
@ -57,7 +57,7 @@ namespace sqlpp
struct distinct_t struct distinct_t
{ {
using _traits = make_traits<no_value_t, tag::is_select_flag>; using _traits = make_traits<no_value_t, tag::is_select_flag>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
}; };
static constexpr distinct_t distinct = {}; static constexpr distinct_t distinct = {};
@ -76,7 +76,7 @@ namespace sqlpp
struct straight_join_t struct straight_join_t
{ {
using _traits = make_traits<no_value_t, tag::is_select_flag>; using _traits = make_traits<no_value_t, tag::is_select_flag>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
}; };
static constexpr straight_join_t straight_join = {}; static constexpr straight_join_t straight_join = {};

View File

@ -58,7 +58,7 @@ namespace sqlpp
NamedExpr...>, select_column_spec_t<Select, NamedExpr>...> NamedExpr...>, select_column_spec_t<Select, NamedExpr>...>
{ {
using _traits = make_traits<no_value_t, tag::is_table, tag::is_pseudo_table>; using _traits = make_traits<no_value_t, tag::is_table, tag::is_pseudo_table>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
select_pseudo_table_t(Select select): select_pseudo_table_t(Select select):
_select(select) _select(select)

View File

@ -39,7 +39,7 @@ namespace sqlpp
_column_t _column; _column_t _column;
using _traits = make_traits<no_value_t, tag::is_noop>; using _traits = make_traits<no_value_t, tag::is_noop>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
}; };
template<typename Context, typename Column> template<typename Context, typename Column>

View File

@ -58,7 +58,7 @@ namespace sqlpp
struct single_table_t struct single_table_t
{ {
using _traits = make_traits<no_value_t, tag::is_single_table>; using _traits = make_traits<no_value_t, tag::is_single_table>;
using _recursive_traits = make_recursive_traits<Table>; using _nodes = std::tuple<Table>;
static_assert(is_table_t<Table>::value, "argument has to be a table"); static_assert(is_table_t<Table>::value, "argument has to be a table");
static_assert(required_tables_of<Table>::size::value == 0, "table depends on another table"); static_assert(required_tables_of<Table>::size::value == 0, "table depends on another table");
@ -99,7 +99,7 @@ namespace sqlpp
struct no_single_table_t struct no_single_table_t
{ {
using _traits = make_traits<no_value_t, tag::is_noop>; using _traits = make_traits<no_value_t, tag::is_noop>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
// Data // Data
using _data_t = no_data_t; using _data_t = no_data_t;

View File

@ -37,7 +37,7 @@ namespace sqlpp
struct some_t struct some_t
{ {
using _traits = make_traits<value_type_of<Select>, tag::is_multi_expression>; using _traits = make_traits<value_type_of<Select>, tag::is_multi_expression>;
using _recursive_traits = make_recursive_traits<Select>; using _nodes = std::tuple<Select>;
struct _alias_t struct _alias_t
{ {

View File

@ -42,7 +42,7 @@ namespace sqlpp
struct sort_order_t struct sort_order_t
{ {
using _traits = make_traits<no_value_t, tag::is_sort_order>; using _traits = make_traits<no_value_t, tag::is_sort_order>;
using _recursive_traits = make_recursive_traits<Expression>; using _nodes = std::tuple<Expression>;
Expression _expression; Expression _expression;
}; };

View File

@ -146,34 +146,23 @@ namespace sqlpp
no_value_t // if a required statement part is missing (e.g. columns in a select), then the statement cannot be used as a value no_value_t // if a required statement part is missing (e.g. columns in a select), then the statement cannot be used as a value
>::type; >::type;
using _traits = make_traits<_value_type, tag_if<tag::is_expression, not std::is_same<_value_type, no_value_t>::value>>;
using _nodes = std::tuple<>;
using _can_be_null = logic::any_t< using _can_be_null = logic::any_t<
can_be_null_t<_result_type_provider>::value, can_be_null_t<_result_type_provider>::value,
detail::make_intersect_set_t< detail::make_intersect_set_t<
required_tables_of<_result_type_provider>, required_tables_of<_result_type_provider>,
_all_provided_outer_tables _all_provided_outer_tables
>::size::value != 0>; >::size::value != 0>;
using _parameters = detail::make_parameter_tuple_t<parameters_of<Policies>...>;
using _traits = make_traits<_value_type, tag_if<tag::is_expression, not std::is_same<_value_type, no_value_t>::value>>; // required_tables and _required_ctes are defined above
struct _recursive_traits
{
using _required_ctes = statement_policies_t::_required_ctes;
using _provided_ctes = detail::type_set<>;
using _required_tables = statement_policies_t::_required_tables;
using _provided_tables = detail::type_set<>;
using _provided_outer_tables = detail::type_set<>;
using _extra_tables = detail::type_set<>;
using _parameters = detail::make_parameter_tuple_t<parameters_of<Policies>...>;
using _tags = typename std::conditional<_can_be_null::value,
detail::type_set<tag::can_be_null>,
detail::type_set<>>::type;
};
using _cte_check = typename std::conditional<_required_ctes::size::value == 0, using _cte_check = typename std::conditional<_required_ctes::size::value == 0,
consistent_t, assert_no_unknown_ctes_t>::type; consistent_t, assert_no_unknown_ctes_t>::type;
using _table_check = typename std::conditional<_required_tables::size::value == 0, using _table_check = typename std::conditional<_required_tables::size::value == 0,
consistent_t, assert_no_unknown_tables_t>::type; consistent_t, assert_no_unknown_tables_t>::type;
using _parameter_check = typename std::conditional<std::tuple_size<typename _recursive_traits::_parameters>::value == 0, using _parameter_check = typename std::conditional<std::tuple_size<_parameters>::value == 0,
consistent_t, assert_no_parameters_t>::type; consistent_t, assert_no_parameters_t>::type;
}; };
} }
@ -212,7 +201,7 @@ namespace sqlpp
tag_if<tag::is_selectable, is_expression_t<_policies_t>::value>, tag_if<tag::is_selectable, is_expression_t<_policies_t>::value>,
tag_if<tag::is_return_value, logic::none_t<is_noop_t<_result_type_provider>::value>::value>, tag_if<tag::is_return_value, logic::none_t<is_noop_t<_result_type_provider>::value>::value>,
tag::requires_braces>; tag::requires_braces>;
using _recursive_traits = typename _policies_t::_recursive_traits; using _nodes = std::tuple<_policies_t>;
using _used_outer_tables = typename _policies_t::_all_provided_outer_tables; using _used_outer_tables = typename _policies_t::_all_provided_outer_tables;
using _alias_t = typename _result_type_provider::_alias_t; using _alias_t = typename _result_type_provider::_alias_t;
@ -286,7 +275,7 @@ namespace sqlpp
struct statement_name_t struct statement_name_t
{ {
using _traits = make_traits<no_value_t, Tag>; using _traits = make_traits<no_value_t, Tag>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
// Data // Data
using _data_t = NameData; using _data_t = NameData;

View File

@ -38,7 +38,7 @@ namespace sqlpp
public alias_operators<sum_t<Flag, Expr>> public alias_operators<sum_t<Flag, Expr>>
{ {
using _traits = make_traits<value_type_of<Expr>, tag::is_expression, tag::is_selectable>; using _traits = make_traits<value_type_of<Expr>, tag::is_expression, tag::is_selectable>;
using _recursive_traits = make_recursive_traits<Expr, aggregate_function>; using _nodes = std::tuple<Expr, aggregate_function>;
static_assert(is_noop<Flag>::value or std::is_same<distinct_t, Flag>::value, "sum() used with flag other than 'distinct'"); static_assert(is_noop<Flag>::value or std::is_same<distinct_t, Flag>::value, "sum() used with flag other than 'distinct'");
static_assert(is_numeric_t<Expr>::value, "sum() requires a numeric expression as argument"); static_assert(is_numeric_t<Expr>::value, "sum() requires a numeric expression as argument");

View File

@ -46,17 +46,8 @@ namespace sqlpp
{ {
using _traits = make_traits<no_value_t, tag::is_table>; using _traits = make_traits<no_value_t, tag::is_table>;
struct _recursive_traits using _nodes = std::tuple<>;
{ using _provided_tables = detail::type_set<Table>;
using _required_ctes = detail::type_set<>;
using _provided_ctes = detail::type_set<>;
using _required_tables = detail::type_set<>;
using _provided_tables = detail::type_set<Table>;
using _provided_outer_tables = detail::type_set<>;
using _extra_tables = detail::type_set<>;
using _parameters = std::tuple<>;
using _tags = detail::type_set<>;
};
static_assert(sizeof...(ColumnSpec), "at least one column required per table"); static_assert(sizeof...(ColumnSpec), "at least one column required per table");
using _required_insert_columns = typename detail::make_type_set_if<require_insert_t, column_t<Table, ColumnSpec>...>::type; using _required_insert_columns = typename detail::make_type_set_if<require_insert_t, column_t<Table, ColumnSpec>...>::type;

View File

@ -42,17 +42,9 @@ namespace sqlpp
//FIXME: Need to add join functionality //FIXME: Need to add join functionality
using _traits = make_traits<value_type_of<Table>, tag::is_table, tag::is_alias, tag_if<tag::is_selectable, is_expression_t<Table>::value>>; using _traits = make_traits<value_type_of<Table>, tag::is_table, tag::is_alias, tag_if<tag::is_selectable, is_expression_t<Table>::value>>;
struct _recursive_traits using _nodes = std::tuple<>;
{ using _required_ctes = required_ctes_of<Table>;
using _required_ctes = required_ctes_of<Table>; using _provided_tables = detail::type_set<AliasProvider>;
using _provided_ctes = detail::type_set<>;
using _required_tables = detail::type_set<>;
using _provided_tables = detail::type_set<AliasProvider>;
using _provided_outer_tables = detail::type_set<>;
using _extra_tables = detail::type_set<>;
using _parameters = std::tuple<>;
using _tags = detail::type_set<>;
};
static_assert(required_tables_of<Table>::size::value == 0, "table aliases must not depend on external tables"); static_assert(required_tables_of<Table>::size::value == 0, "table aliases must not depend on external tables");

View File

@ -40,7 +40,7 @@ namespace sqlpp
struct tvin_arg_t struct tvin_arg_t
{ {
using _traits = make_traits<value_type_of<Operand>, tag::is_expression>; using _traits = make_traits<value_type_of<Operand>, tag::is_expression>;
using _recursive_traits = make_recursive_traits<Operand>; using _nodes = std::tuple<Operand>;
using _operand_t = Operand; using _operand_t = Operand;
@ -102,7 +102,7 @@ namespace sqlpp
struct tvin_t struct tvin_t
{ {
using _traits = make_traits<value_type_of<Operand>, tag::is_expression>; using _traits = make_traits<value_type_of<Operand>, tag::is_expression>;
using _recursive_traits = make_recursive_traits<Operand>; using _nodes = std::tuple<Operand>;
using _operand_t = Operand; using _operand_t = Operand;

View File

@ -38,29 +38,8 @@ namespace sqlpp
namespace tag namespace tag
{ {
struct can_be_null{}; struct can_be_null{};
struct contains_aggregate_function{};
} }
namespace detail
{
template<typename T, typename Enable = void>
struct can_be_null_impl { using type = std::false_type; };
template<typename T>
struct can_be_null_impl<T, typename std::enable_if<is_element_of<tag::can_be_null, typename T::_recursive_traits::_tags>::value>::type> { using type = std::true_type; };
}
template<typename T>
using can_be_null_t = typename detail::can_be_null_impl<T>::type;
namespace detail
{
template<typename T, typename Enable = void>
struct contains_aggregate_function_impl { using type = std::false_type; };
template<typename T>
struct contains_aggregate_function_impl<T, typename std::enable_if<is_element_of<tag::contains_aggregate_function, typename T::_recursive_traits::_tags>::value>::type> { using type = std::true_type; };
}
template<typename T>
using contains_aggregate_function_t = typename detail::contains_aggregate_function_impl<T>::type;
namespace detail namespace detail
{ {
template<typename T, typename Enable = void> template<typename T, typename Enable = void>
@ -82,7 +61,7 @@ namespace sqlpp
template<typename T> template<typename T>
struct is_expression_impl<T, typename std::enable_if< struct is_expression_impl<T, typename std::enable_if<
detail::is_element_of<tag::is_expression, typename T::_traits::_tags>::value detail::is_element_of<tag::is_expression, typename T::_traits::_tags>::value
and not detail::is_element_of<tag::contains_aggregate_function, typename T::_recursive_traits::_tags>::value //and not detail::is_element_of<tag::contains_aggregate_function, typename T::_recursive_traits::_tags>::value FIXME: Needed here?
>::type> { using type = std::true_type; }; >::type> { using type = std::true_type; };
} }
template<typename T> template<typename T>
@ -186,29 +165,80 @@ namespace sqlpp
template<typename T> template<typename T>
using cpp_value_type_of = typename value_type_of<T>::_cpp_value_type; using cpp_value_type_of = typename value_type_of<T>::_cpp_value_type;
template<typename T> #define SQLPP_RECURSIVE_TRAIT_SET_GENERATOR(trait) \
using required_ctes_of = typename T::_recursive_traits::_required_ctes; namespace detail\
{\
template<typename T, typename Leaf = void>\
struct trait##_of_impl\
{\
using type = typename trait##_of_impl<typename T::_nodes>::type;\
};\
template<typename T>\
struct trait##_of_impl<T, typename std::enable_if<std::is_class<typename T::_##trait>::value>::type>\
{\
using type = typename T::_##trait;\
};\
template<typename... Nodes>\
struct trait##_of_impl<std::tuple<Nodes...>, void>\
{\
using type = detail::make_joined_set_t<typename trait##_of_impl<Nodes>::type...>;\
};\
}\
template<typename T>\
using trait##_of = typename detail::trait##_of_impl<T>::type;
template<typename T> SQLPP_RECURSIVE_TRAIT_SET_GENERATOR(required_ctes)
using provided_ctes_of = typename T::_recursive_traits::_provided_ctes; SQLPP_RECURSIVE_TRAIT_SET_GENERATOR(provided_ctes)
SQLPP_RECURSIVE_TRAIT_SET_GENERATOR(required_tables)
SQLPP_RECURSIVE_TRAIT_SET_GENERATOR(provided_tables)
SQLPP_RECURSIVE_TRAIT_SET_GENERATOR(provided_outer_tables)
SQLPP_RECURSIVE_TRAIT_SET_GENERATOR(extra_tables)
template<typename T> #define SQLPP_RECURSIVE_TRAIT_GENERATOR(trait) \
using required_tables_of = typename T::_recursive_traits::_required_tables; namespace detail\
{\
template<typename T, typename Leaf = void>\
struct trait##_impl\
{\
using type = typename trait##_impl<typename T::_nodes>::type;\
};\
template<typename T>\
struct trait##_impl<T, typename std::enable_if<std::is_class<typename T::_##trait>::value>::type>\
{\
using type = typename T::_##trait;\
};\
template<typename... Nodes>\
struct trait##_impl<std::tuple<Nodes...>, void>\
{\
using type = logic::any_t<trait##_impl<Nodes>::type::value...>;\
};\
}\
template<typename T>\
using trait##_t = typename detail::trait##_impl<T>::type;
template<typename T> SQLPP_RECURSIVE_TRAIT_GENERATOR(can_be_null)
using provided_tables_of = typename T::_recursive_traits::_provided_tables; SQLPP_RECURSIVE_TRAIT_GENERATOR(contains_aggregate_function)
template<typename T> namespace detail
using provided_outer_tables_of = typename T::_recursive_traits::_provided_outer_tables; {
template<typename T, typename Leaf = void>
template<typename T> struct parameters_of_impl
using extra_tables_of = typename T::_recursive_traits::_extra_tables; {
using type = typename parameters_of_impl<typename T::_nodes>::type;
template<typename T> };
using parameters_of = typename T::_recursive_traits::_parameters; template<typename T>
struct parameters_of_impl<T, typename std::enable_if<std::is_class<typename T::_parameters>::value>::type>
template<typename T> {
using recursive_tags_of = typename T::_recursive_traits::_tags; using type = typename T::_parameters;
};
template<typename... Nodes>
struct parameters_of_impl<std::tuple<Nodes...>, void>
{
using type = detail::make_parameter_tuple_t<typename parameters_of_impl<Nodes>::type...>;
};
}
template<typename T>\
using parameters_of = typename detail::parameters_of_impl<T>::type;
template<typename T> template<typename T>
using alias_of = typename T::_alias_t; using alias_of = typename T::_alias_t;
@ -223,36 +253,10 @@ namespace sqlpp
using _tags = detail::make_type_set_t<typename ValueType::_tag, Tags...>; using _tags = detail::make_type_set_t<typename ValueType::_tag, Tags...>;
}; };
template<typename... Arguments>
struct make_recursive_traits
{
using _required_ctes = detail::make_joined_set_t<required_ctes_of<Arguments>...>;
using _provided_ctes = detail::make_joined_set_t<provided_ctes_of<Arguments>...>;
using _required_tables = detail::make_joined_set_t<required_tables_of<Arguments>...>;
using _provided_tables = detail::make_joined_set_t<provided_tables_of<Arguments>...>;
using _provided_outer_tables = detail::make_joined_set_t<provided_outer_tables_of<Arguments>...>;
using _extra_tables = detail::make_joined_set_t<extra_tables_of<Arguments>...>;
using _parameters = detail::make_parameter_tuple_t<parameters_of<Arguments>...>;
using _tags = detail::make_joined_set_t<recursive_tags_of<Arguments>...>;
};
template<typename... Tags>
struct recursive_tags
{
using _required_ctes = detail::type_set<>;
using _provided_ctes = detail::type_set<>;
using _required_tables = detail::type_set<>;
using _provided_tables = detail::type_set<>;
using _provided_outer_tables = detail::type_set<>;
using _extra_tables = detail::type_set<>;
using _parameters = std::tuple<>;
using _tags = detail::type_set<Tags...>;
};
struct aggregate_function struct aggregate_function
{ {
struct _traits { using _value_type = void; using _tags = detail::type_set<>; }; using _nodes = std::tuple<>;
using _recursive_traits = recursive_tags<tag::contains_aggregate_function>; using _contains_aggregate_function = std::true_type;
}; };
template<typename NameProvider, typename Member> template<typename NameProvider, typename Member>

View File

@ -66,7 +66,7 @@ namespace sqlpp
struct union_t struct union_t
{ {
using _traits = make_traits<no_value_t, tag::is_union, tag::is_return_value>; using _traits = make_traits<no_value_t, tag::is_union, tag::is_return_value>;
using _recursive_traits = make_recursive_traits<Lhs, Rhs>; using _nodes = std::tuple<Lhs, Rhs>;
using _alias_t = struct{}; using _alias_t = struct{};
@ -114,7 +114,7 @@ namespace sqlpp
struct no_union_t struct no_union_t
{ {
using _traits = make_traits<no_value_t, tag::is_union>; using _traits = make_traits<no_value_t, tag::is_union>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
// Data // Data
using _data_t = no_data_t; using _data_t = no_data_t;

View File

@ -68,7 +68,7 @@ namespace sqlpp
struct update_list_t struct update_list_t
{ {
using _traits = make_traits<no_value_t, tag::is_update_list>; using _traits = make_traits<no_value_t, tag::is_update_list>;
using _recursive_traits = make_recursive_traits<Assignments...>; using _nodes = std::tuple<Assignments...>;
using _is_dynamic = is_database<Database>; using _is_dynamic = is_database<Database>;
// Data // Data
@ -153,7 +153,7 @@ namespace sqlpp
struct no_update_list_t struct no_update_list_t
{ {
using _traits = make_traits<no_value_t, tag::is_where>; using _traits = make_traits<no_value_t, tag::is_where>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
// Data // Data
using _data_t = no_data_t; using _data_t = no_data_t;

View File

@ -58,7 +58,7 @@ namespace sqlpp
struct using_t struct using_t
{ {
using _traits = make_traits<no_value_t, tag::is_using_>; using _traits = make_traits<no_value_t, tag::is_using_>;
using _recursive_traits = make_recursive_traits<Tables...>; using _nodes = std::tuple<Tables...>;
using _is_dynamic = is_database<Database>; using _is_dynamic = is_database<Database>;
@ -121,7 +121,7 @@ namespace sqlpp
struct no_using_t struct no_using_t
{ {
using _traits = make_traits<no_value_t, tag::is_where>; using _traits = make_traits<no_value_t, tag::is_where>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
// Data // Data
using _data_t = no_data_t; using _data_t = no_data_t;

View File

@ -51,7 +51,7 @@ namespace sqlpp
using _cpp_value_type = typename ValueType::_cpp_value_type; using _cpp_value_type = typename ValueType::_cpp_value_type;
using _traits = make_traits<ValueType, tag::is_expression>; using _traits = make_traits<ValueType, tag::is_expression>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
value_or_null_t(_cpp_value_type value): value_or_null_t(_cpp_value_type value):
_value(value), _value(value),

View File

@ -39,10 +39,8 @@ namespace sqlpp
public alias_operators<verbatim_t<ValueType>> public alias_operators<verbatim_t<ValueType>>
{ {
using _traits = make_traits<ValueType, tag::is_expression>; using _traits = make_traits<ValueType, tag::is_expression>;
struct _recursive_traits : public make_recursive_traits<> using _nodes = std::tuple<>;
{ using _can_be_null = std::true_type; // since we do not know what's going on inside the verbatim, we assume it can be null
using _tags = detail::type_set<tag::can_be_null>; // since we do not know what's going on inside the verbatim, we assume it can be null
};
verbatim_t(std::string verbatim): _verbatim(verbatim) {} verbatim_t(std::string verbatim): _verbatim(verbatim) {}
verbatim_t(const verbatim_t&) = default; verbatim_t(const verbatim_t&) = default;

View File

@ -50,10 +50,7 @@ namespace sqlpp
struct verbatim_table_t: public table_t<verbatim_table_t, detail::unusable_pseudo_column_t> struct verbatim_table_t: public table_t<verbatim_table_t, detail::unusable_pseudo_column_t>
{ {
struct _recursive_traits: public table_t<verbatim_table_t, detail::unusable_pseudo_column_t>::_recursive_traits using _nodes = std::tuple<>;
{
using _provided_outer_tables = detail::type_set<verbatim_table_t>;
};
struct _alias_t struct _alias_t
{ {

View File

@ -71,7 +71,7 @@ namespace sqlpp
struct where_t struct where_t
{ {
using _traits = make_traits<no_value_t, tag::is_where>; using _traits = make_traits<no_value_t, tag::is_where>;
using _recursive_traits = make_recursive_traits<Expressions...>; using _nodes = std::tuple<Expressions...>;
using _is_dynamic = is_database<Database>; using _is_dynamic = is_database<Database>;
@ -149,7 +149,7 @@ namespace sqlpp
struct where_t<void, bool> struct where_t<void, bool>
{ {
using _traits = make_traits<no_value_t, tag::is_where>; using _traits = make_traits<no_value_t, tag::is_where>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
// Data // Data
using _data_t = where_data_t<void, bool>; using _data_t = where_data_t<void, bool>;
@ -198,7 +198,7 @@ namespace sqlpp
struct no_where_t struct no_where_t
{ {
using _traits = make_traits<no_value_t, tag::is_where>; using _traits = make_traits<no_value_t, tag::is_where>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
// Data // Data
using _data_t = no_data_t; using _data_t = no_data_t;

View File

@ -66,17 +66,9 @@ namespace sqlpp
struct with_t struct with_t
{ {
using _traits = make_traits<no_value_t, tag::is_with>; using _traits = make_traits<no_value_t, tag::is_with>;
struct _recursive_traits using _nodes = std::tuple<>;
{ using _provided_ctes = detail::make_joined_set_t<required_ctes_of<Expressions>...>; // with provides common table expressions
using _required_ctes = detail::type_set<>; using _parameters = detail::make_parameter_tuple_t<parameters_of<Expressions>...>;
using _provided_ctes = detail::make_joined_set_t<required_ctes_of<Expressions>...>; // with provides common table expressions
using _required_tables = detail::type_set<>;
using _provided_tables = detail::type_set<>;
using _provided_outer_tables = detail::type_set<>;
using _extra_tables = detail::type_set<>;
using _parameters = detail::make_parameter_tuple_t<parameters_of<Expressions>...>;
using _tags = detail::type_set<>;
};
using _is_dynamic = is_database<Database>; using _is_dynamic = is_database<Database>;
@ -116,7 +108,7 @@ namespace sqlpp
struct no_with_t struct no_with_t
{ {
using _traits = make_traits<no_value_t, tag::is_with>; using _traits = make_traits<no_value_t, tag::is_with>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
// Data // Data
using _data_t = no_data_t; using _data_t = no_data_t;

View File

@ -43,7 +43,7 @@ namespace sqlpp
struct boolean_operand: public alias_operators<boolean_operand> struct boolean_operand: public alias_operators<boolean_operand>
{ {
using _traits = make_traits<boolean, tag::is_expression, tag::is_wrapped_value>; using _traits = make_traits<boolean, tag::is_expression, tag::is_wrapped_value>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
using _value_t = bool; using _value_t = bool;
@ -82,7 +82,7 @@ namespace sqlpp
struct integral_operand: public alias_operators<integral_operand> struct integral_operand: public alias_operators<integral_operand>
{ {
using _traits = make_traits<integral, tag::is_expression, tag::is_wrapped_value>; using _traits = make_traits<integral, tag::is_expression, tag::is_wrapped_value>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
using _value_t = int64_t; using _value_t = int64_t;
@ -122,7 +122,7 @@ namespace sqlpp
struct floating_point_operand: public alias_operators<floating_point_operand> struct floating_point_operand: public alias_operators<floating_point_operand>
{ {
using _traits = make_traits<floating_point, tag::is_expression, tag::is_wrapped_value>; using _traits = make_traits<floating_point, tag::is_expression, tag::is_wrapped_value>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
using _value_t = double; using _value_t = double;
@ -161,7 +161,7 @@ namespace sqlpp
struct text_operand: public alias_operators<text_operand> struct text_operand: public alias_operators<text_operand>
{ {
using _traits = make_traits<text, tag::is_expression, tag::is_wrapped_value>; using _traits = make_traits<text, tag::is_expression, tag::is_wrapped_value>;
using _recursive_traits = make_recursive_traits<>; using _nodes = std::tuple<>;
using _value_t = std::string; using _value_t = std::string;