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

Fix serialization of PostgreSQL time data types (#504)

* Use a non-UTC timezone when testing the PostgreSQL timezone support.
* Fix serialization of time of day values for PostgreSQL
* Fix serialization of PostgreSQL values for "timestamp with time zone" and "time with time zone" fields.
This commit is contained in:
MeanSquaredError 2023-07-24 07:40:18 +03:00 committed by GitHub
parent 4a1ed2c02e
commit 4295c29e9a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 15 additions and 9 deletions

View File

@ -199,10 +199,9 @@ namespace sqlpp
{ {
const auto time = ::date::make_time(*value) ; const auto time = ::date::make_time(*value) ;
// Timezone handling - always treat the value as UTC. // Timezone handling - always treat the local value as UTC.
// It is assumed that the database timezone is set to UTC, too.
std::ostringstream os; std::ostringstream os;
os << time; os << time << "+00";
_handle->paramValues[index] = os.str(); _handle->paramValues[index] = os.str();
if (_handle->debug()) if (_handle->debug())
{ {
@ -225,10 +224,9 @@ namespace sqlpp
const auto time = ::date::make_time(::sqlpp::chrono::floor<::std::chrono::microseconds>(*value - dp)); const auto time = ::date::make_time(::sqlpp::chrono::floor<::std::chrono::microseconds>(*value - dp));
const auto ymd = ::date::year_month_day{dp}; const auto ymd = ::date::year_month_day{dp};
// Timezone handling - always treat the value as UTC. // Timezone handling - always treat the local value as UTC.
// It is assumed that the database timezone is set to UTC, too.
std::ostringstream os; std::ostringstream os;
os << ymd << ' ' << time; os << ymd << ' ' << time << "+00";
_handle->paramValues[index] = os.str(); _handle->paramValues[index] = os.str();
if (_handle->debug()) if (_handle->debug())
{ {

View File

@ -65,6 +65,13 @@ namespace sqlpp
context << "TIMESTAMP WITH TIME ZONE '" << ymd << ' ' << time << "+00'"; context << "TIMESTAMP WITH TIME ZONE '" << ymd << ' ' << time << "+00'";
return context; return context;
} }
template <typename Period>
postgresql::context_t& serialize(const time_of_day_operand<Period>& t, postgresql::context_t& context)
{
context << "TIME WITH TIME ZONE '" << ::date::make_time(t._t) << "+00'";
return context;
}
} }
#endif #endif

View File

@ -131,7 +131,8 @@ int TimeZone(int, char*[])
{ {
namespace sql = sqlpp::postgresql; namespace sql = sqlpp::postgresql;
auto dbc = sql::make_test_connection(); // We use a time zone with non-zero offset from UTC in order to catch serialization/parsing bugs
auto dbc = sql::make_test_connection("+1");
dbc.execute("DROP TABLE IF EXISTS tabdatetime;"); dbc.execute("DROP TABLE IF EXISTS tabdatetime;");
dbc.execute( dbc.execute(

View File

@ -51,7 +51,7 @@ namespace sqlpp
} }
// Starts a connection and sets the time zone to UTC // Starts a connection and sets the time zone to UTC
inline ::sqlpp::postgresql::connection make_test_connection() inline ::sqlpp::postgresql::connection make_test_connection(const std::string &tz = "UTC")
{ {
namespace sql = sqlpp::postgresql; namespace sql = sqlpp::postgresql;
@ -69,7 +69,7 @@ namespace sqlpp
throw; throw;
} }
db.execute(R"(SET TIME ZONE 'UTC';)"); db.execute("SET TIME ZONE " + tz + ";");
return db; return db;
} }