4 
4 
* See the LICENSE file for terms of use.

5 
5 
*/

6 
6 
#include <boost/test/unit_test.hpp>


7 
#include <boost/predef.h>

7 
8 

8 
9 
#include <Wt/Dbo/Dbo.h>

9 
10 
#include <Wt/Dbo/FixedSqlConnectionPool.h>

...  ...  
3384 
3385 
}

3385 
3386 
}

3386 
3387 


3388 
BOOST_AUTO_TEST_CASE( dbo_test46 )


3389 
{


3390 
// To be conservative, only run on x86 architecture due to byteorder dependencies


3391 
// in converting hex_values to floating point


3392 
#ifdef BOOST_ARCH_X86


3393 
// Check for issues, including loss of precision, with float values that should roundtrip


3394 
// Test data adapted from:


3395 
// https://raw.githubusercontent.com/postgres/postgres/REL_12_9/src/test/regress/sql/float4.sql


3396 
// See license: https://raw.githubusercontent.com/postgres/postgres/REL_12_9/COPYRIGHT


3397 
DboFixture f;


3398 


3399 
float quiet_nan = std::nanf("");


3400 
static const uint32_t quiet_nan_hex = *(reinterpret_cast<uint32_t*>(&quiet_nan));


3401 


3402 
float positive_infinity = std::numeric_limits<float>::infinity();


3403 
static const uint32_t positive_infinity_hex = *(reinterpret_cast<uint32_t*>(&positive_infinity));


3404 


3405 
float negative_infinity = std::numeric_limits<float>::infinity();


3406 
static const uint32_t negative_infinity_hex = *(reinterpret_cast<uint32_t*>(&negative_infinity));


3407 


3408 
static const uint32_t hex_values[] {


3409 
// some special values


3410 
quiet_nan_hex,


3411 
positive_infinity_hex,


3412 
negative_infinity_hex,


3413 


3414 
// small subnormals


3415 
0x00000001,


3416 
0x00000002, 0x00000003,


3417 
0x00000010, 0x00000011, 0x00000100, 0x00000101,


3418 
0x00004000, 0x00004001, 0x00080000, 0x00080001,


3419 


3420 
// stress values


3421 
0x0053c4f4, // 7693e42


3422 
0x006c85c4, // 996622e44


3423 
0x0041ca76, // 60419369e46


3424 
0x004b7678, // 6930161142e48


3425 


3426 
// taken from upstream testsuite


3427 
0x00000007,


3428 
0x00424fe2,


3429 


3430 
// borderline between subnormal and normal


3431 
0x007ffff0, 0x007ffff1, 0x007ffffe, 0x007fffff,


3432 


3433 
// additional tests


3434 
0x00000000,


3435 


3436 
// smallest normal values


3437 
0x00800000, 0x00800001, 0x00800004, 0x00800005,


3438 
0x00800006,


3439 


3440 
// small normal values chosen for short vs. long output


3441 
0x008002f1, 0x008002f2, 0x008002f3,


3442 
0x00800e17, 0x00800e18, 0x00800e19,


3443 


3444 
// assorted values (random mantissae)


3445 
0x01000001, 0x01102843, 0x01a52c98,


3446 
0x0219c229, 0x02e4464d, 0x037343c1, 0x03a91b36,


3447 
0x047ada65, 0x0496fe87, 0x0550844f, 0x05999da3,


3448 
0x060ea5e2, 0x06e63c45, 0x07f1e548, 0x0fc5282b,


3449 
0x1f850283, 0x2874a9d6,


3450 


3451 
// values around 5e08


3452 
0x3356bf94, 0x3356bf95, 0x3356bf96,


3453 


3454 
// around 1e07


3455 
0x33d6bf94, 0x33d6bf95, 0x33d6bf96,


3456 


3457 
// around 3e07 .. 1e04


3458 
0x34a10faf, 0x34a10fb0, 0x34a10fb1,


3459 
0x350637bc, 0x350637bd, 0x350637be,


3460 
0x35719786, 0x35719787, 0x35719788,


3461 
0x358637bc, 0x358637bd, 0x358637be,


3462 
0x36a7c5ab, 0x36a7c5ac, 0x36a7c5ad,


3463 
0x3727c5ab, 0x3727c5ac, 0x3727c5ad,


3464 


3465 
// format crossover at 1e04


3466 
0x38d1b714, 0x38d1b715, 0x38d1b716,


3467 
0x38d1b717, 0x38d1b718, 0x38d1b719,


3468 
0x38d1b71a, 0x38d1b71b, 0x38d1b71c,


3469 
0x38d1b71d,


3470 


3471 
0x38dffffe, 0x38dfffff, 0x38e00000,


3472 
0x38efffff, 0x38f00000, 0x38f00001,


3473 
0x3a83126e, 0x3a83126f, 0x3a831270,


3474 
0x3c23d709, 0x3c23d70a, 0x3c23d70b,


3475 
0x3dcccccc, 0x3dcccccd, 0x3dccccce,


3476 


3477 
// chosen to need 9 digits for 3dcccd70


3478 
0x3dcccd6f, 0x3dcccd70, 0x3dcccd71,


3479 


3480 
0x3effffff, 0x3f000000, 0x3f000001,


3481 
0x3f333332, 0x3f333333, 0x3f333334,


3482 


3483 
// approach 1.0 with increasing numbers of 9s


3484 
0x3f666665, 0x3f666666, 0x3f666667,


3485 
0x3f7d70a3, 0x3f7d70a4, 0x3f7d70a5,


3486 
0x3f7fbe76, 0x3f7fbe77, 0x3f7fbe78,


3487 
0x3f7ff971, 0x3f7ff972, 0x3f7ff973,


3488 
0x3f7fff57, 0x3f7fff58, 0x3f7fff59,


3489 
0x3f7fffee, 0x3f7fffef,


3490 


3491 
// values very close to 1


3492 
0x3f7ffff0, 0x3f7ffff1, 0x3f7ffff2,


3493 
0x3f7ffff3, 0x3f7ffff4, 0x3f7ffff5,


3494 
0x3f7ffff6, 0x3f7ffff7, 0x3f7ffff8,


3495 
0x3f7ffff9, 0x3f7ffffa, 0x3f7ffffb,


3496 
0x3f7ffffc, 0x3f7ffffd, 0x3f7ffffe,


3497 
0x3f7fffff,


3498 
0x3f800000,


3499 
0x3f800001, 0x3f800002, 0x3f800003,


3500 
0x3f800004, 0x3f800005, 0x3f800006,


3501 
0x3f800007, 0x3f800008, 0x3f800009,


3502 


3503 
// values 1 to 1.1


3504 
0x3f80000f, 0x3f800010, 0x3f800011,


3505 
0x3f800012, 0x3f800013, 0x3f800014,


3506 
0x3f800017, 0x3f800018, 0x3f800019,


3507 
0x3f80001a, 0x3f80001b, 0x3f80001c,


3508 
0x3f800029, 0x3f80002a, 0x3f80002b,


3509 
0x3f800053, 0x3f800054, 0x3f800055,


3510 
0x3f800346, 0x3f800347, 0x3f800348,


3511 
0x3f8020c4, 0x3f8020c5, 0x3f8020c6,


3512 
0x3f8147ad, 0x3f8147ae, 0x3f8147af,


3513 
0x3f8ccccc, 0x3f8ccccd, 0x3f8cccce,


3514 


3515 
0x3fc90fdb, // pi/2


3516 
0x402df854, // e


3517 
0x40490fdb, // pi


3518 


3519 
0x409fffff, 0x40a00000, 0x40a00001,


3520 
0x40afffff, 0x40b00000, 0x40b00001,


3521 
0x411fffff, 0x41200000, 0x41200001,


3522 
0x42c7ffff, 0x42c80000, 0x42c80001,


3523 
0x4479ffff, 0x447a0000, 0x447a0001,


3524 
0x461c3fff, 0x461c4000, 0x461c4001,


3525 
0x47c34fff, 0x47c35000, 0x47c35001,


3526 
0x497423ff, 0x49742400, 0x49742401,


3527 
0x4b18967f, 0x4b189680, 0x4b189681,


3528 
0x4cbebc1f, 0x4cbebc20, 0x4cbebc21,


3529 
0x4e6e6b27, 0x4e6e6b28, 0x4e6e6b29,


3530 
0x501502f8, 0x501502f9, 0x501502fa,


3531 
0x51ba43b6, 0x51ba43b7, 0x51ba43b8,


3532 


3533 
// stress values


3534 
0x1f6c1e4a, // 5e20


3535 
0x59be6cea, // 67e14


3536 
0x5d5ab6c4, // 985e15


3537 
0x2cc4a9bd, // 55895e16


3538 
0x15ae43fd, // 7038531e32


3539 
0x2cf757ca, // 702990899e20


3540 
0x665ba998, // 25933168707e13


3541 
0x743c3324, // 596428896559e20


3542 


3543 
// exercise fixedpoint memmoves


3544 
0x47f1205a,


3545 
0x4640e6ae,


3546 
0x449a5225,


3547 
0x42f6e9d5,


3548 
0x414587dd,


3549 
0x3f9e064b,


3550 


3551 
// these cases come from the upstream's testsuite


3552 
// BoundaryRoundEven


3553 
0x4c000004,


3554 
0x50061c46,


3555 
0x510006a8,


3556 


3557 
// ExactValueRoundEven


3558 
0x48951f84,


3559 
0x45fd1840,


3560 


3561 
// LotsOfTrailingZeros


3562 
0x39800000,


3563 
0x3b200000,


3564 
0x3b900000,


3565 
0x3bd00000,


3566 


3567 
// Regression


3568 
0x63800000,


3569 
0x4b000000,


3570 
0x4b800000,


3571 
0x4c000001,


3572 
0x4c800b0d,


3573 
0x00d24584,


3574 
0x00d90b88,


3575 
0x45803f34,


3576 
0x4f9f24f7,


3577 
0x3a8722c3,


3578 
0x5c800041,


3579 
0x15ae43fd,


3580 
0x5d4cccfb,


3581 
0x4c800001,


3582 
0x57800ed8,


3583 
0x5f000000,


3584 
0x700000f0,


3585 
0x5f23e9ac,


3586 
0x5e9502f9,


3587 
0x5e8012b1,


3588 
0x3c000028,


3589 
0x60cde861,


3590 
0x03aa2a50,


3591 
0x43480000,


3592 
0x4c000000,


3593 


3594 
// LooksLikePow5


3595 
0x5D1502F9,


3596 
0x5D9502F9,


3597 
0x5E1502F9,


3598 


3599 
// OutputLength


3600 
0x3f99999a,


3601 
0x3f9d70a4,


3602 
0x3f9df3b6,


3603 
0x3f9e0419,


3604 
0x3f9e0610,


3605 
0x3f9e064b,


3606 
0x3f9e0651,


3607 
0x03d20cfe


3608 
};


3609 


3610 
for (int i = 0; i < sizeof hex_values / sizeof hex_values[0]; ++i) {


3611 
auto hex_value = hex_values[i];


3612 
float fl = *(reinterpret_cast<float*>(&hex_value));


3613 
char buf[100];


3614 
snprintf(buf, sizeof buf, "%.9g", fl);


3615 
BOOST_TEST_MESSAGE ("hex_value: " << std::hex << hex_value << std::dec << ", value: " << buf );


3616 


3617 
float fl_from_database = 0.0f;


3618 
std::string exception_msg;


3619 


3620 
try {


3621 
{


3622 
dbo::Transaction t(*f.session_);


3623 
auto a = f.session_>addNew<A>();


3624 
a.modify()>i = i;


3625 
a.modify()>f = fl;


3626 
}


3627 


3628 
#ifdef POSTGRES


3629 
{


3630 
dbo::Transaction t(*f.session_);


3631 
std::string fl_from_database_s = f.session_>query<std::string>(


3632 
"SELECT \"f\" FROM " SCHEMA "\"table_a\" WHERE \"i\"=?"


3633 
).bind(i).resultValue();


3634 
BOOST_TEST_MESSAGE ("PG text value: " << fl_from_database_s );


3635 
}


3636 
#endif


3637 


3638 
{


3639 
dbo::Transaction t(*f.session_);


3640 
auto a = f.session_>find<A>().where("\"i\" = ?").bind(i).resultValue();


3641 
fl_from_database = a>f;


3642 
}


3643 
} catch (std::exception& e) {


3644 
exception_msg = std::string("unexpected exception: ") + e.what();


3645 
}


3646 


3647 
BOOST_TEST(exception_msg.empty(), exception_msg);


3648 
if (exception_msg.empty()) {


3649 
if (std::isnan(fl)) {


3650 
BOOST_CHECK(std::isnan(fl_from_database));


3651 
}


3652 
else if (std::isinf(fl)) {


3653 
BOOST_CHECK(std::isinf(fl_from_database));


3654 
BOOST_CHECK_EQUAL(fl_from_database, fl);


3655 
}


3656 
else if (std::fpclassify(fl) == FP_SUBNORMAL) {


3657 
// kludge to improve warning (highlighting that it is a subnormal)


3658 
float subnormal_fl = fl;


3659 
BOOST_CHECK_CLOSE(fl_from_database, subnormal_fl, 1e5);


3660 
// only warn if subnormals do not match, since implementations/support may vary


3661 
BOOST_WARN_EQUAL(fl_from_database, subnormal_fl);


3662 
}


3663 
else {


3664 
BOOST_CHECK_CLOSE(fl_from_database, fl, 1e5);


3665 
BOOST_CHECK_EQUAL(fl_from_database, fl);


3666 
}


3667 
}


3668 
}


3669 
#endif


3670 
}


3671 


3672 
BOOST_AUTO_TEST_CASE( dbo_test47 )


3673 
{


3674 
// To be conservative, only run on x86 architecture due to byteorder dependencies


3675 
// in converting hex_values to floating point


3676 
#ifdef BOOST_ARCH_X86


3677 
// Check for issues, including loss of precision, with double values that should roundtrip


3678 
// Test data adapted from:


3679 
// https://raw.githubusercontent.com/postgres/postgres/REL_12_9/src/test/regress/sql/float8.sql


3680 
// See license: https://raw.githubusercontent.com/postgres/postgres/REL_12_9/COPYRIGHT


3681 
DboFixture f;


3682 


3683 
double quiet_nan = std::nan("");


3684 
static const uint64_t quiet_nan_hex = *(reinterpret_cast<uint64_t*>(&quiet_nan));


3685 


3686 
double positive_infinity = std::numeric_limits<double>::infinity();


3687 
static const uint64_t positive_infinity_hex = *(reinterpret_cast<uint64_t*>(&positive_infinity));


3688 


3689 
double negative_infinity = std::numeric_limits<double>::infinity();


3690 
static const uint64_t negative_infinity_hex = *(reinterpret_cast<uint64_t*>(&negative_infinity));


3691 


3692 
static const uint64_t hex_values[] {


3693 
// some special values


3694 
quiet_nan_hex,


3695 
positive_infinity_hex,


3696 
negative_infinity_hex,


3697 


3698 
// small subnormals


3699 
0x0000000000000001,


3700 
0x0000000000000002, 0x0000000000000003,


3701 
0x0000000000001000, 0x0000000100000000,


3702 
0x0000010000000000, 0x0000010100000000,


3703 
0x0000400000000000, 0x0000400100000000,


3704 
0x0000800000000000, 0x0000800000000001,


3705 


3706 
// these values taken from upstream testsuite


3707 
0x00000000000f4240,


3708 
0x00000000016e3600,


3709 
0x0000008cdcdea440,


3710 


3711 
// borderline between subnormal and normal


3712 
0x000ffffffffffff0, 0x000ffffffffffff1,


3713 
0x000ffffffffffffe, 0x000fffffffffffff,


3714 


3715 
// additional tests


3716 
0x0000000000000000,


3717 


3718 
// smallest normal values


3719 
0x0010000000000000, 0x0010000000000001,


3720 
0x0010000000000002, 0x0018000000000000,


3721 


3722 
0x3ddb7cdfd9d7bdba, 0x3ddb7cdfd9d7bdbb, 0x3ddb7cdfd9d7bdbc,


3723 
0x3e112e0be826d694, 0x3e112e0be826d695, 0x3e112e0be826d696,


3724 
0x3e45798ee2308c39, 0x3e45798ee2308c3a, 0x3e45798ee2308c3b,


3725 
0x3e7ad7f29abcaf47, 0x3e7ad7f29abcaf48, 0x3e7ad7f29abcaf49,


3726 
0x3eb0c6f7a0b5ed8c, 0x3eb0c6f7a0b5ed8d, 0x3eb0c6f7a0b5ed8e,


3727 
0x3ee4f8b588e368ef, 0x3ee4f8b588e368f0, 0x3ee4f8b588e368f1,


3728 
0x3f1a36e2eb1c432c, 0x3f1a36e2eb1c432d, 0x3f1a36e2eb1c432e,


3729 
0x3f50624dd2f1a9fb, 0x3f50624dd2f1a9fc, 0x3f50624dd2f1a9fd,


3730 
0x3f847ae147ae147a, 0x3f847ae147ae147b, 0x3f847ae147ae147c,


3731 
0x3fb9999999999999, 0x3fb999999999999a, 0x3fb999999999999b,


3732 


3733 
// values very close to 1


3734 
0x3feffffffffffff0, 0x3feffffffffffff1, 0x3feffffffffffff2,


3735 
0x3feffffffffffff3, 0x3feffffffffffff4, 0x3feffffffffffff5,


3736 
0x3feffffffffffff6, 0x3feffffffffffff7, 0x3feffffffffffff8,


3737 
0x3feffffffffffff9, 0x3feffffffffffffa, 0x3feffffffffffffb,


3738 
0x3feffffffffffffc, 0x3feffffffffffffd, 0x3feffffffffffffe,


3739 
0x3fefffffffffffff,


3740 
0x3ff0000000000000,


3741 
0x3ff0000000000001, 0x3ff0000000000002, 0x3ff0000000000003,


3742 
0x3ff0000000000004, 0x3ff0000000000005, 0x3ff0000000000006,


3743 
0x3ff0000000000007, 0x3ff0000000000008, 0x3ff0000000000009,


3744 


3745 
0x3ff921fb54442d18,


3746 
0x4005bf0a8b14576a,


3747 
0x400921fb54442d18,


3748 


3749 
0x4023ffffffffffff, 0x4024000000000000, 0x4024000000000001,


3750 
0x4058ffffffffffff, 0x4059000000000000, 0x4059000000000001,


3751 
0x408f3fffffffffff, 0x408f400000000000, 0x408f400000000001,


3752 
0x40c387ffffffffff, 0x40c3880000000000, 0x40c3880000000001,


3753 
0x40f869ffffffffff, 0x40f86a0000000000, 0x40f86a0000000001,


3754 
0x412e847fffffffff, 0x412e848000000000, 0x412e848000000001,


3755 
0x416312cfffffffff, 0x416312d000000000, 0x416312d000000001,


3756 
0x4197d783ffffffff, 0x4197d78400000000, 0x4197d78400000001,


3757 
0x41cdcd64ffffffff, 0x41cdcd6500000000, 0x41cdcd6500000001,


3758 
0x4202a05f1fffffff, 0x4202a05f20000000, 0x4202a05f20000001,


3759 
0x42374876e7ffffff, 0x42374876e8000000, 0x42374876e8000001,


3760 
0x426d1a94a1ffffff, 0x426d1a94a2000000, 0x426d1a94a2000001,


3761 
0x42a2309ce53fffff, 0x42a2309ce5400000, 0x42a2309ce5400001,


3762 
0x42d6bcc41e8fffff, 0x42d6bcc41e900000, 0x42d6bcc41e900001,


3763 
0x430c6bf52633ffff, 0x430c6bf526340000, 0x430c6bf526340001,


3764 
0x4341c37937e07fff, 0x4341c37937e08000, 0x4341c37937e08001,


3765 
0x4376345785d89fff, 0x4376345785d8a000, 0x4376345785d8a001,


3766 
0x43abc16d674ec7ff, 0x43abc16d674ec800, 0x43abc16d674ec801,


3767 
0x43e158e460913cff, 0x43e158e460913d00, 0x43e158e460913d01,


3768 
0x4415af1d78b58c3f, 0x4415af1d78b58c40, 0x4415af1d78b58c41,


3769 
0x444b1ae4d6e2ef4f, 0x444b1ae4d6e2ef50, 0x444b1ae4d6e2ef51,


3770 
0x4480f0cf064dd591, 0x4480f0cf064dd592, 0x4480f0cf064dd593,


3771 
0x44b52d02c7e14af5, 0x44b52d02c7e14af6, 0x44b52d02c7e14af7,


3772 
0x44ea784379d99db3, 0x44ea784379d99db4, 0x44ea784379d99db5,


3773 
0x45208b2a2c280290, 0x45208b2a2c280291, 0x45208b2a2c280292,


3774 


3775 
0x7feffffffffffffe, 0x7fefffffffffffff,


3776 


3777 
// round to even tests (+ve)


3778 
0x4350000000000002,


3779 
0x4350000000002e06,


3780 
0x4352000000000003,


3781 
0x4352000000000004,


3782 
0x4358000000000003,


3783 
0x4358000000000004,


3784 
0x435f000000000020,


3785 


3786 
// round to even tests (ve)


3787 
0xc350000000000002,


3788 
0xc350000000002e06,


3789 
0xc352000000000003,


3790 
0xc352000000000004,


3791 
0xc358000000000003,


3792 
0xc358000000000004,


3793 
0xc35f000000000020,


3794 


3795 
// exercise fixedpoint memmoves


3796 
0x42dc12218377de66,


3797 
0x42a674e79c5fe51f,


3798 
0x4271f71fb04cb74c,


3799 
0x423cbe991a145879,


3800 
0x4206fee0e1a9e061,


3801 
0x41d26580b487e6b4,


3802 
0x419d6f34540ca453,


3803 
0x41678c29dcd6e9dc,


3804 
0x4132d687e3df217d,


3805 
0x40fe240c9fcb68c8,


3806 
0x40c81cd6e63c53d3,


3807 
0x40934a4584fd0fdc,


3808 
0x405edd3c07fb4c93,


3809 
0x4028b0fcd32f7076,


3810 
0x3ff3c0ca428c59f8,


3811 


3812 
// these cases come from the upstream's testsuite


3813 
// LotsOfTrailingZeros)


3814 
0x3e60000000000000,


3815 


3816 
// Regression


3817 
0xc352bd2668e077c4,


3818 
0x434018601510c000,


3819 
0x43d055dc36f24000,


3820 
0x43e052961c6f8000,


3821 
0x3ff3c0ca2a5b1d5d,


3822 


3823 
// LooksLikePow5


3824 
0x4830f0cf064dd592,


3825 
0x4840f0cf064dd592,


3826 
0x4850f0cf064dd592,


3827 


3828 
// OutputLength


3829 
0x3ff3333333333333,


3830 
0x3ff3ae147ae147ae,


3831 
0x3ff3be76c8b43958,


3832 
0x3ff3c083126e978d,


3833 
0x3ff3c0c1fc8f3238,


3834 
0x3ff3c0c9539b8887,


3835 
0x3ff3c0ca2a5b1d5d,


3836 
0x3ff3c0ca4283de1b,


3837 
0x3ff3c0ca43db770a,


3838 
0x3ff3c0ca428abd53,


3839 
0x3ff3c0ca428c1d2b,


3840 
0x3ff3c0ca428c51f2,


3841 
0x3ff3c0ca428c58fc,


3842 
0x3ff3c0ca428c59dd,


3843 
0x3ff3c0ca428c59f8,


3844 
0x3ff3c0ca428c59fb,


3845 


3846 
// 32bit chunking


3847 
0x40112e0be8047a7d,


3848 
0x40112e0be815a889,


3849 
0x40112e0be826d695,


3850 
0x40112e0be83804a1,


3851 
0x40112e0be84932ad,


3852 


3853 
// MinMaxShift


3854 
0x0040000000000000,


3855 
0x007fffffffffffff,


3856 
0x0290000000000000,


3857 
0x029fffffffffffff,


3858 
0x4350000000000000,


3859 
0x435fffffffffffff,


3860 
0x1330000000000000,


3861 
0x133fffffffffffff,


3862 
0x3a6fa7161a4d6e0c


3863 
};


3864 


3865 
for (int i = 0; i < sizeof hex_values / sizeof hex_values[0]; ++i) {


3866 
auto hex_value = hex_values[i];


3867 
double dbl = *(reinterpret_cast<double*>(&hex_value));


3868 
char buf[100];


3869 
snprintf(buf, sizeof buf, "%.17g", dbl);


3870 
BOOST_TEST_MESSAGE ("hex_value: " << std::hex << hex_value << std::dec << ", value: " << buf );


3871 


3872 
double dbl_from_database = 0.0;


3873 
std::string exception_msg;


3874 


3875 
try {


3876 
{


3877 
dbo::Transaction t(*f.session_);


3878 
auto a = f.session_>addNew<A>();


3879 
a.modify()>i = i;


3880 
a.modify()>d = dbl;


3881 
}


3882 


3883 
#ifdef POSTGRES


3884 
{


3885 
dbo::Transaction t(*f.session_);


3886 
std::string dbl_from_database_s = f.session_>query<std::string>(


3887 
"SELECT \"d\" FROM " SCHEMA "\"table_a\" WHERE \"i\"=?"


3888 
).bind(i).resultValue();


3889 
BOOST_TEST_MESSAGE ("PG text value: " << dbl_from_database_s );


3890 
}


3891 
#endif


3892 


3893 
{


3894 
dbo::Transaction t(*f.session_);


3895 
auto a = f.session_>find<A>().where("\"i\" = ?").bind(i).resultValue();


3896 
dbl_from_database = a>d;


3897 
}


3898 
} catch (std::exception& e) {


3899 
exception_msg = std::string("unexpected exception: ") + e.what();


3900 
}


3901 


3902 
BOOST_TEST(exception_msg.empty(), exception_msg);


3903 
if (exception_msg.empty()) {


3904 
if (std::isnan(dbl)) {


3905 
BOOST_CHECK(std::isnan(dbl_from_database));


3906 
}


3907 
else if (std::isinf(dbl)) {


3908 
BOOST_CHECK(std::isinf(dbl_from_database));


3909 
BOOST_CHECK_EQUAL(dbl_from_database, dbl);


3910 
}


3911 
else if (std::fpclassify(dbl) == FP_SUBNORMAL) {


3912 
// kludge to improve warning (highlighting that it is a subnormal)


3913 
double subnormal_dbl = dbl;


3914 
BOOST_CHECK_CLOSE(dbl_from_database, subnormal_dbl, 2e14);


3915 
// only warn if subnormals do not match, since implementations/support may vary


3916 
BOOST_WARN_EQUAL(dbl_from_database, subnormal_dbl);


3917 
}


3918 
else {


3919 
BOOST_CHECK_CLOSE(dbl_from_database, dbl, 2e14);


3920 
BOOST_CHECK_EQUAL(dbl_from_database, dbl);


3921 
}


3922 
}


3923 
}


3924 
#endif


3925 
}


3926 

3387 
3927 
BOOST_AUTO_TEST_SUITE_END()

3388 


