Commit 34be7020 authored by Vadim Zeitlin's avatar Vadim Zeitlin

Test exact round trip for NUMERIC values for all backends.

Unlike with doubles, there should be really no loss of precision when using
fixed point NUMERIC data type, but check for it explicitly as it used to be
broken for Firebird.
parent 24c05399
......@@ -327,24 +327,41 @@ inline bool are_doubles_approx_equal(double const a, double const b)
} while ( (void)0, 0 )
// Compare two floating point numbers either exactly or approximately depending
// on test_context::has_fp_bug() return value.
// Exact double comparison function. We need one, instead of writing "a == b",
// only in order to have some place to put the pragmas disabling gcc warnings.
inline bool
are_doubles_equal(test_context_base const& tc, double a, double b)
are_doubles_exactly_equal(double a, double b)
{
if (tc.has_fp_bug())
{
return are_doubles_approx_equal(a, b);
}
else // can compare exactly and check that we really round trip
{
// Avoid g++ warnings: we do really want the exact equality here.
GCC_WARNING_SUPPRESS(float-equal)
return a == b;
GCC_WARNING_RESTORE(float-equal)
}
}
#define ASSERT_EQUAL_EXACT(a, b) \
do { \
if (!are_doubles_exactly_equal((a), (b))) { \
std::cerr << "Exact equality check failed at " \
<< __FILE__ << ":" << __LINE__ << ":" \
<< std::fixed \
<< std::setprecision(std::numeric_limits<double>::digits10 + 1) \
<< (a) << " != " << (b) \
<< std::endl; \
assert(!"exact equality failed"); \
} \
} while ( (void)0, 0 )
// Compare two floating point numbers either exactly or approximately depending
// on test_context::has_fp_bug() return value.
inline bool
are_doubles_equal(test_context_base const& tc, double a, double b)
{
return tc.has_fp_bug()
? are_doubles_approx_equal(a, b)
: are_doubles_exactly_equal(a, b);
}
// This macro should be used when where we don't have any problems with string
......@@ -432,6 +449,7 @@ public:
test_prepared_insert_with_orm_type();
test_issue154();
test_placeholder_partial_matching_with_orm_type();
test_numeric_round_trip();
}
private:
......@@ -2446,6 +2464,33 @@ void test_placeholder_partial_matching_with_orm_type()
std::cout << "test test_placeholder_partial_matching_with_orm_type passed" << std::endl;
}
void test_numeric_round_trip()
{
session sql(backEndFactory_, connectString_);
auto_table_creator tableCreator(tc_.table_creator_1(sql));
double d1 = 0.003958,
d2;
sql << "insert into soci_test(num76) values (:d1)", use(d1);
sql << "select num76 from soci_test", into(d2);
// The numeric value should make the round trip unchanged, we really want
// to use exact comparisons here.
ASSERT_EQUAL_EXACT(d1, d2);
// test negative doubles too
sql << "delete from soci_test";
d1 = -d1;
sql << "insert into soci_test(num76) values (:d1)", use(d1);
sql << "select num76 from soci_test", into(d2);
ASSERT_EQUAL_EXACT(d1, d2);
std::cout << "test numeric_round_trip passed" << std::endl;
}
// test for bulk fetch with single use
void test16()
{
......
......@@ -32,6 +32,7 @@ struct table_creator_one : public table_creator_base
: table_creator_base(sql)
{
sql << "CREATE TABLE SOCI_TEST(ID INTEGER, VAL SMALLINT, C CHAR, STR VARCHAR(20), SH SMALLINT, UL NUMERIC(20), D DOUBLE, "
"NUM76 NUMERIC(7,6), "
"TM TIMESTAMP, I1 INTEGER, I2 INTEGER, I3 INTEGER, NAME VARCHAR(20))";
}
};
......
......@@ -1238,6 +1238,7 @@ struct TableCreator1 : public tests::table_creator_base
{
sql << "create table soci_test(id integer, val integer, c char, "
"str varchar(20), sh smallint, ul bigint, d double precision, "
"num76 numeric(7,6), "
"tm timestamp, i1 integer, i2 integer, i3 integer, name varchar(20))";
sql.commit();
sql.begin();
......
......@@ -845,6 +845,7 @@ struct table_creator_one : public table_creator_base
{
sql << "create table soci_test(id integer, val integer, c char, "
"str varchar(20), sh int2, ul numeric(20), d float8, "
"num76 numeric(7,6), "
"tm datetime, i1 integer, i2 integer, i3 integer, "
"name varchar(20)) engine=InnoDB";
}
......
......@@ -28,6 +28,7 @@ struct table_creator_one : public table_creator_base
{
sql << "create table soci_test(id integer, val integer, c char, "
"str varchar(20), sh integer, ul number, d float, "
"num76 numeric(7,6), "
"tm timestamp, i1 integer, i2 integer, i3 integer, "
"name varchar(20))";
}
......
......@@ -27,6 +27,7 @@ struct table_creator_one : public table_creator_base
: table_creator_base(sql)
{
sql << "CREATE TABLE SOCI_TEST(ID INTEGER, VAL SMALLINT, C CHAR, STR VARCHAR(20), SH SMALLINT, UL NUMERIC(20), D DOUBLE, "
"NUM76 NUMERIC(7,6), "
"TM TIMESTAMP(9), I1 INTEGER, I2 INTEGER, I3 INTEGER, NAME VARCHAR(20))";
}
};
......
......@@ -28,6 +28,7 @@ struct table_creator_one : public table_creator_base
{
sql << "create table soci_test(id integer, val integer, c char, "
"str varchar(20), sh smallint, ul numeric(20), d float, "
"num76 numeric(7,6), "
"tm datetime, i1 integer, i2 integer, i3 integer, "
"name varchar(20))";
}
......
......@@ -28,6 +28,7 @@ struct table_creator_one : public table_creator_base
{
sql << "create table soci_test(id integer, val integer, c char, "
"str varchar(20), sh int2, ul numeric(20), d float8, "
"num76 numeric(7,6), "
"tm datetime, i1 integer, i2 integer, i3 integer, "
"name varchar(20))";
}
......
......@@ -94,6 +94,7 @@ struct table_creator_one : public table_creator_base
{
sql << "create table soci_test(id integer, val integer, c char, "
"str varchar(20), sh int2, ul numeric(20), d float8, "
"num76 numeric(7,6), "
"tm timestamp, i1 integer, i2 integer, i3 integer, "
"name varchar(20))";
}
......
......@@ -1115,6 +1115,7 @@ struct table_creator_one : public table_creator_base
{
sql << "create table soci_test(id number(10,0), val number(4,0), c char, "
"str varchar2(20), sh number, ul number, d number, "
"num76 numeric(7,6), "
"tm date, i1 number, i2 number, i3 number, name varchar2(20))";
}
};
......
......@@ -734,6 +734,7 @@ struct table_creator_one : public table_creator_base
{
sql << "create table soci_test(id integer, val integer, c char, "
"str varchar(20), sh int2, ul numeric(20), d float8, "
"num76 numeric(7,6), "
"tm timestamp, i1 integer, i2 integer, i3 integer, "
"name varchar(20))";
}
......
......@@ -292,6 +292,7 @@ struct table_creator_one : public table_creator_base
{
sql << "create table soci_test(id integer, val integer, c char, "
"str varchar(20), sh smallint, ul numeric(20), d float, "
"num76 numeric(7,6), "
"tm datetime, i1 integer, i2 integer, i3 integer, "
"name varchar(20))";
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment