Skip to content

Commit

Permalink
feat postgres: more diagnostics for missing parsers
Browse files Browse the repository at this point in the history
Tests: протестировано CI
commit_hash:3893073f97ce7ebaf2bc5adf75c756cabbc3275b
  • Loading branch information
apolukhin committed Nov 28, 2024
1 parent 9d0acd2 commit 55fafd3
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,7 @@ class InvalidParserCategory : public ResultSetError {
class UnknownBufferCategory : public ResultSetError {
public:
UnknownBufferCategory(std::string_view context, Oid type_oid);
UnknownBufferCategory(Oid type_oid, std::string_view cpp_field_type, std::string_view cpp_composite_type);

const Oid type_oid;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,12 @@ struct CompositeBinaryParser : BufferParserBase<T> {
buffer.Read(field_type, BufferCategory::kPlainBuffer);
auto elem_category = GetTypeBufferCategory(categories, field_type);
if (elem_category == BufferCategory::kNoParser) {
throw LogicError{"Buffer category for oid " + std::to_string(field_type) + " is unknown"};
throw UnknownBufferCategory{
static_cast<Oid>(field_type), compiler::GetTypeName<U>(), compiler::GetTypeName<T>()};
}
buffer.ReadRaw(val, categories, elem_category);
}

template <typename Tuple, std::size_t... Indexes>
void
ReadTuple(FieldBuffer& buffer, const TypeBufferCategory& categories, Tuple&& tuple, std::index_sequence<Indexes...>)
Expand Down
21 changes: 20 additions & 1 deletion postgresql/src/storages/postgres/exceptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,26 @@ InvalidParserCategory::InvalidParserCategory(
: ResultSetError(GetInvalidParserCategoryMessage(type, parser, buffer)) {}

UnknownBufferCategory::UnknownBufferCategory(std::string_view context, Oid type_oid)
: ResultSetError(fmt::format("Query {} doesn't have a parser. Type oid is {}", context, type_oid)),
: ResultSetError(fmt::format(
"Query {} doesn't have a parser. Database type {} and it was not retrieved in C++ code as a corresponding "
"C++ type. Refer to the 'Supported data types' in the documentation to find a propper C++ type.",
context,
impl::OidPrettyPrint(type_oid)
)),
type_oid{type_oid} {}

UnknownBufferCategory::UnknownBufferCategory(
Oid type_oid,
std::string_view cpp_field_type,
std::string_view cpp_composite_type
)
: ResultSetError(fmt::format(
"Database type {} and it is not representable as a C++ type '{}' within a C++ composite '{}'. Refer to "
"the 'Supported data types' in the documentation to find a propper C++ type.",
impl::OidPrettyPrint(type_oid),
cpp_field_type,
cpp_composite_type
)),
type_oid{type_oid} {}

InvalidBinaryBuffer::InvalidBinaryBuffer(const std::string& message)
Expand Down
17 changes: 17 additions & 0 deletions postgresql/src/storages/postgres/tests/composite_types_pgtest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@

#include <userver/storages/postgres/io/bitstring.hpp>

// intentionally declared in global namespace
struct PairForUnknownBufferCategoryExceptionReadabilityTest {
int x;
int y;
};

USERVER_NAMESPACE_BEGIN

namespace pg = storages::postgres;
Expand Down Expand Up @@ -844,6 +850,17 @@ UTEST_P(PostgreConnection, CompositeTypeParseExceptionReadability) {
}
}

UTEST_P(PostgreConnection, UnknownBufferCategoryExceptionReadability) {
auto result = GetConn()->Execute("SELECT ROW('fat & (rat | cat)'::tsquery, 1)");
UEXPECT_THROW_MSG(
result[0][0].As<PairForUnknownBufferCategoryExceptionReadabilityTest>(),
storages::postgres::UnknownBufferCategory,
"Database type is 'tsquery' (oid: 3615) and it is not representable as a C++ type 'int' within a C++ composite "
"'PairForUnknownBufferCategoryExceptionReadabilityTest'. Refer to the 'Supported data types' in the "
"documentation to find a propper C++ type."
);
}

} // namespace

USERVER_NAMESPACE_END
10 changes: 10 additions & 0 deletions postgresql/src/storages/postgres/tests/user_types_pgtest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,16 @@ UTEST_P(PostgreConnection, UserDefinedRange) {
UEXPECT_NO_THROW(GetConn()->Execute(kDropTestSchema)) << "Drop schema";
}

UTEST_P(PostgreConnection, UnknownParserExceptionReadability) {
UEXPECT_THROW_MSG(
GetConn()->Execute("SELECT 'fat & (rat | cat)'::tsquery"),
storages::postgres::UnknownBufferCategory,
"Query result set field `tsquery` doesn't have a parser. Database type is 'tsquery' (oid: 3615) and it was not "
"retrieved in C++ code as a corresponding C++ type. Refer to the 'Supported data types' in the documentation "
"to find a propper C++ type."
);
}

} // namespace

USERVER_NAMESPACE_END

0 comments on commit 55fafd3

Please sign in to comment.