taocpp / taopq

C++ client library for PostgreSQL
Boost Software License 1.0
265 stars 40 forks source link

can't get optional string #47

Closed own2pwn closed 2 years ago

own2pwn commented 2 years ago
auto res = db->execute("...").at(0);
auto opt = res.optional<std::string>(3);
/usr/local/include/tao/pq/result_traits.hpp:23:7: error: static_assert failed due to requirement 'internal::dependent_false<std::__1::optional<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>>' "data type T not registered as taopq result type"
      static_assert( internal::dependent_false< T >, "data type T not registered as taopq result type" );
      ^              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/tao/pq/result_traits.hpp:32:66: note: in instantiation of template class 'tao::pq::result_traits<std::__1::optional<std::__1::basic_string<char>>>' requested here
   inline constexpr std::size_t result_traits_size< T, decltype( result_traits< T >::size ) > = result_traits< T >::size;
                                                                 ^
/usr/local/include/tao/pq/row.hpp:206:24: note: during template argument deduction for variable template partial specialization 'result_traits_size<T, decltype(result_traits<T>::size)>' [with T = std::__1::optional<std::__1::basic_string<char>>]
         if constexpr( result_traits_size< T > == 0 ) {
                       ^
/usr/local/include/tao/pq/row.hpp:229:17: note: in instantiation of function template specialization 'tao::pq::row::get<std::__1::optional<std::__1::basic_string<char>>>' requested here
         return get< std::optional< T > >( column );
                ^
/usr/local/include/tao/pq/row.hpp:219:40: error: no member named 'from' in 'tao::pq::result_traits<std::__1::optional<std::__1::basic_string<char>>>'
            return result_traits< T >::from( get( column ) );
                                       ^
/usr/local/include/tao/pq/row.hpp:229:17: note: in instantiation of function template specialization 'tao::pq::row::get<std::__1::optional<std::__1::basic_string<char>>>' requested here
         return get< std::optional< T > >( column );
d-frey commented 2 years ago

What compiler and version are you using? Can you send a small, but complete example program?

d-frey commented 2 years ago

Actually, the code you showed has a problem: When execute() returns a result, you don't really store the result anywhere. You access one row (with .at(0)) and store that, but the result itself gets deleted at the end of that expression. Hence the row now references a deleted object. I should probably put that into the documentation, the fact that you need to keep the result alive as long as you are accessing rows/fields.

It doesn't explain the problem you have, though. Or at least I think so. To make sure, can you please check if

auto res = db->execute("..."); // store the result
auto opt = res.at(0).optional<std::string>(3); // access row 0, field 3 as std::optional<std::string>

makes any difference?

own2pwn commented 2 years ago

I'm on Big Sur 11.4(20F71), Apple clang version 12.0.5 (clang-1205.0.22.11) I tested with your code but result is the same:

In file included from /usr/local/include/tao/pq/connection_pool.hpp:13:
In file included from /usr/local/include/tao/pq/connection.hpp:23:
In file included from /usr/local/include/tao/pq/result.hpp:26:
In file included from /usr/local/include/tao/pq/row.hpp:16:
In file included from /usr/local/include/tao/pq/field.hpp:16:
/usr/local/include/tao/pq/result_traits.hpp:23:7: error: static_assert failed due to requirement 'internal::dependent_false<std::__1::optional<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>>' "data type T not registered as taopq result type"
      static_assert( internal::dependent_false< T >, "data type T not registered as taopq result type" );
      ^              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/tao/pq/result_traits.hpp:32:66: note: in instantiation of template class 'tao::pq::result_traits<std::__1::optional<std::__1::basic_string<char>>>' requested here
   inline constexpr std::size_t result_traits_size< T, decltype( result_traits< T >::size ) > = result_traits< T >::size;
                                                                 ^
/usr/local/include/tao/pq/row.hpp:206:24: note: during template argument deduction for variable template partial specialization 'result_traits_size<T, decltype(result_traits<T>::size)>' [with T = std::__1::optional<std::__1::basic_string<char>>]
         if constexpr( result_traits_size< T > == 0 ) {
                       ^
/usr/local/include/tao/pq/row.hpp:229:17: note: in instantiation of function template specialization 'tao::pq::row::get<std::__1::optional<std::__1::basic_string<char>>>' requested here
         return get< std::optional< T > >( column );
                ^
/usr/local/include/tao/pq/row.hpp:219:40: error: no member named 'from' in 'tao::pq::result_traits<std::__1::optional<std::__1::basic_string<char>>>'
            return result_traits< T >::from( get( column ) );
                                       ^
/usr/local/include/tao/pq/row.hpp:229:17: note: in instantiation of function template specialization 'tao::pq::row::get<std::__1::optional<std::__1::basic_string<char>>>' requested here
         return get< std::optional< T > >( column );
                ^

I'm using connection pool, db defined as return tao::pq::connection_pool::create("")

own2pwn commented 2 years ago

Also, seems there's a similar problem with array-like params:

auto v = std::vector<std::string>{"x"};
auto r = db->execute("...", v);
In file included from /usr/local/include/tao/pq/connection_pool.hpp:13:
In file included from /usr/local/include/tao/pq/connection.hpp:24:
In file included from /usr/local/include/tao/pq/transaction.hpp:21:
/usr/local/include/tao/pq/parameter_traits.hpp:67:7: error: static_assert failed due to requirement 'internal::dependent_false<std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>>>' "data type T not registered as taopq parameter type"
      static_assert( internal::dependent_false< T >, "data type T not registered as taopq parameter type" );
      ^              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/tao/pq/transaction.hpp:96:53: note: in instantiation of template class 'tao::pq::parameter_traits<std::__1::vector<std::__1::basic_string<char>>>' requested here
            return execute_traits( mode, statement, parameter_traits< std::decay_t< As > >( std::forward< As >( as ) )... );
                                                    ^
/usr/local/include/tao/pq/transaction.hpp:111:30: note: in instantiation of function template specialization 'tao::pq::transaction::execute_mode<std::__1::vector<std::__1::basic_string<char>> &>' requested here
         return transaction::execute_mode( result::mode_t::expect_ok, statement, std::forward< As >( as )... );
                             ^
/usr/local/include/tao/pq/connection_pool.hpp:50:41: note: in instantiation of function template specialization 'tao::pq::transaction::execute<std::__1::vector<std::__1::basic_string<char>> &>' requested here
         return connection()->direct()->execute( statement, std::forward< As >( as )... );
                                        ^
main.cpp:38:12: note: in instantiation of function template specialization 'tao::pq::connection_pool::execute<std::__1::vector<std::__1::basic_string<char>> &>' requested here
  db->execute(
           ^
own2pwn commented 2 years ago

Ok, seems that needed headers weren't included. I've used the lib with only #include <tao/pq/connection_pool.hpp> being included

d-frey commented 2 years ago

Ah, OK. Thanks for the feedback. And yes, we should advise users to only use #include <tao/pq.hpp> instead of the individual headers. I'll add it to the documentation when I have the time.

own2pwn commented 2 years ago

Oh, I see. The master header now includes connection pool as well. Last time I used connection pool it wasn't there. Thanks for the lib! @d-frey