Hackers,

Attached is a patch to add a new function, `parse_type()`. It parses a type 
string and returns a record with the typid and typmod for the type, or raises 
an error if the type is invalid. It’s effectively a thin layer over the 
parser’s parseTypeString() function.

The purpose of this function is to allow uses to resolve any type name, 
including aliases, to its formal name as rendered by, for example, pg_dump. An 
example:

david=# WITH s(s) AS (
    SELECT * FROM unnest(ARRAY[
        'timestamp(4)',
        'interval(0)',
        'interval second(0)',
        'timestamptz',
        'timestamptz(6)',
        'varchar',
        'varchar(128)' 
    ])         
),
p(type, typid, typmod) AS (
    SELECT s, ((parse_type(s)).*)
      FROM s                     
)           
SELECT type, format_type(typid, typmod) FROM p;
        type        |          format_type           
--------------------+--------------------------------
 timestamp(4)       | timestamp(4) without time zone
 interval(0)        | interval(0)
 interval second(0) | interval second(0)
 timestamptz        | timestamp with time zone
 timestamptz(6)     | timestamp(6) with time zone
 varchar            | character varying
 varchar(128)       | character varying(128)
(7 rows)


The use case leading to this patch was pgTAP column data type assertions. pgTAP 
traditionally required full type names for testing data types, but recently 
added support for aliases. This broke for some types, because it was difficult 
to extract the typmod correctly, and even when we did, it failed for types such 
as `interval second(0)`, where `second (0)` is the typmod, and there was no 
sensible way to access the bit mask to generate the proper typmod to pass to 
`format_type()`.

Erik Wienhold wrote this function to solve the problem, and I volunteered to 
submit a patch.

Potential issues and questions for this patch:

* Is `parse_type()` the right name to use? I can see arguments for 
`parse_type_string()`, `pg_parse_type()`, and `pg_parse_type_string()`. 
Whatever the consensus is works for me.

* The function returns a record, which is a little fussy. I could see adding a 
`format_type_string()` function that just contains `SELECT 
format_type(p.typmod, p.typid) FROM parse_type($1) p` and returns the formatted 
type. But I think it might also be useful to have access to the typmod and 
typid directly via this method, since they’re already exposed as 
`format_type()`’s arguments.

* Is format_type.c the right home for the function? I put it there because I 
closely associate it with format_type(), but happy to move it to a more 
appropriate location.

* I tried to link to `format_type` from the docs entry for `parse_type`, and 
added an ID for the former, but I’m not sure it resolves.

Best,

David

Attachment: v1-0001-Add-parse_type-SQL-function.patch
Description: Binary data

Reply via email to