Fix #155 Statement::bind truncates long integer to 32 bits on x86_64 Linux

Reproduced the problem with a dedicated unit test, then fixed the bug.

Thanks @tszypenbejl for the clear analysis and the fix.
This commit is contained in:
Sébastien Rombauts 2018-02-23 08:07:45 +01:00
parent d15a84e46e
commit a41629f9ed
3 changed files with 23 additions and 8 deletions

View File

@ -14,7 +14,7 @@
#include <SQLiteCpp/Exception.h>
#include <string>
#include <limits.h>
#include <climits> // For INT_MAX
namespace SQLite
@ -76,7 +76,7 @@ public:
#ifdef SQLITE_ENABLE_COLUMN_METADATA
/**
* @brief Return a pointer to the table column name that is the origin of this result column
*
*
* Require definition of the SQLITE_ENABLE_COLUMN_METADATA preprocessor macro :
* - when building the SQLite library itself (which is the case for the Debian libsqlite3 binary for instance),
* - and also when compiling this wrapper.
@ -187,7 +187,7 @@ public:
{
return getUInt();
}
#else
#else // sizeof(long)==8 means the data model of the system is LLP64 (64bits Linux)
/// Inline cast operator to 64bits long when the data model of the system is ILP64 (Linux 64 bits...)
inline operator long() const
{

View File

@ -14,6 +14,7 @@
#include <string>
#include <map>
#include <climits> // For INT_MAX
// Forward declarations to avoid inclusion of <sqlite3.h> in a header
struct sqlite3;
@ -123,7 +124,7 @@ public:
{
bind(aIndex, static_cast<int>(aValue));
}
#else
#else // sizeof(long)==8 means the data model of the system is LLP64 (64bits Linux)
/**
* @brief Bind a 64bits long value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
@ -205,7 +206,7 @@ public:
{
bind(apName, static_cast<int>(aValue));
}
#else
#else // sizeof(long)==8 means the data model of the system is LLP64 (64bits Linux)
/**
* @brief Bind a 64bits long value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
@ -293,7 +294,7 @@ public:
{
bind(aName.c_str(), static_cast<int>(aValue));
}
#else
#else // sizeof(long)==8 means the data model of the system is LLP64 (64bits Linux)
/**
* @brief Bind a 64bits long value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
@ -408,7 +409,7 @@ public:
/**
* @brief Try to execute a step of the prepared query to fetch one row of results, returning the sqlite result code.
*
*
*
*
* @see exec() execute a one-step prepared statement with no expected result
* @see executeStep() execute a step of the prepared query to fetch one row of results

View File

@ -19,6 +19,7 @@
#include <cstdio>
#include <stdint.h>
#include <climits> // For INT_MAX
TEST(Statement, invalid) {
// Create a new database
@ -751,7 +752,7 @@ TEST(Statement, getColumns) {
EXPECT_EQ("first", testStruct.msg);
EXPECT_EQ(123, testStruct.integer);
EXPECT_EQ(0.123, testStruct.real);
// Get only the first 2 columns
auto testStruct2 = query.getColumns<GetRowTestStruct, 2>();
EXPECT_EQ(1, testStruct2.id);
@ -761,3 +762,16 @@ TEST(Statement, getColumns) {
}
#endif
#if (LONG_MAX > INT_MAX) // sizeof(long)==8 means the data model of the system is LLP64 (64bits Linux)
TEST(Statement, bind64bitsLong) {
// Create a new database
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
EXPECT_EQ(SQLite::OK, db.getErrorCode());
EXPECT_EQ(SQLite::OK, db.getExtendedErrorCode());
SQLite::Statement query(db, "SELECT ?");
query.bind(1, 4294967297L);
query.executeStep();
EXPECT_EQ(4294967297L, query.getColumn(0).getInt64());
}
#endif