Reputation: 734
How to get base type / dimension of an array column in Postgres by Java?
I have a tables that contain arrays like int[][]
and text[]
.
When I traverse the metadata from JDBC I can only get type as java.sql.Array
.
Even in information_schema.columns
it stored simply as ARRAY.
How can I know the base type and its dimension?
I'm now working on tool to dump table info.
Upvotes: 3
Views: 3149
Reputation: 656331
In addition to what @Joe already cleared up, you can use pg_typof()
to get type information from PostgreSQL.
Given a 2-dimensional array of integer in this example:
SELECT pg_typeof(a)::text AS type
,(SELECT typname FROM pg_type WHERE oid = pg_typeof(a)) AS base_type
,array_dims(a) AS dims
FROM (SELECT '{{11,12,13},{21,22,23}}'::int[]) x(a);
type | base_type | dims
-----------+-----------+------------
integer[] | _int4 | [1:2][1:3]
Note that the array dimensions (dims
) can be different for each value. Postgres does not enforce dimensions at present (up to and incl. v9.3).
As documented in the manual, pg_attribute.attndims
is of limited use here:
Number of dimensions, if the column is an array type; otherwise 0. (Presently, the number of dimensions of an array is not enforced, so any nonzero value effectively means "it's an array".)
Upvotes: 2
Reputation: 4252
For the array base type, DatabaseMetaData.getColumns()
returns a ResultSet
containing column metadata. One of the columns returned is TYPE_NAME
. This appears to contain the name of the array base type, prefixed with an underscore. For example, _int4
or _text
. There is some additional information about the type in pg_type that may be helpful.
For the dimensions, it appears unlikely that they will be in the metadata. From the documentation:
However, the current implementation ignores any supplied array size limits, i.e., the behavior is the same as for arrays of unspecified length.
The current implementation does not enforce the declared number of dimensions either. Arrays of a particular element type are all considered to be of the same type, regardless of size or number of dimensions. So, declaring the array size or number of dimensions in CREATE TABLE is simply documentation; it does not affect run-time behavior.
The array_dims
function will return the current dimensions of an array value. But since this could be different for every row in the table, I doubt this will help you.
UPDATE: It appears the dimensions are available in the metadata. See @a_horse_with_no_name's answer.
Upvotes: 4
Reputation:
You can query pg_attributes
directly:
select att.attname,
att.attndims,
pg_catalog.format_type(atttypid, NULL) as display_type
from pg_attribute att
join pg_class tbl on tbl.oid = att.attrelid
join pg_namespace ns on tbl.relnamespace = ns.oid
where tbl.relname = 'your_table_name'
and ns.nspname = 'table_schema'
SQLFiddle example: http://sqlfiddle.com/#!12/50301/1
Note that format_type()
will actually return integer[]
even though the column was defined as int[][]
but the attndims
column will carry the information you want.
Upvotes: 3