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('YES' AS yes_or_no) AS is_udt_dependent, -- FIXME?
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,
1866 CASE WHEN nc.oid = pg_my_temp_schema() THEN 'PRESERVE' -- FIXME
1868 AS character_data) AS commit_action
1870 FROM pg_namespace nc JOIN pg_class c ON (nc.oid = c.relnamespace)
1871 LEFT JOIN (pg_type t JOIN pg_namespace nt ON (t.typnamespace = nt.oid)) ON (c.reloftype = t.oid)
1873 WHERE c.relkind IN ('r', 'v', 'f')
1874 AND (NOT pg_is_other_temp_schema(nc.oid))
1875 AND (pg_has_role(c.relowner, 'USAGE')
1876 OR has_table_privilege(c.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER')
1877 OR has_any_column_privilege(c.oid, 'SELECT, INSERT, UPDATE, REFERENCES') );
1879 GRANT SELECT ON tables TO PUBLIC;
1887 -- feature not supported
1895 -- feature not supported
1900 * TRIGGERED_UPDATE_COLUMNS view
1903 CREATE VIEW triggered_update_columns AS
1904 SELECT CAST(current_database() AS sql_identifier) AS trigger_catalog,
1905 CAST(n.nspname AS sql_identifier) AS trigger_schema,
1906 CAST(t.tgname AS sql_identifier) AS trigger_name,
1907 CAST(current_database() AS sql_identifier) AS event_object_catalog,
1908 CAST(n.nspname AS sql_identifier) AS event_object_schema,
1909 CAST(c.relname AS sql_identifier) AS event_object_table,
1910 CAST(a.attname AS sql_identifier) AS event_object_column
1912 FROM pg_namespace n, pg_class c, pg_trigger t,
1913 (SELECT tgoid, (ta0.tgat).x AS tgattnum, (ta0.tgat).n AS tgattpos
1914 FROM (SELECT oid AS tgoid, information_schema._pg_expandarray(tgattr) AS tgat FROM pg_trigger) AS ta0) AS ta,
1917 WHERE n.oid = c.relnamespace
1918 AND c.oid = t.tgrelid
1919 AND t.oid = ta.tgoid
1920 AND (a.attrelid, a.attnum) = (t.tgrelid, ta.tgattnum)
1921 AND NOT t.tgisinternal
1922 AND (NOT pg_is_other_temp_schema(n.oid))
1923 AND (pg_has_role(c.relowner, 'USAGE')
1924 -- SELECT privilege omitted, per SQL standard
1925 OR has_column_privilege(c.oid, a.attnum, 'INSERT, UPDATE, REFERENCES') );
1927 GRANT SELECT ON triggered_update_columns TO PUBLIC;
1932 * TRIGGER_COLUMN_USAGE view
1935 -- not tracked by PostgreSQL
1940 * TRIGGER_ROUTINE_USAGE view
1943 -- not tracked by PostgreSQL
1948 * TRIGGER_SEQUENCE_USAGE view
1951 -- not tracked by PostgreSQL
1956 * TRIGGER_TABLE_USAGE view
1959 -- not tracked by PostgreSQL
1967 CREATE VIEW triggers AS
1968 SELECT CAST(current_database() AS sql_identifier) AS trigger_catalog,
1969 CAST(n.nspname AS sql_identifier) AS trigger_schema,
1970 CAST(t.tgname AS sql_identifier) AS trigger_name,
1971 CAST(em.text AS character_data) AS event_manipulation,
1972 CAST(current_database() AS sql_identifier) AS event_object_catalog,
1973 CAST(n.nspname AS sql_identifier) AS event_object_schema,
1974 CAST(c.relname AS sql_identifier) AS event_object_table,
1975 CAST(null AS cardinal_number) AS action_order,
1976 -- XXX strange hacks follow
1978 CASE WHEN pg_has_role(c.relowner, 'USAGE')
1979 THEN (SELECT m[1] FROM regexp_matches(pg_get_triggerdef(t.oid), E'.{35,} WHEN \\((.+)\\) EXECUTE PROCEDURE') AS rm(m) LIMIT 1)
1981 AS character_data) AS action_condition,
1983 substring(pg_get_triggerdef(t.oid) from
1984 position('EXECUTE PROCEDURE' in substring(pg_get_triggerdef(t.oid) from 48)) + 47)
1985 AS character_data) AS action_statement,
1987 -- hard-wired reference to TRIGGER_TYPE_ROW
1988 CASE t.tgtype & 1 WHEN 1 THEN 'ROW' ELSE 'STATEMENT' END
1989 AS character_data) AS action_orientation,
1991 -- hard-wired refs to TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_INSTEAD
1992 CASE t.tgtype & 66 WHEN 2 THEN 'BEFORE' WHEN 64 THEN 'INSTEAD OF' ELSE 'AFTER' END
1993 AS character_data) AS action_timing,
1994 CAST(null AS sql_identifier) AS action_reference_old_table,
1995 CAST(null AS sql_identifier) AS action_reference_new_table,
1996 CAST(null AS sql_identifier) AS action_reference_old_row,
1997 CAST(null AS sql_identifier) AS action_reference_new_row,
1998 CAST(null AS time_stamp) AS created
2000 FROM pg_namespace n, pg_class c, pg_trigger t,
2001 -- hard-wired refs to TRIGGER_TYPE_INSERT, TRIGGER_TYPE_DELETE,
2002 -- TRIGGER_TYPE_UPDATE; we intentionally omit TRIGGER_TYPE_TRUNCATE
2003 (VALUES (4, 'INSERT'),
2005 (16, 'UPDATE')) AS em (num, text)
2007 WHERE n.oid = c.relnamespace
2008 AND c.oid = t.tgrelid
2009 AND t.tgtype & em.num <> 0
2010 AND NOT t.tgisinternal
2011 AND (NOT pg_is_other_temp_schema(n.oid))
2012 AND (pg_has_role(c.relowner, 'USAGE')
2013 -- SELECT privilege omitted, per SQL standard
2014 OR has_table_privilege(c.oid, 'INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER')
2015 OR has_any_column_privilege(c.oid, 'INSERT, UPDATE, REFERENCES') );
2017 GRANT SELECT ON triggers TO PUBLIC;
2022 * UDT_PRIVILEGES view
2025 CREATE VIEW udt_privileges AS
2026 SELECT CAST(null AS sql_identifier) AS grantor,
2027 CAST('PUBLIC' AS sql_identifier) AS grantee,
2028 CAST(current_database() AS sql_identifier) AS udt_catalog,
2029 CAST(n.nspname AS sql_identifier) AS udt_schema,
2030 CAST(t.typname AS sql_identifier) AS udt_name,
2031 CAST('TYPE USAGE' AS character_data) AS privilege_type, -- sic
2032 CAST('NO' AS yes_or_no) AS is_grantable
2034 FROM pg_authid u, pg_namespace n, pg_type t
2036 WHERE u.oid = t.typowner
2037 AND n.oid = t.typnamespace
2038 AND t.typtype <> 'd'
2039 AND NOT (t.typelem <> 0 AND t.typlen = -1);
2041 GRANT SELECT ON udt_privileges TO PUBLIC;
2046 * ROLE_UDT_GRANTS view
2049 CREATE VIEW role_udt_grants AS
2058 WHERE grantor IN (SELECT role_name FROM enabled_roles)
2059 OR grantee IN (SELECT role_name FROM enabled_roles);
2061 GRANT SELECT ON role_udt_grants TO PUBLIC;
2066 * USAGE_PRIVILEGES view
2069 CREATE VIEW usage_privileges AS
2072 -- Collations have no real privileges, so we represent all collations with implicit usage privilege here.
2073 SELECT CAST(u.rolname AS sql_identifier) AS grantor,
2074 CAST('PUBLIC' AS sql_identifier) AS grantee,
2075 CAST(current_database() AS sql_identifier) AS object_catalog,
2076 CAST(n.nspname AS sql_identifier) AS object_schema,
2077 CAST(c.collname AS sql_identifier) AS object_name,
2078 CAST('COLLATION' AS character_data) AS object_type,
2079 CAST('USAGE' AS character_data) AS privilege_type,
2080 CAST('NO' AS yes_or_no) AS is_grantable
2086 WHERE u.oid = c.collowner
2087 AND c.collnamespace = n.oid
2088 AND collencoding IN (-1, (SELECT encoding FROM pg_database WHERE datname = current_database()))
2093 -- Domains have no real privileges, so we represent all domains with implicit usage privilege here.
2094 SELECT CAST(u.rolname AS sql_identifier) AS grantor,
2095 CAST('PUBLIC' AS sql_identifier) AS grantee,
2096 CAST(current_database() AS sql_identifier) AS object_catalog,
2097 CAST(n.nspname AS sql_identifier) AS object_schema,
2098 CAST(t.typname AS sql_identifier) AS object_name,
2099 CAST('DOMAIN' AS character_data) AS object_type,
2100 CAST('USAGE' AS character_data) AS privilege_type,
2101 CAST('NO' AS yes_or_no) AS is_grantable
2107 WHERE u.oid = t.typowner
2108 AND t.typnamespace = n.oid
2113 /* foreign-data wrappers */
2114 SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor,
2115 CAST(grantee.rolname AS sql_identifier) AS grantee,
2116 CAST(current_database() AS sql_identifier) AS object_catalog,
2117 CAST('' AS sql_identifier) AS object_schema,
2118 CAST(fdw.fdwname AS sql_identifier) AS object_name,
2119 CAST('FOREIGN DATA WRAPPER' AS character_data) AS object_type,
2120 CAST('USAGE' AS character_data) AS privilege_type,
2123 -- object owner always has grant options
2124 pg_has_role(grantee.oid, fdw.fdwowner, 'USAGE')
2126 THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable
2129 SELECT fdwname, fdwowner, (aclexplode(fdwacl)).* FROM pg_foreign_data_wrapper
2130 ) AS fdw (fdwname, fdwowner, grantor, grantee, prtype, grantable),
2131 pg_authid u_grantor,
2133 SELECT oid, rolname FROM pg_authid
2135 SELECT 0::oid, 'PUBLIC'
2136 ) AS grantee (oid, rolname)
2138 WHERE u_grantor.oid = fdw.grantor
2139 AND grantee.oid = fdw.grantee
2140 AND fdw.prtype IN ('USAGE')
2141 AND (pg_has_role(u_grantor.oid, 'USAGE')
2142 OR pg_has_role(grantee.oid, 'USAGE')
2143 OR grantee.rolname = 'PUBLIC')
2147 /* foreign servers */
2148 SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor,
2149 CAST(grantee.rolname AS sql_identifier) AS grantee,
2150 CAST(current_database() AS sql_identifier) AS object_catalog,
2151 CAST('' AS sql_identifier) AS object_schema,
2152 CAST(srv.srvname AS sql_identifier) AS object_name,
2153 CAST('FOREIGN SERVER' AS character_data) AS object_type,
2154 CAST('USAGE' AS character_data) AS privilege_type,
2157 -- object owner always has grant options
2158 pg_has_role(grantee.oid, srv.srvowner, 'USAGE')
2160 THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable
2163 SELECT srvname, srvowner, (aclexplode(srvacl)).* FROM pg_foreign_server
2164 ) AS srv (srvname, srvowner, grantor, grantee, prtype, grantable),
2165 pg_authid u_grantor,
2167 SELECT oid, rolname FROM pg_authid
2169 SELECT 0::oid, 'PUBLIC'
2170 ) AS grantee (oid, rolname)
2172 WHERE u_grantor.oid = srv.grantor
2173 AND grantee.oid = srv.grantee
2174 AND srv.prtype IN ('USAGE')
2175 AND (pg_has_role(u_grantor.oid, 'USAGE')
2176 OR pg_has_role(grantee.oid, 'USAGE')
2177 OR grantee.rolname = 'PUBLIC');
2179 GRANT SELECT ON usage_privileges TO PUBLIC;
2184 * ROLE_USAGE_GRANTS view
2187 CREATE VIEW role_usage_grants AS
2196 FROM usage_privileges
2197 WHERE grantor IN (SELECT role_name FROM enabled_roles)
2198 OR grantee IN (SELECT role_name FROM enabled_roles);
2200 GRANT SELECT ON role_usage_grants TO PUBLIC;
2205 * USER_DEFINED_TYPES view
2208 CREATE VIEW user_defined_types AS
2209 SELECT CAST(current_database() AS sql_identifier) AS user_defined_type_catalog,
2210 CAST(n.nspname AS sql_identifier) AS user_defined_type_schema,
2211 CAST(c.relname AS sql_identifier) AS user_defined_type_name,
2212 CAST('STRUCTURED' AS character_data) AS user_defined_type_category,
2213 CAST('YES' AS yes_or_no) AS is_instantiable,
2214 CAST(null AS yes_or_no) AS is_final,
2215 CAST(null AS character_data) AS ordering_form,
2216 CAST(null AS character_data) AS ordering_category,
2217 CAST(null AS sql_identifier) AS ordering_routine_catalog,
2218 CAST(null AS sql_identifier) AS ordering_routine_schema,
2219 CAST(null AS sql_identifier) AS ordering_routine_name,
2220 CAST(null AS character_data) AS reference_type,
2221 CAST(null AS character_data) AS data_type,
2222 CAST(null AS cardinal_number) AS character_maximum_length,
2223 CAST(null AS cardinal_number) AS character_octet_length,
2224 CAST(null AS sql_identifier) AS character_set_catalog,
2225 CAST(null AS sql_identifier) AS character_set_schema,
2226 CAST(null AS sql_identifier) AS character_set_name,
2227 CAST(null AS sql_identifier) AS collation_catalog,
2228 CAST(null AS sql_identifier) AS collation_schema,
2229 CAST(null AS sql_identifier) AS collation_name,
2230 CAST(null AS cardinal_number) AS numeric_precision,
2231 CAST(null AS cardinal_number) AS numeric_precision_radix,
2232 CAST(null AS cardinal_number) AS numeric_scale,
2233 CAST(null AS cardinal_number) AS datetime_precision,
2234 CAST(null AS character_data) AS interval_type,
2235 CAST(null AS cardinal_number) AS interval_precision,
2236 CAST(null AS sql_identifier) AS source_dtd_identifier,
2237 CAST(null AS sql_identifier) AS ref_dtd_identifier
2239 FROM pg_namespace n, pg_class c
2241 WHERE n.oid = c.relnamespace
2242 AND c.relkind = 'c';
2244 GRANT SELECT ON user_defined_types TO PUBLIC;
2252 CREATE VIEW view_column_usage AS
2254 CAST(current_database() AS sql_identifier) AS view_catalog,
2255 CAST(nv.nspname AS sql_identifier) AS view_schema,
2256 CAST(v.relname AS sql_identifier) AS view_name,
2257 CAST(current_database() AS sql_identifier) AS table_catalog,
2258 CAST(nt.nspname AS sql_identifier) AS table_schema,
2259 CAST(t.relname AS sql_identifier) AS table_name,
2260 CAST(a.attname AS sql_identifier) AS column_name
2262 FROM pg_namespace nv, pg_class v, pg_depend dv,
2263 pg_depend dt, pg_class t, pg_namespace nt,
2266 WHERE nv.oid = v.relnamespace
2268 AND v.oid = dv.refobjid
2269 AND dv.refclassid = 'pg_catalog.pg_class'::regclass
2270 AND dv.classid = 'pg_catalog.pg_rewrite'::regclass
2271 AND dv.deptype = 'i'
2272 AND dv.objid = dt.objid
2273 AND dv.refobjid <> dt.refobjid
2274 AND dt.classid = 'pg_catalog.pg_rewrite'::regclass
2275 AND dt.refclassid = 'pg_catalog.pg_class'::regclass
2276 AND dt.refobjid = t.oid
2277 AND t.relnamespace = nt.oid
2278 AND t.relkind IN ('r', 'v', 'f')
2279 AND t.oid = a.attrelid
2280 AND dt.refobjsubid = a.attnum
2281 AND pg_has_role(t.relowner, 'USAGE');
2283 GRANT SELECT ON view_column_usage TO PUBLIC;
2288 * VIEW_ROUTINE_USAGE
2291 CREATE VIEW view_routine_usage AS
2293 CAST(current_database() AS sql_identifier) AS table_catalog,
2294 CAST(nv.nspname AS sql_identifier) AS table_schema,
2295 CAST(v.relname AS sql_identifier) AS table_name,
2296 CAST(current_database() AS sql_identifier) AS specific_catalog,
2297 CAST(np.nspname AS sql_identifier) AS specific_schema,
2298 CAST(p.proname || '_' || CAST(p.oid AS text) AS sql_identifier) AS specific_name
2300 FROM pg_namespace nv, pg_class v, pg_depend dv,
2301 pg_depend dp, pg_proc p, pg_namespace np
2303 WHERE nv.oid = v.relnamespace
2305 AND v.oid = dv.refobjid
2306 AND dv.refclassid = 'pg_catalog.pg_class'::regclass
2307 AND dv.classid = 'pg_catalog.pg_rewrite'::regclass
2308 AND dv.deptype = 'i'
2309 AND dv.objid = dp.objid
2310 AND dp.classid = 'pg_catalog.pg_rewrite'::regclass
2311 AND dp.refclassid = 'pg_catalog.pg_proc'::regclass
2312 AND dp.refobjid = p.oid
2313 AND p.pronamespace = np.oid
2314 AND pg_has_role(p.proowner, 'USAGE');
2316 GRANT SELECT ON view_routine_usage TO PUBLIC;
2324 CREATE VIEW view_table_usage AS
2326 CAST(current_database() AS sql_identifier) AS view_catalog,
2327 CAST(nv.nspname AS sql_identifier) AS view_schema,
2328 CAST(v.relname AS sql_identifier) AS view_name,
2329 CAST(current_database() AS sql_identifier) AS table_catalog,
2330 CAST(nt.nspname AS sql_identifier) AS table_schema,
2331 CAST(t.relname AS sql_identifier) AS table_name
2333 FROM pg_namespace nv, pg_class v, pg_depend dv,
2334 pg_depend dt, pg_class t, pg_namespace nt
2336 WHERE nv.oid = v.relnamespace
2338 AND v.oid = dv.refobjid
2339 AND dv.refclassid = 'pg_catalog.pg_class'::regclass
2340 AND dv.classid = 'pg_catalog.pg_rewrite'::regclass
2341 AND dv.deptype = 'i'
2342 AND dv.objid = dt.objid
2343 AND dv.refobjid <> dt.refobjid
2344 AND dt.classid = 'pg_catalog.pg_rewrite'::regclass
2345 AND dt.refclassid = 'pg_catalog.pg_class'::regclass
2346 AND dt.refobjid = t.oid
2347 AND t.relnamespace = nt.oid
2348 AND t.relkind IN ('r', 'v', 'f')
2349 AND pg_has_role(t.relowner, 'USAGE');
2351 GRANT SELECT ON view_table_usage TO PUBLIC;
2359 CREATE VIEW views AS
2360 SELECT CAST(current_database() AS sql_identifier) AS table_catalog,
2361 CAST(nc.nspname AS sql_identifier) AS table_schema,
2362 CAST(c.relname AS sql_identifier) AS table_name,
2365 CASE WHEN pg_has_role(c.relowner, 'USAGE')
2366 THEN pg_get_viewdef(c.oid)
2368 AS character_data) AS view_definition,
2370 CAST('NONE' AS character_data) AS check_option,
2373 CASE WHEN EXISTS (SELECT 1 FROM pg_rewrite WHERE ev_class = c.oid AND ev_type = '2' AND is_instead)
2374 AND EXISTS (SELECT 1 FROM pg_rewrite WHERE ev_class = c.oid AND ev_type = '4' AND is_instead)
2375 THEN 'YES' ELSE 'NO' END
2376 AS yes_or_no) AS is_updatable,
2379 CASE WHEN EXISTS (SELECT 1 FROM pg_rewrite WHERE ev_class = c.oid AND ev_type = '3' AND is_instead)
2380 THEN 'YES' ELSE 'NO' END
2381 AS yes_or_no) AS is_insertable_into,
2384 -- TRIGGER_TYPE_ROW + TRIGGER_TYPE_INSTEAD + TRIGGER_TYPE_UPDATE
2385 CASE WHEN EXISTS (SELECT 1 FROM pg_trigger WHERE tgrelid = c.oid AND tgtype & 81 = 81)
2386 THEN 'YES' ELSE 'NO' END
2387 AS yes_or_no) AS is_trigger_updatable,
2390 -- TRIGGER_TYPE_ROW + TRIGGER_TYPE_INSTEAD + TRIGGER_TYPE_DELETE
2391 CASE WHEN EXISTS (SELECT 1 FROM pg_trigger WHERE tgrelid = c.oid AND tgtype & 73 = 73)
2392 THEN 'YES' ELSE 'NO' END
2393 AS yes_or_no) AS is_trigger_deletable,
2396 -- TRIGGER_TYPE_ROW + TRIGGER_TYPE_INSTEAD + TRIGGER_TYPE_INSERT
2397 CASE WHEN EXISTS (SELECT 1 FROM pg_trigger WHERE tgrelid = c.oid AND tgtype & 69 = 69)
2398 THEN 'YES' ELSE 'NO' END
2399 AS yes_or_no) AS is_trigger_insertable_into
2401 FROM pg_namespace nc, pg_class c
2403 WHERE c.relnamespace = nc.oid
2405 AND (NOT pg_is_other_temp_schema(nc.oid))
2406 AND (pg_has_role(c.relowner, 'USAGE')
2407 OR has_table_privilege(c.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER')
2408 OR has_any_column_privilege(c.oid, 'SELECT, INSERT, UPDATE, REFERENCES') );
2410 GRANT SELECT ON views TO PUBLIC;
2413 -- The following views have dependencies that force them to appear out of order.
2417 * DATA_TYPE_PRIVILEGES view
2420 CREATE VIEW data_type_privileges AS
2421 SELECT CAST(current_database() AS sql_identifier) AS object_catalog,
2422 CAST(x.objschema AS sql_identifier) AS object_schema,
2423 CAST(x.objname AS sql_identifier) AS object_name,
2424 CAST(x.objtype AS character_data) AS object_type,
2425 CAST(x.objdtdid AS sql_identifier) AS dtd_identifier
2429 SELECT udt_schema, udt_name, 'USER-DEFINED TYPE'::text, dtd_identifier FROM attributes
2431 SELECT table_schema, table_name, 'TABLE'::text, dtd_identifier FROM columns
2433 SELECT domain_schema, domain_name, 'DOMAIN'::text, dtd_identifier FROM domains
2435 SELECT specific_schema, specific_name, 'ROUTINE'::text, dtd_identifier FROM parameters
2437 SELECT specific_schema, specific_name, 'ROUTINE'::text, dtd_identifier FROM routines
2438 ) AS x (objschema, objname, objtype, objdtdid);
2440 GRANT SELECT ON data_type_privileges TO PUBLIC;
2445 * ELEMENT_TYPES view
2448 CREATE VIEW element_types AS
2449 SELECT CAST(current_database() AS sql_identifier) AS object_catalog,
2450 CAST(n.nspname AS sql_identifier) AS object_schema,
2451 CAST(x.objname AS sql_identifier) AS object_name,
2452 CAST(x.objtype AS character_data) AS object_type,
2453 CAST(x.objdtdid AS sql_identifier) AS collection_type_identifier,
2455 CASE WHEN nbt.nspname = 'pg_catalog' THEN format_type(bt.oid, null)
2456 ELSE 'USER-DEFINED' END AS character_data) AS data_type,
2458 CAST(null AS cardinal_number) AS character_maximum_length,
2459 CAST(null AS cardinal_number) AS character_octet_length,
2460 CAST(null AS sql_identifier) AS character_set_catalog,
2461 CAST(null AS sql_identifier) AS character_set_schema,
2462 CAST(null AS sql_identifier) AS character_set_name,
2463 CAST(CASE WHEN nco.nspname IS NOT NULL THEN current_database() END AS sql_identifier) AS collation_catalog,
2464 CAST(nco.nspname AS sql_identifier) AS collation_schema,
2465 CAST(co.collname AS sql_identifier) AS collation_name,
2466 CAST(null AS cardinal_number) AS numeric_precision,
2467 CAST(null AS cardinal_number) AS numeric_precision_radix,
2468 CAST(null AS cardinal_number) AS numeric_scale,
2469 CAST(null AS cardinal_number) AS datetime_precision,
2470 CAST(null AS character_data) AS interval_type,
2471 CAST(null AS cardinal_number) AS interval_precision,
2473 CAST(null AS character_data) AS domain_default, -- XXX maybe a bug in the standard
2475 CAST(current_database() AS sql_identifier) AS udt_catalog,
2476 CAST(nbt.nspname AS sql_identifier) AS udt_schema,
2477 CAST(bt.typname AS sql_identifier) AS udt_name,
2479 CAST(null AS sql_identifier) AS scope_catalog,
2480 CAST(null AS sql_identifier) AS scope_schema,
2481 CAST(null AS sql_identifier) AS scope_name,
2483 CAST(null AS cardinal_number) AS maximum_cardinality,
2484 CAST('a' || CAST(x.objdtdid AS text) AS sql_identifier) AS dtd_identifier
2486 FROM pg_namespace n, pg_type at, pg_namespace nbt, pg_type bt,
2488 /* columns, attributes */
2489 SELECT c.relnamespace, CAST(c.relname AS sql_identifier),
2490 CASE WHEN c.relkind = 'c' THEN 'USER-DEFINED TYPE'::text ELSE 'TABLE'::text END,
2491 a.attnum, a.atttypid, a.attcollation
2492 FROM pg_class c, pg_attribute a
2493 WHERE c.oid = a.attrelid
2494 AND c.relkind IN ('r', 'v', 'f', 'c')
2495 AND attnum > 0 AND NOT attisdropped
2500 SELECT t.typnamespace, CAST(t.typname AS sql_identifier),
2501 'DOMAIN'::text, 1, t.typbasetype, t.typcollation
2503 WHERE t.typtype = 'd'
2508 SELECT pronamespace, CAST(proname || '_' || CAST(oid AS text) AS sql_identifier),
2509 'ROUTINE'::text, (ss.x).n, (ss.x).x, 0
2510 FROM (SELECT p.pronamespace, p.proname, p.oid,
2511 _pg_expandarray(coalesce(p.proallargtypes, p.proargtypes::oid[])) AS x
2512 FROM pg_proc p) AS ss
2517 SELECT p.pronamespace, CAST(p.proname || '_' || CAST(p.oid AS text) AS sql_identifier),
2518 'ROUTINE'::text, 0, p.prorettype, 0
2521 ) AS x (objschema, objname, objtype, objdtdid, objtypeid, objcollation)
2522 LEFT JOIN (pg_collation co JOIN pg_namespace nco ON (co.collnamespace = nco.oid))
2523 ON x.objcollation = co.oid AND (nco.nspname, co.collname) <> ('pg_catalog', 'default')
2525 WHERE n.oid = x.objschema
2526 AND at.oid = x.objtypeid
2527 AND (at.typelem <> 0 AND at.typlen = -1)
2528 AND at.typelem = bt.oid
2529 AND nbt.oid = bt.typnamespace
2531 AND (n.nspname, x.objname, x.objtype, CAST(x.objdtdid AS sql_identifier)) IN
2532 ( SELECT object_schema, object_name, object_type, dtd_identifier
2533 FROM data_type_privileges );
2535 GRANT SELECT ON element_types TO PUBLIC;
2538 -- SQL/MED views; these use section numbers from part 9 of the standard.
2540 /* Base view for foreign-data wrappers */
2541 CREATE VIEW _pg_foreign_data_wrappers AS
2545 CAST(current_database() AS sql_identifier) AS foreign_data_wrapper_catalog,
2546 CAST(fdwname AS sql_identifier) AS foreign_data_wrapper_name,
2547 CAST(u.rolname AS sql_identifier) AS authorization_identifier,
2548 CAST('c' AS character_data) AS foreign_data_wrapper_language
2549 FROM pg_foreign_data_wrapper w, pg_authid u
2550 WHERE u.oid = w.fdwowner
2551 AND (pg_has_role(fdwowner, 'USAGE')
2552 OR has_foreign_data_wrapper_privilege(w.oid, 'USAGE'));
2557 * FOREIGN_DATA_WRAPPER_OPTIONS view
2559 CREATE VIEW foreign_data_wrapper_options AS
2560 SELECT foreign_data_wrapper_catalog,
2561 foreign_data_wrapper_name,
2562 CAST((pg_options_to_table(w.fdwoptions)).option_name AS sql_identifier) AS option_name,
2563 CAST((pg_options_to_table(w.fdwoptions)).option_value AS character_data) AS option_value
2564 FROM _pg_foreign_data_wrappers w;
2566 GRANT SELECT ON foreign_data_wrapper_options TO PUBLIC;
2571 * FOREIGN_DATA_WRAPPERS view
2573 CREATE VIEW foreign_data_wrappers AS
2574 SELECT foreign_data_wrapper_catalog,
2575 foreign_data_wrapper_name,
2576 authorization_identifier,
2577 CAST(NULL AS character_data) AS library_name,
2578 foreign_data_wrapper_language
2579 FROM _pg_foreign_data_wrappers w;
2581 GRANT SELECT ON foreign_data_wrappers TO PUBLIC;
2584 /* Base view for foreign servers */
2585 CREATE VIEW _pg_foreign_servers AS
2588 CAST(current_database() AS sql_identifier) AS foreign_server_catalog,
2589 CAST(srvname AS sql_identifier) AS foreign_server_name,
2590 CAST(current_database() AS sql_identifier) AS foreign_data_wrapper_catalog,
2591 CAST(w.fdwname AS sql_identifier) AS foreign_data_wrapper_name,
2592 CAST(srvtype AS character_data) AS foreign_server_type,
2593 CAST(srvversion AS character_data) AS foreign_server_version,
2594 CAST(u.rolname AS sql_identifier) AS authorization_identifier
2595 FROM pg_foreign_server s, pg_foreign_data_wrapper w, pg_authid u
2596 WHERE w.oid = s.srvfdw
2597 AND u.oid = s.srvowner
2598 AND (pg_has_role(s.srvowner, 'USAGE')
2599 OR has_server_privilege(s.oid, 'USAGE'));
2604 * FOREIGN_SERVER_OPTIONS view
2606 CREATE VIEW foreign_server_options AS
2607 SELECT foreign_server_catalog,
2608 foreign_server_name,
2609 CAST((pg_options_to_table(s.srvoptions)).option_name AS sql_identifier) AS option_name,
2610 CAST((pg_options_to_table(s.srvoptions)).option_value AS character_data) AS option_value
2611 FROM _pg_foreign_servers s;
2613 GRANT SELECT ON TABLE foreign_server_options TO PUBLIC;
2618 * FOREIGN_SERVERS view
2620 CREATE VIEW foreign_servers AS
2621 SELECT foreign_server_catalog,
2622 foreign_server_name,
2623 foreign_data_wrapper_catalog,
2624 foreign_data_wrapper_name,
2625 foreign_server_type,
2626 foreign_server_version,
2627 authorization_identifier
2628 FROM _pg_foreign_servers;
2630 GRANT SELECT ON foreign_servers TO PUBLIC;
2633 /* Base view for foreign tables */
2634 CREATE VIEW _pg_foreign_tables AS
2636 CAST(current_database() AS sql_identifier) AS foreign_table_catalog,
2637 n.nspname AS foreign_table_schema,
2638 c.relname AS foreign_table_name,
2639 t.ftoptions AS ftoptions,
2640 CAST(current_database() AS sql_identifier) AS foreign_server_catalog,
2641 CAST(srvname AS sql_identifier) AS foreign_server_name,
2642 CAST(u.rolname AS sql_identifier) AS authorization_identifier
2643 FROM pg_foreign_table t, pg_foreign_server s, pg_foreign_data_wrapper w,
2644 pg_authid u, pg_namespace n, pg_class c
2645 WHERE w.oid = s.srvfdw
2646 AND u.oid = c.relowner
2647 AND (pg_has_role(c.relowner, 'USAGE')
2648 OR has_table_privilege(c.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER')
2649 OR has_any_column_privilege(c.oid, 'SELECT, INSERT, UPDATE, REFERENCES'))
2650 AND n.oid = c.relnamespace
2651 AND c.oid = t.ftrelid
2653 AND s.oid = t.ftserver;
2658 * FOREIGN_TABLE_OPTIONS view
2660 CREATE VIEW foreign_table_options AS
2661 SELECT foreign_table_catalog,
2662 foreign_table_schema,
2664 CAST((pg_options_to_table(t.ftoptions)).option_name AS sql_identifier) AS option_name,
2665 CAST((pg_options_to_table(t.ftoptions)).option_value AS character_data) AS option_value
2666 FROM _pg_foreign_tables t;
2668 GRANT SELECT ON TABLE foreign_table_options TO PUBLIC;
2673 * FOREIGN_TABLES view
2675 CREATE VIEW foreign_tables AS
2676 SELECT foreign_table_catalog,
2677 foreign_table_schema,
2679 foreign_server_catalog,
2681 FROM _pg_foreign_tables;
2683 GRANT SELECT ON foreign_tables TO PUBLIC;
2687 /* Base view for user mappings */
2688 CREATE VIEW _pg_user_mappings AS
2692 CAST(COALESCE(u.rolname,'PUBLIC') AS sql_identifier ) AS authorization_identifier,
2693 s.foreign_server_catalog,
2694 s.foreign_server_name,
2695 s.authorization_identifier AS srvowner
2696 FROM pg_user_mapping um LEFT JOIN pg_authid u ON (u.oid = um.umuser),
2697 _pg_foreign_servers s
2698 WHERE s.oid = um.umserver;
2703 * USER_MAPPING_OPTIONS view
2705 CREATE VIEW user_mapping_options AS
2706 SELECT authorization_identifier,
2707 foreign_server_catalog,
2708 foreign_server_name,
2709 CAST((pg_options_to_table(um.umoptions)).option_name AS sql_identifier) AS option_name,
2710 CAST(CASE WHEN (umuser <> 0 AND authorization_identifier = current_user)
2711 OR (umuser = 0 AND pg_has_role(srvowner, 'USAGE'))
2712 OR (SELECT rolsuper FROM pg_authid WHERE rolname = current_user) THEN (pg_options_to_table(um.umoptions)).option_value
2713 ELSE NULL END AS character_data) AS option_value
2714 FROM _pg_user_mappings um;
2716 GRANT SELECT ON user_mapping_options TO PUBLIC;
2721 * USER_MAPPINGS view
2723 CREATE VIEW user_mappings AS
2724 SELECT authorization_identifier,
2725 foreign_server_catalog,
2727 FROM _pg_user_mappings;
2729 GRANT SELECT ON user_mappings TO PUBLIC;