pg: timestamp(tz) types + more docs

This commit is contained in:
Yorhel 2025-02-21 12:58:24 +01:00
parent 8036b8f0bf
commit 6f1583ddad
3 changed files with 121 additions and 5 deletions

View file

@ -176,11 +176,13 @@ Enable or disable caching of the prepared statement for this particular query.
=item $st->text_params($enable)
Enable or disable sending bind parameters in the text format.
Enable or disable sending bind parameters in the text format. See
L</"Formats and Types"> below for what this means.
=item $st->text_results($enable)
Enable or disable receiving query results in the text format.
Enable or disable receiving query results in the text format. See
L</"Formats and Types"> below for what this means.
=item $st->text($enable)
@ -463,7 +465,98 @@ the same time, that won't end well.
=head2 Formats and Types
I<TODO>
The PostgreSQL wire protocol supports sending bind parameters and receiving
query results in two different formats: text and binary. While the exact wire
protocol is an implementation detail that you don't have to worry about, this
module does have a different approach to processing the two formats.
When you enable C<text> mode, your bind parameters are sent verbatim, as text,
to the PostgreSQL server, where they are then parsed, validated and
interpreted. Likewise, when receiving query results in text mode, it is the
PostreSQL server that is formatting the data into textual strings. Text mode is
essentially a way to tell this module: "don't try to interpret my data, just
send and receive everything as text!"
Instead, in the (default) C<binary> mode, the responsibility of converting
Postgres data to and from Perl values lies with this module. This allows for a
lot of type-specific conveniences, but has the downside of requiring special
code for each supported PostgreSQL type. Most of the Postgres core types are
supported by this module and convert in an intuitive way, but here's a few
type-specific notes:
=over
=item bool
Boolean values are converted to C<builtin::true> and C<builtin::false>. As bind
parameters, Perl's idea of truthiness is used: C<0>, C<false> and C<""> are
false, everything else is true. Objects that overload I<bool> are also
supported. C<undef> always converts to SQL C<NULL>.
=item bytea
The C<bytea> type represents arbitrary binary data and this module will pass
that along as raw binary strings.
=item timestamp / timestamptz
These are converted to and from seconds since the Unix epoch as a floating
point value, similar to the C<time()> (or better: C<Time::HiRes::time()>)
functions.
The timestamp types in Postgres have microsecond accuracy. Floating point can
represent that without loss for dates that are near enough to the epoch (still
seems to be fine in 2025, at least), but this conversion may be lossy for dates
far beyond or before the epoch.
=item json / jsonb
These types are converted through C<json_parse()> and C<json_format()> from
L<FU::Util>.
While C<null> is a valid JSON value, there's currently no way to distinguish
that from SQL C<NULL>. When sending C<undef> as bind parameter, it is sent as
SQL C<NULL>.
=item arrays
PostgreSQL arrays automatically convert to and from Perl arrays as you'd
expect. Arrays in PostgreSQL have the rather unusual feature that the starting
index can be changed for each individual array, but this module doesn't support
that. All arrays received from Postgres will use Perl's usual 0-based indexing
and all arrays sent to Postgres will use their default 1-based indexing.
=item records / row types
These are converted to and from hashrefs.
=item geometric types
=item numeric
=item macaddr
=item money
=item date / time / timetz
=item bit / varbit
=item tsvector / tsquery
=item Extension types
These are not supported at the moment. Not that they're hard to implement (I
think), I simply haven't looked into them yet. Open a bug report if you need
any of these.
=back
I<TODO:> Methods to convert between the various formats.
I<TODO:> Methods to query type info.
I<TODO:> Custom per-type configuration.
=head2 Errors