2 * SQL Information Schema
3 * as defined in ISO/IEC 9075-11:2008
5 * Copyright (c) 2003-2011, PostgreSQL Global Development Group
7 * src/backend/catalog/information_schema.sql
11 * Note: Generally, the definitions in this file should be ordered
12 * according to the clause numbers in the SQL standard, which is also the
13 * alphabetical order. In some cases it is convenient or necessary to
14 * define one information schema view by using another one; in that case,
15 * put the referencing view at the very end and leave a note where it
16 * should have been put.
22 * INFORMATION_SCHEMA schema
25 CREATE SCHEMA information_schema;
26 GRANT USAGE ON SCHEMA information_schema TO PUBLIC;
27 SET search_path TO information_schema;
31 * A few supporting functions first ...
34 /* Expand any 1-D array into a set with integers 1..N */
35 CREATE FUNCTION _pg_expandarray(IN anyarray, OUT x anyelement, OUT n int)
37 LANGUAGE sql STRICT IMMUTABLE
38 AS 'select $1[s], s - pg_catalog.array_lower($1,1) + 1
39 from pg_catalog.generate_series(pg_catalog.array_lower($1,1),
40 pg_catalog.array_upper($1,1),
43 CREATE FUNCTION _pg_keysequal(smallint[], smallint[]) RETURNS boolean
44 LANGUAGE sql IMMUTABLE -- intentionally not STRICT, to allow inlining
45 AS 'select $1 operator(pg_catalog.<@) $2 and $2 operator(pg_catalog.<@) $1';
47 /* Given an index's OID and an underlying-table column number, return the
48 * column's position in the index (NULL if not there) */
49 CREATE FUNCTION _pg_index_position(oid, smallint) RETURNS int
50 LANGUAGE sql STRICT STABLE
53 (SELECT information_schema._pg_expandarray(indkey) AS a
54 FROM pg_catalog.pg_index WHERE indexrelid = $1) ss
58 CREATE FUNCTION _pg_truetypid(pg_attribute, pg_type) RETURNS oid
61 RETURNS NULL ON NULL INPUT
63 $$SELECT CASE WHEN $2.typtype = 'd' THEN $2.typbasetype ELSE $1.atttypid END$$;
65 CREATE FUNCTION _pg_truetypmod(pg_attribute, pg_type) RETURNS int4
68 RETURNS NULL ON NULL INPUT
70 $$SELECT CASE WHEN $2.typtype = 'd' THEN $2.typtypmod ELSE $1.atttypmod END$$;
72 -- these functions encapsulate knowledge about the encoding of typmod:
74 CREATE FUNCTION _pg_char_max_length(typid oid, typmod int4) RETURNS integer
77 RETURNS NULL ON NULL INPUT
80 CASE WHEN $2 = -1 /* default typmod */
82 WHEN $1 IN (1042, 1043) /* char, varchar */
84 WHEN $1 IN (1560, 1562) /* bit, varbit */
89 CREATE FUNCTION _pg_char_octet_length(typid oid, typmod int4) RETURNS integer
92 RETURNS NULL ON NULL INPUT
95 CASE WHEN $1 IN (25, 1042, 1043) /* text, char, varchar */
96 THEN CASE WHEN $2 = -1 /* default typmod */
97 THEN CAST(2^30 AS integer)
98 ELSE information_schema._pg_char_max_length($1, $2) *
99 pg_catalog.pg_encoding_max_length((SELECT encoding FROM pg_catalog.pg_database WHERE datname = pg_catalog.current_database()))
104 CREATE FUNCTION _pg_numeric_precision(typid oid, typmod int4) RETURNS integer
107 RETURNS NULL ON NULL INPUT
111 WHEN 21 /*int2*/ THEN 16
112 WHEN 23 /*int4*/ THEN 32
113 WHEN 20 /*int8*/ THEN 64
114 WHEN 1700 /*numeric*/ THEN
117 ELSE (($2 - 4) >> 16) & 65535
119 WHEN 700 /*float4*/ THEN 24 /*FLT_MANT_DIG*/
120 WHEN 701 /*float8*/ THEN 53 /*DBL_MANT_DIG*/
124 CREATE FUNCTION _pg_numeric_precision_radix(typid oid, typmod int4) RETURNS integer
127 RETURNS NULL ON NULL INPUT
130 CASE WHEN $1 IN (21, 23, 20, 700, 701) THEN 2
131 WHEN $1 IN (1700) THEN 10
135 CREATE FUNCTION _pg_numeric_scale(typid oid, typmod int4) RETURNS integer
138 RETURNS NULL ON NULL INPUT
141 CASE WHEN $1 IN (21, 23, 20) THEN 0
142 WHEN $1 IN (1700) THEN
145 ELSE ($2 - 4) & 65535
150 CREATE FUNCTION _pg_datetime_precision(typid oid, typmod int4) RETURNS integer
153 RETURNS NULL ON NULL INPUT
156 CASE WHEN $1 IN (1082) /* date */
158 WHEN $1 IN (1083, 1114, 1184, 1266) /* time, timestamp, same + tz */
159 THEN CASE WHEN $2 < 0 THEN 6 ELSE $2 END
160 WHEN $1 IN (1186) /* interval */
161 THEN CASE WHEN $2 < 0 OR $2 & 65535 = 65535 THEN 6 ELSE $2 & 65535 END
165 CREATE FUNCTION _pg_interval_type(typid oid, mod int4) RETURNS text
168 RETURNS NULL ON NULL INPUT
171 CASE WHEN $1 IN (1186) /* interval */
172 THEN upper(substring(format_type($1, $2) from 'interval[()0-9]* #"%#"' for '#'))
177 -- 5.2 INFORMATION_SCHEMA_CATALOG_NAME view appears later.
182 * CARDINAL_NUMBER domain
185 CREATE DOMAIN cardinal_number AS integer
186 CONSTRAINT cardinal_number_domain_check CHECK (value >= 0);
191 * CHARACTER_DATA domain
194 CREATE DOMAIN character_data AS character varying;
199 * SQL_IDENTIFIER domain
202 CREATE DOMAIN sql_identifier AS character varying;
207 * INFORMATION_SCHEMA_CATALOG_NAME view
210 CREATE VIEW information_schema_catalog_name AS
211 SELECT CAST(current_database() AS sql_identifier) AS catalog_name;
213 GRANT SELECT ON information_schema_catalog_name TO PUBLIC;
221 CREATE DOMAIN time_stamp AS timestamp(2) with time zone
222 DEFAULT current_timestamp(2);
229 CREATE DOMAIN yes_or_no AS character varying(3)
230 CONSTRAINT yes_or_no_check CHECK (value IN ('YES', 'NO'));
233 -- 5.8 ADMINISTRABLE_ROLE_AUTHORIZATIONS view appears later.
238 * APPLICABLE_ROLES view
241 CREATE VIEW applicable_roles AS
242 SELECT CAST(a.rolname AS sql_identifier) AS grantee,
243 CAST(b.rolname AS sql_identifier) AS role_name,
244 CAST(CASE WHEN m.admin_option THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable
245 FROM pg_auth_members m
246 JOIN pg_authid a ON (m.member = a.oid)
247 JOIN pg_authid b ON (m.roleid = b.oid)
248 WHERE pg_has_role(a.oid, 'USAGE');
250 GRANT SELECT ON applicable_roles TO PUBLIC;
255 * ADMINISTRABLE_ROLE_AUTHORIZATIONS view
258 CREATE VIEW administrable_role_authorizations AS
260 FROM applicable_roles
261 WHERE is_grantable = 'YES';
263 GRANT SELECT ON administrable_role_authorizations TO PUBLIC;
271 -- feature not supported
279 CREATE VIEW attributes AS
280 SELECT CAST(current_database() AS sql_identifier) AS udt_catalog,
281 CAST(nc.nspname AS sql_identifier) AS udt_schema,
282 CAST(c.relname AS sql_identifier) AS udt_name,
283 CAST(a.attname AS sql_identifier) AS attribute_name,
284 CAST(a.attnum AS cardinal_number) AS ordinal_position,
285 CAST(pg_get_expr(ad.adbin, ad.adrelid) AS character_data) AS attribute_default,
286 CAST(CASE WHEN a.attnotnull OR (t.typtype = 'd' AND t.typnotnull) THEN 'NO' ELSE 'YES' END
288 AS is_nullable, -- This column was apparently removed between SQL:2003 and SQL:2008.
291 CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'ARRAY'
292 WHEN nt.nspname = 'pg_catalog' THEN format_type(a.atttypid, null)
293 ELSE 'USER-DEFINED' END
298 _pg_char_max_length(_pg_truetypid(a, t), _pg_truetypmod(a, t))
300 AS character_maximum_length,
303 _pg_char_octet_length(_pg_truetypid(a, t), _pg_truetypmod(a, t))
305 AS character_octet_length,
307 CAST(null AS sql_identifier) AS character_set_catalog,
308 CAST(null AS sql_identifier) AS character_set_schema,
309 CAST(null AS sql_identifier) AS character_set_name,
311 CAST(CASE WHEN nco.nspname IS NOT NULL THEN current_database() END AS sql_identifier) AS collation_catalog,
312 CAST(nco.nspname AS sql_identifier) AS collation_schema,
313 CAST(co.collname AS sql_identifier) AS collation_name,
316 _pg_numeric_precision(_pg_truetypid(a, t), _pg_truetypmod(a, t))
318 AS numeric_precision,
321 _pg_numeric_precision_radix(_pg_truetypid(a, t), _pg_truetypmod(a, t))
323 AS numeric_precision_radix,
326 _pg_numeric_scale(_pg_truetypid(a, t), _pg_truetypmod(a, t))
331 _pg_datetime_precision(_pg_truetypid(a, t), _pg_truetypmod(a, t))
333 AS datetime_precision,
336 _pg_interval_type(_pg_truetypid(a, t), _pg_truetypmod(a, t))
339 CAST(null AS cardinal_number) AS interval_precision,
341 CAST(current_database() AS sql_identifier) AS attribute_udt_catalog,
342 CAST(nt.nspname AS sql_identifier) AS attribute_udt_schema,
343 CAST(t.typname AS sql_identifier) AS attribute_udt_name,
345 CAST(null AS sql_identifier) AS scope_catalog,
346 CAST(null AS sql_identifier) AS scope_schema,
347 CAST(null AS sql_identifier) AS scope_name,
349 CAST(null AS cardinal_number) AS maximum_cardinality,
350 CAST(a.attnum AS sql_identifier) AS dtd_identifier,
351 CAST('NO' AS yes_or_no) AS is_derived_reference_attribute
353 FROM (pg_attribute a LEFT JOIN pg_attrdef ad ON attrelid = adrelid AND attnum = adnum)
354 JOIN (pg_class c JOIN pg_namespace nc ON (c.relnamespace = nc.oid)) ON a.attrelid = c.oid
355 JOIN (pg_type t JOIN pg_namespace nt ON (t.typnamespace = nt.oid)) ON a.atttypid = t.oid
356 LEFT JOIN (pg_collation co JOIN pg_namespace nco ON (co.collnamespace = nco.oid))
357 ON a.attcollation = co.oid AND (nco.nspname, co.collname) <> ('pg_catalog', 'default')
359 WHERE a.attnum > 0 AND NOT a.attisdropped
360 AND c.relkind in ('c');
362 GRANT SELECT ON attributes TO PUBLIC;
367 * CHARACTER_SETS view
370 CREATE VIEW character_sets AS
371 SELECT CAST(null AS sql_identifier) AS character_set_catalog,
372 CAST(null AS sql_identifier) AS character_set_schema,
373 CAST(getdatabaseencoding() AS sql_identifier) AS character_set_name,
374 CAST(CASE WHEN getdatabaseencoding() = 'UTF8' THEN 'UCS' ELSE getdatabaseencoding() END AS sql_identifier) AS character_repertoire,
375 CAST(getdatabaseencoding() AS sql_identifier) AS form_of_use,
376 CAST(current_database() AS sql_identifier) AS default_collate_catalog,
377 CAST(nc.nspname AS sql_identifier) AS default_collate_schema,
378 CAST(c.collname AS sql_identifier) AS default_collate_name
380 LEFT JOIN (pg_collation c JOIN pg_namespace nc ON (c.collnamespace = nc.oid))
381 ON (datcollate = collcollate AND datctype = collctype)
382 WHERE d.datname = current_database()
383 ORDER BY char_length(c.collname) DESC, c.collname ASC -- prefer full/canonical name
386 GRANT SELECT ON character_sets TO PUBLIC;
391 * CHECK_CONSTRAINT_ROUTINE_USAGE view
394 CREATE VIEW check_constraint_routine_usage AS
395 SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog,
396 CAST(nc.nspname AS sql_identifier) AS constraint_schema,
397 CAST(c.conname AS sql_identifier) AS constraint_name,
398 CAST(current_database() AS sql_identifier) AS specific_catalog,
399 CAST(np.nspname AS sql_identifier) AS specific_schema,
400 CAST(p.proname || '_' || CAST(p.oid AS text) AS sql_identifier) AS specific_name
401 FROM pg_namespace nc, pg_constraint c, pg_depend d, pg_proc p, pg_namespace np
402 WHERE nc.oid = c.connamespace
405 AND d.classid = 'pg_catalog.pg_constraint'::regclass
406 AND d.refobjid = p.oid
407 AND d.refclassid = 'pg_catalog.pg_proc'::regclass
408 AND p.pronamespace = np.oid
409 AND pg_has_role(p.proowner, 'USAGE');
411 GRANT SELECT ON check_constraint_routine_usage TO PUBLIC;
416 * CHECK_CONSTRAINTS view
419 CREATE VIEW check_constraints AS
420 SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog,
421 CAST(rs.nspname AS sql_identifier) AS constraint_schema,
422 CAST(con.conname AS sql_identifier) AS constraint_name,
423 CAST(substring(pg_get_constraintdef(con.oid) from 7) AS character_data)
425 FROM pg_constraint con
426 LEFT OUTER JOIN pg_namespace rs ON (rs.oid = con.connamespace)
427 LEFT OUTER JOIN pg_class c ON (c.oid = con.conrelid)
428 LEFT OUTER JOIN pg_type t ON (t.oid = con.contypid)
429 WHERE pg_has_role(coalesce(c.relowner, t.typowner), 'USAGE')
430 AND con.contype = 'c'
433 -- not-null constraints
435 SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog,
436 CAST(n.nspname AS sql_identifier) AS constraint_schema,
437 CAST(CAST(n.oid AS text) || '_' || CAST(r.oid AS text) || '_' || CAST(a.attnum AS text) || '_not_null' AS sql_identifier) AS constraint_name, -- XXX
438 CAST(a.attname || ' IS NOT NULL' AS character_data)
440 FROM pg_namespace n, pg_class r, pg_attribute a
441 WHERE n.oid = r.relnamespace
442 AND r.oid = a.attrelid
444 AND NOT a.attisdropped
447 AND pg_has_role(r.relowner, 'USAGE');
449 GRANT SELECT ON check_constraints TO PUBLIC;
457 CREATE VIEW collations AS
458 SELECT CAST(current_database() AS sql_identifier) AS collation_catalog,
459 CAST(nc.nspname AS sql_identifier) AS collation_schema,
460 CAST(c.collname AS sql_identifier) AS collation_name,
461 CAST('NO PAD' AS character_data) AS pad_attribute
462 FROM pg_collation c, pg_namespace nc
463 WHERE c.collnamespace = nc.oid
464 AND collencoding IN (-1, (SELECT encoding FROM pg_database WHERE datname = current_database()));
466 GRANT SELECT ON collations TO PUBLIC;
471 * COLLATION_CHARACTER_SET_APPLICABILITY view
474 CREATE VIEW collation_character_set_applicability AS
475 SELECT CAST(current_database() AS sql_identifier) AS collation_catalog,
476 CAST(nc.nspname AS sql_identifier) AS collation_schema,
477 CAST(c.collname AS sql_identifier) AS collation_name,
478 CAST(null AS sql_identifier) AS character_set_catalog,
479 CAST(null AS sql_identifier) AS character_set_schema,
480 CAST(getdatabaseencoding() AS sql_identifier) AS character_set_name
481 FROM pg_collation c, pg_namespace nc
482 WHERE c.collnamespace = nc.oid
483 AND collencoding IN (-1, (SELECT encoding FROM pg_database WHERE datname = current_database()));
485 GRANT SELECT ON collation_character_set_applicability TO PUBLIC;
490 * COLUMN_COLUMN_USAGE view
493 -- feature not supported
498 * COLUMN_DOMAIN_USAGE view
501 CREATE VIEW column_domain_usage AS
502 SELECT CAST(current_database() AS sql_identifier) AS domain_catalog,
503 CAST(nt.nspname AS sql_identifier) AS domain_schema,
504 CAST(t.typname AS sql_identifier) AS domain_name,
505 CAST(current_database() AS sql_identifier) AS table_catalog,
506 CAST(nc.nspname AS sql_identifier) AS table_schema,
507 CAST(c.relname AS sql_identifier) AS table_name,
508 CAST(a.attname AS sql_identifier) AS column_name
510 FROM pg_type t, pg_namespace nt, pg_class c, pg_namespace nc,
513 WHERE t.typnamespace = nt.oid
514 AND c.relnamespace = nc.oid
515 AND a.attrelid = c.oid
516 AND a.atttypid = t.oid
518 AND c.relkind IN ('r', 'v', 'f')
520 AND NOT a.attisdropped
521 AND pg_has_role(t.typowner, 'USAGE');
523 GRANT SELECT ON column_domain_usage TO PUBLIC;
531 CREATE VIEW column_privileges AS
532 SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor,
533 CAST(grantee.rolname AS sql_identifier) AS grantee,
534 CAST(current_database() AS sql_identifier) AS table_catalog,
535 CAST(nc.nspname AS sql_identifier) AS table_schema,
536 CAST(x.relname AS sql_identifier) AS table_name,
537 CAST(x.attname AS sql_identifier) AS column_name,
538 CAST(x.prtype AS character_data) AS privilege_type,
541 -- object owner always has grant options
542 pg_has_role(x.grantee, x.relowner, 'USAGE')
544 THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable
555 FROM (SELECT oid, relname, relnamespace, relowner, (aclexplode(relacl)).*
557 WHERE relkind IN ('r', 'v', 'f')
558 ) pr_c (oid, relname, relnamespace, relowner, grantor, grantee, prtype, grantable),
560 WHERE a.attrelid = pr_c.oid
562 AND NOT a.attisdropped
572 FROM (SELECT attrelid, attname, (aclexplode(attacl)).*
576 ) pr_a (attrelid, attname, grantor, grantee, prtype, grantable),
578 WHERE pr_a.attrelid = c.oid
579 AND relkind IN ('r', 'v', 'f')
584 SELECT oid, rolname FROM pg_authid
586 SELECT 0::oid, 'PUBLIC'
587 ) AS grantee (oid, rolname)
589 WHERE x.relnamespace = nc.oid
590 AND x.grantee = grantee.oid
591 AND x.grantor = u_grantor.oid
592 AND x.prtype IN ('INSERT', 'SELECT', 'UPDATE', 'REFERENCES')
593 AND (pg_has_role(u_grantor.oid, 'USAGE')
594 OR pg_has_role(grantee.oid, 'USAGE')
595 OR grantee.rolname = 'PUBLIC');
597 GRANT SELECT ON column_privileges TO PUBLIC;
602 * COLUMN_UDT_USAGE view
605 CREATE VIEW column_udt_usage AS
606 SELECT CAST(current_database() AS sql_identifier) AS udt_catalog,
607 CAST(coalesce(nbt.nspname, nt.nspname) AS sql_identifier) AS udt_schema,
608 CAST(coalesce(bt.typname, t.typname) AS sql_identifier) AS udt_name,
609 CAST(current_database() AS sql_identifier) AS table_catalog,
610 CAST(nc.nspname AS sql_identifier) AS table_schema,
611 CAST(c.relname AS sql_identifier) AS table_name,
612 CAST(a.attname AS sql_identifier) AS column_name
614 FROM pg_attribute a, pg_class c, pg_namespace nc,
615 (pg_type t JOIN pg_namespace nt ON (t.typnamespace = nt.oid))
616 LEFT JOIN (pg_type bt JOIN pg_namespace nbt ON (bt.typnamespace = nbt.oid))
617 ON (t.typtype = 'd' AND t.typbasetype = bt.oid)
619 WHERE a.attrelid = c.oid
620 AND a.atttypid = t.oid
621 AND nc.oid = c.relnamespace
622 AND a.attnum > 0 AND NOT a.attisdropped AND c.relkind in ('r', 'v', 'f')
623 AND pg_has_role(coalesce(bt.typowner, t.typowner), 'USAGE');
625 GRANT SELECT ON column_udt_usage TO PUBLIC;
633 CREATE VIEW columns AS
634 SELECT CAST(current_database() AS sql_identifier) AS table_catalog,
635 CAST(nc.nspname AS sql_identifier) AS table_schema,
636 CAST(c.relname AS sql_identifier) AS table_name,
637 CAST(a.attname AS sql_identifier) AS column_name,
638 CAST(a.attnum AS cardinal_number) AS ordinal_position,
639 CAST(pg_get_expr(ad.adbin, ad.adrelid) AS character_data) AS column_default,
640 CAST(CASE WHEN a.attnotnull OR (t.typtype = 'd' AND t.typnotnull) THEN 'NO' ELSE 'YES' END
645 CASE WHEN t.typtype = 'd' THEN
646 CASE WHEN bt.typelem <> 0 AND bt.typlen = -1 THEN 'ARRAY'
647 WHEN nbt.nspname = 'pg_catalog' THEN format_type(t.typbasetype, null)
648 ELSE 'USER-DEFINED' END
650 CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'ARRAY'
651 WHEN nt.nspname = 'pg_catalog' THEN format_type(a.atttypid, null)
652 ELSE 'USER-DEFINED' END
658 _pg_char_max_length(_pg_truetypid(a, t), _pg_truetypmod(a, t))
660 AS character_maximum_length,
663 _pg_char_octet_length(_pg_truetypid(a, t), _pg_truetypmod(a, t))
665 AS character_octet_length,
668 _pg_numeric_precision(_pg_truetypid(a, t), _pg_truetypmod(a, t))
670 AS numeric_precision,
673 _pg_numeric_precision_radix(_pg_truetypid(a, t), _pg_truetypmod(a, t))
675 AS numeric_precision_radix,
678 _pg_numeric_scale(_pg_truetypid(a, t), _pg_truetypmod(a, t))
683 _pg_datetime_precision(_pg_truetypid(a, t), _pg_truetypmod(a, t))
685 AS datetime_precision,
688 _pg_interval_type(_pg_truetypid(a, t), _pg_truetypmod(a, t))
691 CAST(null AS cardinal_number) AS interval_precision,
693 CAST(null AS sql_identifier) AS character_set_catalog,
694 CAST(null AS sql_identifier) AS character_set_schema,
695 CAST(null AS sql_identifier) AS character_set_name,
697 CAST(CASE WHEN nco.nspname IS NOT NULL THEN current_database() END AS sql_identifier) AS collation_catalog,
698 CAST(nco.nspname AS sql_identifier) AS collation_schema,
699 CAST(co.collname AS sql_identifier) AS collation_name,
701 CAST(CASE WHEN t.typtype = 'd' THEN current_database() ELSE null END
702 AS sql_identifier) AS domain_catalog,
703 CAST(CASE WHEN t.typtype = 'd' THEN nt.nspname ELSE null END
704 AS sql_identifier) AS domain_schema,
705 CAST(CASE WHEN t.typtype = 'd' THEN t.typname ELSE null END
706 AS sql_identifier) AS domain_name,
708 CAST(current_database() AS sql_identifier) AS udt_catalog,
709 CAST(coalesce(nbt.nspname, nt.nspname) AS sql_identifier) AS udt_schema,
710 CAST(coalesce(bt.typname, t.typname) AS sql_identifier) AS udt_name,
712 CAST(null AS sql_identifier) AS scope_catalog,
713 CAST(null AS sql_identifier) AS scope_schema,
714 CAST(null AS sql_identifier) AS scope_name,
716 CAST(null AS cardinal_number) AS maximum_cardinality,
717 CAST(a.attnum AS sql_identifier) AS dtd_identifier,
718 CAST('NO' AS yes_or_no) AS is_self_referencing,
720 CAST('NO' AS yes_or_no) AS is_identity,
721 CAST(null AS character_data) AS identity_generation,
722 CAST(null AS character_data) AS identity_start,
723 CAST(null AS character_data) AS identity_increment,
724 CAST(null AS character_data) AS identity_maximum,
725 CAST(null AS character_data) AS identity_minimum,
726 CAST(null AS yes_or_no) AS identity_cycle,
728 CAST('NEVER' AS character_data) AS is_generated,
729 CAST(null AS character_data) AS generation_expression,
731 CAST(CASE WHEN c.relkind = 'r'
733 AND EXISTS (SELECT 1 FROM pg_rewrite WHERE ev_class = c.oid AND ev_type = '2' AND is_instead)
734 AND EXISTS (SELECT 1 FROM pg_rewrite WHERE ev_class = c.oid AND ev_type = '4' AND is_instead))
735 THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_updatable
737 FROM (pg_attribute a LEFT JOIN pg_attrdef ad ON attrelid = adrelid AND attnum = adnum)
738 JOIN (pg_class c JOIN pg_namespace nc ON (c.relnamespace = nc.oid)) ON a.attrelid = c.oid
739 JOIN (pg_type t JOIN pg_namespace nt ON (t.typnamespace = nt.oid)) ON a.atttypid = t.oid
740 LEFT JOIN (pg_type bt JOIN pg_namespace nbt ON (bt.typnamespace = nbt.oid))
741 ON (t.typtype = 'd' AND t.typbasetype = bt.oid)
742 LEFT JOIN (pg_collation co JOIN pg_namespace nco ON (co.collnamespace = nco.oid))
743 ON a.attcollation = co.oid AND (nco.nspname, co.collname) <> ('pg_catalog', 'default')
745 WHERE (NOT pg_is_other_temp_schema(nc.oid))
747 AND a.attnum > 0 AND NOT a.attisdropped AND c.relkind in ('r', 'v', 'f')
749 AND (pg_has_role(c.relowner, 'USAGE')
750 OR has_column_privilege(c.oid, a.attnum,
751 'SELECT, INSERT, UPDATE, REFERENCES'));
753 GRANT SELECT ON columns TO PUBLIC;
758 * CONSTRAINT_COLUMN_USAGE view
761 CREATE VIEW constraint_column_usage AS
762 SELECT CAST(current_database() AS sql_identifier) AS table_catalog,
763 CAST(tblschema AS sql_identifier) AS table_schema,
764 CAST(tblname AS sql_identifier) AS table_name,
765 CAST(colname AS sql_identifier) AS column_name,
766 CAST(current_database() AS sql_identifier) AS constraint_catalog,
767 CAST(cstrschema AS sql_identifier) AS constraint_schema,
768 CAST(cstrname AS sql_identifier) AS constraint_name
771 /* check constraints */
772 SELECT DISTINCT nr.nspname, r.relname, r.relowner, a.attname, nc.nspname, c.conname
773 FROM pg_namespace nr, pg_class r, pg_attribute a, pg_depend d, pg_namespace nc, pg_constraint c
774 WHERE nr.oid = r.relnamespace
775 AND r.oid = a.attrelid
776 AND d.refclassid = 'pg_catalog.pg_class'::regclass
777 AND d.refobjid = r.oid
778 AND d.refobjsubid = a.attnum
779 AND d.classid = 'pg_catalog.pg_constraint'::regclass
781 AND c.connamespace = nc.oid
784 AND NOT a.attisdropped
788 /* unique/primary key/foreign key constraints */
789 SELECT nr.nspname, r.relname, r.relowner, a.attname, nc.nspname, c.conname
790 FROM pg_namespace nr, pg_class r, pg_attribute a, pg_namespace nc,
792 WHERE nr.oid = r.relnamespace
793 AND r.oid = a.attrelid
794 AND nc.oid = c.connamespace
795 AND (CASE WHEN c.contype = 'f' THEN r.oid = c.confrelid AND a.attnum = ANY (c.confkey)
796 ELSE r.oid = c.conrelid AND a.attnum = ANY (c.conkey) END)
797 AND NOT a.attisdropped
798 AND c.contype IN ('p', 'u', 'f')
801 ) AS x (tblschema, tblname, tblowner, colname, cstrschema, cstrname)
803 WHERE pg_has_role(x.tblowner, 'USAGE');
805 GRANT SELECT ON constraint_column_usage TO PUBLIC;
810 * CONSTRAINT_TABLE_USAGE view
813 CREATE VIEW constraint_table_usage AS
814 SELECT CAST(current_database() AS sql_identifier) AS table_catalog,
815 CAST(nr.nspname AS sql_identifier) AS table_schema,
816 CAST(r.relname AS sql_identifier) AS table_name,
817 CAST(current_database() AS sql_identifier) AS constraint_catalog,
818 CAST(nc.nspname AS sql_identifier) AS constraint_schema,
819 CAST(c.conname AS sql_identifier) AS constraint_name
821 FROM pg_constraint c, pg_namespace nc,
822 pg_class r, pg_namespace nr
824 WHERE c.connamespace = nc.oid AND r.relnamespace = nr.oid
825 AND ( (c.contype = 'f' AND c.confrelid = r.oid)
826 OR (c.contype IN ('p', 'u') AND c.conrelid = r.oid) )
828 AND pg_has_role(r.relowner, 'USAGE');
830 GRANT SELECT ON constraint_table_usage TO PUBLIC;
833 -- 5.24 DATA_TYPE_PRIVILEGES view appears later.
838 * DIRECT_SUPERTABLES view
841 -- feature not supported
846 * DIRECT_SUPERTYPES view
849 -- feature not supported
854 * DOMAIN_CONSTRAINTS view
857 CREATE VIEW domain_constraints AS
858 SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog,
859 CAST(rs.nspname AS sql_identifier) AS constraint_schema,
860 CAST(con.conname AS sql_identifier) AS constraint_name,
861 CAST(current_database() AS sql_identifier) AS domain_catalog,
862 CAST(n.nspname AS sql_identifier) AS domain_schema,
863 CAST(t.typname AS sql_identifier) AS domain_name,
864 CAST(CASE WHEN condeferrable THEN 'YES' ELSE 'NO' END
865 AS yes_or_no) AS is_deferrable,
866 CAST(CASE WHEN condeferred THEN 'YES' ELSE 'NO' END
867 AS yes_or_no) AS initially_deferred
868 FROM pg_namespace rs, pg_namespace n, pg_constraint con, pg_type t
869 WHERE rs.oid = con.connamespace
870 AND n.oid = t.typnamespace
871 AND t.oid = con.contypid;
873 GRANT SELECT ON domain_constraints TO PUBLIC;
877 * DOMAIN_UDT_USAGE view
878 * apparently removed in SQL:2003
881 CREATE VIEW domain_udt_usage AS
882 SELECT CAST(current_database() AS sql_identifier) AS udt_catalog,
883 CAST(nbt.nspname AS sql_identifier) AS udt_schema,
884 CAST(bt.typname AS sql_identifier) AS udt_name,
885 CAST(current_database() AS sql_identifier) AS domain_catalog,
886 CAST(nt.nspname AS sql_identifier) AS domain_schema,
887 CAST(t.typname AS sql_identifier) AS domain_name
889 FROM pg_type t, pg_namespace nt,
890 pg_type bt, pg_namespace nbt
892 WHERE t.typnamespace = nt.oid
893 AND t.typbasetype = bt.oid
894 AND bt.typnamespace = nbt.oid
896 AND pg_has_role(bt.typowner, 'USAGE');
898 GRANT SELECT ON domain_udt_usage TO PUBLIC;
906 CREATE VIEW domains AS
907 SELECT CAST(current_database() AS sql_identifier) AS domain_catalog,
908 CAST(nt.nspname AS sql_identifier) AS domain_schema,
909 CAST(t.typname AS sql_identifier) AS domain_name,
912 CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'ARRAY'
913 WHEN nbt.nspname = 'pg_catalog' THEN format_type(t.typbasetype, null)
914 ELSE 'USER-DEFINED' END
919 _pg_char_max_length(t.typbasetype, t.typtypmod)
921 AS character_maximum_length,
924 _pg_char_octet_length(t.typbasetype, t.typtypmod)
926 AS character_octet_length,
928 CAST(null AS sql_identifier) AS character_set_catalog,
929 CAST(null AS sql_identifier) AS character_set_schema,
930 CAST(null AS sql_identifier) AS character_set_name,
932 CAST(CASE WHEN nco.nspname IS NOT NULL THEN current_database() END AS sql_identifier) AS collation_catalog,
933 CAST(nco.nspname AS sql_identifier) AS collation_schema,
934 CAST(co.collname AS sql_identifier) AS collation_name,
937 _pg_numeric_precision(t.typbasetype, t.typtypmod)
939 AS numeric_precision,
942 _pg_numeric_precision_radix(t.typbasetype, t.typtypmod)
944 AS numeric_precision_radix,
947 _pg_numeric_scale(t.typbasetype, t.typtypmod)
952 _pg_datetime_precision(t.typbasetype, t.typtypmod)
954 AS datetime_precision,
957 _pg_interval_type(t.typbasetype, t.typtypmod)
960 CAST(null AS cardinal_number) AS interval_precision,
962 CAST(t.typdefault AS character_data) AS domain_default,
964 CAST(current_database() AS sql_identifier) AS udt_catalog,
965 CAST(nbt.nspname AS sql_identifier) AS udt_schema,
966 CAST(bt.typname AS sql_identifier) AS udt_name,
968 CAST(null AS sql_identifier) AS scope_catalog,
969 CAST(null AS sql_identifier) AS scope_schema,
970 CAST(null AS sql_identifier) AS scope_name,
972 CAST(null AS cardinal_number) AS maximum_cardinality,
973 CAST(1 AS sql_identifier) AS dtd_identifier
975 FROM (pg_type t JOIN pg_namespace nt ON t.typnamespace = nt.oid)
976 JOIN (pg_type bt JOIN pg_namespace nbt ON bt.typnamespace = nbt.oid)
977 ON (t.typbasetype = bt.oid AND t.typtype = 'd')
978 LEFT JOIN (pg_collation co JOIN pg_namespace nco ON (co.collnamespace = nco.oid))
979 ON t.typcollation = co.oid AND (nco.nspname, co.collname) <> ('pg_catalog', 'default')
983 GRANT SELECT ON domains TO PUBLIC;
986 -- 5.29 ELEMENT_TYPES view appears later.
994 CREATE VIEW enabled_roles AS
995 SELECT CAST(a.rolname AS sql_identifier) AS role_name
997 WHERE pg_has_role(a.oid, 'USAGE');
999 GRANT SELECT ON enabled_roles TO PUBLIC;
1007 -- feature not supported
1012 * KEY_COLUMN_USAGE view
1015 CREATE VIEW key_column_usage AS
1016 SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog,
1017 CAST(nc_nspname AS sql_identifier) AS constraint_schema,
1018 CAST(conname AS sql_identifier) AS constraint_name,
1019 CAST(current_database() AS sql_identifier) AS table_catalog,
1020 CAST(nr_nspname AS sql_identifier) AS table_schema,
1021 CAST(relname AS sql_identifier) AS table_name,
1022 CAST(a.attname AS sql_identifier) AS column_name,
1023 CAST((ss.x).n AS cardinal_number) AS ordinal_position,
1024 CAST(CASE WHEN contype = 'f' THEN
1025 _pg_index_position(ss.conindid, ss.confkey[(ss.x).n])
1027 END AS cardinal_number)
1028 AS position_in_unique_constraint
1029 FROM pg_attribute a,
1030 (SELECT r.oid AS roid, r.relname, r.relowner,
1031 nc.nspname AS nc_nspname, nr.nspname AS nr_nspname,
1032 c.oid AS coid, c.conname, c.contype, c.conindid,
1033 c.confkey, c.confrelid,
1034 _pg_expandarray(c.conkey) AS x
1035 FROM pg_namespace nr, pg_class r, pg_namespace nc,
1037 WHERE nr.oid = r.relnamespace
1038 AND r.oid = c.conrelid
1039 AND nc.oid = c.connamespace
1040 AND c.contype IN ('p', 'u', 'f')
1042 AND (NOT pg_is_other_temp_schema(nr.oid)) ) AS ss
1043 WHERE ss.roid = a.attrelid
1044 AND a.attnum = (ss.x).x
1045 AND NOT a.attisdropped
1046 AND (pg_has_role(relowner, 'USAGE')
1047 OR has_column_privilege(roid, a.attnum,
1048 'SELECT, INSERT, UPDATE, REFERENCES'));
1050 GRANT SELECT ON key_column_usage TO PUBLIC;
1055 * METHOD_SPECIFICATION_PARAMETERS view
1058 -- feature not supported
1063 * METHOD_SPECIFICATIONS view
1066 -- feature not supported
1074 CREATE VIEW parameters AS
1075 SELECT CAST(current_database() AS sql_identifier) AS specific_catalog,
1076 CAST(n_nspname AS sql_identifier) AS specific_schema,
1077 CAST(proname || '_' || CAST(p_oid AS text) AS sql_identifier) AS specific_name,
1078 CAST((ss.x).n AS cardinal_number) AS ordinal_position,
1080 CASE WHEN proargmodes IS NULL THEN 'IN'
1081 WHEN proargmodes[(ss.x).n] = 'i' THEN 'IN'
1082 WHEN proargmodes[(ss.x).n] = 'o' THEN 'OUT'
1083 WHEN proargmodes[(ss.x).n] = 'b' THEN 'INOUT'
1084 WHEN proargmodes[(ss.x).n] = 'v' THEN 'IN'
1085 WHEN proargmodes[(ss.x).n] = 't' THEN 'OUT'
1086 END AS character_data) AS parameter_mode,
1087 CAST('NO' AS yes_or_no) AS is_result,
1088 CAST('NO' AS yes_or_no) AS as_locator,
1089 CAST(NULLIF(proargnames[(ss.x).n], '') AS sql_identifier) AS parameter_name,
1091 CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'ARRAY'
1092 WHEN nt.nspname = 'pg_catalog' THEN format_type(t.oid, null)
1093 ELSE 'USER-DEFINED' END AS character_data)
1095 CAST(null AS cardinal_number) AS character_maximum_length,
1096 CAST(null AS cardinal_number) AS character_octet_length,
1097 CAST(null AS sql_identifier) AS character_set_catalog,
1098 CAST(null AS sql_identifier) AS character_set_schema,
1099 CAST(null AS sql_identifier) AS character_set_name,
1100 CAST(null AS sql_identifier) AS collation_catalog,
1101 CAST(null AS sql_identifier) AS collation_schema,
1102 CAST(null AS sql_identifier) AS collation_name,
1103 CAST(null AS cardinal_number) AS numeric_precision,
1104 CAST(null AS cardinal_number) AS numeric_precision_radix,
1105 CAST(null AS cardinal_number) AS numeric_scale,
1106 CAST(null AS cardinal_number) AS datetime_precision,
1107 CAST(null AS character_data) AS interval_type,
1108 CAST(null AS cardinal_number) AS interval_precision,
1109 CAST(current_database() AS sql_identifier) AS udt_catalog,
1110 CAST(nt.nspname AS sql_identifier) AS udt_schema,
1111 CAST(t.typname AS sql_identifier) AS udt_name,
1112 CAST(null AS sql_identifier) AS scope_catalog,
1113 CAST(null AS sql_identifier) AS scope_schema,
1114 CAST(null AS sql_identifier) AS scope_name,
1115 CAST(null AS cardinal_number) AS maximum_cardinality,
1116 CAST((ss.x).n AS sql_identifier) AS dtd_identifier
1118 FROM pg_type t, pg_namespace nt,
1119 (SELECT n.nspname AS n_nspname, p.proname, p.oid AS p_oid,
1120 p.proargnames, p.proargmodes,
1121 _pg_expandarray(coalesce(p.proallargtypes, p.proargtypes::oid[])) AS x
1122 FROM pg_namespace n, pg_proc p
1123 WHERE n.oid = p.pronamespace
1124 AND (pg_has_role(p.proowner, 'USAGE') OR
1125 has_function_privilege(p.oid, 'EXECUTE'))) AS ss
1126 WHERE t.oid = (ss.x).x AND t.typnamespace = nt.oid;
1128 GRANT SELECT ON parameters TO PUBLIC;
1133 * REFERENCED_TYPES view
1136 -- feature not supported
1141 * REFERENTIAL_CONSTRAINTS view
1144 CREATE VIEW referential_constraints AS
1145 SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog,
1146 CAST(ncon.nspname AS sql_identifier) AS constraint_schema,
1147 CAST(con.conname AS sql_identifier) AS constraint_name,
1149 CASE WHEN npkc.nspname IS NULL THEN NULL
1150 ELSE current_database() END
1151 AS sql_identifier) AS unique_constraint_catalog,
1152 CAST(npkc.nspname AS sql_identifier) AS unique_constraint_schema,
1153 CAST(pkc.conname AS sql_identifier) AS unique_constraint_name,
1156 CASE con.confmatchtype WHEN 'f' THEN 'FULL'
1157 WHEN 'p' THEN 'PARTIAL'
1158 WHEN 'u' THEN 'NONE' END
1159 AS character_data) AS match_option,
1162 CASE con.confupdtype WHEN 'c' THEN 'CASCADE'
1163 WHEN 'n' THEN 'SET NULL'
1164 WHEN 'd' THEN 'SET DEFAULT'
1165 WHEN 'r' THEN 'RESTRICT'
1166 WHEN 'a' THEN 'NO ACTION' END
1167 AS character_data) AS update_rule,
1170 CASE con.confdeltype WHEN 'c' THEN 'CASCADE'
1171 WHEN 'n' THEN 'SET NULL'
1172 WHEN 'd' THEN 'SET DEFAULT'
1173 WHEN 'r' THEN 'RESTRICT'
1174 WHEN 'a' THEN 'NO ACTION' END
1175 AS character_data) AS delete_rule
1177 FROM (pg_namespace ncon
1178 INNER JOIN pg_constraint con ON ncon.oid = con.connamespace
1179 INNER JOIN pg_class c ON con.conrelid = c.oid)
1182 INNER JOIN pg_namespace npkc ON pkc.connamespace = npkc.oid)
1183 ON con.confrelid = pkc.conrelid
1184 AND _pg_keysequal(con.confkey, pkc.conkey)
1186 WHERE c.relkind = 'r'
1187 AND con.contype = 'f'
1188 AND (pkc.contype IN ('p', 'u') OR pkc.contype IS NULL)
1189 AND (pg_has_role(c.relowner, 'USAGE')
1190 -- SELECT privilege omitted, per SQL standard
1191 OR has_table_privilege(c.oid, 'INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER')
1192 OR has_any_column_privilege(c.oid, 'INSERT, UPDATE, REFERENCES') );
1194 GRANT SELECT ON referential_constraints TO PUBLIC;
1199 * ROLE_COLUMN_GRANTS view
1202 CREATE VIEW role_column_grants AS
1211 FROM column_privileges
1212 WHERE grantor IN (SELECT role_name FROM enabled_roles)
1213 OR grantee IN (SELECT role_name FROM enabled_roles);
1215 GRANT SELECT ON role_column_grants TO PUBLIC;
1218 -- 5.39 ROLE_ROUTINE_GRANTS view is based on 5.45 ROUTINE_PRIVILEGES and is defined there instead.
1221 -- 5.40 ROLE_TABLE_GRANTS view is based on 5.60 TABLE_PRIVILEGES and is defined there instead.
1226 * ROLE_TABLE_METHOD_GRANTS view
1229 -- feature not supported
1233 -- 5.42 ROLE_USAGE_GRANTS view is based on 5.71 USAGE_PRIVILEGES and is defined there instead.
1236 -- 5.43 ROLE_UDT_GRANTS view is based on 5.70 UDT_PRIVILEGES and is defined there instead.
1241 * ROUTINE_COLUMN_USAGE view
1244 -- not tracked by PostgreSQL
1249 * ROUTINE_PRIVILEGES view
1252 CREATE VIEW routine_privileges AS
1253 SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor,
1254 CAST(grantee.rolname AS sql_identifier) AS grantee,
1255 CAST(current_database() AS sql_identifier) AS specific_catalog,
1256 CAST(n.nspname AS sql_identifier) AS specific_schema,
1257 CAST(p.proname || '_' || CAST(p.oid AS text) AS sql_identifier) AS specific_name,
1258 CAST(current_database() AS sql_identifier) AS routine_catalog,
1259 CAST(n.nspname AS sql_identifier) AS routine_schema,
1260 CAST(p.proname AS sql_identifier) AS routine_name,
1261 CAST('EXECUTE' AS character_data) AS privilege_type,
1264 -- object owner always has grant options
1265 pg_has_role(grantee.oid, p.proowner, 'USAGE')
1267 THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable
1270 SELECT oid, proname, proowner, pronamespace, (aclexplode(proacl)).* FROM pg_proc
1271 ) p (oid, proname, proowner, pronamespace, grantor, grantee, prtype, grantable),
1273 pg_authid u_grantor,
1275 SELECT oid, rolname FROM pg_authid
1277 SELECT 0::oid, 'PUBLIC'
1278 ) AS grantee (oid, rolname)
1280 WHERE p.pronamespace = n.oid
1281 AND grantee.oid = p.grantee
1282 AND u_grantor.oid = p.grantor
1283 AND p.prtype IN ('EXECUTE')
1284 AND (pg_has_role(u_grantor.oid, 'USAGE')
1285 OR pg_has_role(grantee.oid, 'USAGE')
1286 OR grantee.rolname = 'PUBLIC');
1288 GRANT SELECT ON routine_privileges TO PUBLIC;
1293 * ROLE_ROUTINE_GRANTS view
1296 CREATE VIEW role_routine_grants AS
1307 FROM routine_privileges
1308 WHERE grantor IN (SELECT role_name FROM enabled_roles)
1309 OR grantee IN (SELECT role_name FROM enabled_roles);
1311 GRANT SELECT ON role_routine_grants TO PUBLIC;
1316 * ROUTINE_ROUTINE_USAGE view
1319 -- not tracked by PostgreSQL
1324 * ROUTINE_SEQUENCE_USAGE view
1327 -- not tracked by PostgreSQL
1332 * ROUTINE_TABLE_USAGE view
1335 -- not tracked by PostgreSQL
1343 CREATE VIEW routines AS
1344 SELECT CAST(current_database() AS sql_identifier) AS specific_catalog,
1345 CAST(n.nspname AS sql_identifier) AS specific_schema,
1346 CAST(p.proname || '_' || CAST(p.oid AS text) AS sql_identifier) AS specific_name,
1347 CAST(current_database() AS sql_identifier) AS routine_catalog,
1348 CAST(n.nspname AS sql_identifier) AS routine_schema,
1349 CAST(p.proname AS sql_identifier) AS routine_name,
1350 CAST('FUNCTION' AS character_data) AS routine_type,
1351 CAST(null AS sql_identifier) AS module_catalog,
1352 CAST(null AS sql_identifier) AS module_schema,
1353 CAST(null AS sql_identifier) AS module_name,
1354 CAST(null AS sql_identifier) AS udt_catalog,
1355 CAST(null AS sql_identifier) AS udt_schema,
1356 CAST(null AS sql_identifier) AS udt_name,
1359 CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'ARRAY'
1360 WHEN nt.nspname = 'pg_catalog' THEN format_type(t.oid, null)
1361 ELSE 'USER-DEFINED' END AS character_data)
1363 CAST(null AS cardinal_number) AS character_maximum_length,
1364 CAST(null AS cardinal_number) AS character_octet_length,
1365 CAST(null AS sql_identifier) AS character_set_catalog,
1366 CAST(null AS sql_identifier) AS character_set_schema,
1367 CAST(null AS sql_identifier) AS character_set_name,
1368 CAST(null AS sql_identifier) AS collation_catalog,
1369 CAST(null AS sql_identifier) AS collation_schema,
1370 CAST(null AS sql_identifier) AS collation_name,
1371 CAST(null AS cardinal_number) AS numeric_precision,
1372 CAST(null AS cardinal_number) AS numeric_precision_radix,
1373 CAST(null AS cardinal_number) AS numeric_scale,
1374 CAST(null AS cardinal_number) AS datetime_precision,
1375 CAST(null AS character_data) AS interval_type,
1376 CAST(null AS cardinal_number) AS interval_precision,
1377 CAST(current_database() AS sql_identifier) AS type_udt_catalog,
1378 CAST(nt.nspname AS sql_identifier) AS type_udt_schema,
1379 CAST(t.typname AS sql_identifier) AS type_udt_name,
1380 CAST(null AS sql_identifier) AS scope_catalog,
1381 CAST(null AS sql_identifier) AS scope_schema,
1382 CAST(null AS sql_identifier) AS scope_name,
1383 CAST(null AS cardinal_number) AS maximum_cardinality,
1384 CAST(0 AS sql_identifier) AS dtd_identifier,
1386 CAST(CASE WHEN l.lanname = 'sql' THEN 'SQL' ELSE 'EXTERNAL' END AS character_data)
1389 CASE WHEN pg_has_role(p.proowner, 'USAGE') THEN p.prosrc ELSE null END
1390 AS character_data) AS routine_definition,
1392 CASE WHEN l.lanname = 'c' THEN p.prosrc ELSE null END
1393 AS character_data) AS external_name,
1394 CAST(upper(l.lanname) AS character_data) AS external_language,
1396 CAST('GENERAL' AS character_data) AS parameter_style,
1397 CAST(CASE WHEN p.provolatile = 'i' THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_deterministic,
1398 CAST('MODIFIES' AS character_data) AS sql_data_access,
1399 CAST(CASE WHEN p.proisstrict THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_null_call,
1400 CAST(null AS character_data) AS sql_path,
1401 CAST('YES' AS yes_or_no) AS schema_level_routine,
1402 CAST(0 AS cardinal_number) AS max_dynamic_result_sets,
1403 CAST(null AS yes_or_no) AS is_user_defined_cast,
1404 CAST(null AS yes_or_no) AS is_implicitly_invocable,
1405 CAST(CASE WHEN p.prosecdef THEN 'DEFINER' ELSE 'INVOKER' END AS character_data) AS security_type,
1406 CAST(null AS sql_identifier) AS to_sql_specific_catalog,
1407 CAST(null AS sql_identifier) AS to_sql_specific_schema,
1408 CAST(null AS sql_identifier) AS to_sql_specific_name,
1409 CAST('NO' AS yes_or_no) AS as_locator,
1410 CAST(null AS time_stamp) AS created,
1411 CAST(null AS time_stamp) AS last_altered,
1412 CAST(null AS yes_or_no) AS new_savepoint_level,
1413 CAST('NO' AS yes_or_no) AS is_udt_dependent,
1415 CAST(null AS character_data) AS result_cast_from_data_type,
1416 CAST(null AS yes_or_no) AS result_cast_as_locator,
1417 CAST(null AS cardinal_number) AS result_cast_char_max_length,
1418 CAST(null AS cardinal_number) AS result_cast_char_octet_length,
1419 CAST(null AS sql_identifier) AS result_cast_char_set_catalog,
1420 CAST(null AS sql_identifier) AS result_cast_char_set_schema,
1421 CAST(null AS sql_identifier) AS result_cast_character_set_name,
1422 CAST(null AS sql_identifier) AS result_cast_collation_catalog,
1423 CAST(null AS sql_identifier) AS result_cast_collation_schema,
1424 CAST(null AS sql_identifier) AS result_cast_collation_name,
1425 CAST(null AS cardinal_number) AS result_cast_numeric_precision,
1426 CAST(null AS cardinal_number) AS result_cast_numeric_precision_radix,
1427 CAST(null AS cardinal_number) AS result_cast_numeric_scale,
1428 CAST(null AS cardinal_number) AS result_cast_datetime_precision,
1429 CAST(null AS character_data) AS result_cast_interval_type,
1430 CAST(null AS cardinal_number) AS result_cast_interval_precision,
1431 CAST(null AS sql_identifier) AS result_cast_type_udt_catalog,
1432 CAST(null AS sql_identifier) AS result_cast_type_udt_schema,
1433 CAST(null AS sql_identifier) AS result_cast_type_udt_name,
1434 CAST(null AS sql_identifier) AS result_cast_scope_catalog,
1435 CAST(null AS sql_identifier) AS result_cast_scope_schema,
1436 CAST(null AS sql_identifier) AS result_cast_scope_name,
1437 CAST(null AS cardinal_number) AS result_cast_maximum_cardinality,
1438 CAST(null AS sql_identifier) AS result_cast_dtd_identifier
1440 FROM pg_namespace n, pg_proc p, pg_language l,
1441 pg_type t, pg_namespace nt
1443 WHERE n.oid = p.pronamespace AND p.prolang = l.oid
1444 AND p.prorettype = t.oid AND t.typnamespace = nt.oid
1445 AND (pg_has_role(p.proowner, 'USAGE')
1446 OR has_function_privilege(p.oid, 'EXECUTE'));
1448 GRANT SELECT ON routines TO PUBLIC;
1456 CREATE VIEW schemata AS
1457 SELECT CAST(current_database() AS sql_identifier) AS catalog_name,
1458 CAST(n.nspname AS sql_identifier) AS schema_name,
1459 CAST(u.rolname AS sql_identifier) AS schema_owner,
1460 CAST(null AS sql_identifier) AS default_character_set_catalog,
1461 CAST(null AS sql_identifier) AS default_character_set_schema,
1462 CAST(null AS sql_identifier) AS default_character_set_name,
1463 CAST(null AS character_data) AS sql_path
1464 FROM pg_namespace n, pg_authid u
1465 WHERE n.nspowner = u.oid AND pg_has_role(n.nspowner, 'USAGE');
1467 GRANT SELECT ON schemata TO PUBLIC;
1475 CREATE VIEW sequences AS
1476 SELECT CAST(current_database() AS sql_identifier) AS sequence_catalog,
1477 CAST(nc.nspname AS sql_identifier) AS sequence_schema,
1478 CAST(c.relname AS sql_identifier) AS sequence_name,
1479 CAST('bigint' AS character_data) AS data_type,
1480 CAST(64 AS cardinal_number) AS numeric_precision,
1481 CAST(2 AS cardinal_number) AS numeric_precision_radix,
1482 CAST(0 AS cardinal_number) AS numeric_scale,
1483 -- XXX: The following could be improved if we had LATERAL.
1484 CAST((pg_sequence_parameters(c.oid)).start_value AS character_data) AS start_value,
1485 CAST((pg_sequence_parameters(c.oid)).minimum_value AS character_data) AS minimum_value,
1486 CAST((pg_sequence_parameters(c.oid)).maximum_value AS character_data) AS maximum_value,
1487 CAST((pg_sequence_parameters(c.oid)).increment AS character_data) AS increment,
1488 CAST(CASE WHEN (pg_sequence_parameters(c.oid)).cycle_option THEN 'YES' ELSE 'NO' END AS yes_or_no) AS cycle_option
1489 FROM pg_namespace nc, pg_class c
1490 WHERE c.relnamespace = nc.oid
1492 AND (NOT pg_is_other_temp_schema(nc.oid))
1493 AND (pg_has_role(c.relowner, 'USAGE')
1494 OR has_sequence_privilege(c.oid, 'SELECT, UPDATE, USAGE') );
1496 GRANT SELECT ON sequences TO PUBLIC;
1501 * SQL_FEATURES table
1504 CREATE TABLE sql_features (
1505 feature_id character_data,
1506 feature_name character_data,
1507 sub_feature_id character_data,
1508 sub_feature_name character_data,
1509 is_supported yes_or_no,
1510 is_verified_by character_data,
1511 comments character_data
1514 -- Will be filled with external data by initdb.
1516 GRANT SELECT ON sql_features TO PUBLIC;
1521 * SQL_IMPLEMENTATION_INFO table
1524 -- Note: Implementation information items are defined in ISO/IEC 9075-3:2008,
1527 CREATE TABLE sql_implementation_info (
1528 implementation_info_id character_data,
1529 implementation_info_name character_data,
1530 integer_value cardinal_number,
1531 character_value character_data,
1532 comments character_data
1535 INSERT INTO sql_implementation_info VALUES ('10003', 'CATALOG NAME', NULL, 'Y', NULL);
1536 INSERT INTO sql_implementation_info VALUES ('10004', 'COLLATING SEQUENCE', NULL, (SELECT default_collate_name FROM character_sets), NULL);
1537 INSERT INTO sql_implementation_info VALUES ('23', 'CURSOR COMMIT BEHAVIOR', 1, NULL, 'close cursors and retain prepared statements');
1538 INSERT INTO sql_implementation_info VALUES ('2', 'DATA SOURCE NAME', NULL, '', NULL);
1539 INSERT INTO sql_implementation_info VALUES ('17', 'DBMS NAME', NULL, (select trim(trailing ' ' from substring(version() from '^[^0-9]*'))), NULL);
1540 INSERT INTO sql_implementation_info VALUES ('18', 'DBMS VERSION', NULL, '???', NULL); -- filled by initdb
1541 INSERT INTO sql_implementation_info VALUES ('26', 'DEFAULT TRANSACTION ISOLATION', 2, NULL, 'READ COMMITTED; user-settable');
1542 INSERT INTO sql_implementation_info VALUES ('28', 'IDENTIFIER CASE', 3, NULL, 'stored in mixed case - case sensitive');
1543 INSERT INTO sql_implementation_info VALUES ('85', 'NULL COLLATION', 0, NULL, 'nulls higher than non-nulls');
1544 INSERT INTO sql_implementation_info VALUES ('13', 'SERVER NAME', NULL, '', NULL);
1545 INSERT INTO sql_implementation_info VALUES ('94', 'SPECIAL CHARACTERS', NULL, '', 'all non-ASCII characters allowed');
1546 INSERT INTO sql_implementation_info VALUES ('46', 'TRANSACTION CAPABLE', 2, NULL, 'both DML and DDL');
1548 GRANT SELECT ON sql_implementation_info TO PUBLIC;
1552 * SQL_LANGUAGES table
1553 * apparently removed in SQL:2008
1556 CREATE TABLE sql_languages (
1557 sql_language_source character_data,
1558 sql_language_year character_data,
1559 sql_language_conformance character_data,
1560 sql_language_integrity character_data,
1561 sql_language_implementation character_data,
1562 sql_language_binding_style character_data,
1563 sql_language_programming_language character_data
1566 INSERT INTO sql_languages VALUES ('ISO 9075', '1999', 'CORE', NULL, NULL, 'DIRECT', NULL);
1567 INSERT INTO sql_languages VALUES ('ISO 9075', '1999', 'CORE', NULL, NULL, 'EMBEDDED', 'C');
1568 INSERT INTO sql_languages VALUES ('ISO 9075', '2003', 'CORE', NULL, NULL, 'DIRECT', NULL);
1569 INSERT INTO sql_languages VALUES ('ISO 9075', '2003', 'CORE', NULL, NULL, 'EMBEDDED', 'C');
1571 GRANT SELECT ON sql_languages TO PUBLIC;
1576 * SQL_PACKAGES table
1579 CREATE TABLE sql_packages (
1580 feature_id character_data,
1581 feature_name character_data,
1582 is_supported yes_or_no,
1583 is_verified_by character_data,
1584 comments character_data
1587 INSERT INTO sql_packages VALUES ('PKG000', 'Core', 'NO', NULL, '');
1588 INSERT INTO sql_packages VALUES ('PKG001', 'Enhanced datetime facilities', 'YES', NULL, '');
1589 INSERT INTO sql_packages VALUES ('PKG002', 'Enhanced integrity management', 'NO', NULL, '');
1590 INSERT INTO sql_packages VALUES ('PKG003', 'OLAP facilities', 'NO', NULL, '');
1591 INSERT INTO sql_packages VALUES ('PKG004', 'PSM', 'NO', NULL, 'PL/pgSQL is similar.');
1592 INSERT INTO sql_packages VALUES ('PKG005', 'CLI', 'NO', NULL, 'ODBC is similar.');
1593 INSERT INTO sql_packages VALUES ('PKG006', 'Basic object support', 'NO', NULL, '');
1594 INSERT INTO sql_packages VALUES ('PKG007', 'Enhanced object support', 'NO', NULL, '');
1595 INSERT INTO sql_packages VALUES ('PKG008', 'Active database', 'NO', NULL, '');
1596 INSERT INTO sql_packages VALUES ('PKG010', 'OLAP', 'NO', NULL, 'NO');
1598 GRANT SELECT ON sql_packages TO PUBLIC;
1606 CREATE TABLE sql_parts (
1607 feature_id character_data,
1608 feature_name character_data,
1609 is_supported yes_or_no,
1610 is_verified_by character_data,
1611 comments character_data
1614 INSERT INTO sql_parts VALUES ('1', 'Framework (SQL/Framework)', 'NO', NULL, '');
1615 INSERT INTO sql_parts VALUES ('2', 'Foundation (SQL/Foundation)', 'NO', NULL, '');
1616 INSERT INTO sql_parts VALUES ('3', 'Call-Level Interface (SQL/CLI)', 'NO', NULL, '');
1617 INSERT INTO sql_parts VALUES ('4', 'Persistent Stored Modules (SQL/PSM)', 'NO', NULL, '');
1618 INSERT INTO sql_parts VALUES ('9', 'Management of External Data (SQL/MED)', 'NO', NULL, '');
1619 INSERT INTO sql_parts VALUES ('10', 'Object Language Bindings (SQL/OLB)', 'NO', NULL, '');
1620 INSERT INTO sql_parts VALUES ('11', 'Information and Definition Schema (SQL/Schemata)', 'NO', NULL, '');
1621 INSERT INTO sql_parts VALUES ('13', 'Routines and Types Using the Java Programming Language (SQL/JRT)', 'NO', NULL, '');
1622 INSERT INTO sql_parts VALUES ('14', 'XML-Related Specifications (SQL/XML)', 'YES', NULL, '');
1630 -- Note: Sizing items are defined in ISO/IEC 9075-3:2008, clause 9.2.
1632 CREATE TABLE sql_sizing (
1633 sizing_id cardinal_number,
1634 sizing_name character_data,
1635 supported_value cardinal_number,
1636 comments character_data
1639 INSERT INTO sql_sizing VALUES (34, 'MAXIMUM CATALOG NAME LENGTH', 63, NULL);
1640 INSERT INTO sql_sizing VALUES (30, 'MAXIMUM COLUMN NAME LENGTH', 63, NULL);
1641 INSERT INTO sql_sizing VALUES (97, 'MAXIMUM COLUMNS IN GROUP BY', 0, NULL);
1642 INSERT INTO sql_sizing VALUES (99, 'MAXIMUM COLUMNS IN ORDER BY', 0, NULL);
1643 INSERT INTO sql_sizing VALUES (100, 'MAXIMUM COLUMNS IN SELECT', 1664, NULL); -- match MaxTupleAttributeNumber
1644 INSERT INTO sql_sizing VALUES (101, 'MAXIMUM COLUMNS IN TABLE', 1600, NULL); -- match MaxHeapAttributeNumber
1645 INSERT INTO sql_sizing VALUES (1, 'MAXIMUM CONCURRENT ACTIVITIES', 0, NULL);
1646 INSERT INTO sql_sizing VALUES (31, 'MAXIMUM CURSOR NAME LENGTH', 63, NULL);
1647 INSERT INTO sql_sizing VALUES (0, 'MAXIMUM DRIVER CONNECTIONS', NULL, NULL);
1648 INSERT INTO sql_sizing VALUES (10005, 'MAXIMUM IDENTIFIER LENGTH', 63, NULL);
1649 INSERT INTO sql_sizing VALUES (32, 'MAXIMUM SCHEMA NAME LENGTH', 63, NULL);
1650 INSERT INTO sql_sizing VALUES (20000, 'MAXIMUM STATEMENT OCTETS', 0, NULL);
1651 INSERT INTO sql_sizing VALUES (20001, 'MAXIMUM STATEMENT OCTETS DATA', 0, NULL);
1652 INSERT INTO sql_sizing VALUES (20002, 'MAXIMUM STATEMENT OCTETS SCHEMA', 0, NULL);
1653 INSERT INTO sql_sizing VALUES (35, 'MAXIMUM TABLE NAME LENGTH', 63, NULL);
1654 INSERT INTO sql_sizing VALUES (106, 'MAXIMUM TABLES IN SELECT', 0, NULL);
1655 INSERT INTO sql_sizing VALUES (107, 'MAXIMUM USER NAME LENGTH', 63, NULL);
1656 INSERT INTO sql_sizing VALUES (25000, 'MAXIMUM CURRENT DEFAULT TRANSFORM GROUP LENGTH', NULL, NULL);
1657 INSERT INTO sql_sizing VALUES (25001, 'MAXIMUM CURRENT TRANSFORM GROUP LENGTH', NULL, NULL);
1658 INSERT INTO sql_sizing VALUES (25002, 'MAXIMUM CURRENT PATH LENGTH', 0, NULL);
1659 INSERT INTO sql_sizing VALUES (25003, 'MAXIMUM CURRENT ROLE LENGTH', NULL, NULL);
1660 INSERT INTO sql_sizing VALUES (25004, 'MAXIMUM SESSION USER LENGTH', 63, NULL);
1661 INSERT INTO sql_sizing VALUES (25005, 'MAXIMUM SYSTEM USER LENGTH', 63, NULL);
1664 SET supported_value = (SELECT typlen-1 FROM pg_catalog.pg_type WHERE typname = 'name'),
1665 comments = 'Might be less, depending on character set.'
1666 WHERE supported_value = 63;
1668 GRANT SELECT ON sql_sizing TO PUBLIC;
1673 * SQL_SIZING_PROFILES table
1676 -- The data in this table are defined by various profiles of SQL.
1677 -- Since we don't have any information about such profiles, we provide
1680 CREATE TABLE sql_sizing_profiles (
1681 sizing_id cardinal_number,
1682 sizing_name character_data,
1683 profile_id character_data,
1684 required_value cardinal_number,
1685 comments character_data
1688 GRANT SELECT ON sql_sizing_profiles TO PUBLIC;
1693 * TABLE_CONSTRAINTS view
1696 CREATE VIEW table_constraints AS
1697 SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog,
1698 CAST(nc.nspname AS sql_identifier) AS constraint_schema,
1699 CAST(c.conname AS sql_identifier) AS constraint_name,
1700 CAST(current_database() AS sql_identifier) AS table_catalog,
1701 CAST(nr.nspname AS sql_identifier) AS table_schema,
1702 CAST(r.relname AS sql_identifier) AS table_name,
1704 CASE c.contype WHEN 'c' THEN 'CHECK'
1705 WHEN 'f' THEN 'FOREIGN KEY'
1706 WHEN 'p' THEN 'PRIMARY KEY'
1707 WHEN 'u' THEN 'UNIQUE' END
1708 AS character_data) AS constraint_type,
1709 CAST(CASE WHEN c.condeferrable THEN 'YES' ELSE 'NO' END AS yes_or_no)
1711 CAST(CASE WHEN c.condeferred THEN 'YES' ELSE 'NO' END AS yes_or_no)
1712 AS initially_deferred
1714 FROM pg_namespace nc,
1719 WHERE nc.oid = c.connamespace AND nr.oid = r.relnamespace
1720 AND c.conrelid = r.oid
1721 AND c.contype NOT IN ('t', 'x') -- ignore nonstandard constraints
1723 AND (NOT pg_is_other_temp_schema(nr.oid))
1724 AND (pg_has_role(r.relowner, 'USAGE')
1725 -- SELECT privilege omitted, per SQL standard
1726 OR has_table_privilege(r.oid, 'INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER')
1727 OR has_any_column_privilege(r.oid, 'INSERT, UPDATE, REFERENCES') )
1731 -- not-null constraints
1733 SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog,
1734 CAST(nr.nspname AS sql_identifier) AS constraint_schema,
1735 CAST(CAST(nr.oid AS text) || '_' || CAST(r.oid AS text) || '_' || CAST(a.attnum AS text) || '_not_null' AS sql_identifier) AS constraint_name, -- XXX
1736 CAST(current_database() AS sql_identifier) AS table_catalog,
1737 CAST(nr.nspname AS sql_identifier) AS table_schema,
1738 CAST(r.relname AS sql_identifier) AS table_name,
1739 CAST('CHECK' AS character_data) AS constraint_type,
1740 CAST('NO' AS yes_or_no) AS is_deferrable,
1741 CAST('NO' AS yes_or_no) AS initially_deferred
1743 FROM pg_namespace nr,
1747 WHERE nr.oid = r.relnamespace
1748 AND r.oid = a.attrelid
1751 AND NOT a.attisdropped
1753 AND (NOT pg_is_other_temp_schema(nr.oid))
1754 AND (pg_has_role(r.relowner, 'USAGE')
1755 -- SELECT privilege omitted, per SQL standard
1756 OR has_table_privilege(r.oid, 'INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER')
1757 OR has_any_column_privilege(r.oid, 'INSERT, UPDATE, REFERENCES') );
1759 GRANT SELECT ON table_constraints TO PUBLIC;
1764 * TABLE_METHOD_PRIVILEGES view
1767 -- feature not supported
1772 * TABLE_PRIVILEGES view
1775 CREATE VIEW table_privileges AS
1776 SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor,
1777 CAST(grantee.rolname AS sql_identifier) AS grantee,
1778 CAST(current_database() AS sql_identifier) AS table_catalog,
1779 CAST(nc.nspname AS sql_identifier) AS table_schema,
1780 CAST(c.relname AS sql_identifier) AS table_name,
1781 CAST(c.prtype AS character_data) AS privilege_type,
1784 -- object owner always has grant options
1785 pg_has_role(grantee.oid, c.relowner, 'USAGE')
1787 THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable,
1788 CAST('NO' AS yes_or_no) AS with_hierarchy
1791 SELECT oid, relname, relnamespace, relkind, relowner, (aclexplode(relacl)).* FROM pg_class
1792 ) AS c (oid, relname, relnamespace, relkind, relowner, grantor, grantee, prtype, grantable),
1794 pg_authid u_grantor,
1796 SELECT oid, rolname FROM pg_authid
1798 SELECT 0::oid, 'PUBLIC'
1799 ) AS grantee (oid, rolname)
1801 WHERE c.relnamespace = nc.oid
1802 AND c.relkind IN ('r', 'v')
1803 AND c.grantee = grantee.oid
1804 AND c.grantor = u_grantor.oid
1805 AND c.prtype IN ('INSERT', 'SELECT', 'UPDATE', 'DELETE', 'TRUNCATE', 'REFERENCES', 'TRIGGER')
1806 AND (pg_has_role(u_grantor.oid, 'USAGE')
1807 OR pg_has_role(grantee.oid, 'USAGE')
1808 OR grantee.rolname = 'PUBLIC');
1810 GRANT SELECT ON table_privileges TO PUBLIC;
1815 * ROLE_TABLE_GRANTS view
1818 CREATE VIEW role_table_grants AS
1827 FROM table_privileges
1828 WHERE grantor IN (SELECT role_name FROM enabled_roles)
1829 OR grantee IN (SELECT role_name FROM enabled_roles);
1831 GRANT SELECT ON role_table_grants TO PUBLIC;
1839 CREATE VIEW tables AS
1840 SELECT CAST(current_database() AS sql_identifier) AS table_catalog,
1841 CAST(nc.nspname AS sql_identifier) AS table_schema,
1842 CAST(c.relname AS sql_identifier) AS table_name,
1845 CASE WHEN nc.oid = pg_my_temp_schema() THEN 'LOCAL TEMPORARY'
1846 WHEN c.relkind = 'r' THEN 'BASE TABLE'
1847 WHEN c.relkind = 'v' THEN 'VIEW'
1848 WHEN c.relkind = 'f' THEN 'FOREIGN TABLE'
1850 AS character_data) AS table_type,
1852 CAST(null AS sql_identifier) AS self_referencing_column_name,
1853 CAST(null AS character_data) AS reference_generation,
1855 CAST(CASE WHEN t.typname IS NOT NULL THEN current_database() ELSE null END AS sql_identifier) AS user_defined_type_catalog,
1856 CAST(nt.nspname AS sql_identifier) AS user_defined_type_schema,
1857 CAST(t.typname AS sql_identifier) AS user_defined_type_name,
1859 CAST(CASE WHEN c.relkind = 'r'
1861 AND EXISTS (SELECT 1 FROM pg_rewrite WHERE ev_class = c.oid AND ev_type = '3' AND is_instead))
1862 THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_insertable_into,
1864 CAST(CASE WHEN t.typname IS NOT NULL THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_typed,
1865 CAST(null AS character_data) AS commit_action
1867 FROM pg_namespace nc JOIN pg_class c ON (nc.oid = c.relnamespace)
1868 LEFT JOIN (pg_type t JOIN pg_namespace nt ON (t.typnamespace = nt.oid)) ON (c.reloftype = t.oid)
1870 WHERE c.relkind IN ('r', 'v', 'f')
1871 AND (NOT pg_is_other_temp_schema(nc.oid))
1872 AND (pg_has_role(c.relowner, 'USAGE')
1873 OR has_table_privilege(c.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER')
1874 OR has_any_column_privilege(c.oid, 'SELECT, INSERT, UPDATE, REFERENCES') );
1876 GRANT SELECT ON tables TO PUBLIC;
1884 -- feature not supported
1892 -- feature not supported
1897 * TRIGGERED_UPDATE_COLUMNS view
1900 CREATE VIEW triggered_update_columns AS
1901 SELECT CAST(current_database() AS sql_identifier) AS trigger_catalog,
1902 CAST(n.nspname AS sql_identifier) AS trigger_schema,
1903 CAST(t.tgname AS sql_identifier) AS trigger_name,
1904 CAST(current_database() AS sql_identifier) AS event_object_catalog,
1905 CAST(n.nspname AS sql_identifier) AS event_object_schema,
1906 CAST(c.relname AS sql_identifier) AS event_object_table,
1907 CAST(a.attname AS sql_identifier) AS event_object_column
1909 FROM pg_namespace n, pg_class c, pg_trigger t,
1910 (SELECT tgoid, (ta0.tgat).x AS tgattnum, (ta0.tgat).n AS tgattpos
1911 FROM (SELECT oid AS tgoid, information_schema._pg_expandarray(tgattr) AS tgat FROM pg_trigger) AS ta0) AS ta,
1914 WHERE n.oid = c.relnamespace
1915 AND c.oid = t.tgrelid
1916 AND t.oid = ta.tgoid
1917 AND (a.attrelid, a.attnum) = (t.tgrelid, ta.tgattnum)
1918 AND NOT t.tgisinternal
1919 AND (NOT pg_is_other_temp_schema(n.oid))
1920 AND (pg_has_role(c.relowner, 'USAGE')
1921 -- SELECT privilege omitted, per SQL standard
1922 OR has_column_privilege(c.oid, a.attnum, 'INSERT, UPDATE, REFERENCES') );
1924 GRANT SELECT ON triggered_update_columns TO PUBLIC;
1929 * TRIGGER_COLUMN_USAGE view
1932 -- not tracked by PostgreSQL
1937 * TRIGGER_ROUTINE_USAGE view
1940 -- not tracked by PostgreSQL
1945 * TRIGGER_SEQUENCE_USAGE view
1948 -- not tracked by PostgreSQL
1953 * TRIGGER_TABLE_USAGE view
1956 -- not tracked by PostgreSQL
1964 CREATE VIEW triggers AS
1965 SELECT CAST(current_database() AS sql_identifier) AS trigger_catalog,
1966 CAST(n.nspname AS sql_identifier) AS trigger_schema,
1967 CAST(t.tgname AS sql_identifier) AS trigger_name,
1968 CAST(em.text AS character_data) AS event_manipulation,
1969 CAST(current_database() AS sql_identifier) AS event_object_catalog,
1970 CAST(n.nspname AS sql_identifier) AS event_object_schema,
1971 CAST(c.relname AS sql_identifier) AS event_object_table,
1972 CAST(null AS cardinal_number) AS action_order,
1973 -- XXX strange hacks follow
1975 CASE WHEN pg_has_role(c.relowner, 'USAGE')
1976 THEN (SELECT m[1] FROM regexp_matches(pg_get_triggerdef(t.oid), E'.{35,} WHEN \\((.+)\\) EXECUTE PROCEDURE') AS rm(m) LIMIT 1)
1978 AS character_data) AS action_condition,
1980 substring(pg_get_triggerdef(t.oid) from
1981 position('EXECUTE PROCEDURE' in substring(pg_get_triggerdef(t.oid) from 48)) + 47)
1982 AS character_data) AS action_statement,
1984 -- hard-wired reference to TRIGGER_TYPE_ROW
1985 CASE t.tgtype & 1 WHEN 1 THEN 'ROW' ELSE 'STATEMENT' END
1986 AS character_data) AS action_orientation,
1988 -- hard-wired refs to TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_INSTEAD
1989 CASE t.tgtype & 66 WHEN 2 THEN 'BEFORE' WHEN 64 THEN 'INSTEAD OF' ELSE 'AFTER' END
1990 AS character_data) AS action_timing,
1991 CAST(null AS sql_identifier) AS action_reference_old_table,
1992 CAST(null AS sql_identifier) AS action_reference_new_table,
1993 CAST(null AS sql_identifier) AS action_reference_old_row,
1994 CAST(null AS sql_identifier) AS action_reference_new_row,
1995 CAST(null AS time_stamp) AS created
1997 FROM pg_namespace n, pg_class c, pg_trigger t,
1998 -- hard-wired refs to TRIGGER_TYPE_INSERT, TRIGGER_TYPE_DELETE,
1999 -- TRIGGER_TYPE_UPDATE; we intentionally omit TRIGGER_TYPE_TRUNCATE
2000 (VALUES (4, 'INSERT'),
2002 (16, 'UPDATE')) AS em (num, text)
2004 WHERE n.oid = c.relnamespace
2005 AND c.oid = t.tgrelid
2006 AND t.tgtype & em.num <> 0
2007 AND NOT t.tgisinternal
2008 AND (NOT pg_is_other_temp_schema(n.oid))
2009 AND (pg_has_role(c.relowner, 'USAGE')
2010 -- SELECT privilege omitted, per SQL standard
2011 OR has_table_privilege(c.oid, 'INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER')
2012 OR has_any_column_privilege(c.oid, 'INSERT, UPDATE, REFERENCES') );
2014 GRANT SELECT ON triggers TO PUBLIC;
2019 * UDT_PRIVILEGES view
2022 CREATE VIEW udt_privileges AS
2023 SELECT CAST(null AS sql_identifier) AS grantor,
2024 CAST('PUBLIC' AS sql_identifier) AS grantee,
2025 CAST(current_database() AS sql_identifier) AS udt_catalog,
2026 CAST(n.nspname AS sql_identifier) AS udt_schema,
2027 CAST(t.typname AS sql_identifier) AS udt_name,
2028 CAST('TYPE USAGE' AS character_data) AS privilege_type, -- sic
2029 CAST('NO' AS yes_or_no) AS is_grantable
2031 FROM pg_authid u, pg_namespace n, pg_type t
2033 WHERE u.oid = t.typowner
2034 AND n.oid = t.typnamespace
2035 AND t.typtype <> 'd'
2036 AND NOT (t.typelem <> 0 AND t.typlen = -1);
2038 GRANT SELECT ON udt_privileges TO PUBLIC;
2043 * ROLE_UDT_GRANTS view
2046 CREATE VIEW role_udt_grants AS
2055 WHERE grantor IN (SELECT role_name FROM enabled_roles)
2056 OR grantee IN (SELECT role_name FROM enabled_roles);
2058 GRANT SELECT ON role_udt_grants TO PUBLIC;
2063 * USAGE_PRIVILEGES view
2066 CREATE VIEW usage_privileges AS
2069 -- Collations have no real privileges, so we represent all collations with implicit usage privilege here.
2070 SELECT CAST(u.rolname AS sql_identifier) AS grantor,
2071 CAST('PUBLIC' AS sql_identifier) AS grantee,
2072 CAST(current_database() AS sql_identifier) AS object_catalog,
2073 CAST(n.nspname AS sql_identifier) AS object_schema,
2074 CAST(c.collname AS sql_identifier) AS object_name,
2075 CAST('COLLATION' AS character_data) AS object_type,
2076 CAST('USAGE' AS character_data) AS privilege_type,
2077 CAST('NO' AS yes_or_no) AS is_grantable
2083 WHERE u.oid = c.collowner
2084 AND c.collnamespace = n.oid
2085 AND collencoding IN (-1, (SELECT encoding FROM pg_database WHERE datname = current_database()))
2090 -- Domains have no real privileges, so we represent all domains with implicit usage privilege here.
2091 SELECT CAST(u.rolname AS sql_identifier) AS grantor,
2092 CAST('PUBLIC' AS sql_identifier) AS grantee,
2093 CAST(current_database() AS sql_identifier) AS object_catalog,
2094 CAST(n.nspname AS sql_identifier) AS object_schema,
2095 CAST(t.typname AS sql_identifier) AS object_name,
2096 CAST('DOMAIN' AS character_data) AS object_type,
2097 CAST('USAGE' AS character_data) AS privilege_type,
2098 CAST('NO' AS yes_or_no) AS is_grantable
2104 WHERE u.oid = t.typowner
2105 AND t.typnamespace = n.oid
2110 /* foreign-data wrappers */
2111 SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor,
2112 CAST(grantee.rolname AS sql_identifier) AS grantee,
2113 CAST(current_database() AS sql_identifier) AS object_catalog,
2114 CAST('' AS sql_identifier) AS object_schema,
2115 CAST(fdw.fdwname AS sql_identifier) AS object_name,
2116 CAST('FOREIGN DATA WRAPPER' AS character_data) AS object_type,
2117 CAST('USAGE' AS character_data) AS privilege_type,
2120 -- object owner always has grant options
2121 pg_has_role(grantee.oid, fdw.fdwowner, 'USAGE')
2123 THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable
2126 SELECT fdwname, fdwowner, (aclexplode(fdwacl)).* FROM pg_foreign_data_wrapper
2127 ) AS fdw (fdwname, fdwowner, grantor, grantee, prtype, grantable),
2128 pg_authid u_grantor,
2130 SELECT oid, rolname FROM pg_authid
2132 SELECT 0::oid, 'PUBLIC'
2133 ) AS grantee (oid, rolname)
2135 WHERE u_grantor.oid = fdw.grantor
2136 AND grantee.oid = fdw.grantee
2137 AND fdw.prtype IN ('USAGE')
2138 AND (pg_has_role(u_grantor.oid, 'USAGE')
2139 OR pg_has_role(grantee.oid, 'USAGE')
2140 OR grantee.rolname = 'PUBLIC')
2144 /* foreign servers */
2145 SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor,
2146 CAST(grantee.rolname AS sql_identifier) AS grantee,
2147 CAST(current_database() AS sql_identifier) AS object_catalog,
2148 CAST('' AS sql_identifier) AS object_schema,
2149 CAST(srv.srvname AS sql_identifier) AS object_name,
2150 CAST('FOREIGN SERVER' AS character_data) AS object_type,
2151 CAST('USAGE' AS character_data) AS privilege_type,
2154 -- object owner always has grant options
2155 pg_has_role(grantee.oid, srv.srvowner, 'USAGE')
2157 THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable
2160 SELECT srvname, srvowner, (aclexplode(srvacl)).* FROM pg_foreign_server
2161 ) AS srv (srvname, srvowner, grantor, grantee, prtype, grantable),
2162 pg_authid u_grantor,
2164 SELECT oid, rolname FROM pg_authid
2166 SELECT 0::oid, 'PUBLIC'
2167 ) AS grantee (oid, rolname)
2169 WHERE u_grantor.oid = srv.grantor
2170 AND grantee.oid = srv.grantee
2171 AND srv.prtype IN ('USAGE')
2172 AND (pg_has_role(u_grantor.oid, 'USAGE')
2173 OR pg_has_role(grantee.oid, 'USAGE')
2174 OR grantee.rolname = 'PUBLIC');
2176 GRANT SELECT ON usage_privileges TO PUBLIC;
2181 * ROLE_USAGE_GRANTS view
2184 CREATE VIEW role_usage_grants AS
2193 FROM usage_privileges
2194 WHERE grantor IN (SELECT role_name FROM enabled_roles)
2195 OR grantee IN (SELECT role_name FROM enabled_roles);
2197 GRANT SELECT ON role_usage_grants TO PUBLIC;
2202 * USER_DEFINED_TYPES view
2205 CREATE VIEW user_defined_types AS
2206 SELECT CAST(current_database() AS sql_identifier) AS user_defined_type_catalog,
2207 CAST(n.nspname AS sql_identifier) AS user_defined_type_schema,
2208 CAST(c.relname AS sql_identifier) AS user_defined_type_name,
2209 CAST('STRUCTURED' AS character_data) AS user_defined_type_category,
2210 CAST('YES' AS yes_or_no) AS is_instantiable,
2211 CAST(null AS yes_or_no) AS is_final,
2212 CAST(null AS character_data) AS ordering_form,
2213 CAST(null AS character_data) AS ordering_category,
2214 CAST(null AS sql_identifier) AS ordering_routine_catalog,
2215 CAST(null AS sql_identifier) AS ordering_routine_schema,
2216 CAST(null AS sql_identifier) AS ordering_routine_name,
2217 CAST(null AS character_data) AS reference_type,
2218 CAST(null AS character_data) AS data_type,
2219 CAST(null AS cardinal_number) AS character_maximum_length,
2220 CAST(null AS cardinal_number) AS character_octet_length,
2221 CAST(null AS sql_identifier) AS character_set_catalog,
2222 CAST(null AS sql_identifier) AS character_set_schema,
2223 CAST(null AS sql_identifier) AS character_set_name,
2224 CAST(null AS sql_identifier) AS collation_catalog,
2225 CAST(null AS sql_identifier) AS collation_schema,
2226 CAST(null AS sql_identifier) AS collation_name,
2227 CAST(null AS cardinal_number) AS numeric_precision,
2228 CAST(null AS cardinal_number) AS numeric_precision_radix,
2229 CAST(null AS cardinal_number) AS numeric_scale,
2230 CAST(null AS cardinal_number) AS datetime_precision,
2231 CAST(null AS character_data) AS interval_type,
2232 CAST(null AS cardinal_number) AS interval_precision,
2233 CAST(null AS sql_identifier) AS source_dtd_identifier,
2234 CAST(null AS sql_identifier) AS ref_dtd_identifier
2236 FROM pg_namespace n, pg_class c
2238 WHERE n.oid = c.relnamespace
2239 AND c.relkind = 'c';
2241 GRANT SELECT ON user_defined_types TO PUBLIC;
2249 CREATE VIEW view_column_usage AS
2251 CAST(current_database() AS sql_identifier) AS view_catalog,
2252 CAST(nv.nspname AS sql_identifier) AS view_schema,
2253 CAST(v.relname AS sql_identifier) AS view_name,
2254 CAST(current_database() AS sql_identifier) AS table_catalog,
2255 CAST(nt.nspname AS sql_identifier) AS table_schema,
2256 CAST(t.relname AS sql_identifier) AS table_name,
2257 CAST(a.attname AS sql_identifier) AS column_name
2259 FROM pg_namespace nv, pg_class v, pg_depend dv,
2260 pg_depend dt, pg_class t, pg_namespace nt,
2263 WHERE nv.oid = v.relnamespace
2265 AND v.oid = dv.refobjid
2266 AND dv.refclassid = 'pg_catalog.pg_class'::regclass
2267 AND dv.classid = 'pg_catalog.pg_rewrite'::regclass
2268 AND dv.deptype = 'i'
2269 AND dv.objid = dt.objid
2270 AND dv.refobjid <> dt.refobjid
2271 AND dt.classid = 'pg_catalog.pg_rewrite'::regclass
2272 AND dt.refclassid = 'pg_catalog.pg_class'::regclass
2273 AND dt.refobjid = t.oid
2274 AND t.relnamespace = nt.oid
2275 AND t.relkind IN ('r', 'v', 'f')
2276 AND t.oid = a.attrelid
2277 AND dt.refobjsubid = a.attnum
2278 AND pg_has_role(t.relowner, 'USAGE');
2280 GRANT SELECT ON view_column_usage TO PUBLIC;
2285 * VIEW_ROUTINE_USAGE
2288 CREATE VIEW view_routine_usage AS
2290 CAST(current_database() AS sql_identifier) AS table_catalog,
2291 CAST(nv.nspname AS sql_identifier) AS table_schema,
2292 CAST(v.relname AS sql_identifier) AS table_name,
2293 CAST(current_database() AS sql_identifier) AS specific_catalog,
2294 CAST(np.nspname AS sql_identifier) AS specific_schema,
2295 CAST(p.proname || '_' || CAST(p.oid AS text) AS sql_identifier) AS specific_name
2297 FROM pg_namespace nv, pg_class v, pg_depend dv,
2298 pg_depend dp, pg_proc p, pg_namespace np
2300 WHERE nv.oid = v.relnamespace
2302 AND v.oid = dv.refobjid
2303 AND dv.refclassid = 'pg_catalog.pg_class'::regclass
2304 AND dv.classid = 'pg_catalog.pg_rewrite'::regclass
2305 AND dv.deptype = 'i'
2306 AND dv.objid = dp.objid
2307 AND dp.classid = 'pg_catalog.pg_rewrite'::regclass
2308 AND dp.refclassid = 'pg_catalog.pg_proc'::regclass
2309 AND dp.refobjid = p.oid
2310 AND p.pronamespace = np.oid
2311 AND pg_has_role(p.proowner, 'USAGE');
2313 GRANT SELECT ON view_routine_usage TO PUBLIC;
2321 CREATE VIEW view_table_usage AS
2323 CAST(current_database() AS sql_identifier) AS view_catalog,
2324 CAST(nv.nspname AS sql_identifier) AS view_schema,
2325 CAST(v.relname AS sql_identifier) AS view_name,
2326 CAST(current_database() AS sql_identifier) AS table_catalog,
2327 CAST(nt.nspname AS sql_identifier) AS table_schema,
2328 CAST(t.relname AS sql_identifier) AS table_name
2330 FROM pg_namespace nv, pg_class v, pg_depend dv,
2331 pg_depend dt, pg_class t, pg_namespace nt
2333 WHERE nv.oid = v.relnamespace
2335 AND v.oid = dv.refobjid
2336 AND dv.refclassid = 'pg_catalog.pg_class'::regclass
2337 AND dv.classid = 'pg_catalog.pg_rewrite'::regclass
2338 AND dv.deptype = 'i'
2339 AND dv.objid = dt.objid
2340 AND dv.refobjid <> dt.refobjid
2341 AND dt.classid = 'pg_catalog.pg_rewrite'::regclass
2342 AND dt.refclassid = 'pg_catalog.pg_class'::regclass
2343 AND dt.refobjid = t.oid
2344 AND t.relnamespace = nt.oid
2345 AND t.relkind IN ('r', 'v', 'f')
2346 AND pg_has_role(t.relowner, 'USAGE');
2348 GRANT SELECT ON view_table_usage TO PUBLIC;
2356 CREATE VIEW views AS
2357 SELECT CAST(current_database() AS sql_identifier) AS table_catalog,
2358 CAST(nc.nspname AS sql_identifier) AS table_schema,
2359 CAST(c.relname AS sql_identifier) AS table_name,
2362 CASE WHEN pg_has_role(c.relowner, 'USAGE')
2363 THEN pg_get_viewdef(c.oid)
2365 AS character_data) AS view_definition,
2367 CAST('NONE' AS character_data) AS check_option,
2370 CASE WHEN EXISTS (SELECT 1 FROM pg_rewrite WHERE ev_class = c.oid AND ev_type = '2' AND is_instead)
2371 AND EXISTS (SELECT 1 FROM pg_rewrite WHERE ev_class = c.oid AND ev_type = '4' AND is_instead)
2372 THEN 'YES' ELSE 'NO' END
2373 AS yes_or_no) AS is_updatable,
2376 CASE WHEN EXISTS (SELECT 1 FROM pg_rewrite WHERE ev_class = c.oid AND ev_type = '3' AND is_instead)
2377 THEN 'YES' ELSE 'NO' END
2378 AS yes_or_no) AS is_insertable_into,
2381 -- TRIGGER_TYPE_ROW + TRIGGER_TYPE_INSTEAD + TRIGGER_TYPE_UPDATE
2382 CASE WHEN EXISTS (SELECT 1 FROM pg_trigger WHERE tgrelid = c.oid AND tgtype & 81 = 81)
2383 THEN 'YES' ELSE 'NO' END
2384 AS yes_or_no) AS is_trigger_updatable,
2387 -- TRIGGER_TYPE_ROW + TRIGGER_TYPE_INSTEAD + TRIGGER_TYPE_DELETE
2388 CASE WHEN EXISTS (SELECT 1 FROM pg_trigger WHERE tgrelid = c.oid AND tgtype & 73 = 73)
2389 THEN 'YES' ELSE 'NO' END
2390 AS yes_or_no) AS is_trigger_deletable,
2393 -- TRIGGER_TYPE_ROW + TRIGGER_TYPE_INSTEAD + TRIGGER_TYPE_INSERT
2394 CASE WHEN EXISTS (SELECT 1 FROM pg_trigger WHERE tgrelid = c.oid AND tgtype & 69 = 69)
2395 THEN 'YES' ELSE 'NO' END
2396 AS yes_or_no) AS is_trigger_insertable_into
2398 FROM pg_namespace nc, pg_class c
2400 WHERE c.relnamespace = nc.oid
2402 AND (NOT pg_is_other_temp_schema(nc.oid))
2403 AND (pg_has_role(c.relowner, 'USAGE')
2404 OR has_table_privilege(c.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER')
2405 OR has_any_column_privilege(c.oid, 'SELECT, INSERT, UPDATE, REFERENCES') );
2407 GRANT SELECT ON views TO PUBLIC;
2410 -- The following views have dependencies that force them to appear out of order.
2414 * DATA_TYPE_PRIVILEGES view
2417 CREATE VIEW data_type_privileges AS
2418 SELECT CAST(current_database() AS sql_identifier) AS object_catalog,
2419 CAST(x.objschema AS sql_identifier) AS object_schema,
2420 CAST(x.objname AS sql_identifier) AS object_name,
2421 CAST(x.objtype AS character_data) AS object_type,
2422 CAST(x.objdtdid AS sql_identifier) AS dtd_identifier
2426 SELECT udt_schema, udt_name, 'USER-DEFINED TYPE'::text, dtd_identifier FROM attributes
2428 SELECT table_schema, table_name, 'TABLE'::text, dtd_identifier FROM columns
2430 SELECT domain_schema, domain_name, 'DOMAIN'::text, dtd_identifier FROM domains
2432 SELECT specific_schema, specific_name, 'ROUTINE'::text, dtd_identifier FROM parameters
2434 SELECT specific_schema, specific_name, 'ROUTINE'::text, dtd_identifier FROM routines
2435 ) AS x (objschema, objname, objtype, objdtdid);
2437 GRANT SELECT ON data_type_privileges TO PUBLIC;
2442 * ELEMENT_TYPES view
2445 CREATE VIEW element_types AS
2446 SELECT CAST(current_database() AS sql_identifier) AS object_catalog,
2447 CAST(n.nspname AS sql_identifier) AS object_schema,
2448 CAST(x.objname AS sql_identifier) AS object_name,
2449 CAST(x.objtype AS character_data) AS object_type,
2450 CAST(x.objdtdid AS sql_identifier) AS collection_type_identifier,
2452 CASE WHEN nbt.nspname = 'pg_catalog' THEN format_type(bt.oid, null)
2453 ELSE 'USER-DEFINED' END AS character_data) AS data_type,
2455 CAST(null AS cardinal_number) AS character_maximum_length,
2456 CAST(null AS cardinal_number) AS character_octet_length,
2457 CAST(null AS sql_identifier) AS character_set_catalog,
2458 CAST(null AS sql_identifier) AS character_set_schema,
2459 CAST(null AS sql_identifier) AS character_set_name,
2460 CAST(CASE WHEN nco.nspname IS NOT NULL THEN current_database() END AS sql_identifier) AS collation_catalog,
2461 CAST(nco.nspname AS sql_identifier) AS collation_schema,
2462 CAST(co.collname AS sql_identifier) AS collation_name,
2463 CAST(null AS cardinal_number) AS numeric_precision,
2464 CAST(null AS cardinal_number) AS numeric_precision_radix,
2465 CAST(null AS cardinal_number) AS numeric_scale,
2466 CAST(null AS cardinal_number) AS datetime_precision,
2467 CAST(null AS character_data) AS interval_type,
2468 CAST(null AS cardinal_number) AS interval_precision,
2470 CAST(null AS character_data) AS domain_default, -- XXX maybe a bug in the standard
2472 CAST(current_database() AS sql_identifier) AS udt_catalog,
2473 CAST(nbt.nspname AS sql_identifier) AS udt_schema,
2474 CAST(bt.typname AS sql_identifier) AS udt_name,
2476 CAST(null AS sql_identifier) AS scope_catalog,
2477 CAST(null AS sql_identifier) AS scope_schema,
2478 CAST(null AS sql_identifier) AS scope_name,
2480 CAST(null AS cardinal_number) AS maximum_cardinality,
2481 CAST('a' || CAST(x.objdtdid AS text) AS sql_identifier) AS dtd_identifier
2483 FROM pg_namespace n, pg_type at, pg_namespace nbt, pg_type bt,
2485 /* columns, attributes */
2486 SELECT c.relnamespace, CAST(c.relname AS sql_identifier),
2487 CASE WHEN c.relkind = 'c' THEN 'USER-DEFINED TYPE'::text ELSE 'TABLE'::text END,
2488 a.attnum, a.atttypid, a.attcollation
2489 FROM pg_class c, pg_attribute a
2490 WHERE c.oid = a.attrelid
2491 AND c.relkind IN ('r', 'v', 'f', 'c')
2492 AND attnum > 0 AND NOT attisdropped
2497 SELECT t.typnamespace, CAST(t.typname AS sql_identifier),
2498 'DOMAIN'::text, 1, t.typbasetype, t.typcollation
2500 WHERE t.typtype = 'd'
2505 SELECT pronamespace, CAST(proname || '_' || CAST(oid AS text) AS sql_identifier),
2506 'ROUTINE'::text, (ss.x).n, (ss.x).x, 0
2507 FROM (SELECT p.pronamespace, p.proname, p.oid,
2508 _pg_expandarray(coalesce(p.proallargtypes, p.proargtypes::oid[])) AS x
2509 FROM pg_proc p) AS ss
2514 SELECT p.pronamespace, CAST(p.proname || '_' || CAST(p.oid AS text) AS sql_identifier),
2515 'ROUTINE'::text, 0, p.prorettype, 0
2518 ) AS x (objschema, objname, objtype, objdtdid, objtypeid, objcollation)
2519 LEFT JOIN (pg_collation co JOIN pg_namespace nco ON (co.collnamespace = nco.oid))
2520 ON x.objcollation = co.oid AND (nco.nspname, co.collname) <> ('pg_catalog', 'default')
2522 WHERE n.oid = x.objschema
2523 AND at.oid = x.objtypeid
2524 AND (at.typelem <> 0 AND at.typlen = -1)
2525 AND at.typelem = bt.oid
2526 AND nbt.oid = bt.typnamespace
2528 AND (n.nspname, x.objname, x.objtype, CAST(x.objdtdid AS sql_identifier)) IN
2529 ( SELECT object_schema, object_name, object_type, dtd_identifier
2530 FROM data_type_privileges );
2532 GRANT SELECT ON element_types TO PUBLIC;
2535 -- SQL/MED views; these use section numbers from part 9 of the standard.
2537 /* Base view for foreign table columns */
2538 CREATE VIEW _pg_foreign_table_columns AS
2543 FROM pg_foreign_table t, pg_authid u, pg_namespace n, pg_class c,
2545 WHERE u.oid = c.relowner
2546 AND (pg_has_role(c.relowner, 'USAGE')
2547 OR has_column_privilege(c.oid, a.attnum, 'SELECT, INSERT, UPDATE, REFERENCES'))
2548 AND n.oid = c.relnamespace
2549 AND c.oid = t.ftrelid
2551 AND a.attrelid = c.oid
2556 * COLUMN_OPTIONS view
2558 CREATE VIEW column_options AS
2559 SELECT CAST(current_database() AS sql_identifier) AS table_catalog,
2560 c.nspname AS table_schema,
2561 c.relname AS table_name,
2562 c.attname AS column_name,
2563 CAST((pg_options_to_table(c.attfdwoptions)).option_name AS sql_identifier) AS option_name,
2564 CAST((pg_options_to_table(c.attfdwoptions)).option_value AS character_data) AS option_value
2565 FROM _pg_foreign_table_columns c;
2567 GRANT SELECT ON column_options TO PUBLIC;
2570 /* Base view for foreign-data wrappers */
2571 CREATE VIEW _pg_foreign_data_wrappers AS
2575 CAST(current_database() AS sql_identifier) AS foreign_data_wrapper_catalog,
2576 CAST(fdwname AS sql_identifier) AS foreign_data_wrapper_name,
2577 CAST(u.rolname AS sql_identifier) AS authorization_identifier,
2578 CAST('c' AS character_data) AS foreign_data_wrapper_language
2579 FROM pg_foreign_data_wrapper w, pg_authid u
2580 WHERE u.oid = w.fdwowner
2581 AND (pg_has_role(fdwowner, 'USAGE')
2582 OR has_foreign_data_wrapper_privilege(w.oid, 'USAGE'));
2587 * FOREIGN_DATA_WRAPPER_OPTIONS view
2589 CREATE VIEW foreign_data_wrapper_options AS
2590 SELECT foreign_data_wrapper_catalog,
2591 foreign_data_wrapper_name,
2592 CAST((pg_options_to_table(w.fdwoptions)).option_name AS sql_identifier) AS option_name,
2593 CAST((pg_options_to_table(w.fdwoptions)).option_value AS character_data) AS option_value
2594 FROM _pg_foreign_data_wrappers w;
2596 GRANT SELECT ON foreign_data_wrapper_options TO PUBLIC;
2601 * FOREIGN_DATA_WRAPPERS view
2603 CREATE VIEW foreign_data_wrappers AS
2604 SELECT foreign_data_wrapper_catalog,
2605 foreign_data_wrapper_name,
2606 authorization_identifier,
2607 CAST(NULL AS character_data) AS library_name,
2608 foreign_data_wrapper_language
2609 FROM _pg_foreign_data_wrappers w;
2611 GRANT SELECT ON foreign_data_wrappers TO PUBLIC;
2614 /* Base view for foreign servers */
2615 CREATE VIEW _pg_foreign_servers AS
2618 CAST(current_database() AS sql_identifier) AS foreign_server_catalog,
2619 CAST(srvname AS sql_identifier) AS foreign_server_name,
2620 CAST(current_database() AS sql_identifier) AS foreign_data_wrapper_catalog,
2621 CAST(w.fdwname AS sql_identifier) AS foreign_data_wrapper_name,
2622 CAST(srvtype AS character_data) AS foreign_server_type,
2623 CAST(srvversion AS character_data) AS foreign_server_version,
2624 CAST(u.rolname AS sql_identifier) AS authorization_identifier
2625 FROM pg_foreign_server s, pg_foreign_data_wrapper w, pg_authid u
2626 WHERE w.oid = s.srvfdw
2627 AND u.oid = s.srvowner
2628 AND (pg_has_role(s.srvowner, 'USAGE')
2629 OR has_server_privilege(s.oid, 'USAGE'));
2634 * FOREIGN_SERVER_OPTIONS view
2636 CREATE VIEW foreign_server_options AS
2637 SELECT foreign_server_catalog,
2638 foreign_server_name,
2639 CAST((pg_options_to_table(s.srvoptions)).option_name AS sql_identifier) AS option_name,
2640 CAST((pg_options_to_table(s.srvoptions)).option_value AS character_data) AS option_value
2641 FROM _pg_foreign_servers s;
2643 GRANT SELECT ON TABLE foreign_server_options TO PUBLIC;
2648 * FOREIGN_SERVERS view
2650 CREATE VIEW foreign_servers AS
2651 SELECT foreign_server_catalog,
2652 foreign_server_name,
2653 foreign_data_wrapper_catalog,
2654 foreign_data_wrapper_name,
2655 foreign_server_type,
2656 foreign_server_version,
2657 authorization_identifier
2658 FROM _pg_foreign_servers;
2660 GRANT SELECT ON foreign_servers TO PUBLIC;
2663 /* Base view for foreign tables */
2664 CREATE VIEW _pg_foreign_tables AS
2666 CAST(current_database() AS sql_identifier) AS foreign_table_catalog,
2667 n.nspname AS foreign_table_schema,
2668 c.relname AS foreign_table_name,
2669 t.ftoptions AS ftoptions,
2670 CAST(current_database() AS sql_identifier) AS foreign_server_catalog,
2671 CAST(srvname AS sql_identifier) AS foreign_server_name,
2672 CAST(u.rolname AS sql_identifier) AS authorization_identifier
2673 FROM pg_foreign_table t, pg_foreign_server s, pg_foreign_data_wrapper w,
2674 pg_authid u, pg_namespace n, pg_class c
2675 WHERE w.oid = s.srvfdw
2676 AND u.oid = c.relowner
2677 AND (pg_has_role(c.relowner, 'USAGE')
2678 OR has_table_privilege(c.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER')
2679 OR has_any_column_privilege(c.oid, 'SELECT, INSERT, UPDATE, REFERENCES'))
2680 AND n.oid = c.relnamespace
2681 AND c.oid = t.ftrelid
2683 AND s.oid = t.ftserver;
2688 * FOREIGN_TABLE_OPTIONS view
2690 CREATE VIEW foreign_table_options AS
2691 SELECT foreign_table_catalog,
2692 foreign_table_schema,
2694 CAST((pg_options_to_table(t.ftoptions)).option_name AS sql_identifier) AS option_name,
2695 CAST((pg_options_to_table(t.ftoptions)).option_value AS character_data) AS option_value
2696 FROM _pg_foreign_tables t;
2698 GRANT SELECT ON TABLE foreign_table_options TO PUBLIC;
2703 * FOREIGN_TABLES view
2705 CREATE VIEW foreign_tables AS
2706 SELECT foreign_table_catalog,
2707 foreign_table_schema,
2709 foreign_server_catalog,
2711 FROM _pg_foreign_tables;
2713 GRANT SELECT ON foreign_tables TO PUBLIC;
2717 /* Base view for user mappings */
2718 CREATE VIEW _pg_user_mappings AS
2722 CAST(COALESCE(u.rolname,'PUBLIC') AS sql_identifier ) AS authorization_identifier,
2723 s.foreign_server_catalog,
2724 s.foreign_server_name,
2725 s.authorization_identifier AS srvowner
2726 FROM pg_user_mapping um LEFT JOIN pg_authid u ON (u.oid = um.umuser),
2727 _pg_foreign_servers s
2728 WHERE s.oid = um.umserver;
2733 * USER_MAPPING_OPTIONS view
2735 CREATE VIEW user_mapping_options AS
2736 SELECT authorization_identifier,
2737 foreign_server_catalog,
2738 foreign_server_name,
2739 CAST((pg_options_to_table(um.umoptions)).option_name AS sql_identifier) AS option_name,
2740 CAST(CASE WHEN (umuser <> 0 AND authorization_identifier = current_user)
2741 OR (umuser = 0 AND pg_has_role(srvowner, 'USAGE'))
2742 OR (SELECT rolsuper FROM pg_authid WHERE rolname = current_user) THEN (pg_options_to_table(um.umoptions)).option_value
2743 ELSE NULL END AS character_data) AS option_value
2744 FROM _pg_user_mappings um;
2746 GRANT SELECT ON user_mapping_options TO PUBLIC;
2751 * USER_MAPPINGS view
2753 CREATE VIEW user_mappings AS
2754 SELECT authorization_identifier,
2755 foreign_server_catalog,
2757 FROM _pg_user_mappings;
2759 GRANT SELECT ON user_mappings TO PUBLIC;