Merlin Moncure wrote:
On Wed, Mar 5, 2008 at 5:47 PM, Florian G. Pflug <[EMAIL PROTECTED]> wrote:
Merlin Moncure wrote:
> Yesterday, we notified -hackers of the latest version of the libpq
> type system. Just to be sure the right people are getting notified,
> we are posting the latest patch here as well. Would love to get some
> feedback on this.
Sorry if this has been discussed before, but why is it necessary
to specify the type when calling PQgetf on a result? It seems that this
formatting string *always* has to match the type list of your select
yes...it always has to match. the format string requirements could in
theory be relaxed (for 'get') but this would break symmetry with 'put'
and you would lose a sanity check...getf like scanf writes directly
into application memory so the double-specifying (directly in the
format string and indirectly in the query) isn't necessarily a bad
thing. imagine if your application was 'select * from table' and one
of the field types changed...disaster.
A few other reasons....
>>why is it necessary to specify the type when calling PQgetf on a result
Unlike PQgetvalue, all values returned by PQgetf are either native C types or
structures ... not C strings. When you call getf you must tell it what types to
read out of the result object. Like scanf, they must be the correctly sized
PQgetf(result, tup_num, "%date %int4", 0, &date, 1, &i4);
Specifying anything other than a %date or %int4 in the above example is a
programming error. You would be asking to fetch a value of the wrong type.
Without the formatting string, libpq would have to va_arg(ASSUME_T) your value.
// no specifier
PQgetf(result, tup, field, &i);
In the above, libpq would have to use PQftype to determine what the native C
type is of your variable argument. If PQftype returned INT8OID, you begin to
clobber your application's memory space ... va_arg(ap, long long) on a 32-bit
value. This problem is solved by telling libpq what data type you want from a
Also, the libpq type system enforces strict type checking when performing getf
calls. This protects from mis-matches "programming errors" on types:
-- create table t (a int8);
PQresult *result = PQexec(conn, "SELECT a FROM t");
char *val = PQgetvalue(result, ...);
int a = atoi(val); // assumed its an int4
In the above example, the libpq user thinks the 'a' column of the 't' table is
an int4 when in fact its an int8. The above may work most of the time but will
eventually truncate the value and nip you in the butt. With PQgetf, you would
get an error saying the server returned an int8 and you are asking for an int4.
Thus, the programming bug would be squashed immediately.
Also, user-defined types are not known to libpq so PQftype would not really
work. They could if the libpq type system referenced data types by OID, but
this is not portable to other servers. It is more portable to use the type
name. For example, a company with 15 postgresql servers that use the same
collection of company-specific user-defined data types. The type names would be
the same across the 15 servers but there is no guarentee the OIDs would be.
Composites and arrays caused a few issues as well.
We also tried to provide as much protection as possible ... in the spirit of the
every bit counts
Sent via pgsql-patches mailing list (email@example.com)
To make changes to your subscription: