by snakess on Sat Jan 15, 2005 10:37 pm
'pg_get_serial_sequence' is an internal function written in C, it's not a query;
To get the names of the columns that use a sequence for their default values
along with the names of the sequences you can use the following query:
SELECT a.attname AS column_name, c2.relname AS seq_name
FROM pg_class c1, pg_class c2, pg_namespace n, pg_depend d, pg_attribute a
WHERE n.nspname = 'schemaName' AND c1.relname = 'tableName'
AND c2.relkind = 'S'AND c1.relnamespace = n.oid
AND d.refobjid = c1.oid AND c2.oid = d.objid
AND a.attrelid = c1.oid AND d.refobjsubid = a.attnum
Once you have the name of the sequence you can get
the values for \"AutoKeySeed\" and \"AutoKeyIncrement\" with:
SELECT min_value, increment_by FROM \"sequence_name\";
I was unclear about the primary key issue.
The problem isn't that the primary keys aren't found but that all columns that are
indexed are displayed as belonging to the primary key. (pgAdmin does this too)
If you create the following table and view it in MyGeneration (or pgAdmin) you will see
that all three columns appears as they belong to the primary key.
CREATE TABLE test ( col1 int4, col2 int4, col3 int4, PRIMARY KEY (col1, col2));
CREATE INDEX my_index ON test (col3);
To get the names of the columns in the primary key for a table you can use:
SELECT a.attname
FROM pg_class c, pg_namespace n, pg_index i, pg_attribute a
WHERE n.nspname = 'schemaName' AND c.relname = 'tableName'
AND c.relnamespace = n.oid AND i.indrelid = c.oid AND i.indisprimary
AND a.attrelid = i.indexrelid;
or just append \"AND b.indisprimary\" to the query you posted.
I've tested the above queries with PostgreSQL 8.0, 7.4.5 and 7.4
The information_schema views looks like this:
columns:
----------------------------------------------------------------------------------------------------
CREATE OR REPLACE VIEW information_schema.columns AS
SELECT current_database()::information_schema.sql_identifier AS table_catalog, nc.nspname::information_schema.sql_identifier AS table_schema, c.relname::information_schema.sql_identifier AS table_name, a.attname::information_schema.sql_identifier AS column_name, a.attnum::information_schema.cardinal_number AS ordinal_position,
CASE
WHEN u.usename = \"current_user\"() THEN ad.adsrc
ELSE NULL::text
END::information_schema.character_data AS column_default,
CASE
WHEN a.attnotnull OR t.typtype = 'd'::\"char\" AND t.typnotnull THEN 'NO'::text
ELSE 'YES'::text
END::information_schema.character_data AS is_nullable,
CASE
WHEN t.typtype = 'd'::\"char\" THEN
CASE
WHEN bt.typelem <> 0::oid AND bt.typlen = -1 THEN 'ARRAY'::text
WHEN nbt.nspname = 'pg_catalog'::name THEN format_type(t.typbasetype, NULL::integer)
ELSE 'USER-DEFINED'::text
END
ELSE
CASE
WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'ARRAY'::text
WHEN nt.nspname = 'pg_catalog'::name THEN format_type(a.atttypid, NULL::integer)
ELSE 'USER-DEFINED'::text
END
END::information_schema.character_data AS data_type, information_schema._pg_char_max_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*))::information_schema.cardinal_number AS character_maximum_length, information_schema._pg_char_octet_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*))::information_schema.cardinal_number AS character_octet_length, information_schema._pg_numeric_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*))::information_schema.cardinal_number AS numeric_precision, information_schema._pg_numeric_precision_radix(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*))::information_schema.cardinal_number AS numeric_precision_radix, information_schema._pg_numeric_scale(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*))::information_schema.cardinal_number AS numeric_scale, information_schema._pg_datetime_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*))::information_schema.cardinal_number AS datetime_precision, NULL::information_schema.character_data::information_schema.character_data AS interval_type, NULL::information_schema.character_data::information_schema.character_data AS interval_precision, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS character_set_catalog, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS character_set_schema, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS character_set_name, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS collation_catalog, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS collation_schema, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS collation_name,
CASE
WHEN t.typtype = 'd'::\"char\" THEN current_database()
ELSE NULL::name
END::information_schema.sql_identifier AS domain_catalog,
CASE
WHEN t.typtype = 'd'::\"char\" THEN nt.nspname
ELSE NULL::name
END::information_schema.sql_identifier AS domain_schema,
CASE
WHEN t.typtype = 'd'::\"char\" THEN t.typname
ELSE NULL::name
END::information_schema.sql_identifier AS domain_name, current_database()::information_schema.sql_identifier AS udt_catalog, COALESCE(nbt.nspname, nt.nspname)::information_schema.sql_identifier AS udt_schema, COALESCE(bt.typname, t.typname)::information_schema.sql_identifier AS udt_name, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS scope_catalog, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS scope_schema, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS scope_name, NULL::information_schema.cardinal_number::information_schema.cardinal_number AS maximum_cardinality, a.attnum::information_schema.sql_identifier AS dtd_identifier, 'NO'::information_schema.character_data::information_schema.character_data AS is_self_referencing
FROM pg_attribute a
LEFT JOIN pg_attrdef ad ON a.attrelid = ad.adrelid AND a.attnum = ad.adnum, pg_class c, pg_namespace nc, pg_user u, pg_type t
JOIN pg_namespace nt ON t.typnamespace = nt.oid
LEFT JOIN (pg_type bt
JOIN pg_namespace nbt ON bt.typnamespace = nbt.oid) ON t.typtype = 'd'::\"char\" AND t.typbasetype = bt.oid
WHERE a.attrelid = c.oid AND a.atttypid = t.oid AND u.usesysid = c.relowner AND nc.oid = c.relnamespace AND a.attnum > 0 AND NOT a.attisdropped AND (c.relkind = 'r'::\"char\" OR c.relkind = 'v'::\"char\") AND (u.usename = \"current_user\"() OR has_table_privilege(c.oid, 'SELECT'::text) OR has_table_privilege(c.oid, 'INSERT'::text) OR has_table_privilege(c.oid, 'UPDATE'::text) OR has_table_privilege(c.oid, 'REFERENCES'::text));
parameters:
------------------------------------------------------------------------------------------------------
CREATE OR REPLACE VIEW information_schema.parameters AS
SELECT current_database()::information_schema.sql_identifier AS specific_catalog, n.nspname::information_schema.sql_identifier AS specific_schema, ((p.proname::text || '_'::text) || p.oid::text)::information_schema.sql_identifier AS specific_name, pos.n::information_schema.cardinal_number AS ordinal_position, 'IN'::information_schema.character_data::information_schema.character_data AS parameter_mode, 'NO'::information_schema.character_data::information_schema.character_data AS is_result, 'NO'::information_schema.character_data::information_schema.character_data AS as_locator, NULLIF(p.proargnames[pos.n], ''::text)::information_schema.sql_identifier AS parameter_name,
CASE
WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'ARRAY'::text
WHEN nt.nspname = 'pg_catalog'::name THEN format_type(t.oid, NULL::integer)
ELSE 'USER-DEFINED'::text
END::information_schema.character_data AS data_type, NULL::information_schema.cardinal_number::information_schema.cardinal_number AS character_maximum_length, NULL::information_schema.cardinal_number::information_schema.cardinal_number AS character_octet_length, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS character_set_catalog, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS character_set_schema, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS character_set_name, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS collation_catalog, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS collation_schema, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS collation_name, NULL::information_schema.cardinal_number::information_schema.cardinal_number AS numeric_precision, NULL::information_schema.cardinal_number::information_schema.cardinal_number AS numeric_precision_radix, NULL::information_schema.cardinal_number::information_schema.cardinal_number AS numeric_scale, NULL::information_schema.cardinal_number::information_schema.cardinal_number AS datetime_precision, NULL::information_schema.character_data::information_schema.character_data AS interval_type, NULL::information_schema.character_data::information_schema.character_data AS interval_precision, current_database()::information_schema.sql_identifier AS udt_catalog, nt.nspname::information_schema.sql_identifier AS udt_schema, t.typname::information_schema.sql_identifier AS udt_name, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS scope_catalog, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS scope_schema, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS scope_name, NULL::information_schema.cardinal_number::information_schema.cardinal_number AS maximum_cardinality, pos.n::information_schema.sql_identifier AS dtd_identifier
FROM pg_namespace n, pg_proc p, pg_type t, pg_namespace nt, pg_user u, information_schema._pg_keypositions() pos(n)
WHERE n.oid = p.pronamespace AND p.pronargs >= pos.n AND p.proargtypes[pos.n - 1] = t.oid AND t.typnamespace = nt.oid AND p.proowner = u.usesysid AND (u.usename = \"current_user\"() OR has_function_privilege(p.oid, 'EXECUTE'::text));
There is no view named procedures, it's called routines:
-------------------------------------------------------------------------------------------------
CREATE OR REPLACE VIEW information_schema.routines AS
SELECT current_database()::information_schema.sql_identifier AS specific_catalog, n.nspname::information_schema.sql_identifier AS specific_schema, ((p.proname::text || '_'::text) || p.oid::text)::information_schema.sql_identifier AS specific_name, current_database()::information_schema.sql_identifier AS routine_catalog, n.nspname::information_schema.sql_identifier AS routine_schema, p.proname::information_schema.sql_identifier AS routine_name, 'FUNCTION'::information_schema.character_data::information_schema.character_data AS routine_type, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS module_catalog, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS module_schema, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS module_name, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS udt_catalog, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS udt_schema, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS udt_name,
CASE
WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'ARRAY'::text
WHEN nt.nspname = 'pg_catalog'::name THEN format_type(t.oid, NULL::integer)
ELSE 'USER-DEFINED'::text
END::information_schema.character_data AS data_type, NULL::information_schema.cardinal_number::information_schema.cardinal_number AS character_maximum_length, NULL::information_schema.cardinal_number::information_schema.cardinal_number AS character_octet_length, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS character_set_catalog, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS character_set_schema, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS character_set_name, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS collation_catalog, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS collation_schema, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS collation_name, NULL::information_schema.cardinal_number::information_schema.cardinal_number AS numeric_precision, NULL::information_schema.cardinal_number::information_schema.cardinal_number AS numeric_precision_radix, NULL::information_schema.cardinal_number::information_schema.cardinal_number AS numeric_scale, NULL::information_schema.cardinal_number::information_schema.cardinal_number AS datetime_precision, NULL::information_schema.character_data::information_schema.character_data AS interval_type, NULL::information_schema.character_data::information_schema.character_data AS interval_precision, current_database()::information_schema.sql_identifier AS type_udt_catalog, nt.nspname::information_schema.sql_identifier AS type_udt_schema, t.typname::information_schema.sql_identifier AS type_udt_name, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS scope_catalog, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS scope_schema, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS scope_name, NULL::information_schema.cardinal_number::information_schema.cardinal_number AS maximum_cardinality, 0::information_schema.sql_identifier AS dtd_identifier,
CASE
WHEN l.lanname = 'sql'::name THEN 'SQL'::text
ELSE 'EXTERNAL'::text
END::information_schema.character_data AS routine_body,
CASE
WHEN u.usename = \"current_user\"() THEN p.prosrc
ELSE NULL::text
END::information_schema.character_data AS routine_definition,
CASE
WHEN l.lanname = 'c'::name THEN p.prosrc
ELSE NULL::text
END::information_schema.character_data AS external_name, upper(l.lanname::text)::information_schema.character_data AS external_language, 'GENERAL'::information_schema.character_data::information_schema.character_data AS parameter_style,
CASE
WHEN p.provolatile = 'i'::\"char\" THEN 'YES'::text
ELSE 'NO'::text
END::information_schema.character_data AS is_deterministic, 'MODIFIES'::information_schema.character_data::information_schema.character_data AS sql_data_access,
CASE
WHEN p.proisstrict THEN 'YES'::text
ELSE 'NO'::text
END::information_schema.character_data AS is_null_call, NULL::information_schema.character_data::information_schema.character_data AS sql_path, 'YES'::information_schema.character_data::information_schema.character_data AS schema_level_routine, 0::information_schema.cardinal_number AS max_dynamic_result_sets, NULL::information_schema.character_data::information_schema.character_data AS is_user_defined_cast, NULL::information_schema.character_data::information_schema.character_data AS is_implicitly_invocable,
CASE
WHEN p.prosecdef THEN 'DEFINER'::text
ELSE 'INVOKER'::text
END::information_schema.character_data AS security_type, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS to_sql_specific_catalog, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS to_sql_specific_schema, NULL::information_schema.sql_identifier::information_schema.sql_identifier AS to_sql_specific_name, 'NO'::information_schema.character_data::information_schema.character_data AS as_locator
FROM pg_namespace n, pg_proc p, pg_language l, pg_user u, pg_type t, pg_namespace nt
WHERE n.oid = p.pronamespace AND p.prolang = l.oid AND p.proowner = u.usesysid AND p.prorettype = t.oid AND t.typnamespace = nt.oid AND (u.usename = \"current_user\"() OR has_function_privilege(p.oid, 'EXECUTE'::text));
Not the simplest views I've seen...