From f2f68b75c91e44f2a0f5427facfc432da00aa18a Mon Sep 17 00:00:00 2001 From: Henrik Jakobsson Majava Date: Thu, 26 Sep 2019 10:49:09 +0200 Subject: [PATCH 1/6] Added some bindings for std::string_view when using c++17 --- include/SQLiteCpp/Statement.h | 64 +++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/include/SQLiteCpp/Statement.h b/include/SQLiteCpp/Statement.h index f5e082c4..39879dd4 100644 --- a/include/SQLiteCpp/Statement.h +++ b/include/SQLiteCpp/Statement.h @@ -394,6 +394,70 @@ class Statement bind(aName.c_str()); } + // Provide bindings for std::string_view if using at least c++17 +#if __cplusplus >= 201703L + /** + * @brief Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) + * + * @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use + */ + inline void bind(const int aIndex, std::string_view aValue) + { + bind(aIndex, aValue.data(), aValue.size()); + } + /** + * @brief Bind a text value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) + * + * Main usage is with null-terminated literal text (aka in code static strings) + * + * @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement. + */ + inline void bindNoCopy(const int aIndex, std::string_view aValue) + { + bindNoCopy(aIndex, aValue.data(), aValue.size()); + } + /** + * @brief Bind a string_view value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) + * + * @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use + */ + inline void bind(const char* apName, std::string_view aValue) + { + bind(apName, aValue.data(), aValue.size()); + } + /** + * @brief Bind a string_view value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) + * + * The string can contain null characters as it is binded using its size. + * + * @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement. + */ + inline void bindNoCopy(const char* apName, std::string_view aValue) + { + bind(apName, aValue.data(), aValue.size()); + } + /** + * @brief Bind a string_view value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) + * + * @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use + */ + inline void bind(const std::string& aName, std::string_view aValue) + { + bind(aName.c_str(), aValue.data(), aValue.size()); + } + /** + * @brief Bind a string_view value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) + * + * The string can contain null characters as it is binded using its size. + * + * @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement. + */ + inline void bindNoCopy(const std::string& aName, std::string_view aValue) + { + bindNoCopy(aName.c_str(), aValue.data(), aValue.size()); + } +#endif + //////////////////////////////////////////////////////////////////////////// /** From 7002c1fdc3f88a4aaf2c888974bd5fe0da3a6a8b Mon Sep 17 00:00:00 2001 From: Henrik Jakobsson Majava Date: Thu, 26 Sep 2019 11:23:11 +0200 Subject: [PATCH 2/6] Added a size parameter to const char * bind functions --- include/SQLiteCpp/Statement.h | 72 ++++++++++++++++++++++++++++++++--- src/Statement.cpp | 16 ++++---- 2 files changed, 74 insertions(+), 14 deletions(-) diff --git a/include/SQLiteCpp/Statement.h b/include/SQLiteCpp/Statement.h index 39879dd4..1835116a 100644 --- a/include/SQLiteCpp/Statement.h +++ b/include/SQLiteCpp/Statement.h @@ -162,7 +162,16 @@ class Statement * * @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use */ - void bind(const int aIndex, const char* apValue); + void bind(const int aIndex, const char* apValue, const int aSize); + /** + * @brief Bind a text value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) + * + * @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use + */ + inline void bind(const int aIndex, const char* apValue) + { + bind(aIndex, apValue, -1); + } /** * @brief Bind a binary blob value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) * @@ -177,6 +186,14 @@ class Statement * @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement. */ void bindNoCopy(const int aIndex, const std::string& aValue); + /** + * @brief Bind a text value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) + * + * Main usage is with text which might not be null-terminated. + * + * @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement. + */ + void bindNoCopy(const int aIndex, const char* apValue, const int aSize); /** * @brief Bind a text value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) * @@ -184,7 +201,10 @@ class Statement * * @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement. */ - void bindNoCopy(const int aIndex, const char* apValue); + inline void bindNoCopy(const int aIndex, const char* apValue) + { + bindNoCopy(aIndex, apValue, -1); + } /** * @brief Bind a binary blob value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) * @@ -243,7 +263,16 @@ class Statement * * @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use */ - void bind(const char* apName, const char* apValue); + void bind(const char* apName, const char* apValue, const int aSize); + /** + * @brief Bind a text value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) + * + * @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use + */ + inline void bind(const char* apName, const char* apValue) + { + bind(apName, apValue, -1); + } /** * @brief Bind a binary blob value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) * @@ -258,6 +287,14 @@ class Statement * @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement. */ void bindNoCopy(const char* apName, const std::string& aValue); + /** + * @brief Bind a text value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) + * + * Main usage is with text which might not be null-terminated + * + * @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement. + */ + void bindNoCopy(const char* apName, const char* apValue, const int aSize); /** * @brief Bind a text value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) * @@ -265,7 +302,10 @@ class Statement * * @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement. */ - void bindNoCopy(const char* apName, const char* apValue); + inline void bindNoCopy(const char* apName, const char* apValue) + { + bindNoCopy(apName, apValue, -1); + } /** * @brief Bind a binary blob value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) * @@ -342,7 +382,16 @@ class Statement */ inline void bind(const std::string& aName, const char* apValue) { - bind(aName.c_str(), apValue); + bind(aName.c_str(), apValue, -1); + } + /** + * @brief Bind a text value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) + * + * @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use + */ + inline void bind(const std::string& aName, const char* apValue, const int aSize) + { + bind(aName.c_str(), apValue, aSize); } /** * @brief Bind a binary blob value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) @@ -373,7 +422,18 @@ class Statement */ inline void bindNoCopy(const std::string& aName, const char* apValue) { - bindNoCopy(aName.c_str(), apValue); + bindNoCopy(aName.c_str(), apValue, -1); + } + /** + * @brief Bind a text value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) + * + * Main usage is with null-terminated literal text (aka in code static strings) + * + * @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement. + */ + inline void bindNoCopy(const std::string& aName, const char* apValue, const int aSize) + { + bindNoCopy(aName.c_str(), apValue, aSize); } /** * @brief Bind a binary blob value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) diff --git a/src/Statement.cpp b/src/Statement.cpp index 6af7556f..6c51913a 100644 --- a/src/Statement.cpp +++ b/src/Statement.cpp @@ -120,9 +120,9 @@ void Statement::bind(const int aIndex, const std::string& aValue) } // Bind a text value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement -void Statement::bind(const int aIndex, const char* apValue) +void Statement::bind(const int aIndex, const char* apValue, const int aSize) { - const int ret = sqlite3_bind_text(mStmtPtr, aIndex, apValue, -1, SQLITE_TRANSIENT); + const int ret = sqlite3_bind_text(mStmtPtr, aIndex, apValue, aSize, SQLITE_TRANSIENT); check(ret); } @@ -142,9 +142,9 @@ void Statement::bindNoCopy(const int aIndex, const std::string& aValue) } // Bind a text value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement -void Statement::bindNoCopy(const int aIndex, const char* apValue) +void Statement::bindNoCopy(const int aIndex, const char* apValue, const int aSize) { - const int ret = sqlite3_bind_text(mStmtPtr, aIndex, apValue, -1, SQLITE_STATIC); + const int ret = sqlite3_bind_text(mStmtPtr, aIndex, apValue, aSize, SQLITE_STATIC); check(ret); } @@ -205,10 +205,10 @@ void Statement::bind(const char* apName, const std::string& aValue) } // Bind a text value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement -void Statement::bind(const char* apName, const char* apValue) +void Statement::bind(const char* apName, const char* apValue, const int aSize) { const int index = sqlite3_bind_parameter_index(mStmtPtr, apName); - const int ret = sqlite3_bind_text(mStmtPtr, index, apValue, -1, SQLITE_TRANSIENT); + const int ret = sqlite3_bind_text(mStmtPtr, index, apValue, aSize, SQLITE_TRANSIENT); check(ret); } @@ -230,10 +230,10 @@ void Statement::bindNoCopy(const char* apName, const std::string& aValue) } // Bind a text value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement -void Statement::bindNoCopy(const char* apName, const char* apValue) +void Statement::bindNoCopy(const char* apName, const char* apValue, const int aSize) { const int index = sqlite3_bind_parameter_index(mStmtPtr, apName); - const int ret = sqlite3_bind_text(mStmtPtr, index, apValue, -1, SQLITE_STATIC); + const int ret = sqlite3_bind_text(mStmtPtr, index, apValue, aSize, SQLITE_STATIC); check(ret); } From 2d3ffb1f9c6f1939bd1af1a197f9c128dcca2cfe Mon Sep 17 00:00:00 2001 From: Henrik Jakobsson Majava Date: Mon, 20 Jan 2020 14:14:58 +0100 Subject: [PATCH 3/6] Restored test coverage --- tests/Statement_test.cpp | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/tests/Statement_test.cpp b/tests/Statement_test.cpp index b80b35d8..bc69dcdc 100644 --- a/tests/Statement_test.cpp +++ b/tests/Statement_test.cpp @@ -341,8 +341,8 @@ TEST(Statement, bindings) // Fifth row with binary buffer and a null parameter { - const char buffer[] = "binary"; - insert.bind(1, buffer, sizeof(buffer)); + char buffer[] = "binary"; + insert.bind(1, static_cast(buffer), sizeof(buffer)); insert.bind(2); EXPECT_EQ(1, insert.exec()); @@ -406,25 +406,26 @@ TEST(Statement, bindNoCopy) EXPECT_EQ(SQLite::OK, db.getErrorCode()); // Create a new table - EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, txt1 TEXT, txt2 TEXT, binary BLOB)")); + EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, txt1 TEXT, txt2 TEXT, txt3 TEXT, binary BLOB)")); EXPECT_EQ(SQLite::OK, db.getErrorCode()); // Insertion with bindable parameters - SQLite::Statement insert(db, "INSERT INTO test VALUES (NULL, ?, ?, ?)"); + SQLite::Statement insert(db, "INSERT INTO test VALUES (NULL, ?, ?, ?, ?)"); // Compile a SQL query to check the results SQLite::Statement query(db, "SELECT * FROM test"); EXPECT_STREQ("SELECT * FROM test", query.getQuery().c_str()); - EXPECT_EQ(4, query.getColumnCount()); + EXPECT_EQ(5, query.getColumnCount()); // Insert one row with all variants of bindNoCopy() { const char* txt1 = "first"; const std::string txt2 = "sec\0nd"; - const char blob[] = {'b','l','\0','b'}; + char blob[] = {'b','l','\0','b'}; insert.bindNoCopy(1, txt1); insert.bindNoCopy(2, txt2); - insert.bindNoCopy(3, blob, sizeof(blob)); + insert.bindNoCopy(3, txt2.c_str(), static_cast(txt2.size())); + insert.bindNoCopy(4, static_cast(blob), sizeof(blob)); EXPECT_EQ(1, insert.exec()); EXPECT_EQ(SQLITE_DONE, db.getErrorCode()); @@ -435,7 +436,8 @@ TEST(Statement, bindNoCopy) EXPECT_EQ(1, query.getColumn(0).getInt64()); EXPECT_STREQ(txt1, query.getColumn(1).getText()); EXPECT_EQ(0, memcmp(&txt2[0], &query.getColumn(2).getString()[0], txt2.size())); - EXPECT_EQ(0, memcmp(blob, &query.getColumn(3).getString()[0], sizeof(blob))); + EXPECT_EQ(0, memcmp(&txt2[0], &query.getColumn(3).getString()[0], txt2.size())); + EXPECT_EQ(0, memcmp(blob, &query.getColumn(4).getString()[0], sizeof(blob))); } } @@ -621,8 +623,8 @@ TEST(Statement, bindByNameString) // Third row with binary buffer and a null parameter { - const char buffer[] = "binary"; - insert.bind(amsg, buffer, sizeof(buffer)); + char buffer[] = "binary"; + insert.bind(amsg, static_cast(buffer), sizeof(buffer)); insert.bind(aint); EXPECT_EQ(1, insert.exec()); @@ -709,10 +711,10 @@ TEST(Statement, bindNoCopyByName) const std::string ablob = "@blob"; const char* txt1 = "first2"; const std::string txt2 = "sec\0nd2"; - const char blob[] = { 'b','l','\0','b','2' }; + char blob[] = { 'b','l','\0','b','2' }; insert.bindNoCopy(atxt1, txt1); insert.bindNoCopy(atxt2, txt2); - insert.bindNoCopy(ablob, blob, sizeof(blob)); + insert.bindNoCopy(ablob, static_cast(blob), sizeof(blob)); EXPECT_EQ(1, insert.exec()); EXPECT_EQ(2, db.getLastInsertRowid()); EXPECT_EQ(SQLITE_DONE, db.getErrorCode()); From f25364e125ca2a06c848617cee40989547399d3a Mon Sep 17 00:00:00 2001 From: Henrik Jakobsson Majava Date: Mon, 20 Jan 2020 15:11:09 +0100 Subject: [PATCH 4/6] More coverage fixes --- tests/Statement_test.cpp | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/tests/Statement_test.cpp b/tests/Statement_test.cpp index bc69dcdc..e66fe9aa 100644 --- a/tests/Statement_test.cpp +++ b/tests/Statement_test.cpp @@ -341,8 +341,8 @@ TEST(Statement, bindings) // Fifth row with binary buffer and a null parameter { - char buffer[] = "binary"; - insert.bind(1, static_cast(buffer), sizeof(buffer)); + const unsigned char buffer[] = "binary"; + insert.bind(1, buffer, sizeof(buffer)); insert.bind(2); EXPECT_EQ(1, insert.exec()); @@ -351,7 +351,7 @@ TEST(Statement, bindings) EXPECT_TRUE (query.hasRow()); EXPECT_FALSE(query.isDone()); EXPECT_EQ(5, query.getColumn(0).getInt64()); - EXPECT_STREQ(buffer, query.getColumn(1).getText()); + EXPECT_EQ(0, memcmp(buffer, &query.getColumn(1).getString()[0], sizeof(buffer))); EXPECT_TRUE (query.isColumnNull(2)); EXPECT_EQ(0, query.getColumn(2).getInt()); EXPECT_EQ(0.234f, query.getColumn(3).getDouble()); @@ -421,11 +421,11 @@ TEST(Statement, bindNoCopy) { const char* txt1 = "first"; const std::string txt2 = "sec\0nd"; - char blob[] = {'b','l','\0','b'}; + const unsigned char blob[] = {'b','l','\0','b'}; insert.bindNoCopy(1, txt1); insert.bindNoCopy(2, txt2); insert.bindNoCopy(3, txt2.c_str(), static_cast(txt2.size())); - insert.bindNoCopy(4, static_cast(blob), sizeof(blob)); + insert.bindNoCopy(4, blob, sizeof(blob)); EXPECT_EQ(1, insert.exec()); EXPECT_EQ(SQLITE_DONE, db.getErrorCode()); @@ -623,8 +623,8 @@ TEST(Statement, bindByNameString) // Third row with binary buffer and a null parameter { - char buffer[] = "binary"; - insert.bind(amsg, static_cast(buffer), sizeof(buffer)); + const unsigned char buffer[] = "binary"; + insert.bind(amsg, buffer, sizeof(buffer)); insert.bind(aint); EXPECT_EQ(1, insert.exec()); @@ -633,7 +633,7 @@ TEST(Statement, bindByNameString) EXPECT_TRUE(query.hasRow()); EXPECT_FALSE(query.isDone()); EXPECT_EQ(3, query.getColumn(0).getInt64()); - EXPECT_STREQ(buffer, query.getColumn(1).getText()); + EXPECT_EQ(0, memcmp(buffer, query.getColumn(1).getText(), 6)); EXPECT_TRUE(query.isColumnNull(2)); EXPECT_EQ(0, query.getColumn(2).getInt()); EXPECT_EQ(0.234f, query.getColumn(3).getDouble()); @@ -659,6 +659,23 @@ TEST(Statement, bindByNameString) EXPECT_EQ(4294967295U, query.getColumn(2).getUInt()); EXPECT_EQ(12345678900000LL, query.getColumn(4).getInt64()); } + + // reset() without clearbindings() + insert.reset(); + + // Fifth row with string + { + const std::string first = "fir\0st"; + insert.bind(amsg, first.c_str(), static_cast(first.size())); + EXPECT_EQ(1, insert.exec()); + EXPECT_EQ(SQLITE_DONE, db.getErrorCode()); + + // Check the result + query.executeStep(); + EXPECT_TRUE(query.hasRow()); + EXPECT_FALSE(query.isDone()); + EXPECT_EQ(first, query.getColumn(1).getString()); + } } TEST(Statement, bindNoCopyByName) @@ -711,10 +728,10 @@ TEST(Statement, bindNoCopyByName) const std::string ablob = "@blob"; const char* txt1 = "first2"; const std::string txt2 = "sec\0nd2"; - char blob[] = { 'b','l','\0','b','2' }; + const unsigned char blob[] = { 'b','l','\0','b','2' }; insert.bindNoCopy(atxt1, txt1); - insert.bindNoCopy(atxt2, txt2); - insert.bindNoCopy(ablob, static_cast(blob), sizeof(blob)); + insert.bindNoCopy(atxt2, txt2.c_str(), static_cast(atxt2.size())); + insert.bindNoCopy(ablob, blob, sizeof(blob)); EXPECT_EQ(1, insert.exec()); EXPECT_EQ(2, db.getLastInsertRowid()); EXPECT_EQ(SQLITE_DONE, db.getErrorCode()); From 1a98ec4fa7fdbfab929d1de0c0677c0155b7edcd Mon Sep 17 00:00:00 2001 From: Henrik Jakobsson Majava Date: Mon, 20 Jan 2020 15:54:07 +0100 Subject: [PATCH 5/6] More coverage fixes and small typo fix --- tests/Statement_test.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/tests/Statement_test.cpp b/tests/Statement_test.cpp index e66fe9aa..713a6520 100644 --- a/tests/Statement_test.cpp +++ b/tests/Statement_test.cpp @@ -730,7 +730,7 @@ TEST(Statement, bindNoCopyByName) const std::string txt2 = "sec\0nd2"; const unsigned char blob[] = { 'b','l','\0','b','2' }; insert.bindNoCopy(atxt1, txt1); - insert.bindNoCopy(atxt2, txt2.c_str(), static_cast(atxt2.size())); + insert.bindNoCopy(atxt2, txt2.c_str(), static_cast(txt2.size())); insert.bindNoCopy(ablob, blob, sizeof(blob)); EXPECT_EQ(1, insert.exec()); EXPECT_EQ(2, db.getLastInsertRowid()); @@ -746,6 +746,27 @@ TEST(Statement, bindNoCopyByName) EXPECT_EQ(0, memcmp(&txt2[0], &query.getColumn(2).getString()[0], txt2.size())); EXPECT_EQ(0, memcmp(blob, &query.getColumn(3).getString()[0], sizeof(blob))); } + + insert.reset(); + query.reset(); + + // Insert a third row with some more variants of bindNoCopy() using std::string names + { + const std::string atxt1 = "@txt1"; + const std::string txt1 = "fir\0st"; + insert.bindNoCopy(atxt1, txt1); + EXPECT_EQ(1, insert.exec()); + EXPECT_EQ(3, db.getLastInsertRowid()); + EXPECT_EQ(SQLITE_DONE, db.getErrorCode()); + + // Check the result + query.executeStep(); // pass on the first row + query.executeStep(); // pass on the second row as well + query.executeStep(); + EXPECT_TRUE(query.hasRow()); + EXPECT_FALSE(query.isDone()); + EXPECT_EQ(txt1, query.getColumn(1).getString()); + } } TEST(Statement, isColumnNull) From 7465704cfc132140ad57d82fcc2ab9e8d7cc0477 Mon Sep 17 00:00:00 2001 From: Henrik Jakobsson Majava Date: Mon, 20 Jan 2020 16:09:02 +0100 Subject: [PATCH 6/6] Address sanitizer fix --- tests/Statement_test.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Statement_test.cpp b/tests/Statement_test.cpp index 713a6520..fb7020ca 100644 --- a/tests/Statement_test.cpp +++ b/tests/Statement_test.cpp @@ -748,6 +748,7 @@ TEST(Statement, bindNoCopyByName) } insert.reset(); + insert.clearBindings(); query.reset(); // Insert a third row with some more variants of bindNoCopy() using std::string names