libpqxx
The C++ client library for PostgreSQL
pqxx::result Class Referencefinal

Result set containing data returned by a query or command. More...

#include <result.hxx>

Public Types

using size_type = result_size_type
 
using difference_type = result_difference_type
 
using reference = row_ref
 
using const_iterator = const_result_iterator
 
using pointer = const_iterator
 
using iterator = const_iterator
 
using const_reverse_iterator = const_reverse_result_iterator
 
using reverse_iterator = const_reverse_iterator
 

Public Member Functions

 result () noexcept=default
 
 result (result const &rhs) noexcept=default
 
 result (result &&rhs) noexcept=default
 
 ~result ()=default
 
resultoperator= (result const &rhs) noexcept=default
 Assign one result to another. More...
 
resultoperator= (result &&rhs) noexcept=default
 Assign one result to another, invaliding the old one. More...
 
Comparisons
Warning
The meaning of these comparisons has changed in 8.0. The old comparisons went through the results' data (but not metadata!) and looked for differences. This was fairly arbitrary and a potential performance trap.

A result is essentially a reference-counted pointer to a data structure that we received from the database. When you copy a result (through assignment or copy construction) you get a second reference to the same underlying data structure.

This can be important because efficient code will use all kinds of direct references to that data: row_ref, field_ref, std::string_vew, zview, raw C-style string pointers. Those all stay valid even when you copy your result and destroy the original, because all you really did was replace one smart pointer with another. The actual data structure underneath stays exactly where it was.

(This may also help explain why we have row and field classes on the one hand, and row_ref, field_ref, and iterators on the other. row and field contain their own copy of the result. Those other classes carry just a pointer to the result.)

The meaning of the result comparison operators is: Do these two result objects refer to the same underlying data structure?

bool operator== (result const &rhs) const noexcept
 Compare two results for equality. More...
 
bool operator!= (result const &rhs) const noexcept
 Compare two results for inequality. More...
 
Iteration

A result acts like a container of rows. Each row in turn acts like a container of fields.

template<typename... TYPE>
auto iter () const
 Iterate rows, reading them directly into a tuple of "TYPE...". More...
 
PQXX_PURE const_reverse_iterator rbegin () const noexcept
 
PQXX_PURE const_reverse_iterator crbegin () const noexcept
 
PQXX_PURE const_reverse_iterator rend () const noexcept
 
PQXX_PURE const_reverse_iterator crend () const noexcept
 
PQXX_PURE const_iterator begin () const noexcept
 
PQXX_PURE const_iterator cbegin () const noexcept
 
PQXX_PURE const_iterator end () const noexcept
 
PQXX_PURE const_iterator cend () const noexcept
 
PQXX_PURE row_ref front () const noexcept
 
PQXX_PURE row_ref back () const noexcept
 
PQXX_PURE size_type size () const noexcept
 
PQXX_PURE bool empty () const noexcept
 
PQXX_PURE size_type capacity () const noexcept
 
void swap (result &) noexcept
 Exchange two result values in an exception-safe manner. More...
 
PQXX_PURE row_ref operator[] (size_type i) const noexcept
 Index a result by number to get to a row. More...
 
row_ref at (size_type, sl=sl::current()) const
 Index a row by number, but check that the row number is valid. More...
 
field_ref at (size_type, row_size_type, sl=sl::current()) const
 Index a field by row number and column number. More...
 
void clear () noexcept
 Let go of the result's data. More...
 

Column information

class pqxx::internal::gate::result_pipeline
 
class pqxx::internal::gate::result_field_ref
 
class pqxx::internal::gate::result_creation
 
class pqxx::internal::gate::result_connection
 
class pqxx::internal::gate::result_row
 
class pqxx::internal::gate::result_sql_cursor
 
PQXX_PURE row_size_type columns () const noexcept
 Number of columns in result. More...
 
row_size_type column_number (zview name, sl=sl::current()) const
 Number of given column (throws exception if it doesn't exist). More...
 
PQXX_RETURNS_NONNULL char const * column_name (row_size_type number, sl=sl::current()) const &
 Name of column with this number (throws exception if it doesn't exist). More...
 
int column_storage (row_size_type number, sl=sl::current()) const
 Server-side storage size for field of column's type, in bytes. More...
 
int column_type_modifier (row_size_type number) const noexcept
 Type modifier of the column with this number. More...
 
oid column_type (row_size_type col_num, sl=sl::current()) const
 Return column's type, as an OID from the system catalogue. More...
 
oid column_type (zview col_name, sl loc=sl::current()) const
 Return column's type, as an OID from the system catalogue. More...
 
oid column_table (row_size_type col_num, sl=sl::current()) const
 What table did this column come from? More...
 
oid column_table (zview col_name, sl loc=sl::current()) const
 What table did this column come from? More...
 
row_size_type table_column (row_size_type col_num, sl=sl::current()) const
 What column in its table did this column come from? More...
 
row_size_type table_column (zview col_name, sl loc=sl::current()) const
 What column in its table did this column come from? More...
 
PQXX_PURE std::string const & query () const &noexcept
 Query that produced this result, if available (empty string otherwise) More...
 
PQXX_PURE oid inserted_oid (sl=sl::current()) const
 If command was an INSERT of 1 row, return oid of the inserted row. More...
 
PQXX_PURE size_type affected_rows () const
 Number of rows affected by the SQL command whose result this is. More...
 
template<typename CALLABLE >
void for_each (CALLABLE &&func, sl=sl::current()) const
 Run func on each row, passing the row's fields as parameters. More...
 
result const & expect_rows (size_type n, sl loc=sl::current()) const
 Check that result contains exactly n rows. More...
 
row one_row (sl=sl::current()) const
 Check that result contains exactly 1 row, and return that row. More...
 
row_ref one_row_ref (sl=sl::current()) const
 Check that result contains exactly 1 row, and return a reference to it. More...
 
std::optional< rowopt_row (sl=sl::current()) const
 Expect that result contains at most one row, and return as optional. More...
 
std::optional< row_refopt_row_ref (sl=sl::current()) const
 Expect that result contains at most one row, and return as optional. More...
 
result const & no_rows (sl loc=sl::current()) const
 Expect that result contains no rows. Return result for convenience. More...
 
result const & expect_columns (row_size_type cols, sl loc=sl::current()) const
 Expect that result consists of exactly cols columns. More...
 
field one_field (sl=sl::current()) const
 Expect that result consists of exactly 1 row and 1 column; return it. More...
 
field_ref one_field_ref (sl=sl::current()) const
 Expect that result consists of exactly 1 row and 1 column; return it. More...
 
encoding_group get_encoding_group () const noexcept
 Retrieve encoding group for this result's client encoding. More...
 

Detailed Description

Result set containing data returned by a query or command.

This behaves as a container (as defined by the C++ standard library) and provides random access const iterators to iterate over its rows. You can also access a row by indexing a result R by the row's zero-based number:

for (result::size_type i=0; i < std::size(R); ++i) Process(R[i]);
result_size_type size_type
Definition: result.hxx:103

Result sets in libpqxx are lightweight, reference-counted wrapper objects which are relatively small and cheap to copy. Think of a result object as a "smart pointer" to an underlying result set.

Warning
The result set that a result object points to is not thread-safe. If you copy a result object, it still refers to the same underlying result set. So never copy, destroy, query, or otherwise access a result while another thread may be copying, destroying, querying, or otherwise accessing the same result set–even if it is doing so through a different result object!

Member Typedef Documentation

◆ const_iterator

◆ const_reverse_iterator

◆ difference_type

◆ iterator

◆ pointer

◆ reference

◆ reverse_iterator

◆ size_type

Constructor & Destructor Documentation

◆ result() [1/3]

pqxx::result::result ( )
defaultnoexcept

◆ result() [2/3]

pqxx::result::result ( result const &  rhs)
defaultnoexcept

◆ result() [3/3]

pqxx::result::result ( result &&  rhs)
defaultnoexcept

◆ ~result()

pqxx::result::~result ( )
default

Member Function Documentation

◆ affected_rows()

pqxx::result::size_type pqxx::result::affected_rows ( ) const

Number of rows affected by the SQL command whose result this is.

Returns the number of rows affected if the command was a SELECT, CREATE TABLE AS, INSERT, UPDATE, DELETE, MERGE, MOVE, FETCH, or COPY; or an EXECUTE or a parameterised or prepared statement that did an INSERT, UPDATE, DELETE, or MERGE.

Otherwise, returns zero.

◆ at() [1/2]

pqxx::field_ref pqxx::result::at ( size_type  row_num,
pqxx::row_size_type  col_num,
sl  loc = sl::current() 
) const

Index a field by row number and column number.

◆ at() [2/2]

pqxx::row_ref pqxx::result::at ( size_type  i,
sl  loc = sl::current() 
) const

Index a row by number, but check that the row number is valid.

◆ back()

pqxx::row_ref pqxx::result::back ( ) const
noexcept

◆ begin()

pqxx::result::const_iterator pqxx::result::begin ( ) const
noexcept

◆ capacity()

PQXX_PURE size_type pqxx::result::capacity ( ) const
inlinenoexcept

◆ cbegin()

pqxx::result::const_iterator pqxx::result::cbegin ( ) const
noexcept

◆ cend()

const_result_iterator pqxx::result::cend ( ) const
inlinenoexcept

◆ clear()

void pqxx::result::clear ( )
inlinenoexcept

Let go of the result's data.

Use this if you need to deallocate the result data earlier than you can destroy the result object itself.

Multiple result objects can refer to the same set of underlying data. The underlying data will be deallocated once all result objects that refer to it are cleared or destroyed.

◆ column_name()

char const * pqxx::result::column_name ( row_size_type  number,
sl  loc = sl::current() 
) const &

Name of column with this number (throws exception if it doesn't exist).

◆ column_number()

pqxx::row::size_type pqxx::result::column_number ( zview  name,
sl  loc = sl::current() 
) const

Number of given column (throws exception if it doesn't exist).

By default, as everywhere in PostgreSQL, upper-case letters in identifiers get converted to lower-case, and of course special characters such as quotes also cause problems.

Therefore, if the column name may contain any upper-case letters that you do not want lower-cased, or special characters, escape and quote it first: myresult.column_number(mytransaction.quote_name(name)).

◆ column_storage()

int pqxx::result::column_storage ( row_size_type  number,
sl  loc = sl::current() 
) const

Server-side storage size for field of column's type, in bytes.

Returns the size of the server's internal representation of the column's data type. A negative value indicates the data type is variable-length.

◆ column_table() [1/2]

pqxx::oid pqxx::result::column_table ( row_size_type  col_num,
sl  loc = sl::current() 
) const

What table did this column come from?

◆ column_table() [2/2]

oid pqxx::result::column_table ( zview  col_name,
sl  loc = sl::current() 
) const
inline

What table did this column come from?

By default, as everywhere in PostgreSQL, upper-case letters in identifiers get converted to lower-case, and of course special characters such as quotes also cause problems.

Therefore, if the column name may contain any upper-case letters that you do not want lower-cased, or special characters, escape and quote it first: myresult.column_table(mytransaction.quote_name(name)).

◆ column_type() [1/2]

pqxx::oid pqxx::result::column_type ( row_size_type  col_num,
sl  loc = sl::current() 
) const

Return column's type, as an OID from the system catalogue.

◆ column_type() [2/2]

oid pqxx::result::column_type ( zview  col_name,
sl  loc = sl::current() 
) const
inline

Return column's type, as an OID from the system catalogue.

By default, as everywhere in PostgreSQL, upper-case letters in identifiers get converted to lower-case, and of course special characters such as quotes also cause problems.

Therefore, if the column name may contain any upper-case letters that you do not want lower-cased, or special characters, escape and quote it first: myresult.column_type(mytransaction.quote_name(col_name)).

◆ column_type_modifier()

int pqxx::result::column_type_modifier ( row_size_type  number) const
noexcept

Type modifier of the column with this number.

The meaning of modifier values is type-specific; they typically indicate precision or size limits.

Use this only if you know what you're doing. Most applications do not need it, and most types do not use modifiers.

The value -1 indicates "no information available."

Warning
There is no check for errors, such as an invalid column number.

◆ columns()

pqxx::row::size_type pqxx::result::columns ( ) const
noexcept

Number of columns in result.

◆ crbegin()

pqxx::result::const_reverse_iterator pqxx::result::crbegin ( ) const
noexcept

◆ crend()

pqxx::result::const_reverse_iterator pqxx::result::crend ( ) const
noexcept

◆ empty()

bool pqxx::result::empty ( ) const
noexcept

◆ end()

PQXX_INLINE_ONLY const_result_iterator pqxx::result::end ( ) const
inlinenoexcept

◆ expect_columns()

result const& pqxx::result::expect_columns ( row_size_type  cols,
sl  loc = sl::current() 
) const
inline

Expect that result consists of exactly cols columns.

Returns
The result itself, for convenience.
Exceptions

◆ expect_rows()

result const& pqxx::result::expect_rows ( size_type  n,
sl  loc = sl::current() 
) const
inline

Check that result contains exactly n rows.

Returns
The result itself, for convenience.
Exceptions

◆ for_each()

template<typename CALLABLE >
void pqxx::result::for_each ( CALLABLE &&  func,
sl  loc = sl::current() 
) const
inline

Run func on each row, passing the row's fields as parameters.

Goes through the rows from first to last. You provide a callable func.

For each row in the result, for_each will call func. It converts the row's fields to the types of func's parameters, and pass them to func.

(Therefore func must have a single signature. It can't be a generic lambda, or an object of a class with multiple overloaded function call operators. Otherwise, for_each will have no way to detect a parameter list without ambiguity.)

If any of your parameter types is std::string_view, it refers to the underlying storage of this result.

If any of your parameter types is a reference type, its argument will refer to a temporary value which only lives for the duration of that single invocation to func. If the reference is an lvalue reference, it must be const.

For example, this queries employee names and salaries from the database and prints how much each would like to earn instead:

tx.exec("SELECT name, salary FROM employee").for_each(
[](std::string_view name, float salary){
std::cout << name << " would like " << salary * 2 << ".\n";
})

If func throws an exception, processing stops at that point and propagates the exception.

Exceptions
pqxx::usage_errorif func's number of parameters does not match the number of columns in this result.

The parameter types must have conversions from PostgreSQL's string format defined; see Supporting additional data types.

◆ front()

pqxx::row_ref pqxx::result::front ( ) const
noexcept

◆ get_encoding_group()

encoding_group pqxx::result::get_encoding_group ( ) const
inlinenoexcept

Retrieve encoding group for this result's client encoding.

◆ inserted_oid()

pqxx::oid pqxx::result::inserted_oid ( sl  loc = sl::current()) const

If command was an INSERT of 1 row, return oid of the inserted row.

Returns
Identifier of inserted row if exactly one row was inserted, or oid_none otherwise.

◆ iter()

template<typename... TYPE>
auto pqxx::result::iter
inline

Iterate rows, reading them directly into a tuple of "TYPE...".

Converts the fields to values of the given respective types.

Use this only with a ranged "for" loop. The iteration produces std::tuple<TYPE...> which you can "unpack" to a series of auto variables.

◆ no_rows()

result const& pqxx::result::no_rows ( sl  loc = sl::current()) const
inline

Expect that result contains no rows. Return result for convenience.

◆ one_field()

pqxx::field pqxx::result::one_field ( sl  loc = sl::current()) const

Expect that result consists of exactly 1 row and 1 column; return it.

A field is less efficient than a field_ref, but will ensure that the underlying result data stays valid for as long as the field object exists.

Exceptions

◆ one_field_ref()

pqxx::field_ref pqxx::result::one_field_ref ( sl  loc = sl::current()) const

Expect that result consists of exactly 1 row and 1 column; return it.

You must ensure that the result object stays valid, and does not move, whenever you access the row.

Exceptions

◆ one_row()

pqxx::row pqxx::result::one_row ( sl  loc = sl::current()) const

Check that result contains exactly 1 row, and return that row.

A row is less efficient than a row_ref, but will ensure that the underlying result data stays valid for as long as the row object exists.

Exceptions

◆ one_row_ref()

pqxx::row_ref pqxx::result::one_row_ref ( sl  loc = sl::current()) const

Check that result contains exactly 1 row, and return a reference to it.

You must ensure that the result object stays valid, and does not move, whenever you access the row.

Exceptions

◆ operator!=()

bool pqxx::result::operator!= ( result const &  rhs) const
inlinenoexcept

Compare two results for inequality.

◆ operator=() [1/2]

result& pqxx::result::operator= ( result &&  rhs)
defaultnoexcept

Assign one result to another, invaliding the old one.

◆ operator=() [2/2]

result& pqxx::result::operator= ( result const &  rhs)
defaultnoexcept

Assign one result to another.

Copying results is cheap: it copies only smart pointers, but the actual data stays in the same place.

◆ operator==()

bool pqxx::result::operator== ( result const &  rhs) const
inlinenoexcept

Compare two results for equality.

◆ operator[]()

pqxx::row_ref pqxx::result::operator[] ( size_type  i) const
noexcept

Index a result by number to get to a row.

This returns a row object. Generally you should not keep the row around as a variable, but if you do, make sure that your variable is a row, not a row&.

If you are working in C++23 or better, the two-dimensional indexing operator is likely to be more efficient. Otherwise, consider at().

◆ opt_row()

std::optional< pqxx::row > pqxx::result::opt_row ( sl  loc = sl::current()) const

Expect that result contains at most one row, and return as optional.

Returns an empty std::optional if the result is empty, or if it has exactly one row, a std::optional containing the row.

Exceptions

◆ opt_row_ref()

std::optional< pqxx::row_ref > pqxx::result::opt_row_ref ( sl  loc = sl::current()) const

Expect that result contains at most one row, and return as optional.

Returns an empty std::optional if the result is empty, or if it has exactly one row, a std::optional containing the row.

Exceptions

◆ query()

std::string const & pqxx::result::query ( ) const &
noexcept

Query that produced this result, if available (empty string otherwise)

◆ rbegin()

pqxx::result::const_reverse_iterator pqxx::result::rbegin ( ) const
noexcept

◆ rend()

pqxx::result::const_reverse_iterator pqxx::result::rend ( ) const
noexcept

◆ size()

pqxx::result::size_type pqxx::result::size ( ) const
noexcept

◆ swap()

void pqxx::result::swap ( result rhs)
noexcept

Exchange two result values in an exception-safe manner.

If the swap fails, the two values will be exactly as they were before.

The swap is not necessarily thread-safe.

◆ table_column() [1/2]

pqxx::row::size_type pqxx::result::table_column ( row_size_type  col_num,
sl  loc = sl::current() 
) const

What column in its table did this column come from?

◆ table_column() [2/2]

row_size_type pqxx::result::table_column ( zview  col_name,
sl  loc = sl::current() 
) const
inline

What column in its table did this column come from?

By default, as everywhere in PostgreSQL, upper-case letters in identifiers get converted to lower-case, and of course special characters such as quotes also cause problems.

Therefore, if the column name may contain any upper-case letters that you do not want lower-cased, or special characters, escape and quote it first: myresult.table_column(mytransaction.quote_name(col_name)).

Friends And Related Function Documentation

◆ pqxx::internal::gate::result_connection

◆ pqxx::internal::gate::result_creation

◆ pqxx::internal::gate::result_field_ref

◆ pqxx::internal::gate::result_pipeline

◆ pqxx::internal::gate::result_row

friend class pqxx::internal::gate::result_row
friend

◆ pqxx::internal::gate::result_sql_cursor


The documentation for this class was generated from the following files: