diff --git a/include/sqlpp11/select.h b/include/sqlpp11/select.h index defdb5ac..55077409 100644 --- a/include/sqlpp11/select.h +++ b/include/sqlpp11/select.h @@ -95,6 +95,10 @@ namespace sqlpp using _result_type_provider = detail::get_last_if; + struct _result_methods_t: public _result_type_provider::template _result_methods_t + {}; + + // A select can be used as a pseudo table if // - at least one column is selected // - the select is complete (leaks no tables) @@ -135,6 +139,7 @@ namespace sqlpp struct select_t: public Policies..., public detail::select_policies_t::_value_type::template expression_operators>, + public detail::select_policies_t::_result_methods_t, public detail::select_policies_t::_methods_t { using _policies_t = typename detail::select_policies_t; @@ -174,21 +179,6 @@ namespace sqlpp ~select_t() = default; // PseudoTable - template - struct _pseudo_table_t - { - using table = typename _result_type_provider::template _pseudo_table_t; - using alias = typename table::template _alias_t; - }; - - template - typename _pseudo_table_t::alias as(const AliasProvider& aliasProvider) const - { - static_assert(_policies_t::_can_be_used_as_table::value, "select cannot be used as table, incomplete from()"); - return typename _pseudo_table_t::table( - *this).as(aliasProvider); - } - const _dynamic_names_t& get_dynamic_names() const { return static_cast(*this)._dynamic_columns._dynamic_expression_names; diff --git a/include/sqlpp11/vendor/select_column_list.h b/include/sqlpp11/vendor/select_column_list.h index ef3ad4e2..89c25263 100644 --- a/include/sqlpp11/vendor/select_column_list.h +++ b/include/sqlpp11/vendor/select_column_list.h @@ -222,6 +222,32 @@ namespace sqlpp void _add_column_impl(NamedExpression namedExpression, const std::false_type&); }; + template + struct _result_methods_t + { + using _statement_t = typename Policies::_statement_t; + + template + struct _deferred_table_t + { + using table = _pseudo_table_t<_statement_t>; + using alias = typename _pseudo_table_t<_statement_t>::template _alias_t; + }; + + template + using _table_t = typename _deferred_table_t::table; + + template + using _alias_t = typename _deferred_table_t::alias; + + template + _alias_t as(const AliasProvider& aliasProvider) const + { + static_assert(Policies::_can_be_used_as_table::value, "statement cannot be used as table, e.g. due to missing tables"); + return _table_t(static_cast(*this)).as(aliasProvider); + } + }; + const select_column_list_t& _column_list() const { return *this; } std::tuple _columns; @@ -277,6 +303,10 @@ namespace sqlpp return { *static_cast(this), ::sqlpp::detail::make_select_column_list_t<_database_t, Args...>{std::tuple_cat(::sqlpp::detail::as_tuple::_(args)...)} }; } }; + + template + struct _result_methods_t + {}; }; // Interpreters diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ad2d430a..71f89d92 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -10,8 +10,8 @@ endmacro () #build_and_run(InsertTest) #build_and_run(RemoveTest) #build_and_run(UpdateTest) -#build_and_run(SelectTest) -build_and_run(SelectTypeTest) +build_and_run(SelectTest) +#build_and_run(SelectTypeTest) #build_and_run(FunctionTest) #build_and_run(PreparedTest) diff --git a/tests/SelectTest.cpp b/tests/SelectTest.cpp index c82f1dc2..8d336c65 100644 --- a/tests/SelectTest.cpp +++ b/tests/SelectTest.cpp @@ -83,5 +83,8 @@ int main() int64_t a = row.alpha; } + + auto X = select(all_of(t)).from(t).as(t.alpha); + return 0; }