libpqxx: MacOS: error: inline function 'pqxx::string_traits::size_buffer' is not defined
Hello, again.
I am using libpqxx 7.1.1 and this is based on #326
I have the following code
...
m_conn.prepare("seen_fingerprints", "SELECT fingerprint FROM basis WHERE fingerprint IN $1");
...
....
{
std::vector<pqxx::binarystring> fingerprints;
for (auto it = seen_fingerprints.begin(); it != seen_fingerprints.end(); ++it)
{
auto fingerprint = pqxx::binarystring(it->first.data(), it->first.size());
fingerprints.push_back(fingerprint);
}
pqxx::work worker{m_conn};
pqxx::result res {worker.exec_prepared("seen_fingerprints", fingerprints)};
....
worker.commit();
}
This build on Linux, no problem. But on MacOS I get these errors:
[ 99/102] Compiling src/alexandria-storage-node/database.cpp
In file included from ../src/alexandria-storage-node/database.cpp:1:
In file included from ../src/alexandria-storage-node/database.hpp:5:
In file included from /usr/local/include/pqxx/pqxx:4:
In file included from /usr/local/include/pqxx/connection:6:
In file included from /usr/local/include/pqxx/connection.hxx:27:
In file included from /usr/local/include/pqxx/prepared_statement.hxx:17:
In file included from /usr/local/include/pqxx/internal/statement_parameters.hxx:26:
In file included from /usr/local/include/pqxx/strconv:4:
/usr/local/include/pqxx/strconv.hxx:168:3: error: inline function 'pqxx::string_traits<pqxx::binarystring>::size_buffer' is not defined [-Werror,-Wundefined-inline]
size_buffer(TYPE const &value) noexcept;
^
/usr/local/include/pqxx/internal/conversions.hxx:672:55: note: used here
elt_traits::size_buffer(elt) - 1};
^
In file included from ../src/alexandria-storage-node/database.cpp:1:
In file included from ../src/alexandria-storage-node/database.hpp:5:
In file included from /usr/local/include/pqxx/pqxx:4:
In file included from /usr/local/include/pqxx/connection:6:
In file included from /usr/local/include/pqxx/connection.hxx:27:
In file included from /usr/local/include/pqxx/prepared_statement.hxx:17:
In file included from /usr/local/include/pqxx/internal/statement_parameters.hxx:26:
In file included from /usr/local/include/pqxx/strconv:4:
/usr/local/include/pqxx/strconv.hxx:154:23: error: inline function 'pqxx::string_traits<pqxx::binarystring>::into_buf' is not defined [-Werror,-Wundefined-inline]
static inline char *into_buf(char *begin, char *end, TYPE const &value);
^
/usr/local/include/pqxx/internal/conversions.hxx:732:23: note: used here
string_traits<T>::into_buf(buf.data(), buf.data() + buf.size(), value)};
^
2 errors generated.
I have tried to configure like this CXX=clang++ ./configure --disable-documentation CXXFLAGS=-O3 and ./configure --disable-documentation CXXFLAGS=-O3. Both works on Linux.
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 16 (10 by maintainers)
We’re talking about two different things here: transferring the data to the database, and storing the data in the database. It should be possible to transfer your data in hex-escaped form (as with
esc_raw()) but into a binary form (as with the BYTEA type). Should cost you a bit of CPU and network time, but no extra storage on the server. Arrays may complicate things a bit though.Some very good news is that as long as the back-end is recent enough, it’ll easy enough to build a
to_stringetc. forbinarystring. And the result is faster as well!I think I may see the problem. There’s a special case.
When you pass a
binarystringto a prepared statement, libpqxx never converts it to a string. There’s a special facility in libpq for passing binary parameters. So, libpqxx keeps it in binary form and passes it that way. For that, we don’t need a conversion frombinarystringto string form. And so I never implemented that conversion, because I saw it as an open invitation to make code inefficient. Why convert binary to text format and have the server parse it back, when there’s a way to pass binary directly?But what happens when you try to pass a
std::vector<pqxx::binarystring>? Well, there’s a string conversion forstd::vector<T>, but it (of course) makes use of the string conversion forT. In this case,Tisbinarystring, and so… not implemented.I have no idea why this would compile on one platform and not on another. I would suspect that there’s some unnoticed difference, perhaps hidden in an old object file that isn’t being recompiled, something like that. Or perhaps it’s related to what @KayEss said:
charbeing signed on one platform and unsigned on the other. Sounds plausible, I just can’t think how it might come into play.One thing I can try to help address the problem is to implement a string conversion for
binarystring. It’s not as efficient as passing abinarystringto a prepared statement, because it needs to do escaping, so I’ll have to add copious amounts of documentation on sane use. And of course we’ll still have to see whether it works with theINsyntax in the first place.(I think I’ve also found a bunch of dead code related to prepared statements, so I also need to clean that up.)
charissignedon Mac, butunsignedon Linux (or the other way around – in any case different). This could change the specialisation looked for and would be easy to mix up.