Frequently Asked Questions

General questions

Can I become a project member?

Probably not, simply because there are no members. Everyone's welcome to contribute, and since libpqxx is developed out in the open, gets public credit.

If you wish to collaborate on the project, that's easy. Just do it! Try posting your patches, bug reports, complaints or suggestions on the GitHub project. Build a name for yourself helping answer other users' questions in the issue tracker, and join in design discussions.

What platforms does libpqxx run on?

For starters, just about anything that bears any resemblance to Unix (the various flavours of GNU/Linux and of BSD, Apple's OS/X, Solaris, AIX, HP/UX, Irix etc.). The processor architecture doesn't matter much: libpqxx has been extensively tested on many different CPU architectures without any required changes or special support.

Then there's Microsoft Windows. This platform is supported, but it's a bit more difficult because of its lack of package management, software distribution infrastructure, standardised development environment, filesystem layout standards, and so on. The easiest way to build and use libpqxx on a Windows system is to use CMake.

What PostgreSQL versions are supported?

As a general rule, all currently supported major PostgreSQL releases. At this entry's time of writing, both front-end and back-end need to be version 9.3 or better.

I want to use libpq++ and I have a question!

These two libraries are completely separate projects. You're looking at the libpqxx site, not the libpq++ one.

In fact libpqxx was written from scratch because the problems with libpq++ ran too deep to fix. Around the same time libpqxx was published, all postgres client interfaces were taken out of the main package and this included both the older libpq++ and the new libpqxx.

How does libpqxx relate to libpq++? Which one should I choose?

libpqxx was written, starting in the year 2000, to replace the aging libpq++, and has been the official C++ interface for many years. I'm obviously biased, but you should probably just forget about libpq++.

Isn't "Postgre" a strange name?

Yes. That's why it's not actually the name.

The correct short version of PostgreSQL is postgres, with the "s" at the end.

Why isn't there any documentation?

There is. Check out README.md and the documentation on Read The Docs.

Furthermore, the header files in the include/pqxx/ part of the source tree are extensively commented. These comments are automatically extracted to generate the reference documentation on Read The Docs.

Finally, the test programs in the test/ directory provide working examples of how to program using libpqxx.

Feature Questions

Data is transferred in text form. Can I make it work directly in binary?

Many people ask for this feature because they are looking for increased performance. The underlying libpq library can transfer all data in binary form, but this is not likely to be supported in libpqxx any time soon.

There are good reasons for this:

Nevertheless, there are special cases where binary transfers do make sense, and these are fully supported by libpqxx:

  1. Large objects, a.k.a. "blobs." See the argeobject classes. Large objects are stored separately from regular data, and you access them using a file-like API. It's possible to retrieve or even rewrite just a part of a very large object, without having to transfer the whole thing to the client and back to the server.

  2. Prepared statements can take binary parameters. Some applications wrap INSERT statements in prepared statements to save the server from having to parse the entire statement, so for inserting data this may be close to what you're doing already. But for efficient bulk insertion of data, the stream_to class is probably a better choice.

Apart from large objects, there is no way to retrieve regular data directly in binary form. If you want to work with relatively large binary objects but do not wish to use the large-object API, the best alternative is to keep them in regular columns of BYTEA type. Insert them using a prepared statement to avoid text conversion on the way to the server, and retrieve them into binarystring objects.

Can I let libpqxx write data from the database directly into my objects?

Some users would like to can access SQL fields as if they were C++ struct/class members.

This is not generally supported. Streaming queries will let you map fields directly into local variables, but not into the members of an object.

If you use stream_to, and stream_from, you can stream instances of std::tuple. Each field in the tuple corresponds to a field in the database.

There is also at least one Object-Relational Mapper (or ORM) based on libpqxx, and it's built into FOST.

Can you expose this C-level libpq structure that libpqxx hides from me?

Generally, no. If you require support for specific high-level functionality, the better solution is usually to build it into the abstraction layer rather than to break the abstraction layer open like this.

Some of the things libpqxx does for you may become impossible if the library does not have full and unique control over the underlying C-level structures, or it might lead to subtle and complex bugs in your program.

Feel free, however, to prototype enhancements that meet your own needs, see what works best for you, and then submit a pull request or a feature request.

Can I have two or more simultaneous transactions?

Not within the same connection. Even if you use nested transactions (see the subtransaction class), a connection is always dealing with just one transaction at a time. Of course you can create a new transaction on the same connection once the previous one has completed.

If you want to have multiple concurrent transactions, let them work on different connections.

Questions about Building libpqxx and your own code

Will it work with my compiler?

It mainly depends on whether your compiler supports the right version of C++. For example, libpqxx 7.0 requires C++17 or better.

Can I build libpqxx and my own application with different compilers?

No. This is a drawback of how C++ works, or of the C-style linking process, depending on how you look at it. Generally you can't link code built with one compiler to code built with another.

Even different versions of the same compiler may differ. In the case of gcc, today's versions adhere to a standard interface that should keep object files compatible between gcc versions. There are still minor changes from time to time, however.

Do I need libpq when I use libpqxx?

Yes; libpqxx is built on top of libpq. You call libpqxx, and libpqxx in turn calls libpq. You won't need to use or know any libpq functions yourself though.

You may get link errors about missing symbols such as _PQconnectdb, _PQfinish, _PQexec and so on. Usually this means one or more of:

How compatible are different libpqxx versions?

Releases are versioned like x.y.z.

Generally speaking, if you've compiled your application against libpqxx x.y.z, using a libpqxxx.y.z+1` binary will probably work. It can't be guaranteed though.

Also generally speaking, code written against libpqxx x.y.z will generally compile. link, and run against x.y+1.*.

When upgrading from x.y.z to x+1.*.* though, all bets are off. This is where we do major incompatible changes. Even then, there's a good chance that your code will still compile and work — but expect to do some maintenance.

Why so few guarantees? It's just too easy to break ABI compatibility in a C++ library. A small sensible change can do it, and sometimes it might break compatibility on one compiler but not on another. Even a compiler upgrade might break binary compatibility.

Can I build a dynamic library?

You should get one if you use the configure script's --enable-shared option, or CMake's -DBUILD_SHARED_LIBS=1 option.

Are shared libraries a good idea? The answer depends on your OS.

On Windows, you'll probably want to build a DLL and ship it with your application. In that case, a shared library is a safe choice since nobody's going to upgrade the binary on their own. A shared library seems to be a conventional choice for Windows, so go ahead.

On other systems, shared libraries are usually packaged and installed globally, independent from any individual application. That's great if you have a library which promises binary compatibility between releases, but libpqxx isn't one of those. So, prefer a static library unless you need to dlopen() it at runtime.

Why can't the build procedure find libpq? It's in plain sight!

The build has several different ways of finding the libpq library and headers:

CMake

The CMake build uses the standard CMake machine for finding the PostgreSQL package, but there are ways of overriding it if that doesn't work.

If you have CMake 3.12 or better, you can set the PostgreSQL_ROOT variable when running cmake: "-DPostgreSQL_ROOT=../PostgreSQL-13". This tells the build where to look for both the libpq library and its headers.

Or, you can set individual variables for the various parts: PostgreSQL_LIBRARY, PostgreSQL_INCLUDE_DIR, PostgreSQL_TYPE_INCLUDE_DIR.

configure

The configure script, by default, tries to find libpq by running pkg-config. Make sure that script is in your PATH, and knows where to find your PostgreSQL installation.

If that doesn't work, configure will try the pg_config script which comes with postgres. If you have the script in your PATH, you'll get the libpq belonging to the same PostgreSQL install whose pg_config script you used.

But, you can also set the paths explicitly. Pass --with-postgres-include for libpq's headers directory, and --with-postgres-lib for its library directory.

Visual C++: Debug and Release

Visual C++ likes to build both libpq and libpqxx, as well as your program, in two flavours: debug and release.

When building your program in the Debug flavour, you must link to the Debug-flavoured builds of both libraries as well.

When building in the Release flavour, use only the Release-flavoured libraries.

Visual C++: min() and max()

This has been giving people no end of trouble. Visual C++, by default, defines min() and max() as preprocessor macros… meaning that a lot of correct, standard-conforming code will not compile properly.

The libpqxx headers disable this feature by defining the NOMINMAX preprocessor macro, which tells the Visual C++ headers not to #define min() and max(). However this seems to cause some of Visual C++'s own headers to fail to compile.

One way around this is always to include libpqxx headers before system headers, and #undef NOMINMAX between the two sets of #includes. Another workaround, suggested by Trigve Siver, is to include first the system headers and then the libpqxx headers (for older libpqxx versions that don't define NOMINIMAX it's the other way around), and finally:

#include <algorithm>
#define max(x,y) std::max(x,y)
#define min(x,y) std::min(x,y)

Troubleshooting Questions

I'm running into a bug. What can I do?

Have a look at the GitHub page. The "Issues" section is meant for bug reports, questions, and user problems.

Before you open an issue though, try searching for your problem — both in the issue tracker and on the Internet at large.

Does WinZip mess up the source tree?

Sometimes. This problem occurs on Windows systems only. If you use WinZip to extract the libpqxx source tarball, try disabling the "tar file smart CR/LF conversion" option.

I can't catch exceptions!

Some people report that their programs crash when an exception occurs. You're most likely to see this when logging into the database fails, because that's something you're likely to do very early on in your program.

Some common solution to try:

Why does my program crash when a connection to the database breaks?

Sometimes connections to the database are lost even after they have been successfully established. This can happen for many reasons: a broken cable, a power outage in the wrong place, a crashed server, a change to your network configuration, or even a firewall dropping your connection because it hasn't been used for too long.

When it does, your program (on Unix-like systems at least) may also receive the SIGPIPE signal. Your program's default response to receiving this error is to abort. That can be useful for simple, short-lived programs but many more complex applications can not afford to crash just because a network connection was lost.

All you need to do deal with broken connections in libpqxx on Unix-like systems (and that includes GNU and BSD systems) is to make your program ignore this signal. Just include something like this in your program:

#include <signal.h>

int main()
{
  signal(SIGPIPE, SIG_IGN);
  // ...

If libpqxx finds that a connection is broken as you try to use it, the library will try to reactivate the connection automatically. If that fails also, a broken_connection exception will be thrown that can be handled by your program as a normal C++ exception.

Why does my program crash when it fails to connect to the database?

Usually this means there's an exception, and the exception isn't being caught properly.

See "I can't catch exceptions!" above.