Extracting metadata about attributes from catalog

Started by Bernardo Ponsover 24 years ago7 messages
#1Bernardo Pons
bernardo@atlas-iap.es

I make queries on catalog tables in order get metadata about table
attributes. I need this metadata in order to help me controlling the data
that users enter using html forms dynamically generated with PHP.

The problem I've found is that the attribute that stores the info about data
length (attribute atttypmod of catalog table pg_attribute) is some kind of
internal coding. For example, for an attribute varchar(100) atttypmod value
is 104; for an attribute numeric(6,0) atttypmod value is 393220.

I guess I would need some kind of function in order to get the actual lenght
for the attributes. Does this function exist? Where can I find it?

Any help will be appreciated.

--
Bernardo Pons

P.S.

For example, typical output of \d <tablename> in psql is:

Attribute | Type | Modifier
-----------------+--------------+----------
CustomerId | numeric(6,0) | not null
Name | varchar(100) |
Series | numeric(2,0) | not null
Number | numeric(6,0) | not null
ObjectId | numeric(6,0) |
ObjectType | numeric(3,0) |
Quantity | numeric(8,2) | not null
Price | numeric(8,2) | not null

Using a query like

SELECT a.attname, t.typname, a.atttypmod, a.attnum FROM pg_class c,
pg_attribute a, pg_type t WHERE c.relname = <tablename> AND a.attnum > 0 AND
a.attrelid = c.oid AND a.atttypid = t.oid ORDER BY a.attnum;

on system catalog tables I get:

attname | typname | atttypmod | attnum
-----------------+---------+-----------+--------
CustomerId | numeric | 393220 | 1
Name | varchar | 104 | 2
Series | numeric | 131076 | 1
Number | numeric | 393220 | 2
ObjectId | numeric | 393220 | 3
ObjectType | numeric | 196612 | 4
Quantity | numeric | 524294 | 7
Price | numeric | 524294 | 8

#2Alex Pilosov
alex@pilosoft.com
In reply to: Bernardo Pons (#1)
Re: Extracting metadata about attributes from catalog

Do 'psql -E ...', it will display actual queries used by psql.

Your particular query is:
SELECT a.attname, t.typname, a.attlen, a.atttypmod, a.attnotnull,
a.atthasdef, a.attnum
FROM pg_class c, pg_attribute a, pg_type t
WHERE c.relname = '...tablename...'
AND a.attnum > 0 AND a.attrelid = c.oid AND a.atttypid = t.oid
ORDER BY a.attnum

And pg_type has all information you need.

On Fri, 22 Jun 2001, Bernardo Pons wrote:

Show quoted text

I make queries on catalog tables in order get metadata about table
attributes. I need this metadata in order to help me controlling the data
that users enter using html forms dynamically generated with PHP.

The problem I've found is that the attribute that stores the info about data
length (attribute atttypmod of catalog table pg_attribute) is some kind of
internal coding. For example, for an attribute varchar(100) atttypmod value
is 104; for an attribute numeric(6,0) atttypmod value is 393220.

I guess I would need some kind of function in order to get the actual lenght
for the attributes. Does this function exist? Where can I find it?

Any help will be appreciated.

--
Bernardo Pons

P.S.

For example, typical output of \d <tablename> in psql is:

Attribute | Type | Modifier
-----------------+--------------+----------
CustomerId | numeric(6,0) | not null
Name | varchar(100) |
Series | numeric(2,0) | not null
Number | numeric(6,0) | not null
ObjectId | numeric(6,0) |
ObjectType | numeric(3,0) |
Quantity | numeric(8,2) | not null
Price | numeric(8,2) | not null

Using a query like

SELECT a.attname, t.typname, a.atttypmod, a.attnum FROM pg_class c,
pg_attribute a, pg_type t WHERE c.relname = <tablename> AND a.attnum > 0 AND
a.attrelid = c.oid AND a.atttypid = t.oid ORDER BY a.attnum;

on system catalog tables I get:

attname | typname | atttypmod | attnum
-----------------+---------+-----------+--------
CustomerId | numeric | 393220 | 1
Name | varchar | 104 | 2
Series | numeric | 131076 | 1
Number | numeric | 393220 | 2
ObjectId | numeric | 393220 | 3
ObjectType | numeric | 196612 | 4
Quantity | numeric | 524294 | 7
Price | numeric | 524294 | 8

---------------------------(end of broadcast)---------------------------
TIP 5: Have you checked our extensive FAQ?

http://www.postgresql.org/users-lounge/docs/faq.html

#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bernardo Pons (#1)
Re: Extracting metadata about attributes from catalog

"Bernardo Pons" <bernardo@atlas-iap.es> writes:

The problem I've found is that the attribute that stores the info about data
length (attribute atttypmod of catalog table pg_attribute) is some kind of
internal coding. For example, for an attribute varchar(100) atttypmod value
is 104; for an attribute numeric(6,0) atttypmod value is 393220.

Yup.

I guess I would need some kind of function in order to get the actual lenght
for the attributes. Does this function exist? Where can I find it?

In 7.1, "format_type(typeoid, typmod)" is what produces the type
displays seen in psql. This may or may not be exactly what you want,
but that's how the knowledge of typmod encoding is exported at the
moment.

regards, tom lane

#4Bernardo Pons
bernardo@atlas-iap.es
In reply to: Alex Pilosov (#2)
RE: Extracting metadata about attributes from catalog

Do 'psql -E ...', it will display actual queries used by psql.

I already do it. At the end of my first message there was an example with
exactly the query you suggested.

Your particular query is:
SELECT a.attname, t.typname, a.attlen, a.atttypmod, a.attnotnull,
a.atthasdef, a.attnum
FROM pg_class c, pg_attribute a, pg_type t
WHERE c.relname = '...tablename...'
AND a.attnum > 0 AND a.attrelid = c.oid AND a.atttypid = t.oid
ORDER BY a.attnum

And pg_type has all information you need.

But, I'm afraid pg_type has not the information I need.

Just in case I missed something you have seen I wrote down a query showing
all attributes of the pg_type

SELECT a.attname, t.typname, t.typowner, t.typlen, t.typprtlen, t.typbyval,
t.typtype, t.typisdefined, t.typdelim, t.typrelid, t.typelem, t.typinput,
t.typoutput, t.typreceive, t.typsend, t.typalign, t.typdefault, a.atttypmod,
a.attnum FROM pg_class c, pg_attribute a, pg_type t WHERE c.relname =
..TABLENAME.. AND a.attnum > 0 AND a.attrelid = c.oid AND a.atttypid = t.oid
ORDER BY a.attnum;

but there's neither a field showing me, for example, a value 100 for a
varchar(100) field nor two fields showing value 6 and 2 for a numeric(6,2)
field.

Maybe I'm missing something from your answer?

Regards,

--
Bernardo Pons

#5Bernardo Pons
bernardo@atlas-iap.es
In reply to: Tom Lane (#3)
RE: Extracting metadata about attributes from catalog

I guess I would need some kind of function in order to get the

actual lenght

for the attributes. Does this function exist? Where can I find it?

In 7.1, "format_type(typeoid, typmod)" is what produces the type
displays seen in psql. This may or may not be exactly what you want,
but that's how the knowledge of typmod encoding is exported at the
moment.

There's 957 functions in psql (output of \df).

Would I be so lucky that none of these functions is the one that you
suggested? :-(

Is "format_type(typeoid, typmod)" an internal C language function of the
Postgres backend? (please... please... say no :-)

If so (I'm afraid it will be) the only way to extract the actual length of a
varchar field or length of integer/fractional part of a numeric field would
be implementing the same functions the backend uses in my PHP modules. Any
other suggestion?

Regards,

--
Bernardo Pons

#6Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bernardo Pons (#5)
Re: Extracting metadata about attributes from catalog

"Bernardo Pons" <bernardo@atlas-iap.es> writes:

In 7.1, "format_type(typeoid, typmod)" is what produces the type
displays seen in psql. This may or may not be exactly what you want,
but that's how the knowledge of typmod encoding is exported at the
moment.

There's 957 functions in psql (output of \df).

Would I be so lucky that none of these functions is the one that you
suggested? :-(

regression=# \df format_type
List of functions
Result | Function | Arguments
--------+-------------+--------------
text | format_type | oid, integer
(1 row)

I did say 7.1, however. What version are you using?

regards, tom lane

#7Alex Pilosov
alex@pilosoft.com
In reply to: Bernardo Pons (#4)
RE: Extracting metadata about attributes from catalog

On Sun, 24 Jun 2001, Bernardo Pons wrote:

Do 'psql -E ...', it will display actual queries used by psql.

I already do it. At the end of my first message there was an example with
exactly the query you suggested.

Your particular query is:
SELECT a.attname, t.typname, a.attlen, a.atttypmod, a.attnotnull,
a.atthasdef, a.attnum
FROM pg_class c, pg_attribute a, pg_type t
WHERE c.relname = '...tablename...'
AND a.attnum > 0 AND a.attrelid = c.oid AND a.atttypid = t.oid
ORDER BY a.attnum

Sorry about that. For parameterized types (like numeric, varchar),
atttypmod contains specific information. For varchar-like parameters, its
length of the field+4 (54 means varchar(50), for example). For numeric
paremeter (numeric(a,b)), its 327680*b+a

I'm not sure if there's a better (and more documented) way to decode those
numbers, though.....