Protoco...tgreSQL(3)
π¦ Protocol::Database::PostgreSQL(3) π¦
Okay bestie, so this is a User Contributed Perl Documentation page for Protocol::Database::PostgreSQL β yes that's the module name, yes it's a mouthful, we move. π
β¨ NAME β¨
Protocol::Database::PostgreSQL β literally just support for the PostgreSQL wire protocol. That's it. That's the whole vibe. π
πΈ SYNOPSIS πΈ
use strict;
use warnings;
use mro;
package Example::PostgreSQL::Client;
sub new { bless { @_[1..$#_] }, $_[0] }
sub protocol {
my ($self) = @_;
$self->{protocol} //= Protocol::Database::PostgresQL->new(
outgoing => $self->outgoing,
)
}
# Any received packets will arrive here
sub incoming { shift->{incoming} //= Ryu::Source->new }
# Anything we want to send goes here
sub outgoing { shift->{outgoing} //= Ryu::Source->new }
...
# We raise events on our incoming source in this example -
# if you prefer to handle each message as it's extracted you
# could add that directly in the loop
$self->incoming
->switch_str(
sub { $_->type },
authentication_request => sub { ... },
sub { warn 'unknown message - ' . $_->type }
);
# When there's something to write, we'll get an event here
$self->outgoing
->each(sub { $sock->write($_) });
while(1) {
$sock->read(my $buf, 1_000_000);
while(my $msg = $self->protocol->extract_message(\$buf)) {
$self->incoming->emit($msg);
}
}
(And yes, copy that verbatim, including the PostgresQL capitalization situation β that's how it's written, don't come for me. π)
π DESCRIPTION π
This thing gives you protocol-level support for PostgreSQL 7.4+, exactly as defined over at <http://www.postgresql.org/docs/current/static/protocol.html>. No cap, that's the spec it's following.
π«Ά How do I use this?
The short answer: don't.
Use Database::Async::Engine::PostgreSQL instead β like, genuinely β unless you're out here writing a driver for talking to PostgreSQL (or compatible) systems. That's the only main character usage.
This distribution provides the abstract protocol handling, meaning it understands the packets that make up the PostgreSQL communication protocol, but it does not attempt to send or receive those packets itself. It's giving brain-no-hands. π§ β You need to provide the transport layer yourself (typically this would involve TCP or Unix sockets).
π Connection states
Here are the possible states, bestie, in order of the journey:
- Unconnected β we have a valid instantiated PostgreSQL object, but no connection yet.
- Connected β transport layer has made a connection for us.
- AuthRequested β the server has challenged us to identify. Prove it. π
- Authenticated β we have successfully identified with the server.
- Idle β session is active and ready for commands.
- Parsing β a statement has been passed to the server for parsing.
- Describing β the indicated statement is being described, called after the transport layer has sent the Describe request.
- Binding β parameters for a given query have been transmitted.
- Executing β we have sent a request to execute.
- ShuttingDown β terminate request sent. Bye bestie π
- CopyIn β the server is expecting data for a
COPYcommand.
π¦ Message types
The "type" in Protocol::Database::Backend for incoming messages can currently include the following:
"send_request"β Called each time there is a new message to be sent to the other side of the connection."authenticated"β Called when authentication is complete."copy_data"β we have received data from an ongoingCOPYrequest."copy_complete"β the activeCOPYrequest has completed.
For the client, the following additional callbacks are available (this list is long, I know, but every single one matters π):
"request_ready"β the server is ready for the next request."bind_complete"β a Bind request has completed."close_complete"β the Close request has completed."command_complete"β the requested command has finished, this will typically be followed by an on_request_ready event."copy_in_response"β indicates that the server is ready to receiveCOPYdata."copy_out_response"β indicates that the server is ready to sendCOPYdata."copy_both_response"β indicates that the server is ready to exchangeCOPYdata (for replication)."data_row"β data from the current query."empty_query"β special-case response when sent an empty query, can be used for 'ping'. Typically followed by on_request_ready."error"β server has raised an error. π"function_call_result"β results from a function call."no_data"β indicate that a query returned no data, typically followed by on_request_ready."notice"β server has sent us a notice."notification"β server has sent us aNOTIFY."parameter_description"β parameters are being described."parameter_status"β parameter status..."parse_complete"β parsing is done."portal_suspended"β the portal has been suspended, probably hit the row limit."ready_for_query"β we're ready for queries. π₯"row_description"β descriptive information about the rows we're likely to be seeing shortly.
And there are also these potential events back from the server:
"copy_fail"β the frontend is indicating that the copy has failed."describe"β request for something to be described."execute"β request execution of a given portal."flush"β request flush."function_call"β request execution of a given function."parse"β request to parse something."password"β password information."query"β simple query request."ssl_request"β we have an SSL request."startup_message"β we have an SSL request."sync"β sync request."terminate"β termination request.
π METHODS π
π new
Instantiate a new object. Blesses an empty hashref and calls "configure" β subclasses can bypass this entirely and just call "configure" directly after instantiation. Iconic flexibility, honestly.
π configure
Does the real preparation for the object. The actual work. The main character of setup. β¨
π frontend_bind
Bind parameters to an existing prepared statement.
π frontend_copy_data
(No description in the original β it's just vibing there. π«Ά)
π frontend_close
(Also just vibing. π«Ά)
π frontend_copy_done
(Still vibing. π«Ά)
π frontend_describe
Describe expected SQL results.
π frontend_execute
Execute either a named or anonymous portal (prepared statement with bind vars).
π frontend_parse
Parse SQL for a prepared statement.
π frontend_password_message
Password data, possibly encrypted depending on what the server specified. π
π frontend_sasl_initial
Initial client response for SASL authentication.
π frontend_query
Simple query.
π frontend_startup_message
Initial mesage informing the server which database and user we want. (Yes, "mesage" β keeping the original spelling because I respect the source. π )
π frontend_sync
Synchonise after a prepared statement has finished execution. (Yes, "Synchonise" β again, respecting the source. π)
π frontend_terminate
(No description given. It terminates, bestie. That's the whole thing. π)
π is_authenticated
Returns true if we are authenticated (and can start sending real data).
π is_first_message
Returns true if this is the first message, as per <http://developer.postgresql.org/pgdocs/postgres/protocol-overview.html>:
"For historical reasons, the very first message sent by the client (the startup message)
has no initial message-type byte."
π send_message
Send a message.
π method_for_frontend_type
Returns the method name for the given frontend type.
π is_known_frontend_message_type
Returns true if the given frontend type is one that we know how to handle.
π message
Creates a new message of the given type.
π handle_message
Handle an incoming message from the server.
π message_length
Returns the length of the given message.
π simple_query
Send a simple query to the server β only supports plain queries (no bind parameters). Keep it simple, periodt.
π copy_data
Send copy data to the server.
π copy_done
Indicate that the COPY data from the client is complete.
π backend_state
Accessor for current backend state.
π is_ready
Returns true if we're ready to send more data to the server.
π send_copy_data
Send COPY data to the server. Takes an arrayref and replaces any reserved characters with quoted versions. Responsible king. π
π build_message
Construct a new message.
π₯ SEE ALSO π₯
Some PostgreSQL-related modules β plenty of things build on these, so have a look at the relevant reverse deps if you're after something higher level:
DBD::Pgβ uses the official library and (unlike this module) provides full support for DBI.Pg::PQβ another libpq wrapper.Postgresβ quite an old (1998) libpq binding.Pgβ slightly less old (2000) libpq binding.DBD::PgPPβ provides another pure-Perl implemmentation, with the focus on DBI compatibility. (Yep, three m's in "implemmentation", leaving it exactly as found π«‘)
Other related database protocols (the crossover episode nobody asked for but we all needed π):
Protocol::MySQLβ Oracle's popular database product.Protocol::TDSβ the tabular data stream protocol, mainly of interest for SQL Server users.
π AUTHOR π
Tom Molesworth <TEAM@cpan.org>
πΈ LICENSE πΈ
Copyright Tom Molesworth 2010-2019. Licensed under the same terms as Perl itself.
π And that's the whole page, bestie β courtesy ofperl v5.42.2, dated2026-02-15. Go forth and speak wire protocol responsibly. Slay. π β¨π¦
π¦ where this page comes from
- alpine 3.24: perl-protocol-database-postgresql-doc 2.001-r1 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms