From: Oliver M. B. <ol...@go...> - 2003-02-06 17:41:20
|
On Thu, Feb 06, 2003 at 05:21:00PM +0100, "Oliver M. Bolzer" <ol...@go...> wrote... > A really quick glance into DBD::Pg shows that the type conversion is > done according to type_map and the type of a column according to pg_result.type > > For example BIGINT[] gives type 1016, VARCHAR(255)[] gives 1015 as type > on my system, but they are not contained in type_map, so they are converted > to String.... I've done some more digging into PostgreSQL itself. After looking, how DBD::Pg assembles it's type_map and repeating the queries myself, i tought that the pg_type table does not contain information about Array types, but consulting the PostgreSQL documentation, it seems like DBD::Pg's assembly of type_map is wrong. Currently, type_map is assembled using typname and typelem from pg_type. The typeid from PGResult.type(index) comes from pg_attribute.atttypid, which is an reference to pg_type.oid, not pg_type.typelem. pg_type.typdelem is the type of elements of an array. But because an INT[] array always wraps INTs, the current code functions correctly. Applying the following patch, the code still works the same way. Even the mysterious 1114 timestamp type could be folded into the case block. IMHO, this is more correct and could be the base for Array support. What do you think? --- Pg.rb.orig 2003-02-06 18:32:10.000000000 +0100 +++ Pg.rb 2003-02-06 18:32:37.000000000 +0100 @@ -299,18 +299,18 @@ @type_map = Hash.new @coerce = PgCoerce.new - res = @connection.exec("SELECT typname, typelem FROM pg_type") + res = @connection.exec("SELECT typname, oid FROM pg_type") res.result.each { |name, idstr| @type_map[idstr.to_i] = case name - when '_bool' then :as_bool - when '_int8', '_int4', '_int2' then :as_int - when '_varchar' then :as_str - when '_float4','_float8' then :as_float - when '_timestamp', '_timestamptz' then :as_timestamp - when '_date' then :as_date - when '_bytea' then :as_bytea + when 'bool' then :as_bool + when 'int8', 'int4', 'int2' then :as_int + when 'varchar' then :as_str + when 'float4','float8' then :as_float + when 'timestamp', 'timestamptz' then :as_timestamp + when 'date' then :as_date + when 'bytea' then :as_bytea else :as_str end } -- Oliver M. Bolzer ol...@go... GPG (PGP) Fingerprint = 621B 52F6 2AC1 36DB 8761 018F 8786 87AD EF50 D1FF |