mirror of
https://github.com/SOCI/soci.git
synced 2026-02-13 00:59:39 -06:00
Fix uint64 vector unit tests
Firebird and SQLite store UINT64_MAX incorrectly, leading to an incorrect value ordering when retrieving sorted table contents.
This commit is contained in:
@@ -466,6 +466,11 @@ public:
|
||||
// strings (Oracle does this).
|
||||
virtual bool treats_empty_strings_as_null() const { return false; }
|
||||
|
||||
// Override this if the backend does not store values bigger than INT64_MAX
|
||||
// correctly. This can lead to an unexpected ordering of values as larger
|
||||
// values might be stored as overflown and therefore negative integer.
|
||||
virtual bool has_uint64_storage_bug() const { return false; }
|
||||
|
||||
// Override this to call commit() if it's necessary for the DDL statements
|
||||
// to be taken into account (currently this is only the case for Firebird).
|
||||
virtual void on_after_ddl(session&) const { }
|
||||
@@ -2406,12 +2411,24 @@ TEST_CASE_METHOD(common_tests, "Use vector", "[core][use][vector]")
|
||||
|
||||
sql << "select ul from soci_test order by ul", into(v2);
|
||||
CHECK(v2.size() == 6);
|
||||
CHECK(v2[0] == (std::numeric_limits<uint64_t>::min)());
|
||||
CHECK(v2[1] == 0);
|
||||
CHECK(v2[2] == 1);
|
||||
CHECK(v2[3] == 123);
|
||||
CHECK(v2[4] == 1000);
|
||||
CHECK(v2[5] == (std::numeric_limits<uint64_t>::max)());
|
||||
if (tc_.has_uint64_storage_bug())
|
||||
{
|
||||
CHECK(v2[0] == (std::numeric_limits<uint64_t>::max)());
|
||||
CHECK(v2[1] == (std::numeric_limits<uint64_t>::min)());
|
||||
CHECK(v2[2] == 0);
|
||||
CHECK(v2[3] == 1);
|
||||
CHECK(v2[4] == 123);
|
||||
CHECK(v2[5] == 1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK(v2[0] == (std::numeric_limits<uint64_t>::min)());
|
||||
CHECK(v2[1] == 0);
|
||||
CHECK(v2[2] == 1);
|
||||
CHECK(v2[3] == 123);
|
||||
CHECK(v2[4] == 1000);
|
||||
CHECK(v2[5] == (std::numeric_limits<uint64_t>::max)());
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("double")
|
||||
|
||||
@@ -1339,6 +1339,17 @@ class test_context : public tests::test_context_base
|
||||
return "'" + datdt_string + "'";
|
||||
}
|
||||
|
||||
bool has_uint64_storage_bug() const override
|
||||
{
|
||||
// Firebird does not support unsigned integer types.
|
||||
// We're using Firebird 3, which does not yet support a data
|
||||
// type that can correctly store a UINT64_MAX. The biggest
|
||||
// numeric data type available is numeric(18,0).
|
||||
// Firebird 4 introduces the data type int128 and numeric(36,0),
|
||||
// which will be sufficient for that in the future.
|
||||
return true;
|
||||
}
|
||||
|
||||
void on_after_ddl(soci::session& sql) const override
|
||||
{
|
||||
sql.commit();
|
||||
|
||||
@@ -665,6 +665,13 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool has_uint64_storage_bug() const override
|
||||
{
|
||||
// SQLite processes integers as 8-byte signed values. Values bigger
|
||||
// than INT64_MAX therefore overflow and are stored as negative values.
|
||||
return true;
|
||||
}
|
||||
|
||||
bool enable_std_char_padding(soci::session&) const override
|
||||
{
|
||||
// SQLite does not support right padded char type.
|
||||
|
||||
Reference in New Issue
Block a user