yandex / ozo

OZO is a C++17 Boost.Asio based header-only library for asyncronous communication with PostgreSQL DBMS.
PostgreSQL License
227 stars 46 forks source link

Nested array of custom types support #294

Closed neogenie closed 3 years ago

neogenie commented 3 years ago

It seems that nested custom types doesn't works as expected:

Simple we have User custom type nested into Group custom type:

CREATE TYPE t_user AS
(
    id        INTEGER,
    name      TEXT,
);

CREATE TYPE t_group AS
(
    id        INTEGER,
    user      t_user,
);
struct User {
    std::int64_t id;
    std::optional<std::string> name;
};

BOOST_HANA_ADAPT_STRUCT(User, id, name);
OZO_PG_DEFINE_CUSTOM_TYPE(User, "t_user");
OZO_PG_DEFINE_CUSTOM_TYPE(std::vector<User>, "t_user[]");

And

struct Group {
    std::int64_t id;
    User user; 
};

BOOST_HANA_ADAPT_STRUCT(Group, id, user);
OZO_PG_DEFINE_CUSTOM_TYPE(Group, "t_group");
OZO_PG_DEFINE_CUSTOM_TYPE(std::vector<Group>, "t_group[]");

Works as expected and compiles with

using OzoOidMap = ozo::oid_map_t<User, std::vector<User>, Group, std::vector<Group>>;
using OzoConnectionInfo = ozo::connection_info<OzoOidMap>;
using OzoConnectionPoolConfig = ozo::connection_pool_config;
using OzoConnectionPool = ozo::connection_pool<OzoConnectionInfo>;

OzoConnectionPool connectionPool = ozo::make_connection_pool(
          OzoConnectionInfo("..."),
          OzoConnectionPoolConfig{...})

But it doesn't compiles when Group contains an array of nested User model:

CREATE TYPE t_user AS
(
    id        INTEGER,
    name      TEXT,
);

CREATE TYPE t_group AS
(
    id        INTEGER,
    users     t_user[],
);
struct User {
    std::int64_t id;
    std::optional<std::string> name;
};

BOOST_HANA_ADAPT_STRUCT(User, id, name);
OZO_PG_DEFINE_CUSTOM_TYPE(User, "t_user");
OZO_PG_DEFINE_CUSTOM_TYPE(std::vector<User>, "t_user[]");

And

struct Group {
    std::int64_t id;
    std::vector<User> users; 
};

BOOST_HANA_ADAPT_STRUCT(Group, id, users);
OZO_PG_DEFINE_CUSTOM_TYPE(Group, "t_group");
OZO_PG_DEFINE_CUSTOM_TYPE(std::vector<Group>, "t_group[]");

with error like this:

/ozo-src/include/ozo/io/ostream.h:81:16: error: no matching member function for call to 'write'
    return out.write(std::forward<Ts>(vs)...);
           ~~~~^~~~~
/ozo-src/include/ozo/io/send.h:56:16: note: in instantiation of function template specialization 'ozo::write<const std::__1::vector<User, std::__1::allocator<User>> &>' requested here
        return write(out, in);
               ^
thed636 commented 3 years ago

Hi Neo!

I think the problem is the redundant definition of array types as custom types. I suppose the removing of OZO_PG_DEFINE_CUSTOM_TYPE(std::vector<User>, "t_user[]"); and OZO_PG_DEFINE_CUSTOM_TYPE(std::vector<Group>, "t_group[]"); should help. Arrays aren't needed to be defined as custom types. They should be registered to get oids mapping, but no extra definition is needed.

Hope that helps.

neogenie commented 3 years ago

Thanks!