]> granicus.if.org Git - postgresql/blob - src/backend/catalog/information_schema.sql
Information schema views for collation support
[postgresql] / src / backend / catalog / information_schema.sql
1 /*
2  * SQL Information Schema
3  * as defined in ISO/IEC 9075-11:2008
4  *
5  * Copyright (c) 2003-2011, PostgreSQL Global Development Group
6  *
7  * src/backend/catalog/information_schema.sql
8  */
9
10 /*
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.
17  */
18
19
20 /*
21  * 5.1
22  * INFORMATION_SCHEMA schema
23  */
24
25 CREATE SCHEMA information_schema;
26 GRANT USAGE ON SCHEMA information_schema TO PUBLIC;
27 SET search_path TO information_schema;
28
29
30 /*
31  * A few supporting functions first ...
32  */
33
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)
36     RETURNS SETOF RECORD
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),
41                                         1) as g(s)';
42
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';
46
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
51     AS $$
52 SELECT (ss.a).n FROM
53   (SELECT information_schema._pg_expandarray(indkey) AS a
54    FROM pg_catalog.pg_index WHERE indexrelid = $1) ss
55   WHERE (ss.a).x = $2;
56 $$;
57
58 CREATE FUNCTION _pg_truetypid(pg_attribute, pg_type) RETURNS oid
59     LANGUAGE sql
60     IMMUTABLE
61     RETURNS NULL ON NULL INPUT
62     AS
63 $$SELECT CASE WHEN $2.typtype = 'd' THEN $2.typbasetype ELSE $1.atttypid END$$;
64
65 CREATE FUNCTION _pg_truetypmod(pg_attribute, pg_type) RETURNS int4
66     LANGUAGE sql
67     IMMUTABLE
68     RETURNS NULL ON NULL INPUT
69     AS
70 $$SELECT CASE WHEN $2.typtype = 'd' THEN $2.typtypmod ELSE $1.atttypmod END$$;
71
72 -- these functions encapsulate knowledge about the encoding of typmod:
73
74 CREATE FUNCTION _pg_char_max_length(typid oid, typmod int4) RETURNS integer
75     LANGUAGE sql
76     IMMUTABLE
77     RETURNS NULL ON NULL INPUT
78     AS
79 $$SELECT
80   CASE WHEN $2 = -1 /* default typmod */
81        THEN null
82        WHEN $1 IN (1042, 1043) /* char, varchar */
83        THEN $2 - 4
84        WHEN $1 IN (1560, 1562) /* bit, varbit */
85        THEN $2
86        ELSE null
87   END$$;
88
89 CREATE FUNCTION _pg_char_octet_length(typid oid, typmod int4) RETURNS integer
90     LANGUAGE sql
91     IMMUTABLE
92     RETURNS NULL ON NULL INPUT
93     AS
94 $$SELECT
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()))
100             END
101        ELSE null
102   END$$;
103
104 CREATE FUNCTION _pg_numeric_precision(typid oid, typmod int4) RETURNS integer
105     LANGUAGE sql
106     IMMUTABLE
107     RETURNS NULL ON NULL INPUT
108     AS
109 $$SELECT
110   CASE $1
111          WHEN 21 /*int2*/ THEN 16
112          WHEN 23 /*int4*/ THEN 32
113          WHEN 20 /*int8*/ THEN 64
114          WHEN 1700 /*numeric*/ THEN
115               CASE WHEN $2 = -1
116                    THEN null
117                    ELSE (($2 - 4) >> 16) & 65535
118                    END
119          WHEN 700 /*float4*/ THEN 24 /*FLT_MANT_DIG*/
120          WHEN 701 /*float8*/ THEN 53 /*DBL_MANT_DIG*/
121          ELSE null
122   END$$;
123
124 CREATE FUNCTION _pg_numeric_precision_radix(typid oid, typmod int4) RETURNS integer
125     LANGUAGE sql
126     IMMUTABLE
127     RETURNS NULL ON NULL INPUT
128     AS
129 $$SELECT
130   CASE WHEN $1 IN (21, 23, 20, 700, 701) THEN 2
131        WHEN $1 IN (1700) THEN 10
132        ELSE null
133   END$$;
134
135 CREATE FUNCTION _pg_numeric_scale(typid oid, typmod int4) RETURNS integer
136     LANGUAGE sql
137     IMMUTABLE
138     RETURNS NULL ON NULL INPUT
139     AS
140 $$SELECT
141   CASE WHEN $1 IN (21, 23, 20) THEN 0
142        WHEN $1 IN (1700) THEN
143             CASE WHEN $2 = -1
144                  THEN null
145                  ELSE ($2 - 4) & 65535
146                  END
147        ELSE null
148   END$$;
149
150 CREATE FUNCTION _pg_datetime_precision(typid oid, typmod int4) RETURNS integer
151     LANGUAGE sql
152     IMMUTABLE
153     RETURNS NULL ON NULL INPUT
154     AS
155 $$SELECT
156   CASE WHEN $1 IN (1082) /* date */
157            THEN 0
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 THEN 6 ELSE $2 & 65535 END
162        ELSE null
163   END$$;
164
165
166 -- 5.2 INFORMATION_SCHEMA_CATALOG_NAME view appears later.
167
168
169 /*
170  * 5.3
171  * CARDINAL_NUMBER domain
172  */
173
174 CREATE DOMAIN cardinal_number AS integer
175     CONSTRAINT cardinal_number_domain_check CHECK (value >= 0);
176
177
178 /*
179  * 5.4
180  * CHARACTER_DATA domain
181  */
182
183 CREATE DOMAIN character_data AS character varying;
184
185
186 /*
187  * 5.5
188  * SQL_IDENTIFIER domain
189  */
190
191 CREATE DOMAIN sql_identifier AS character varying;
192
193
194 /*
195  * 5.2
196  * INFORMATION_SCHEMA_CATALOG_NAME view
197  */
198
199 CREATE VIEW information_schema_catalog_name AS
200     SELECT CAST(current_database() AS sql_identifier) AS catalog_name;
201
202 GRANT SELECT ON information_schema_catalog_name TO PUBLIC;
203
204
205 /*
206  * 5.6
207  * TIME_STAMP domain
208  */
209
210 CREATE DOMAIN time_stamp AS timestamp(2) with time zone
211     DEFAULT current_timestamp(2);
212
213 /*
214  * 5.7
215  * YES_OR_NO domain
216  */
217
218 CREATE DOMAIN yes_or_no AS character varying(3)
219     CONSTRAINT yes_or_no_check CHECK (value IN ('YES', 'NO'));
220
221
222 -- 5.8 ADMINISTRABLE_ROLE_AUTHORIZATIONS view appears later.
223
224
225 /*
226  * 5.9
227  * APPLICABLE_ROLES view
228  */
229
230 CREATE VIEW applicable_roles AS
231     SELECT CAST(a.rolname AS sql_identifier) AS grantee,
232            CAST(b.rolname AS sql_identifier) AS role_name,
233            CAST(CASE WHEN m.admin_option THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable
234     FROM pg_auth_members m
235          JOIN pg_authid a ON (m.member = a.oid)
236          JOIN pg_authid b ON (m.roleid = b.oid)
237     WHERE pg_has_role(a.oid, 'USAGE');
238
239 GRANT SELECT ON applicable_roles TO PUBLIC;
240
241
242 /*
243  * 5.8
244  * ADMINISTRABLE_ROLE_AUTHORIZATIONS view
245  */
246
247 CREATE VIEW administrable_role_authorizations AS
248     SELECT *
249     FROM applicable_roles
250     WHERE is_grantable = 'YES';
251
252 GRANT SELECT ON administrable_role_authorizations TO PUBLIC;
253
254
255 /*
256  * 5.10
257  * ASSERTIONS view
258  */
259
260 -- feature not supported
261
262
263 /*
264  * 5.11
265  * ATTRIBUTES view
266  */
267
268 CREATE VIEW attributes AS
269     SELECT CAST(current_database() AS sql_identifier) AS udt_catalog,
270            CAST(nc.nspname AS sql_identifier) AS udt_schema,
271            CAST(c.relname AS sql_identifier) AS udt_name,
272            CAST(a.attname AS sql_identifier) AS attribute_name,
273            CAST(a.attnum AS cardinal_number) AS ordinal_position,
274            CAST(pg_get_expr(ad.adbin, ad.adrelid) AS character_data) AS attribute_default,
275            CAST(CASE WHEN a.attnotnull OR (t.typtype = 'd' AND t.typnotnull) THEN 'NO' ELSE 'YES' END
276              AS yes_or_no)
277              AS is_nullable,
278
279            CAST(
280              CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'ARRAY'
281                   WHEN nt.nspname = 'pg_catalog' THEN format_type(a.atttypid, null)
282                   ELSE 'USER-DEFINED' END
283              AS character_data)
284              AS data_type,
285
286            CAST(
287              _pg_char_max_length(_pg_truetypid(a, t), _pg_truetypmod(a, t))
288              AS cardinal_number)
289              AS character_maximum_length,
290
291            CAST(
292              _pg_char_octet_length(_pg_truetypid(a, t), _pg_truetypmod(a, t))
293              AS cardinal_number)
294              AS character_octet_length,
295
296            CAST(null AS sql_identifier) AS character_set_catalog,
297            CAST(null AS sql_identifier) AS character_set_schema,
298            CAST(null AS sql_identifier) AS character_set_name,
299
300            CAST(null AS sql_identifier) AS collation_catalog,
301            CAST(null AS sql_identifier) AS collation_schema,
302            CAST(null AS sql_identifier) AS collation_name,
303
304            CAST(
305              _pg_numeric_precision(_pg_truetypid(a, t), _pg_truetypmod(a, t))
306              AS cardinal_number)
307              AS numeric_precision,
308
309            CAST(
310              _pg_numeric_precision_radix(_pg_truetypid(a, t), _pg_truetypmod(a, t))
311              AS cardinal_number)
312              AS numeric_precision_radix,
313
314            CAST(
315              _pg_numeric_scale(_pg_truetypid(a, t), _pg_truetypmod(a, t))
316              AS cardinal_number)
317              AS numeric_scale,
318
319            CAST(
320              _pg_datetime_precision(_pg_truetypid(a, t), _pg_truetypmod(a, t))
321              AS cardinal_number)
322              AS datetime_precision,
323
324            CAST(null AS character_data) AS interval_type, -- FIXME
325            CAST(null AS character_data) AS interval_precision, -- FIXME
326
327            CAST(current_database() AS sql_identifier) AS attribute_udt_catalog,
328            CAST(nt.nspname AS sql_identifier) AS attribute_udt_schema,
329            CAST(t.typname AS sql_identifier) AS attribute_udt_name,
330
331            CAST(null AS sql_identifier) AS scope_catalog,
332            CAST(null AS sql_identifier) AS scope_schema,
333            CAST(null AS sql_identifier) AS scope_name,
334
335            CAST(null AS cardinal_number) AS maximum_cardinality,
336            CAST(a.attnum AS sql_identifier) AS dtd_identifier,
337            CAST('NO' AS yes_or_no) AS is_derived_reference_attribute
338
339     FROM (pg_attribute a LEFT JOIN pg_attrdef ad ON attrelid = adrelid AND attnum = adnum),
340          pg_class c, pg_namespace nc,
341          (pg_type t JOIN pg_namespace nt ON (t.typnamespace = nt.oid))
342
343     WHERE a.attrelid = c.oid
344           AND a.atttypid = t.oid
345           AND nc.oid = c.relnamespace
346           AND a.attnum > 0 AND NOT a.attisdropped
347           AND c.relkind in ('c');
348
349 GRANT SELECT ON attributes TO PUBLIC;
350
351
352 /*
353  * 5.12
354  * CHARACTER_SETS view
355  */
356
357 CREATE VIEW character_sets AS
358     SELECT CAST(null AS sql_identifier) AS character_set_catalog,
359            CAST(null AS sql_identifier) AS character_set_schema,
360            CAST(getdatabaseencoding() AS sql_identifier) AS character_set_name,
361            CAST(CASE WHEN getdatabaseencoding() = 'UTF8' THEN 'UCS' ELSE getdatabaseencoding() END AS sql_identifier) AS character_repertoire,
362            CAST(getdatabaseencoding() AS sql_identifier) AS form_of_use,
363            CAST(current_database() AS sql_identifier) AS default_collate_catalog,
364            CAST(nc.nspname AS sql_identifier) AS default_collate_schema,
365            CAST(c.collname AS sql_identifier) AS default_collate_name
366     FROM pg_database d
367          LEFT JOIN (pg_collation c JOIN pg_namespace nc ON (c.collnamespace = nc.oid))
368              ON (datcollate = collcollate AND datctype = collctype)
369     WHERE d.datname = current_database()
370     ORDER BY char_length(c.collname) DESC, c.collname ASC -- prefer full/canonical name
371     LIMIT 1;
372
373 GRANT SELECT ON character_sets TO PUBLIC;
374
375
376 /*
377  * 5.13
378  * CHECK_CONSTRAINT_ROUTINE_USAGE view
379  */
380
381 CREATE VIEW check_constraint_routine_usage AS
382     SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog,
383            CAST(nc.nspname AS sql_identifier) AS constraint_schema,
384            CAST(c.conname AS sql_identifier) AS constraint_name,
385            CAST(current_database() AS sql_identifier) AS specific_catalog,
386            CAST(np.nspname AS sql_identifier) AS specific_schema,
387            CAST(p.proname || '_' || CAST(p.oid AS text) AS sql_identifier) AS specific_name
388     FROM pg_namespace nc, pg_constraint c, pg_depend d, pg_proc p, pg_namespace np
389     WHERE nc.oid = c.connamespace
390       AND c.contype = 'c'
391       AND c.oid = d.objid
392       AND d.classid = 'pg_catalog.pg_constraint'::regclass
393       AND d.refobjid = p.oid
394       AND d.refclassid = 'pg_catalog.pg_proc'::regclass
395       AND p.pronamespace = np.oid
396       AND pg_has_role(p.proowner, 'USAGE');
397
398 GRANT SELECT ON check_constraint_routine_usage TO PUBLIC;
399
400
401 /*
402  * 5.14
403  * CHECK_CONSTRAINTS view
404  */
405
406 CREATE VIEW check_constraints AS
407     SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog,
408            CAST(rs.nspname AS sql_identifier) AS constraint_schema,
409            CAST(con.conname AS sql_identifier) AS constraint_name,
410            CAST(substring(pg_get_constraintdef(con.oid) from 7) AS character_data)
411              AS check_clause
412     FROM pg_constraint con
413            LEFT OUTER JOIN pg_namespace rs ON (rs.oid = con.connamespace)
414            LEFT OUTER JOIN pg_class c ON (c.oid = con.conrelid)
415            LEFT OUTER JOIN pg_type t ON (t.oid = con.contypid)
416     WHERE pg_has_role(coalesce(c.relowner, t.typowner), 'USAGE')
417       AND con.contype = 'c'
418
419     UNION
420     -- not-null constraints
421
422     SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog,
423            CAST(n.nspname AS sql_identifier) AS constraint_schema,
424            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
425            CAST(a.attname || ' IS NOT NULL' AS character_data)
426              AS check_clause
427     FROM pg_namespace n, pg_class r, pg_attribute a
428     WHERE n.oid = r.relnamespace
429       AND r.oid = a.attrelid
430       AND a.attnum > 0
431       AND NOT a.attisdropped
432       AND a.attnotnull
433       AND r.relkind = 'r'
434       AND pg_has_role(r.relowner, 'USAGE');
435
436 GRANT SELECT ON check_constraints TO PUBLIC;
437
438
439 /*
440  * 5.15
441  * COLLATIONS view
442  */
443
444 CREATE VIEW collations AS
445     SELECT CAST(current_database() AS sql_identifier) AS collation_catalog,
446            CAST(nc.nspname AS sql_identifier) AS collation_schema,
447            CAST(c.collname AS sql_identifier) AS collation_name,
448            CAST('NO PAD' AS character_data) AS pad_attribute
449     FROM pg_collation c, pg_namespace nc
450     WHERE c.collnamespace = nc.oid
451           AND collencoding = (SELECT encoding FROM pg_catalog.pg_database WHERE datname = pg_catalog.current_database());
452
453 GRANT SELECT ON collations TO PUBLIC;
454
455
456 /*
457  * 5.16
458  * COLLATION_CHARACTER_SET_APPLICABILITY view
459  */
460
461 CREATE VIEW collation_character_set_applicability AS
462     SELECT CAST(current_database() AS sql_identifier) AS collation_catalog,
463            CAST(nc.nspname AS sql_identifier) AS collation_schema,
464            CAST(c.collname AS sql_identifier) AS collation_name,
465            CAST(null AS sql_identifier) AS character_set_catalog,
466            CAST(null AS sql_identifier) AS character_set_schema,
467            CAST(getdatabaseencoding() AS sql_identifier) AS character_set_name
468     FROM pg_collation c, pg_namespace nc
469     WHERE c.collnamespace = nc.oid
470           AND collencoding = (SELECT encoding FROM pg_catalog.pg_database WHERE datname = pg_catalog.current_database());
471
472 GRANT SELECT ON collation_character_set_applicability TO PUBLIC;
473
474
475 /*
476  * 5.17
477  * COLUMN_COLUMN_USAGE view
478  */
479
480 -- feature not supported
481
482
483 /*
484  * 5.18
485  * COLUMN_DOMAIN_USAGE view
486  */
487
488 CREATE VIEW column_domain_usage AS
489     SELECT CAST(current_database() AS sql_identifier) AS domain_catalog,
490            CAST(nt.nspname AS sql_identifier) AS domain_schema,
491            CAST(t.typname AS sql_identifier) AS domain_name,
492            CAST(current_database() AS sql_identifier) AS table_catalog,
493            CAST(nc.nspname AS sql_identifier) AS table_schema,
494            CAST(c.relname AS sql_identifier) AS table_name,
495            CAST(a.attname AS sql_identifier) AS column_name
496
497     FROM pg_type t, pg_namespace nt, pg_class c, pg_namespace nc,
498          pg_attribute a
499
500     WHERE t.typnamespace = nt.oid
501           AND c.relnamespace = nc.oid
502           AND a.attrelid = c.oid
503           AND a.atttypid = t.oid
504           AND t.typtype = 'd'
505           AND c.relkind IN ('r', 'v', 'f')
506           AND a.attnum > 0
507           AND NOT a.attisdropped
508           AND pg_has_role(t.typowner, 'USAGE');
509
510 GRANT SELECT ON column_domain_usage TO PUBLIC;
511
512
513 /*
514  * 5.19
515  * COLUMN_PRIVILEGES
516  */
517
518 CREATE VIEW column_privileges AS
519     SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor,
520            CAST(grantee.rolname AS sql_identifier) AS grantee,
521            CAST(current_database() AS sql_identifier) AS table_catalog,
522            CAST(nc.nspname AS sql_identifier) AS table_schema,
523            CAST(x.relname AS sql_identifier) AS table_name,
524            CAST(x.attname AS sql_identifier) AS column_name,
525            CAST(x.prtype AS character_data) AS privilege_type,
526            CAST(
527              CASE WHEN
528                   -- object owner always has grant options
529                   pg_has_role(x.grantee, x.relowner, 'USAGE')
530                   OR x.grantable
531                   THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable
532
533     FROM (
534            SELECT pr_c.grantor,
535                   pr_c.grantee,
536                   attname,
537                   relname,
538                   relnamespace,
539                   pr_c.prtype,
540                   pr_c.grantable,
541                   pr_c.relowner
542            FROM (SELECT oid, relname, relnamespace, relowner, (aclexplode(relacl)).*
543                  FROM pg_class
544                  WHERE relkind IN ('r', 'v', 'f')
545                 ) pr_c (oid, relname, relnamespace, relowner, grantor, grantee, prtype, grantable),
546                 pg_attribute a
547            WHERE a.attrelid = pr_c.oid
548                  AND a.attnum > 0
549                  AND NOT a.attisdropped
550            UNION
551            SELECT pr_a.grantor,
552                   pr_a.grantee,
553                   attname,
554                   relname,
555                   relnamespace,
556                   pr_a.prtype,
557                   pr_a.grantable,
558                   c.relowner
559            FROM (SELECT attrelid, attname, (aclexplode(attacl)).*
560                  FROM pg_attribute
561                  WHERE attnum > 0
562                        AND NOT attisdropped
563                 ) pr_a (attrelid, attname, grantor, grantee, prtype, grantable),
564                 pg_class c
565            WHERE pr_a.attrelid = c.oid
566                  AND relkind IN ('r', 'v', 'f')
567          ) x,
568          pg_namespace nc,
569          pg_authid u_grantor,
570          (
571            SELECT oid, rolname FROM pg_authid
572            UNION ALL
573            SELECT 0::oid, 'PUBLIC'
574          ) AS grantee (oid, rolname)
575
576     WHERE x.relnamespace = nc.oid
577           AND x.grantee = grantee.oid
578           AND x.grantor = u_grantor.oid
579           AND x.prtype IN ('INSERT', 'SELECT', 'UPDATE', 'REFERENCES')
580           AND (pg_has_role(u_grantor.oid, 'USAGE')
581                OR pg_has_role(grantee.oid, 'USAGE')
582                OR grantee.rolname = 'PUBLIC');
583
584 GRANT SELECT ON column_privileges TO PUBLIC;
585
586
587 /*
588  * 5.20
589  * COLUMN_UDT_USAGE view
590  */
591
592 CREATE VIEW column_udt_usage AS
593     SELECT CAST(current_database() AS sql_identifier) AS udt_catalog,
594            CAST(coalesce(nbt.nspname, nt.nspname) AS sql_identifier) AS udt_schema,
595            CAST(coalesce(bt.typname, t.typname) AS sql_identifier) AS udt_name,
596            CAST(current_database() AS sql_identifier) AS table_catalog,
597            CAST(nc.nspname AS sql_identifier) AS table_schema,
598            CAST(c.relname AS sql_identifier) AS table_name,
599            CAST(a.attname AS sql_identifier) AS column_name
600
601     FROM pg_attribute a, pg_class c, pg_namespace nc,
602          (pg_type t JOIN pg_namespace nt ON (t.typnamespace = nt.oid))
603            LEFT JOIN (pg_type bt JOIN pg_namespace nbt ON (bt.typnamespace = nbt.oid))
604            ON (t.typtype = 'd' AND t.typbasetype = bt.oid)
605
606     WHERE a.attrelid = c.oid
607           AND a.atttypid = t.oid
608           AND nc.oid = c.relnamespace
609           AND a.attnum > 0 AND NOT a.attisdropped AND c.relkind in ('r', 'v', 'f')
610           AND pg_has_role(coalesce(bt.typowner, t.typowner), 'USAGE');
611
612 GRANT SELECT ON column_udt_usage TO PUBLIC;
613
614
615 /*
616  * 5.21
617  * COLUMNS view
618  */
619
620 CREATE VIEW columns AS
621     SELECT CAST(current_database() AS sql_identifier) AS table_catalog,
622            CAST(nc.nspname AS sql_identifier) AS table_schema,
623            CAST(c.relname AS sql_identifier) AS table_name,
624            CAST(a.attname AS sql_identifier) AS column_name,
625            CAST(a.attnum AS cardinal_number) AS ordinal_position,
626            CAST(pg_get_expr(ad.adbin, ad.adrelid) AS character_data) AS column_default,
627            CAST(CASE WHEN a.attnotnull OR (t.typtype = 'd' AND t.typnotnull) THEN 'NO' ELSE 'YES' END
628              AS yes_or_no)
629              AS is_nullable,
630
631            CAST(
632              CASE WHEN t.typtype = 'd' THEN
633                CASE WHEN bt.typelem <> 0 AND bt.typlen = -1 THEN 'ARRAY'
634                     WHEN nbt.nspname = 'pg_catalog' THEN format_type(t.typbasetype, null)
635                     ELSE 'USER-DEFINED' END
636              ELSE
637                CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'ARRAY'
638                     WHEN nt.nspname = 'pg_catalog' THEN format_type(a.atttypid, null)
639                     ELSE 'USER-DEFINED' END
640              END
641              AS character_data)
642              AS data_type,
643
644            CAST(
645              _pg_char_max_length(_pg_truetypid(a, t), _pg_truetypmod(a, t))
646              AS cardinal_number)
647              AS character_maximum_length,
648
649            CAST(
650              _pg_char_octet_length(_pg_truetypid(a, t), _pg_truetypmod(a, t))
651              AS cardinal_number)
652              AS character_octet_length,
653
654            CAST(
655              _pg_numeric_precision(_pg_truetypid(a, t), _pg_truetypmod(a, t))
656              AS cardinal_number)
657              AS numeric_precision,
658
659            CAST(
660              _pg_numeric_precision_radix(_pg_truetypid(a, t), _pg_truetypmod(a, t))
661              AS cardinal_number)
662              AS numeric_precision_radix,
663
664            CAST(
665              _pg_numeric_scale(_pg_truetypid(a, t), _pg_truetypmod(a, t))
666              AS cardinal_number)
667              AS numeric_scale,
668
669            CAST(
670              _pg_datetime_precision(_pg_truetypid(a, t), _pg_truetypmod(a, t))
671              AS cardinal_number)
672              AS datetime_precision,
673
674            CAST(null AS character_data) AS interval_type, -- FIXME
675            CAST(null AS character_data) AS interval_precision, -- FIXME
676
677            CAST(null AS sql_identifier) AS character_set_catalog,
678            CAST(null AS sql_identifier) AS character_set_schema,
679            CAST(null AS sql_identifier) AS character_set_name,
680
681            CAST(null AS sql_identifier) AS collation_catalog,
682            CAST(null AS sql_identifier) AS collation_schema,
683            CAST(null AS sql_identifier) AS collation_name,
684
685            CAST(CASE WHEN t.typtype = 'd' THEN current_database() ELSE null END
686              AS sql_identifier) AS domain_catalog,
687            CAST(CASE WHEN t.typtype = 'd' THEN nt.nspname ELSE null END
688              AS sql_identifier) AS domain_schema,
689            CAST(CASE WHEN t.typtype = 'd' THEN t.typname ELSE null END
690              AS sql_identifier) AS domain_name,
691
692            CAST(current_database() AS sql_identifier) AS udt_catalog,
693            CAST(coalesce(nbt.nspname, nt.nspname) AS sql_identifier) AS udt_schema,
694            CAST(coalesce(bt.typname, t.typname) AS sql_identifier) AS udt_name,
695
696            CAST(null AS sql_identifier) AS scope_catalog,
697            CAST(null AS sql_identifier) AS scope_schema,
698            CAST(null AS sql_identifier) AS scope_name,
699
700            CAST(null AS cardinal_number) AS maximum_cardinality,
701            CAST(a.attnum AS sql_identifier) AS dtd_identifier,
702            CAST('NO' AS yes_or_no) AS is_self_referencing,
703
704            CAST('NO' AS yes_or_no) AS is_identity,
705            CAST(null AS character_data) AS identity_generation,
706            CAST(null AS character_data) AS identity_start,
707            CAST(null AS character_data) AS identity_increment,
708            CAST(null AS character_data) AS identity_maximum,
709            CAST(null AS character_data) AS identity_minimum,
710            CAST(null AS yes_or_no) AS identity_cycle,
711
712            CAST('NEVER' AS character_data) AS is_generated,
713            CAST(null AS character_data) AS generation_expression,
714
715            CAST(CASE WHEN c.relkind = 'r'
716                           OR (c.relkind = 'v'
717                               AND EXISTS (SELECT 1 FROM pg_rewrite WHERE ev_class = c.oid AND ev_type = '2' AND is_instead)
718                               AND EXISTS (SELECT 1 FROM pg_rewrite WHERE ev_class = c.oid AND ev_type = '4' AND is_instead))
719                 THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_updatable
720
721     FROM (pg_attribute a LEFT JOIN pg_attrdef ad ON attrelid = adrelid AND attnum = adnum),
722          pg_class c, pg_namespace nc,
723          (pg_type t JOIN pg_namespace nt ON (t.typnamespace = nt.oid))
724            LEFT JOIN (pg_type bt JOIN pg_namespace nbt ON (bt.typnamespace = nbt.oid))
725            ON (t.typtype = 'd' AND t.typbasetype = bt.oid)
726
727     WHERE a.attrelid = c.oid
728           AND a.atttypid = t.oid
729           AND nc.oid = c.relnamespace
730           AND (NOT pg_is_other_temp_schema(nc.oid))
731
732           AND a.attnum > 0 AND NOT a.attisdropped AND c.relkind in ('r', 'v', 'f')
733
734           AND (pg_has_role(c.relowner, 'USAGE')
735                OR has_column_privilege(c.oid, a.attnum,
736                                        'SELECT, INSERT, UPDATE, REFERENCES'));
737
738 GRANT SELECT ON columns TO PUBLIC;
739
740
741 /*
742  * 5.22
743  * CONSTRAINT_COLUMN_USAGE view
744  */
745
746 CREATE VIEW constraint_column_usage AS
747     SELECT CAST(current_database() AS sql_identifier) AS table_catalog,
748            CAST(tblschema AS sql_identifier) AS table_schema,
749            CAST(tblname AS sql_identifier) AS table_name,
750            CAST(colname AS sql_identifier) AS column_name,
751            CAST(current_database() AS sql_identifier) AS constraint_catalog,
752            CAST(cstrschema AS sql_identifier) AS constraint_schema,
753            CAST(cstrname AS sql_identifier) AS constraint_name
754
755     FROM (
756         /* check constraints */
757         SELECT DISTINCT nr.nspname, r.relname, r.relowner, a.attname, nc.nspname, c.conname
758           FROM pg_namespace nr, pg_class r, pg_attribute a, pg_depend d, pg_namespace nc, pg_constraint c
759           WHERE nr.oid = r.relnamespace
760             AND r.oid = a.attrelid
761             AND d.refclassid = 'pg_catalog.pg_class'::regclass
762             AND d.refobjid = r.oid
763             AND d.refobjsubid = a.attnum
764             AND d.classid = 'pg_catalog.pg_constraint'::regclass
765             AND d.objid = c.oid
766             AND c.connamespace = nc.oid
767             AND c.contype = 'c'
768             AND r.relkind = 'r'
769             AND NOT a.attisdropped
770
771         UNION ALL
772
773         /* unique/primary key/foreign key constraints */
774         SELECT nr.nspname, r.relname, r.relowner, a.attname, nc.nspname, c.conname
775           FROM pg_namespace nr, pg_class r, pg_attribute a, pg_namespace nc,
776                pg_constraint c
777           WHERE nr.oid = r.relnamespace
778             AND r.oid = a.attrelid
779             AND nc.oid = c.connamespace
780             AND (CASE WHEN c.contype = 'f' THEN r.oid = c.confrelid AND a.attnum = ANY (c.confkey)
781                       ELSE r.oid = c.conrelid AND a.attnum = ANY (c.conkey) END)
782             AND NOT a.attisdropped
783             AND c.contype IN ('p', 'u', 'f')
784             AND r.relkind = 'r'
785
786       ) AS x (tblschema, tblname, tblowner, colname, cstrschema, cstrname)
787
788     WHERE pg_has_role(x.tblowner, 'USAGE');
789
790 GRANT SELECT ON constraint_column_usage TO PUBLIC;
791
792
793 /*
794  * 5.23
795  * CONSTRAINT_TABLE_USAGE view
796  */
797
798 CREATE VIEW constraint_table_usage AS
799     SELECT CAST(current_database() AS sql_identifier) AS table_catalog,
800            CAST(nr.nspname AS sql_identifier) AS table_schema,
801            CAST(r.relname AS sql_identifier) AS table_name,
802            CAST(current_database() AS sql_identifier) AS constraint_catalog,
803            CAST(nc.nspname AS sql_identifier) AS constraint_schema,
804            CAST(c.conname AS sql_identifier) AS constraint_name
805
806     FROM pg_constraint c, pg_namespace nc,
807          pg_class r, pg_namespace nr
808
809     WHERE c.connamespace = nc.oid AND r.relnamespace = nr.oid
810           AND ( (c.contype = 'f' AND c.confrelid = r.oid)
811              OR (c.contype IN ('p', 'u') AND c.conrelid = r.oid) )
812           AND r.relkind = 'r'
813           AND pg_has_role(r.relowner, 'USAGE');
814
815 GRANT SELECT ON constraint_table_usage TO PUBLIC;
816
817
818 -- 5.24 DATA_TYPE_PRIVILEGES view appears later.
819
820
821 /*
822  * 5.25
823  * DIRECT_SUPERTABLES view
824  */
825
826 -- feature not supported
827
828
829 /*
830  * 5.26
831  * DIRECT_SUPERTYPES view
832  */
833
834 -- feature not supported
835
836
837 /*
838  * 5.27
839  * DOMAIN_CONSTRAINTS view
840  */
841
842 CREATE VIEW domain_constraints AS
843     SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog,
844            CAST(rs.nspname AS sql_identifier) AS constraint_schema,
845            CAST(con.conname AS sql_identifier) AS constraint_name,
846            CAST(current_database() AS sql_identifier) AS domain_catalog,
847            CAST(n.nspname AS sql_identifier) AS domain_schema,
848            CAST(t.typname AS sql_identifier) AS domain_name,
849            CAST(CASE WHEN condeferrable THEN 'YES' ELSE 'NO' END
850              AS yes_or_no) AS is_deferrable,
851            CAST(CASE WHEN condeferred THEN 'YES' ELSE 'NO' END
852              AS yes_or_no) AS initially_deferred
853     FROM pg_namespace rs, pg_namespace n, pg_constraint con, pg_type t
854     WHERE rs.oid = con.connamespace
855           AND n.oid = t.typnamespace
856           AND t.oid = con.contypid;
857
858 GRANT SELECT ON domain_constraints TO PUBLIC;
859
860
861 /*
862  * DOMAIN_UDT_USAGE view
863  * apparently removed in SQL:2003
864  */
865
866 CREATE VIEW domain_udt_usage AS
867     SELECT CAST(current_database() AS sql_identifier) AS udt_catalog,
868            CAST(nbt.nspname AS sql_identifier) AS udt_schema,
869            CAST(bt.typname AS sql_identifier) AS udt_name,
870            CAST(current_database() AS sql_identifier) AS domain_catalog,
871            CAST(nt.nspname AS sql_identifier) AS domain_schema,
872            CAST(t.typname AS sql_identifier) AS domain_name
873
874     FROM pg_type t, pg_namespace nt,
875          pg_type bt, pg_namespace nbt
876
877     WHERE t.typnamespace = nt.oid
878           AND t.typbasetype = bt.oid
879           AND bt.typnamespace = nbt.oid
880           AND t.typtype = 'd'
881           AND pg_has_role(bt.typowner, 'USAGE');
882
883 GRANT SELECT ON domain_udt_usage TO PUBLIC;
884
885
886 /*
887  * 5.28
888  * DOMAINS view
889  */
890
891 CREATE VIEW domains AS
892     SELECT CAST(current_database() AS sql_identifier) AS domain_catalog,
893            CAST(nt.nspname AS sql_identifier) AS domain_schema,
894            CAST(t.typname AS sql_identifier) AS domain_name,
895
896            CAST(
897              CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'ARRAY'
898                   WHEN nbt.nspname = 'pg_catalog' THEN format_type(t.typbasetype, null)
899                   ELSE 'USER-DEFINED' END
900              AS character_data)
901              AS data_type,
902
903            CAST(
904              _pg_char_max_length(t.typbasetype, t.typtypmod)
905              AS cardinal_number)
906              AS character_maximum_length,
907
908            CAST(
909              _pg_char_octet_length(t.typbasetype, t.typtypmod)
910              AS cardinal_number)
911              AS character_octet_length,
912
913            CAST(null AS sql_identifier) AS character_set_catalog,
914            CAST(null AS sql_identifier) AS character_set_schema,
915            CAST(null AS sql_identifier) AS character_set_name,
916
917            CAST(null AS sql_identifier) AS collation_catalog,
918            CAST(null AS sql_identifier) AS collation_schema,
919            CAST(null AS sql_identifier) AS collation_name,
920
921            CAST(
922              _pg_numeric_precision(t.typbasetype, t.typtypmod)
923              AS cardinal_number)
924              AS numeric_precision,
925
926            CAST(
927              _pg_numeric_precision_radix(t.typbasetype, t.typtypmod)
928              AS cardinal_number)
929              AS numeric_precision_radix,
930
931            CAST(
932              _pg_numeric_scale(t.typbasetype, t.typtypmod)
933              AS cardinal_number)
934              AS numeric_scale,
935
936            CAST(
937              _pg_datetime_precision(t.typbasetype, t.typtypmod)
938              AS cardinal_number)
939              AS datetime_precision,
940
941            CAST(null AS character_data) AS interval_type, -- FIXME
942            CAST(null AS character_data) AS interval_precision, -- FIXME
943
944            CAST(t.typdefault AS character_data) AS domain_default,
945
946            CAST(current_database() AS sql_identifier) AS udt_catalog,
947            CAST(nbt.nspname AS sql_identifier) AS udt_schema,
948            CAST(bt.typname AS sql_identifier) AS udt_name,
949
950            CAST(null AS sql_identifier) AS scope_catalog,
951            CAST(null AS sql_identifier) AS scope_schema,
952            CAST(null AS sql_identifier) AS scope_name,
953
954            CAST(null AS cardinal_number) AS maximum_cardinality,
955            CAST(1 AS sql_identifier) AS dtd_identifier
956
957     FROM pg_type t, pg_namespace nt,
958          pg_type bt, pg_namespace nbt
959
960     WHERE t.typnamespace = nt.oid
961           AND t.typbasetype = bt.oid
962           AND bt.typnamespace = nbt.oid
963           AND t.typtype = 'd';
964
965 GRANT SELECT ON domains TO PUBLIC;
966
967
968 -- 5.29 ELEMENT_TYPES view appears later.
969
970
971 /*
972  * 5.30
973  * ENABLED_ROLES view
974  */
975
976 CREATE VIEW enabled_roles AS
977     SELECT CAST(a.rolname AS sql_identifier) AS role_name
978     FROM pg_authid a
979     WHERE pg_has_role(a.oid, 'USAGE');
980
981 GRANT SELECT ON enabled_roles TO PUBLIC;
982
983
984 /*
985  * 5.31
986  * FIELDS view
987  */
988
989 -- feature not supported
990
991
992 /*
993  * 5.32
994  * KEY_COLUMN_USAGE view
995  */
996
997 CREATE VIEW key_column_usage AS
998     SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog,
999            CAST(nc_nspname AS sql_identifier) AS constraint_schema,
1000            CAST(conname AS sql_identifier) AS constraint_name,
1001            CAST(current_database() AS sql_identifier) AS table_catalog,
1002            CAST(nr_nspname AS sql_identifier) AS table_schema,
1003            CAST(relname AS sql_identifier) AS table_name,
1004            CAST(a.attname AS sql_identifier) AS column_name,
1005            CAST((ss.x).n AS cardinal_number) AS ordinal_position,
1006            CAST(CASE WHEN contype = 'f' THEN
1007                        _pg_index_position(ss.conindid, ss.confkey[(ss.x).n])
1008                      ELSE NULL
1009                 END AS cardinal_number)
1010              AS position_in_unique_constraint
1011     FROM pg_attribute a,
1012          (SELECT r.oid AS roid, r.relname, r.relowner,
1013                  nc.nspname AS nc_nspname, nr.nspname AS nr_nspname,
1014                  c.oid AS coid, c.conname, c.contype, c.conindid,
1015                  c.confkey, c.confrelid,
1016                  _pg_expandarray(c.conkey) AS x
1017           FROM pg_namespace nr, pg_class r, pg_namespace nc,
1018                pg_constraint c
1019           WHERE nr.oid = r.relnamespace
1020                 AND r.oid = c.conrelid
1021                 AND nc.oid = c.connamespace
1022                 AND c.contype IN ('p', 'u', 'f')
1023                 AND r.relkind = 'r'
1024                 AND (NOT pg_is_other_temp_schema(nr.oid)) ) AS ss
1025     WHERE ss.roid = a.attrelid
1026           AND a.attnum = (ss.x).x
1027           AND NOT a.attisdropped
1028           AND (pg_has_role(relowner, 'USAGE')
1029                OR has_column_privilege(roid, a.attnum,
1030                                        'SELECT, INSERT, UPDATE, REFERENCES'));
1031
1032 GRANT SELECT ON key_column_usage TO PUBLIC;
1033
1034
1035 /*
1036  * 5.33
1037  * METHOD_SPECIFICATION_PARAMETERS view
1038  */
1039
1040 -- feature not supported
1041
1042
1043 /*
1044  * 5.34
1045  * METHOD_SPECIFICATIONS view
1046  */
1047
1048 -- feature not supported
1049
1050
1051 /*
1052  * 5.35
1053  * PARAMETERS view
1054  */
1055
1056 CREATE VIEW parameters AS
1057     SELECT CAST(current_database() AS sql_identifier) AS specific_catalog,
1058            CAST(n_nspname AS sql_identifier) AS specific_schema,
1059            CAST(proname || '_' || CAST(p_oid AS text) AS sql_identifier) AS specific_name,
1060            CAST((ss.x).n AS cardinal_number) AS ordinal_position,
1061            CAST(
1062              CASE WHEN proargmodes IS NULL THEN 'IN'
1063                 WHEN proargmodes[(ss.x).n] = 'i' THEN 'IN'
1064                 WHEN proargmodes[(ss.x).n] = 'o' THEN 'OUT'
1065                 WHEN proargmodes[(ss.x).n] = 'b' THEN 'INOUT'
1066                 WHEN proargmodes[(ss.x).n] = 'v' THEN 'IN'
1067                 WHEN proargmodes[(ss.x).n] = 't' THEN 'OUT'
1068              END AS character_data) AS parameter_mode,
1069            CAST('NO' AS yes_or_no) AS is_result,
1070            CAST('NO' AS yes_or_no) AS as_locator,
1071            CAST(NULLIF(proargnames[(ss.x).n], '') AS sql_identifier) AS parameter_name,
1072            CAST(
1073              CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'ARRAY'
1074                   WHEN nt.nspname = 'pg_catalog' THEN format_type(t.oid, null)
1075                   ELSE 'USER-DEFINED' END AS character_data)
1076              AS data_type,
1077            CAST(null AS cardinal_number) AS character_maximum_length,
1078            CAST(null AS cardinal_number) AS character_octet_length,
1079            CAST(null AS sql_identifier) AS character_set_catalog,
1080            CAST(null AS sql_identifier) AS character_set_schema,
1081            CAST(null AS sql_identifier) AS character_set_name,
1082            CAST(null AS sql_identifier) AS collation_catalog,
1083            CAST(null AS sql_identifier) AS collation_schema,
1084            CAST(null AS sql_identifier) AS collation_name,
1085            CAST(null AS cardinal_number) AS numeric_precision,
1086            CAST(null AS cardinal_number) AS numeric_precision_radix,
1087            CAST(null AS cardinal_number) AS numeric_scale,
1088            CAST(null AS cardinal_number) AS datetime_precision,
1089            CAST(null AS character_data) AS interval_type,
1090            CAST(null AS character_data) AS interval_precision,
1091            CAST(current_database() AS sql_identifier) AS udt_catalog,
1092            CAST(nt.nspname AS sql_identifier) AS udt_schema,
1093            CAST(t.typname AS sql_identifier) AS udt_name,
1094            CAST(null AS sql_identifier) AS scope_catalog,
1095            CAST(null AS sql_identifier) AS scope_schema,
1096            CAST(null AS sql_identifier) AS scope_name,
1097            CAST(null AS cardinal_number) AS maximum_cardinality,
1098            CAST((ss.x).n AS sql_identifier) AS dtd_identifier
1099
1100     FROM pg_type t, pg_namespace nt,
1101          (SELECT n.nspname AS n_nspname, p.proname, p.oid AS p_oid,
1102                  p.proargnames, p.proargmodes,
1103                  _pg_expandarray(coalesce(p.proallargtypes, p.proargtypes::oid[])) AS x
1104           FROM pg_namespace n, pg_proc p
1105           WHERE n.oid = p.pronamespace
1106                 AND (pg_has_role(p.proowner, 'USAGE') OR
1107                      has_function_privilege(p.oid, 'EXECUTE'))) AS ss
1108     WHERE t.oid = (ss.x).x AND t.typnamespace = nt.oid;
1109
1110 GRANT SELECT ON parameters TO PUBLIC;
1111
1112
1113 /*
1114  * 5.36
1115  * REFERENCED_TYPES view
1116  */
1117
1118 -- feature not supported
1119
1120
1121 /*
1122  * 5.37
1123  * REFERENTIAL_CONSTRAINTS view
1124  */
1125
1126 CREATE VIEW referential_constraints AS
1127     SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog,
1128            CAST(ncon.nspname AS sql_identifier) AS constraint_schema,
1129            CAST(con.conname AS sql_identifier) AS constraint_name,
1130            CAST(
1131              CASE WHEN npkc.nspname IS NULL THEN NULL
1132                   ELSE current_database() END
1133              AS sql_identifier) AS unique_constraint_catalog,
1134            CAST(npkc.nspname AS sql_identifier) AS unique_constraint_schema,
1135            CAST(pkc.conname AS sql_identifier) AS unique_constraint_name,
1136
1137            CAST(
1138              CASE con.confmatchtype WHEN 'f' THEN 'FULL'
1139                                     WHEN 'p' THEN 'PARTIAL'
1140                                     WHEN 'u' THEN 'NONE' END
1141              AS character_data) AS match_option,
1142
1143            CAST(
1144              CASE con.confupdtype WHEN 'c' THEN 'CASCADE'
1145                                   WHEN 'n' THEN 'SET NULL'
1146                                   WHEN 'd' THEN 'SET DEFAULT'
1147                                   WHEN 'r' THEN 'RESTRICT'
1148                                   WHEN 'a' THEN 'NO ACTION' END
1149              AS character_data) AS update_rule,
1150
1151            CAST(
1152              CASE con.confdeltype WHEN 'c' THEN 'CASCADE'
1153                                   WHEN 'n' THEN 'SET NULL'
1154                                   WHEN 'd' THEN 'SET DEFAULT'
1155                                   WHEN 'r' THEN 'RESTRICT'
1156                                   WHEN 'a' THEN 'NO ACTION' END
1157              AS character_data) AS delete_rule
1158
1159     FROM (pg_namespace ncon
1160           INNER JOIN pg_constraint con ON ncon.oid = con.connamespace
1161           INNER JOIN pg_class c ON con.conrelid = c.oid)
1162          LEFT JOIN
1163          (pg_constraint pkc
1164           INNER JOIN pg_namespace npkc ON pkc.connamespace = npkc.oid)
1165          ON con.confrelid = pkc.conrelid
1166             AND _pg_keysequal(con.confkey, pkc.conkey)
1167
1168     WHERE c.relkind = 'r'
1169           AND con.contype = 'f'
1170           AND (pkc.contype IN ('p', 'u') OR pkc.contype IS NULL)
1171           AND (pg_has_role(c.relowner, 'USAGE')
1172                -- SELECT privilege omitted, per SQL standard
1173                OR has_table_privilege(c.oid, 'INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER')
1174                OR has_any_column_privilege(c.oid, 'INSERT, UPDATE, REFERENCES') );
1175
1176 GRANT SELECT ON referential_constraints TO PUBLIC;
1177
1178
1179 /*
1180  * 5.38
1181  * ROLE_COLUMN_GRANTS view
1182  */
1183
1184 CREATE VIEW role_column_grants AS
1185     SELECT grantor,
1186            grantee,
1187            table_catalog,
1188            table_schema,
1189            table_name,
1190            column_name,
1191            privilege_type,
1192            is_grantable
1193     FROM column_privileges
1194     WHERE grantor IN (SELECT role_name FROM enabled_roles)
1195           OR grantee IN (SELECT role_name FROM enabled_roles);
1196
1197 GRANT SELECT ON role_column_grants TO PUBLIC;
1198
1199
1200 -- 5.39 ROLE_ROUTINE_GRANTS view is based on 5.45 ROUTINE_PRIVILEGES and is defined there instead.
1201
1202
1203 -- 5.40 ROLE_TABLE_GRANTS view is based on 5.60 TABLE_PRIVILEGES and is defined there instead.
1204
1205
1206 /*
1207  * 5.41
1208  * ROLE_TABLE_METHOD_GRANTS view
1209  */
1210
1211 -- feature not supported
1212
1213
1214
1215 -- 5.42 ROLE_USAGE_GRANTS view is based on 5.71 USAGE_PRIVILEGES and is defined there instead.
1216
1217
1218 /*
1219  * 5.43
1220  * ROLE_UDT_GRANTS view
1221  */
1222
1223 -- feature not supported
1224
1225
1226 /*
1227  * 5.44
1228  * ROUTINE_COLUMN_USAGE view
1229  */
1230
1231 -- not tracked by PostgreSQL
1232
1233
1234 /*
1235  * 5.45
1236  * ROUTINE_PRIVILEGES view
1237  */
1238
1239 CREATE VIEW routine_privileges AS
1240     SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor,
1241            CAST(grantee.rolname AS sql_identifier) AS grantee,
1242            CAST(current_database() AS sql_identifier) AS specific_catalog,
1243            CAST(n.nspname AS sql_identifier) AS specific_schema,
1244            CAST(p.proname || '_' || CAST(p.oid AS text) AS sql_identifier) AS specific_name,
1245            CAST(current_database() AS sql_identifier) AS routine_catalog,
1246            CAST(n.nspname AS sql_identifier) AS routine_schema,
1247            CAST(p.proname AS sql_identifier) AS routine_name,
1248            CAST('EXECUTE' AS character_data) AS privilege_type,
1249            CAST(
1250              CASE WHEN
1251                   -- object owner always has grant options
1252                   pg_has_role(grantee.oid, p.proowner, 'USAGE')
1253                   OR p.grantable
1254                   THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable
1255
1256     FROM (
1257             SELECT oid, proname, proowner, pronamespace, (aclexplode(proacl)).* FROM pg_proc
1258          ) p (oid, proname, proowner, pronamespace, grantor, grantee, prtype, grantable),
1259          pg_namespace n,
1260          pg_authid u_grantor,
1261          (
1262            SELECT oid, rolname FROM pg_authid
1263            UNION ALL
1264            SELECT 0::oid, 'PUBLIC'
1265          ) AS grantee (oid, rolname)
1266
1267     WHERE p.pronamespace = n.oid
1268           AND grantee.oid = p.grantee
1269           AND u_grantor.oid = p.grantor
1270           AND p.prtype IN ('EXECUTE')
1271           AND (pg_has_role(u_grantor.oid, 'USAGE')
1272                OR pg_has_role(grantee.oid, 'USAGE')
1273                OR grantee.rolname = 'PUBLIC');
1274
1275 GRANT SELECT ON routine_privileges TO PUBLIC;
1276
1277
1278 /*
1279  * 5.39
1280  * ROLE_ROUTINE_GRANTS view
1281  */
1282
1283 CREATE VIEW role_routine_grants AS
1284     SELECT grantor,
1285            grantee,
1286            specific_catalog,
1287            specific_schema,
1288            specific_name,
1289            routine_catalog,
1290            routine_schema,
1291            routine_name,
1292            privilege_type,
1293            is_grantable
1294     FROM routine_privileges
1295     WHERE grantor IN (SELECT role_name FROM enabled_roles)
1296           OR grantee IN (SELECT role_name FROM enabled_roles);
1297
1298 GRANT SELECT ON role_routine_grants TO PUBLIC;
1299
1300
1301 /*
1302  * 5.46
1303  * ROUTINE_ROUTINE_USAGE view
1304  */
1305
1306 -- not tracked by PostgreSQL
1307
1308
1309 /*
1310  * 5.47
1311  * ROUTINE_SEQUENCE_USAGE view
1312  */
1313
1314 -- not tracked by PostgreSQL
1315
1316
1317 /*
1318  * 5.48
1319  * ROUTINE_TABLE_USAGE view
1320  */
1321
1322 -- not tracked by PostgreSQL
1323
1324
1325 /*
1326  * 5.49
1327  * ROUTINES view
1328  */
1329
1330 CREATE VIEW routines AS
1331     SELECT CAST(current_database() AS sql_identifier) AS specific_catalog,
1332            CAST(n.nspname AS sql_identifier) AS specific_schema,
1333            CAST(p.proname || '_' || CAST(p.oid AS text) AS sql_identifier) AS specific_name,
1334            CAST(current_database() AS sql_identifier) AS routine_catalog,
1335            CAST(n.nspname AS sql_identifier) AS routine_schema,
1336            CAST(p.proname AS sql_identifier) AS routine_name,
1337            CAST('FUNCTION' AS character_data) AS routine_type,
1338            CAST(null AS sql_identifier) AS module_catalog,
1339            CAST(null AS sql_identifier) AS module_schema,
1340            CAST(null AS sql_identifier) AS module_name,
1341            CAST(null AS sql_identifier) AS udt_catalog,
1342            CAST(null AS sql_identifier) AS udt_schema,
1343            CAST(null AS sql_identifier) AS udt_name,
1344
1345            CAST(
1346              CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'ARRAY'
1347                   WHEN nt.nspname = 'pg_catalog' THEN format_type(t.oid, null)
1348                   ELSE 'USER-DEFINED' END AS character_data)
1349              AS data_type,
1350            CAST(null AS cardinal_number) AS character_maximum_length,
1351            CAST(null AS cardinal_number) AS character_octet_length,
1352            CAST(null AS sql_identifier) AS character_set_catalog,
1353            CAST(null AS sql_identifier) AS character_set_schema,
1354            CAST(null AS sql_identifier) AS character_set_name,
1355            CAST(null AS sql_identifier) AS collation_catalog,
1356            CAST(null AS sql_identifier) AS collation_schema,
1357            CAST(null AS sql_identifier) AS collation_name,
1358            CAST(null AS cardinal_number) AS numeric_precision,
1359            CAST(null AS cardinal_number) AS numeric_precision_radix,
1360            CAST(null AS cardinal_number) AS numeric_scale,
1361            CAST(null AS cardinal_number) AS datetime_precision,
1362            CAST(null AS character_data) AS interval_type,
1363            CAST(null AS character_data) AS interval_precision,
1364            CAST(current_database() AS sql_identifier) AS type_udt_catalog,
1365            CAST(nt.nspname AS sql_identifier) AS type_udt_schema,
1366            CAST(t.typname AS sql_identifier) AS type_udt_name,
1367            CAST(null AS sql_identifier) AS scope_catalog,
1368            CAST(null AS sql_identifier) AS scope_schema,
1369            CAST(null AS sql_identifier) AS scope_name,
1370            CAST(null AS cardinal_number) AS maximum_cardinality,
1371            CAST(0 AS sql_identifier) AS dtd_identifier,
1372
1373            CAST(CASE WHEN l.lanname = 'sql' THEN 'SQL' ELSE 'EXTERNAL' END AS character_data)
1374              AS routine_body,
1375            CAST(
1376              CASE WHEN pg_has_role(p.proowner, 'USAGE') THEN p.prosrc ELSE null END
1377              AS character_data) AS routine_definition,
1378            CAST(
1379              CASE WHEN l.lanname = 'c' THEN p.prosrc ELSE null END
1380              AS character_data) AS external_name,
1381            CAST(upper(l.lanname) AS character_data) AS external_language,
1382
1383            CAST('GENERAL' AS character_data) AS parameter_style,
1384            CAST(CASE WHEN p.provolatile = 'i' THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_deterministic,
1385            CAST('MODIFIES' AS character_data) AS sql_data_access,
1386            CAST(CASE WHEN p.proisstrict THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_null_call,
1387            CAST(null AS character_data) AS sql_path,
1388            CAST('YES' AS yes_or_no) AS schema_level_routine,
1389            CAST(0 AS cardinal_number) AS max_dynamic_result_sets,
1390            CAST(null AS yes_or_no) AS is_user_defined_cast,
1391            CAST(null AS yes_or_no) AS is_implicitly_invocable,
1392            CAST(CASE WHEN p.prosecdef THEN 'DEFINER' ELSE 'INVOKER' END AS character_data) AS security_type,
1393            CAST(null AS sql_identifier) AS to_sql_specific_catalog,
1394            CAST(null AS sql_identifier) AS to_sql_specific_schema,
1395            CAST(null AS sql_identifier) AS to_sql_specific_name,
1396            CAST('NO' AS yes_or_no) AS as_locator,
1397            CAST(null AS time_stamp) AS created,
1398            CAST(null AS time_stamp) AS last_altered,
1399            CAST(null AS yes_or_no) AS new_savepoint_level,
1400            CAST('YES' AS yes_or_no) AS is_udt_dependent, -- FIXME?
1401
1402            CAST(null AS character_data) AS result_cast_from_data_type,
1403            CAST(null AS yes_or_no) AS result_cast_as_locator,
1404            CAST(null AS cardinal_number) AS result_cast_char_max_length,
1405            CAST(null AS cardinal_number) AS result_cast_char_octet_length,
1406            CAST(null AS sql_identifier) AS result_cast_char_set_catalog,
1407            CAST(null AS sql_identifier) AS result_cast_char_set_schema,
1408            CAST(null AS sql_identifier) AS result_cast_character_set_name,
1409            CAST(null AS sql_identifier) AS result_cast_collation_catalog,
1410            CAST(null AS sql_identifier) AS result_cast_collation_schema,
1411            CAST(null AS sql_identifier) AS result_cast_collation_name,
1412            CAST(null AS cardinal_number) AS result_cast_numeric_precision,
1413            CAST(null AS cardinal_number) AS result_cast_numeric_precision_radix,
1414            CAST(null AS cardinal_number) AS result_cast_numeric_scale,
1415            CAST(null AS cardinal_number) AS result_cast_datetime_precision,
1416            CAST(null AS character_data) AS result_cast_interval_type,
1417            CAST(null AS character_data) AS result_cast_interval_precision,
1418            CAST(null AS sql_identifier) AS result_cast_type_udt_catalog,
1419            CAST(null AS sql_identifier) AS result_cast_type_udt_schema,
1420            CAST(null AS sql_identifier) AS result_cast_type_udt_name,
1421            CAST(null AS sql_identifier) AS result_cast_scope_catalog,
1422            CAST(null AS sql_identifier) AS result_cast_scope_schema,
1423            CAST(null AS sql_identifier) AS result_cast_scope_name,
1424            CAST(null AS cardinal_number) AS result_cast_maximum_cardinality,
1425            CAST(null AS sql_identifier) AS result_cast_dtd_identifier
1426
1427     FROM pg_namespace n, pg_proc p, pg_language l,
1428          pg_type t, pg_namespace nt
1429
1430     WHERE n.oid = p.pronamespace AND p.prolang = l.oid
1431           AND p.prorettype = t.oid AND t.typnamespace = nt.oid
1432           AND (pg_has_role(p.proowner, 'USAGE')
1433                OR has_function_privilege(p.oid, 'EXECUTE'));
1434
1435 GRANT SELECT ON routines TO PUBLIC;
1436
1437
1438 /*
1439  * 5.50
1440  * SCHEMATA view
1441  */
1442
1443 CREATE VIEW schemata AS
1444     SELECT CAST(current_database() AS sql_identifier) AS catalog_name,
1445            CAST(n.nspname AS sql_identifier) AS schema_name,
1446            CAST(u.rolname AS sql_identifier) AS schema_owner,
1447            CAST(null AS sql_identifier) AS default_character_set_catalog,
1448            CAST(null AS sql_identifier) AS default_character_set_schema,
1449            CAST(null AS sql_identifier) AS default_character_set_name,
1450            CAST(null AS character_data) AS sql_path
1451     FROM pg_namespace n, pg_authid u
1452     WHERE n.nspowner = u.oid AND pg_has_role(n.nspowner, 'USAGE');
1453
1454 GRANT SELECT ON schemata TO PUBLIC;
1455
1456
1457 /*
1458  * 5.51
1459  * SEQUENCES view
1460  */
1461
1462 CREATE VIEW sequences AS
1463     SELECT CAST(current_database() AS sql_identifier) AS sequence_catalog,
1464            CAST(nc.nspname AS sql_identifier) AS sequence_schema,
1465            CAST(c.relname AS sql_identifier) AS sequence_name,
1466            CAST('bigint' AS character_data) AS data_type,
1467            CAST(64 AS cardinal_number) AS numeric_precision,
1468            CAST(2 AS cardinal_number) AS numeric_precision_radix,
1469            CAST(0 AS cardinal_number) AS numeric_scale,
1470            -- XXX: The following could be improved if we had LATERAL.
1471            CAST((pg_sequence_parameters(c.oid)).start_value AS character_data) AS start_value,
1472            CAST((pg_sequence_parameters(c.oid)).minimum_value AS character_data) AS minimum_value,
1473            CAST((pg_sequence_parameters(c.oid)).maximum_value AS character_data) AS maximum_value,
1474            CAST((pg_sequence_parameters(c.oid)).increment AS character_data) AS increment,
1475            CAST(CASE WHEN (pg_sequence_parameters(c.oid)).cycle_option THEN 'YES' ELSE 'NO' END AS yes_or_no) AS cycle_option
1476     FROM pg_namespace nc, pg_class c
1477     WHERE c.relnamespace = nc.oid
1478           AND c.relkind = 'S'
1479           AND (NOT pg_is_other_temp_schema(nc.oid))
1480           AND (pg_has_role(c.relowner, 'USAGE')
1481                OR has_sequence_privilege(c.oid, 'SELECT, UPDATE, USAGE') );
1482
1483 GRANT SELECT ON sequences TO PUBLIC;
1484
1485
1486 /*
1487  * 5.52
1488  * SQL_FEATURES table
1489  */
1490
1491 CREATE TABLE sql_features (
1492     feature_id          character_data,
1493     feature_name        character_data,
1494     sub_feature_id      character_data,
1495     sub_feature_name    character_data,
1496     is_supported        yes_or_no,
1497     is_verified_by      character_data,
1498     comments            character_data
1499 ) WITHOUT OIDS;
1500
1501 -- Will be filled with external data by initdb.
1502
1503 GRANT SELECT ON sql_features TO PUBLIC;
1504
1505
1506 /*
1507  * 5.53
1508  * SQL_IMPLEMENTATION_INFO table
1509  */
1510
1511 -- Note: Implementation information items are defined in ISO/IEC 9075-3:2008,
1512 -- clause 9.1.
1513
1514 CREATE TABLE sql_implementation_info (
1515     implementation_info_id      character_data,
1516     implementation_info_name    character_data,
1517     integer_value               cardinal_number,
1518     character_value             character_data,
1519     comments                    character_data
1520 ) WITHOUT OIDS;
1521
1522 INSERT INTO sql_implementation_info VALUES ('10003', 'CATALOG NAME', NULL, 'Y', NULL);
1523 INSERT INTO sql_implementation_info VALUES ('10004', 'COLLATING SEQUENCE', NULL, '', 'not supported');
1524 INSERT INTO sql_implementation_info VALUES ('23',    'CURSOR COMMIT BEHAVIOR', 1, NULL, 'close cursors and retain prepared statements');
1525 INSERT INTO sql_implementation_info VALUES ('2',     'DATA SOURCE NAME', NULL, '', NULL);
1526 INSERT INTO sql_implementation_info VALUES ('17',    'DBMS NAME', NULL, (select trim(trailing ' ' from substring(version() from '^[^0-9]*'))), NULL);
1527 INSERT INTO sql_implementation_info VALUES ('18',    'DBMS VERSION', NULL, '???', NULL); -- filled by initdb
1528 INSERT INTO sql_implementation_info VALUES ('26',    'DEFAULT TRANSACTION ISOLATION', 2, NULL, 'READ COMMITTED; user-settable');
1529 INSERT INTO sql_implementation_info VALUES ('28',    'IDENTIFIER CASE', 3, NULL, 'stored in mixed case - case sensitive');
1530 INSERT INTO sql_implementation_info VALUES ('85',    'NULL COLLATION', 0, NULL, 'nulls higher than non-nulls');
1531 INSERT INTO sql_implementation_info VALUES ('13',    'SERVER NAME', NULL, '', NULL);
1532 INSERT INTO sql_implementation_info VALUES ('94',    'SPECIAL CHARACTERS', NULL, '', 'all non-ASCII characters allowed');
1533 INSERT INTO sql_implementation_info VALUES ('46',    'TRANSACTION CAPABLE', 2, NULL, 'both DML and DDL');
1534
1535 GRANT SELECT ON sql_implementation_info TO PUBLIC;
1536
1537
1538 /*
1539  * SQL_LANGUAGES table
1540  * apparently removed in SQL:2008
1541  */
1542
1543 CREATE TABLE sql_languages (
1544     sql_language_source         character_data,
1545     sql_language_year           character_data,
1546     sql_language_conformance    character_data,
1547     sql_language_integrity      character_data,
1548     sql_language_implementation character_data,
1549     sql_language_binding_style  character_data,
1550     sql_language_programming_language character_data
1551 ) WITHOUT OIDS;
1552
1553 INSERT INTO sql_languages VALUES ('ISO 9075', '1999', 'CORE', NULL, NULL, 'DIRECT', NULL);
1554 INSERT INTO sql_languages VALUES ('ISO 9075', '1999', 'CORE', NULL, NULL, 'EMBEDDED', 'C');
1555 INSERT INTO sql_languages VALUES ('ISO 9075', '2003', 'CORE', NULL, NULL, 'DIRECT', NULL);
1556 INSERT INTO sql_languages VALUES ('ISO 9075', '2003', 'CORE', NULL, NULL, 'EMBEDDED', 'C');
1557
1558 GRANT SELECT ON sql_languages TO PUBLIC;
1559
1560
1561 /*
1562  * 5.54
1563  * SQL_PACKAGES table
1564  */
1565
1566 CREATE TABLE sql_packages (
1567     feature_id      character_data,
1568     feature_name    character_data,
1569     is_supported    yes_or_no,
1570     is_verified_by  character_data,
1571     comments        character_data
1572 ) WITHOUT OIDS;
1573
1574 INSERT INTO sql_packages VALUES ('PKG000', 'Core', 'NO', NULL, '');
1575 INSERT INTO sql_packages VALUES ('PKG001', 'Enhanced datetime facilities', 'YES', NULL, '');
1576 INSERT INTO sql_packages VALUES ('PKG002', 'Enhanced integrity management', 'NO', NULL, '');
1577 INSERT INTO sql_packages VALUES ('PKG003', 'OLAP facilities', 'NO', NULL, '');
1578 INSERT INTO sql_packages VALUES ('PKG004', 'PSM', 'NO', NULL, 'PL/pgSQL is similar.');
1579 INSERT INTO sql_packages VALUES ('PKG005', 'CLI', 'NO', NULL, 'ODBC is similar.');
1580 INSERT INTO sql_packages VALUES ('PKG006', 'Basic object support', 'NO', NULL, '');
1581 INSERT INTO sql_packages VALUES ('PKG007', 'Enhanced object support', 'NO', NULL, '');
1582 INSERT INTO sql_packages VALUES ('PKG008', 'Active database', 'NO', NULL, '');
1583 INSERT INTO sql_packages VALUES ('PKG010', 'OLAP', 'NO', NULL, 'NO');
1584
1585 GRANT SELECT ON sql_packages TO PUBLIC;
1586
1587
1588 /*
1589  * 5.55
1590  * SQL_PARTS table
1591  */
1592
1593 CREATE TABLE sql_parts (
1594     feature_id      character_data,
1595     feature_name    character_data,
1596     is_supported    yes_or_no,
1597     is_verified_by  character_data,
1598     comments        character_data
1599 ) WITHOUT OIDS;
1600
1601 INSERT INTO sql_parts VALUES ('1', 'Framework (SQL/Framework)', 'NO', NULL, '');
1602 INSERT INTO sql_parts VALUES ('2', 'Foundation (SQL/Foundation)', 'NO', NULL, '');
1603 INSERT INTO sql_parts VALUES ('3', 'Call-Level Interface (SQL/CLI)', 'NO', NULL, '');
1604 INSERT INTO sql_parts VALUES ('4', 'Persistent Stored Modules (SQL/PSM)', 'NO', NULL, '');
1605 INSERT INTO sql_parts VALUES ('9', 'Management of External Data (SQL/MED)', 'NO', NULL, '');
1606 INSERT INTO sql_parts VALUES ('10', 'Object Language Bindings (SQL/OLB)', 'NO', NULL, '');
1607 INSERT INTO sql_parts VALUES ('11', 'Information and Definition Schema (SQL/Schemata)', 'NO', NULL, '');
1608 INSERT INTO sql_parts VALUES ('13', 'Routines and Types Using the Java Programming Language (SQL/JRT)', 'NO', NULL, '');
1609 INSERT INTO sql_parts VALUES ('14', 'XML-Related Specifications (SQL/XML)', 'YES', NULL, '');
1610
1611
1612 /*
1613  * 5.56
1614  * SQL_SIZING table
1615  */
1616
1617 -- Note: Sizing items are defined in ISO/IEC 9075-3:2008, clause 9.2.
1618
1619 CREATE TABLE sql_sizing (
1620     sizing_id       cardinal_number,
1621     sizing_name     character_data,
1622     supported_value cardinal_number,
1623     comments        character_data
1624 ) WITHOUT OIDS;
1625
1626 INSERT INTO sql_sizing VALUES (34,    'MAXIMUM CATALOG NAME LENGTH', 63, NULL);
1627 INSERT INTO sql_sizing VALUES (30,    'MAXIMUM COLUMN NAME LENGTH', 63, NULL);
1628 INSERT INTO sql_sizing VALUES (97,    'MAXIMUM COLUMNS IN GROUP BY', 0, NULL);
1629 INSERT INTO sql_sizing VALUES (99,    'MAXIMUM COLUMNS IN ORDER BY', 0, NULL);
1630 INSERT INTO sql_sizing VALUES (100,   'MAXIMUM COLUMNS IN SELECT', 1664, NULL); -- match MaxTupleAttributeNumber
1631 INSERT INTO sql_sizing VALUES (101,   'MAXIMUM COLUMNS IN TABLE', 1600, NULL); -- match MaxHeapAttributeNumber
1632 INSERT INTO sql_sizing VALUES (1,     'MAXIMUM CONCURRENT ACTIVITIES', 0, NULL);
1633 INSERT INTO sql_sizing VALUES (31,    'MAXIMUM CURSOR NAME LENGTH', 63, NULL);
1634 INSERT INTO sql_sizing VALUES (0,     'MAXIMUM DRIVER CONNECTIONS', NULL, NULL);
1635 INSERT INTO sql_sizing VALUES (10005, 'MAXIMUM IDENTIFIER LENGTH', 63, NULL);
1636 INSERT INTO sql_sizing VALUES (32,    'MAXIMUM SCHEMA NAME LENGTH', 63, NULL);
1637 INSERT INTO sql_sizing VALUES (20000, 'MAXIMUM STATEMENT OCTETS', 0, NULL);
1638 INSERT INTO sql_sizing VALUES (20001, 'MAXIMUM STATEMENT OCTETS DATA', 0, NULL);
1639 INSERT INTO sql_sizing VALUES (20002, 'MAXIMUM STATEMENT OCTETS SCHEMA', 0, NULL);
1640 INSERT INTO sql_sizing VALUES (35,    'MAXIMUM TABLE NAME LENGTH', 63, NULL);
1641 INSERT INTO sql_sizing VALUES (106,   'MAXIMUM TABLES IN SELECT', 0, NULL);
1642 INSERT INTO sql_sizing VALUES (107,   'MAXIMUM USER NAME LENGTH', 63, NULL);
1643 INSERT INTO sql_sizing VALUES (25000, 'MAXIMUM CURRENT DEFAULT TRANSFORM GROUP LENGTH', NULL, NULL);
1644 INSERT INTO sql_sizing VALUES (25001, 'MAXIMUM CURRENT TRANSFORM GROUP LENGTH', NULL, NULL);
1645 INSERT INTO sql_sizing VALUES (25002, 'MAXIMUM CURRENT PATH LENGTH', 0, NULL);
1646 INSERT INTO sql_sizing VALUES (25003, 'MAXIMUM CURRENT ROLE LENGTH', NULL, NULL);
1647 INSERT INTO sql_sizing VALUES (25004, 'MAXIMUM SESSION USER LENGTH', 63, NULL);
1648 INSERT INTO sql_sizing VALUES (25005, 'MAXIMUM SYSTEM USER LENGTH', 63, NULL);
1649
1650 UPDATE sql_sizing
1651     SET supported_value = (SELECT typlen-1 FROM pg_catalog.pg_type WHERE typname = 'name'),
1652         comments = 'Might be less, depending on character set.'
1653     WHERE supported_value = 63;
1654
1655 GRANT SELECT ON sql_sizing TO PUBLIC;
1656
1657
1658 /*
1659  * 5.57
1660  * SQL_SIZING_PROFILES table
1661  */
1662
1663 -- The data in this table are defined by various profiles of SQL.
1664 -- Since we don't have any information about such profiles, we provide
1665 -- an empty table.
1666
1667 CREATE TABLE sql_sizing_profiles (
1668     sizing_id       cardinal_number,
1669     sizing_name     character_data,
1670     profile_id      character_data,
1671     required_value  cardinal_number,
1672     comments        character_data
1673 ) WITHOUT OIDS;
1674
1675 GRANT SELECT ON sql_sizing_profiles TO PUBLIC;
1676
1677
1678 /*
1679  * 5.58
1680  * TABLE_CONSTRAINTS view
1681  */
1682
1683 CREATE VIEW table_constraints AS
1684     SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog,
1685            CAST(nc.nspname AS sql_identifier) AS constraint_schema,
1686            CAST(c.conname AS sql_identifier) AS constraint_name,
1687            CAST(current_database() AS sql_identifier) AS table_catalog,
1688            CAST(nr.nspname AS sql_identifier) AS table_schema,
1689            CAST(r.relname AS sql_identifier) AS table_name,
1690            CAST(
1691              CASE c.contype WHEN 'c' THEN 'CHECK'
1692                             WHEN 'f' THEN 'FOREIGN KEY'
1693                             WHEN 'p' THEN 'PRIMARY KEY'
1694                             WHEN 'u' THEN 'UNIQUE' END
1695              AS character_data) AS constraint_type,
1696            CAST(CASE WHEN c.condeferrable THEN 'YES' ELSE 'NO' END AS yes_or_no)
1697              AS is_deferrable,
1698            CAST(CASE WHEN c.condeferred THEN 'YES' ELSE 'NO' END AS yes_or_no)
1699              AS initially_deferred
1700
1701     FROM pg_namespace nc,
1702          pg_namespace nr,
1703          pg_constraint c,
1704          pg_class r
1705
1706     WHERE nc.oid = c.connamespace AND nr.oid = r.relnamespace
1707           AND c.conrelid = r.oid
1708           AND c.contype NOT IN ('t', 'x')  -- ignore nonstandard constraints
1709           AND r.relkind = 'r'
1710           AND (NOT pg_is_other_temp_schema(nr.oid))
1711           AND (pg_has_role(r.relowner, 'USAGE')
1712                -- SELECT privilege omitted, per SQL standard
1713                OR has_table_privilege(r.oid, 'INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER')
1714                OR has_any_column_privilege(r.oid, 'INSERT, UPDATE, REFERENCES') )
1715
1716     UNION ALL
1717
1718     -- not-null constraints
1719
1720     SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog,
1721            CAST(nr.nspname AS sql_identifier) AS constraint_schema,
1722            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
1723            CAST(current_database() AS sql_identifier) AS table_catalog,
1724            CAST(nr.nspname AS sql_identifier) AS table_schema,
1725            CAST(r.relname AS sql_identifier) AS table_name,
1726            CAST('CHECK' AS character_data) AS constraint_type,
1727            CAST('NO' AS yes_or_no) AS is_deferrable,
1728            CAST('NO' AS yes_or_no) AS initially_deferred
1729
1730     FROM pg_namespace nr,
1731          pg_class r,
1732          pg_attribute a
1733
1734     WHERE nr.oid = r.relnamespace
1735           AND r.oid = a.attrelid
1736           AND a.attnotnull
1737           AND a.attnum > 0
1738           AND NOT a.attisdropped
1739           AND r.relkind = 'r'
1740           AND (NOT pg_is_other_temp_schema(nr.oid))
1741           AND (pg_has_role(r.relowner, 'USAGE')
1742                -- SELECT privilege omitted, per SQL standard
1743                OR has_table_privilege(r.oid, 'INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER')
1744                OR has_any_column_privilege(r.oid, 'INSERT, UPDATE, REFERENCES') );
1745
1746 GRANT SELECT ON table_constraints TO PUBLIC;
1747
1748
1749 /*
1750  * 5.59
1751  * TABLE_METHOD_PRIVILEGES view
1752  */
1753
1754 -- feature not supported
1755
1756
1757 /*
1758  * 5.60
1759  * TABLE_PRIVILEGES view
1760  */
1761
1762 CREATE VIEW table_privileges AS
1763     SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor,
1764            CAST(grantee.rolname AS sql_identifier) AS grantee,
1765            CAST(current_database() AS sql_identifier) AS table_catalog,
1766            CAST(nc.nspname AS sql_identifier) AS table_schema,
1767            CAST(c.relname AS sql_identifier) AS table_name,
1768            CAST(c.prtype AS character_data) AS privilege_type,
1769            CAST(
1770              CASE WHEN
1771                   -- object owner always has grant options
1772                   pg_has_role(grantee.oid, c.relowner, 'USAGE')
1773                   OR c.grantable
1774                   THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable,
1775            CAST('NO' AS yes_or_no) AS with_hierarchy
1776
1777     FROM (
1778             SELECT oid, relname, relnamespace, relkind, relowner, (aclexplode(relacl)).* FROM pg_class
1779          ) AS c (oid, relname, relnamespace, relkind, relowner, grantor, grantee, prtype, grantable),
1780          pg_namespace nc,
1781          pg_authid u_grantor,
1782          (
1783            SELECT oid, rolname FROM pg_authid
1784            UNION ALL
1785            SELECT 0::oid, 'PUBLIC'
1786          ) AS grantee (oid, rolname)
1787
1788     WHERE c.relnamespace = nc.oid
1789           AND c.relkind IN ('r', 'v')
1790           AND c.grantee = grantee.oid
1791           AND c.grantor = u_grantor.oid
1792           AND c.prtype IN ('INSERT', 'SELECT', 'UPDATE', 'DELETE', 'TRUNCATE', 'REFERENCES', 'TRIGGER')
1793           AND (pg_has_role(u_grantor.oid, 'USAGE')
1794                OR pg_has_role(grantee.oid, 'USAGE')
1795                OR grantee.rolname = 'PUBLIC');
1796
1797 GRANT SELECT ON table_privileges TO PUBLIC;
1798
1799
1800 /*
1801  * 5.40
1802  * ROLE_TABLE_GRANTS view
1803  */
1804
1805 CREATE VIEW role_table_grants AS
1806     SELECT grantor,
1807            grantee,
1808            table_catalog,
1809            table_schema,
1810            table_name,
1811            privilege_type,
1812            is_grantable,
1813            with_hierarchy
1814     FROM table_privileges
1815     WHERE grantor IN (SELECT role_name FROM enabled_roles)
1816           OR grantee IN (SELECT role_name FROM enabled_roles);
1817
1818 GRANT SELECT ON role_table_grants TO PUBLIC;
1819
1820
1821 /*
1822  * 5.61
1823  * TABLES view
1824  */
1825
1826 CREATE VIEW tables AS
1827     SELECT CAST(current_database() AS sql_identifier) AS table_catalog,
1828            CAST(nc.nspname AS sql_identifier) AS table_schema,
1829            CAST(c.relname AS sql_identifier) AS table_name,
1830
1831            CAST(
1832              CASE WHEN nc.oid = pg_my_temp_schema() THEN 'LOCAL TEMPORARY'
1833                   WHEN c.relkind = 'r' THEN 'BASE TABLE'
1834                   WHEN c.relkind = 'v' THEN 'VIEW'
1835                   WHEN c.relkind = 'f' THEN 'FOREIGN TABLE'
1836                   ELSE null END
1837              AS character_data) AS table_type,
1838
1839            CAST(null AS sql_identifier) AS self_referencing_column_name,
1840            CAST(null AS character_data) AS reference_generation,
1841
1842            CAST(CASE WHEN t.typname IS NOT NULL THEN current_database() ELSE null END AS sql_identifier) AS user_defined_type_catalog,
1843            CAST(nt.nspname AS sql_identifier) AS user_defined_type_schema,
1844            CAST(t.typname AS sql_identifier) AS user_defined_type_name,
1845
1846            CAST(CASE WHEN c.relkind = 'r'
1847                           OR (c.relkind = 'v'
1848                               AND EXISTS (SELECT 1 FROM pg_rewrite WHERE ev_class = c.oid AND ev_type = '3' AND is_instead))
1849                 THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_insertable_into,
1850
1851            CAST(CASE WHEN t.typname IS NOT NULL THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_typed,
1852            CAST(
1853              CASE WHEN nc.oid = pg_my_temp_schema() THEN 'PRESERVE' -- FIXME
1854                   ELSE null END
1855              AS character_data) AS commit_action
1856
1857     FROM pg_namespace nc JOIN pg_class c ON (nc.oid = c.relnamespace)
1858            LEFT JOIN (pg_type t JOIN pg_namespace nt ON (t.typnamespace = nt.oid)) ON (c.reloftype = t.oid)
1859
1860     WHERE c.relkind IN ('r', 'v', 'f')
1861           AND (NOT pg_is_other_temp_schema(nc.oid))
1862           AND (pg_has_role(c.relowner, 'USAGE')
1863                OR has_table_privilege(c.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER')
1864                OR has_any_column_privilege(c.oid, 'SELECT, INSERT, UPDATE, REFERENCES') );
1865
1866 GRANT SELECT ON tables TO PUBLIC;
1867
1868
1869 /*
1870  * 5.62
1871  * TRANSFORMS view
1872  */
1873
1874 -- feature not supported
1875
1876
1877 /*
1878  * 5.63
1879  * TRANSLATIONS view
1880  */
1881
1882 -- feature not supported
1883
1884
1885 /*
1886  * 5.64
1887  * TRIGGERED_UPDATE_COLUMNS view
1888  */
1889
1890 CREATE VIEW triggered_update_columns AS
1891     SELECT CAST(current_database() AS sql_identifier) AS trigger_catalog,
1892            CAST(n.nspname AS sql_identifier) AS trigger_schema,
1893            CAST(t.tgname AS sql_identifier) AS trigger_name,
1894            CAST(current_database() AS sql_identifier) AS event_object_catalog,
1895            CAST(n.nspname AS sql_identifier) AS event_object_schema,
1896            CAST(c.relname AS sql_identifier) AS event_object_table,
1897            CAST(a.attname AS sql_identifier) AS event_object_column
1898
1899     FROM pg_namespace n, pg_class c, pg_trigger t,
1900          (SELECT tgoid, (ta0.tgat).x AS tgattnum, (ta0.tgat).n AS tgattpos
1901           FROM (SELECT oid AS tgoid, information_schema._pg_expandarray(tgattr) AS tgat FROM pg_trigger) AS ta0) AS ta,
1902          pg_attribute a
1903
1904     WHERE n.oid = c.relnamespace
1905           AND c.oid = t.tgrelid
1906           AND t.oid = ta.tgoid
1907           AND (a.attrelid, a.attnum) = (t.tgrelid, ta.tgattnum)
1908           AND NOT t.tgisinternal
1909           AND (NOT pg_is_other_temp_schema(n.oid))
1910           AND (pg_has_role(c.relowner, 'USAGE')
1911                -- SELECT privilege omitted, per SQL standard
1912                OR has_column_privilege(c.oid, a.attnum, 'INSERT, UPDATE, REFERENCES') );
1913
1914 GRANT SELECT ON triggered_update_columns TO PUBLIC;
1915
1916
1917 /*
1918  * 5.65
1919  * TRIGGER_COLUMN_USAGE view
1920  */
1921
1922 -- not tracked by PostgreSQL
1923
1924
1925 /*
1926  * 5.66
1927  * TRIGGER_ROUTINE_USAGE view
1928  */
1929
1930 -- not tracked by PostgreSQL
1931
1932
1933 /*
1934  * 5.67
1935  * TRIGGER_SEQUENCE_USAGE view
1936  */
1937
1938 -- not tracked by PostgreSQL
1939
1940
1941 /*
1942  * 5.68
1943  * TRIGGER_TABLE_USAGE view
1944  */
1945
1946 -- not tracked by PostgreSQL
1947
1948
1949 /*
1950  * 5.69
1951  * TRIGGERS view
1952  */
1953
1954 CREATE VIEW triggers AS
1955     SELECT CAST(current_database() AS sql_identifier) AS trigger_catalog,
1956            CAST(n.nspname AS sql_identifier) AS trigger_schema,
1957            CAST(t.tgname AS sql_identifier) AS trigger_name,
1958            CAST(em.text AS character_data) AS event_manipulation,
1959            CAST(current_database() AS sql_identifier) AS event_object_catalog,
1960            CAST(n.nspname AS sql_identifier) AS event_object_schema,
1961            CAST(c.relname AS sql_identifier) AS event_object_table,
1962            CAST(null AS cardinal_number) AS action_order,
1963            -- XXX strange hacks follow
1964            CAST(
1965              CASE WHEN pg_has_role(c.relowner, 'USAGE')
1966                THEN (SELECT m[1] FROM regexp_matches(pg_get_triggerdef(t.oid), E'.{35,} WHEN \\((.+)\\) EXECUTE PROCEDURE') AS rm(m) LIMIT 1)
1967                ELSE null END
1968              AS character_data) AS action_condition,
1969            CAST(
1970              substring(pg_get_triggerdef(t.oid) from
1971                        position('EXECUTE PROCEDURE' in substring(pg_get_triggerdef(t.oid) from 48)) + 47)
1972              AS character_data) AS action_statement,
1973            CAST(
1974              -- hard-wired reference to TRIGGER_TYPE_ROW
1975              CASE t.tgtype & 1 WHEN 1 THEN 'ROW' ELSE 'STATEMENT' END
1976              AS character_data) AS action_orientation,
1977            CAST(
1978              -- hard-wired refs to TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_INSTEAD
1979              CASE t.tgtype & 66 WHEN 2 THEN 'BEFORE' WHEN 64 THEN 'INSTEAD OF' ELSE 'AFTER' END
1980              AS character_data) AS action_timing,
1981            CAST(null AS sql_identifier) AS action_reference_old_table,
1982            CAST(null AS sql_identifier) AS action_reference_new_table,
1983            CAST(null AS sql_identifier) AS action_reference_old_row,
1984            CAST(null AS sql_identifier) AS action_reference_new_row,
1985            CAST(null AS time_stamp) AS created
1986
1987     FROM pg_namespace n, pg_class c, pg_trigger t,
1988          -- hard-wired refs to TRIGGER_TYPE_INSERT, TRIGGER_TYPE_DELETE,
1989          -- TRIGGER_TYPE_UPDATE; we intentionally omit TRIGGER_TYPE_TRUNCATE
1990          (VALUES (4, 'INSERT'),
1991                  (8, 'DELETE'),
1992                  (16, 'UPDATE')) AS em (num, text)
1993
1994     WHERE n.oid = c.relnamespace
1995           AND c.oid = t.tgrelid
1996           AND t.tgtype & em.num <> 0
1997           AND NOT t.tgisinternal
1998           AND (NOT pg_is_other_temp_schema(n.oid))
1999           AND (pg_has_role(c.relowner, 'USAGE')
2000                -- SELECT privilege omitted, per SQL standard
2001                OR has_table_privilege(c.oid, 'INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER')
2002                OR has_any_column_privilege(c.oid, 'INSERT, UPDATE, REFERENCES') );
2003
2004 GRANT SELECT ON triggers TO PUBLIC;
2005
2006
2007 /*
2008  * 5.70
2009  * UDT_PRIVILEGES view
2010  */
2011
2012 -- feature not supported
2013
2014
2015 /*
2016  * 5.71
2017  * USAGE_PRIVILEGES view
2018  */
2019
2020 CREATE VIEW usage_privileges AS
2021
2022     /* domains */
2023     -- Domains have no real privileges, so we represent all domains with implicit usage privilege here.
2024     SELECT CAST(u.rolname AS sql_identifier) AS grantor,
2025            CAST('PUBLIC' AS sql_identifier) AS grantee,
2026            CAST(current_database() AS sql_identifier) AS object_catalog,
2027            CAST(n.nspname AS sql_identifier) AS object_schema,
2028            CAST(t.typname AS sql_identifier) AS object_name,
2029            CAST('DOMAIN' AS character_data) AS object_type,
2030            CAST('USAGE' AS character_data) AS privilege_type,
2031            CAST('NO' AS yes_or_no) AS is_grantable
2032
2033     FROM pg_authid u,
2034          pg_namespace n,
2035          pg_type t
2036
2037     WHERE u.oid = t.typowner
2038           AND t.typnamespace = n.oid
2039           AND t.typtype = 'd'
2040
2041     UNION ALL
2042
2043     /* foreign-data wrappers */
2044     SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor,
2045            CAST(grantee.rolname AS sql_identifier) AS grantee,
2046            CAST(current_database() AS sql_identifier) AS object_catalog,
2047            CAST('' AS sql_identifier) AS object_schema,
2048            CAST(fdw.fdwname AS sql_identifier) AS object_name,
2049            CAST('FOREIGN DATA WRAPPER' AS character_data) AS object_type,
2050            CAST('USAGE' AS character_data) AS privilege_type,
2051            CAST(
2052              CASE WHEN
2053                   -- object owner always has grant options
2054                   pg_has_role(grantee.oid, fdw.fdwowner, 'USAGE')
2055                   OR fdw.grantable
2056                   THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable
2057
2058     FROM (
2059             SELECT fdwname, fdwowner, (aclexplode(fdwacl)).* FROM pg_foreign_data_wrapper
2060          ) AS fdw (fdwname, fdwowner, grantor, grantee, prtype, grantable),
2061          pg_authid u_grantor,
2062          (
2063            SELECT oid, rolname FROM pg_authid
2064            UNION ALL
2065            SELECT 0::oid, 'PUBLIC'
2066          ) AS grantee (oid, rolname)
2067
2068     WHERE u_grantor.oid = fdw.grantor
2069           AND grantee.oid = fdw.grantee
2070           AND fdw.prtype IN ('USAGE')
2071           AND (pg_has_role(u_grantor.oid, 'USAGE')
2072                OR pg_has_role(grantee.oid, 'USAGE')
2073                OR grantee.rolname = 'PUBLIC')
2074
2075     UNION ALL
2076
2077     /* foreign servers */
2078     SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor,
2079            CAST(grantee.rolname AS sql_identifier) AS grantee,
2080            CAST(current_database() AS sql_identifier) AS object_catalog,
2081            CAST('' AS sql_identifier) AS object_schema,
2082            CAST(srv.srvname AS sql_identifier) AS object_name,
2083            CAST('FOREIGN SERVER' AS character_data) AS object_type,
2084            CAST('USAGE' AS character_data) AS privilege_type,
2085            CAST(
2086              CASE WHEN
2087                   -- object owner always has grant options
2088                   pg_has_role(grantee.oid, srv.srvowner, 'USAGE')
2089                   OR srv.grantable
2090                   THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable
2091
2092     FROM (
2093             SELECT srvname, srvowner, (aclexplode(srvacl)).* FROM pg_foreign_server
2094          ) AS srv (srvname, srvowner, grantor, grantee, prtype, grantable),
2095          pg_authid u_grantor,
2096          (
2097            SELECT oid, rolname FROM pg_authid
2098            UNION ALL
2099            SELECT 0::oid, 'PUBLIC'
2100          ) AS grantee (oid, rolname)
2101
2102     WHERE u_grantor.oid = srv.grantor
2103           AND grantee.oid = srv.grantee
2104           AND srv.prtype IN ('USAGE')
2105           AND (pg_has_role(u_grantor.oid, 'USAGE')
2106                OR pg_has_role(grantee.oid, 'USAGE')
2107                OR grantee.rolname = 'PUBLIC');
2108
2109 GRANT SELECT ON usage_privileges TO PUBLIC;
2110
2111
2112 /*
2113  * 5.42
2114  * ROLE_USAGE_GRANTS view
2115  */
2116
2117 CREATE VIEW role_usage_grants AS
2118     SELECT grantor,
2119            grantee,
2120            object_catalog,
2121            object_schema,
2122            object_name,
2123            object_type,
2124            privilege_type,
2125            is_grantable
2126     FROM usage_privileges
2127     WHERE grantor IN (SELECT role_name FROM enabled_roles)
2128           OR grantee IN (SELECT role_name FROM enabled_roles);
2129
2130 GRANT SELECT ON role_usage_grants TO PUBLIC;
2131
2132
2133 /*
2134  * 5.72
2135  * USER_DEFINED_TYPES view
2136  */
2137
2138 -- feature not supported
2139
2140
2141 /*
2142  * 5.73
2143  * VIEW_COLUMN_USAGE
2144  */
2145
2146 CREATE VIEW view_column_usage AS
2147     SELECT DISTINCT
2148            CAST(current_database() AS sql_identifier) AS view_catalog,
2149            CAST(nv.nspname AS sql_identifier) AS view_schema,
2150            CAST(v.relname AS sql_identifier) AS view_name,
2151            CAST(current_database() AS sql_identifier) AS table_catalog,
2152            CAST(nt.nspname AS sql_identifier) AS table_schema,
2153            CAST(t.relname AS sql_identifier) AS table_name,
2154            CAST(a.attname AS sql_identifier) AS column_name
2155
2156     FROM pg_namespace nv, pg_class v, pg_depend dv,
2157          pg_depend dt, pg_class t, pg_namespace nt,
2158          pg_attribute a
2159
2160     WHERE nv.oid = v.relnamespace
2161           AND v.relkind = 'v'
2162           AND v.oid = dv.refobjid
2163           AND dv.refclassid = 'pg_catalog.pg_class'::regclass
2164           AND dv.classid = 'pg_catalog.pg_rewrite'::regclass
2165           AND dv.deptype = 'i'
2166           AND dv.objid = dt.objid
2167           AND dv.refobjid <> dt.refobjid
2168           AND dt.classid = 'pg_catalog.pg_rewrite'::regclass
2169           AND dt.refclassid = 'pg_catalog.pg_class'::regclass
2170           AND dt.refobjid = t.oid
2171           AND t.relnamespace = nt.oid
2172           AND t.relkind IN ('r', 'v', 'f')
2173           AND t.oid = a.attrelid
2174           AND dt.refobjsubid = a.attnum
2175           AND pg_has_role(t.relowner, 'USAGE');
2176
2177 GRANT SELECT ON view_column_usage TO PUBLIC;
2178
2179
2180 /*
2181  * 5.74
2182  * VIEW_ROUTINE_USAGE
2183  */
2184
2185 CREATE VIEW view_routine_usage AS
2186     SELECT DISTINCT
2187            CAST(current_database() AS sql_identifier) AS table_catalog,
2188            CAST(nv.nspname AS sql_identifier) AS table_schema,
2189            CAST(v.relname AS sql_identifier) AS table_name,
2190            CAST(current_database() AS sql_identifier) AS specific_catalog,
2191            CAST(np.nspname AS sql_identifier) AS specific_schema,
2192            CAST(p.proname || '_' || CAST(p.oid AS text)  AS sql_identifier) AS specific_name
2193
2194     FROM pg_namespace nv, pg_class v, pg_depend dv,
2195          pg_depend dp, pg_proc p, pg_namespace np
2196
2197     WHERE nv.oid = v.relnamespace
2198           AND v.relkind = 'v'
2199           AND v.oid = dv.refobjid
2200           AND dv.refclassid = 'pg_catalog.pg_class'::regclass
2201           AND dv.classid = 'pg_catalog.pg_rewrite'::regclass
2202           AND dv.deptype = 'i'
2203           AND dv.objid = dp.objid
2204           AND dp.classid = 'pg_catalog.pg_rewrite'::regclass
2205           AND dp.refclassid = 'pg_catalog.pg_proc'::regclass
2206           AND dp.refobjid = p.oid
2207           AND p.pronamespace = np.oid
2208           AND pg_has_role(p.proowner, 'USAGE');
2209
2210 GRANT SELECT ON view_routine_usage TO PUBLIC;
2211
2212
2213 /*
2214  * 5.75
2215  * VIEW_TABLE_USAGE
2216  */
2217
2218 CREATE VIEW view_table_usage AS
2219     SELECT DISTINCT
2220            CAST(current_database() AS sql_identifier) AS view_catalog,
2221            CAST(nv.nspname AS sql_identifier) AS view_schema,
2222            CAST(v.relname AS sql_identifier) AS view_name,
2223            CAST(current_database() AS sql_identifier) AS table_catalog,
2224            CAST(nt.nspname AS sql_identifier) AS table_schema,
2225            CAST(t.relname AS sql_identifier) AS table_name
2226
2227     FROM pg_namespace nv, pg_class v, pg_depend dv,
2228          pg_depend dt, pg_class t, pg_namespace nt
2229
2230     WHERE nv.oid = v.relnamespace
2231           AND v.relkind = 'v'
2232           AND v.oid = dv.refobjid
2233           AND dv.refclassid = 'pg_catalog.pg_class'::regclass
2234           AND dv.classid = 'pg_catalog.pg_rewrite'::regclass
2235           AND dv.deptype = 'i'
2236           AND dv.objid = dt.objid
2237           AND dv.refobjid <> dt.refobjid
2238           AND dt.classid = 'pg_catalog.pg_rewrite'::regclass
2239           AND dt.refclassid = 'pg_catalog.pg_class'::regclass
2240           AND dt.refobjid = t.oid
2241           AND t.relnamespace = nt.oid
2242           AND t.relkind IN ('r', 'v', 'f')
2243           AND pg_has_role(t.relowner, 'USAGE');
2244
2245 GRANT SELECT ON view_table_usage TO PUBLIC;
2246
2247
2248 /*
2249  * 5.76
2250  * VIEWS view
2251  */
2252
2253 CREATE VIEW views AS
2254     SELECT CAST(current_database() AS sql_identifier) AS table_catalog,
2255            CAST(nc.nspname AS sql_identifier) AS table_schema,
2256            CAST(c.relname AS sql_identifier) AS table_name,
2257
2258            CAST(
2259              CASE WHEN pg_has_role(c.relowner, 'USAGE')
2260                   THEN pg_get_viewdef(c.oid)
2261                   ELSE null END
2262              AS character_data) AS view_definition,
2263
2264            CAST('NONE' AS character_data) AS check_option,
2265
2266            CAST(
2267              CASE WHEN EXISTS (SELECT 1 FROM pg_rewrite WHERE ev_class = c.oid AND ev_type = '2' AND is_instead)
2268                    AND EXISTS (SELECT 1 FROM pg_rewrite WHERE ev_class = c.oid AND ev_type = '4' AND is_instead)
2269                   THEN 'YES' ELSE 'NO' END
2270              AS yes_or_no) AS is_updatable,
2271
2272            CAST(
2273              CASE WHEN EXISTS (SELECT 1 FROM pg_rewrite WHERE ev_class = c.oid AND ev_type = '3' AND is_instead)
2274                   THEN 'YES' ELSE 'NO' END
2275              AS yes_or_no) AS is_insertable_into,
2276
2277            CAST(
2278              -- TRIGGER_TYPE_ROW + TRIGGER_TYPE_INSTEAD + TRIGGER_TYPE_UPDATE
2279              CASE WHEN EXISTS (SELECT 1 FROM pg_trigger WHERE tgrelid = c.oid AND tgtype & 81 = 81)
2280                   THEN 'YES' ELSE 'NO' END
2281            AS yes_or_no) AS is_trigger_updatable,
2282
2283            CAST(
2284              -- TRIGGER_TYPE_ROW + TRIGGER_TYPE_INSTEAD + TRIGGER_TYPE_DELETE
2285              CASE WHEN EXISTS (SELECT 1 FROM pg_trigger WHERE tgrelid = c.oid AND tgtype & 73 = 73)
2286                   THEN 'YES' ELSE 'NO' END
2287            AS yes_or_no) AS is_trigger_deletable,
2288
2289            CAST(
2290              -- TRIGGER_TYPE_ROW + TRIGGER_TYPE_INSTEAD + TRIGGER_TYPE_INSERT
2291              CASE WHEN EXISTS (SELECT 1 FROM pg_trigger WHERE tgrelid = c.oid AND tgtype & 69 = 69)
2292                   THEN 'YES' ELSE 'NO' END
2293            AS yes_or_no) AS is_trigger_insertable_into
2294
2295     FROM pg_namespace nc, pg_class c
2296
2297     WHERE c.relnamespace = nc.oid
2298           AND c.relkind = 'v'
2299           AND (NOT pg_is_other_temp_schema(nc.oid))
2300           AND (pg_has_role(c.relowner, 'USAGE')
2301                OR has_table_privilege(c.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER')
2302                OR has_any_column_privilege(c.oid, 'SELECT, INSERT, UPDATE, REFERENCES') );
2303
2304 GRANT SELECT ON views TO PUBLIC;
2305
2306
2307 -- The following views have dependencies that force them to appear out of order.
2308
2309 /*
2310  * 5.24
2311  * DATA_TYPE_PRIVILEGES view
2312  */
2313
2314 CREATE VIEW data_type_privileges AS
2315     SELECT CAST(current_database() AS sql_identifier) AS object_catalog,
2316            CAST(x.objschema AS sql_identifier) AS object_schema,
2317            CAST(x.objname AS sql_identifier) AS object_name,
2318            CAST(x.objtype AS character_data) AS object_type,
2319            CAST(x.objdtdid AS sql_identifier) AS dtd_identifier
2320
2321     FROM
2322       (
2323         SELECT udt_schema, udt_name, 'USER-DEFINED TYPE'::text, dtd_identifier FROM attributes
2324         UNION ALL
2325         SELECT table_schema, table_name, 'TABLE'::text, dtd_identifier FROM columns
2326         UNION ALL
2327         SELECT domain_schema, domain_name, 'DOMAIN'::text, dtd_identifier FROM domains
2328         UNION ALL
2329         SELECT specific_schema, specific_name, 'ROUTINE'::text, dtd_identifier FROM parameters
2330         UNION ALL
2331         SELECT specific_schema, specific_name, 'ROUTINE'::text, dtd_identifier FROM routines
2332       ) AS x (objschema, objname, objtype, objdtdid);
2333
2334 GRANT SELECT ON data_type_privileges TO PUBLIC;
2335
2336
2337 /*
2338  * 5.29
2339  * ELEMENT_TYPES view
2340  */
2341
2342 CREATE VIEW element_types AS
2343     SELECT CAST(current_database() AS sql_identifier) AS object_catalog,
2344            CAST(n.nspname AS sql_identifier) AS object_schema,
2345            CAST(x.objname AS sql_identifier) AS object_name,
2346            CAST(x.objtype AS character_data) AS object_type,
2347            CAST(x.objdtdid AS sql_identifier) AS collection_type_identifier,
2348            CAST(
2349              CASE WHEN nbt.nspname = 'pg_catalog' THEN format_type(bt.oid, null)
2350                   ELSE 'USER-DEFINED' END AS character_data) AS data_type,
2351
2352            CAST(null AS cardinal_number) AS character_maximum_length,
2353            CAST(null AS cardinal_number) AS character_octet_length,
2354            CAST(null AS sql_identifier) AS character_set_catalog,
2355            CAST(null AS sql_identifier) AS character_set_schema,
2356            CAST(null AS sql_identifier) AS character_set_name,
2357            CAST(null AS sql_identifier) AS collation_catalog,
2358            CAST(null AS sql_identifier) AS collation_schema,
2359            CAST(null AS sql_identifier) AS collation_name,
2360            CAST(null AS cardinal_number) AS numeric_precision,
2361            CAST(null AS cardinal_number) AS numeric_precision_radix,
2362            CAST(null AS cardinal_number) AS numeric_scale,
2363            CAST(null AS cardinal_number) AS datetime_precision,
2364            CAST(null AS character_data) AS interval_type,
2365            CAST(null AS character_data) AS interval_precision,
2366
2367            CAST(null AS character_data) AS domain_default, -- XXX maybe a bug in the standard
2368
2369            CAST(current_database() AS sql_identifier) AS udt_catalog,
2370            CAST(nbt.nspname AS sql_identifier) AS udt_schema,
2371            CAST(bt.typname AS sql_identifier) AS udt_name,
2372
2373            CAST(null AS sql_identifier) AS scope_catalog,
2374            CAST(null AS sql_identifier) AS scope_schema,
2375            CAST(null AS sql_identifier) AS scope_name,
2376
2377            CAST(null AS cardinal_number) AS maximum_cardinality,
2378            CAST('a' || CAST(x.objdtdid AS text) AS sql_identifier) AS dtd_identifier
2379
2380     FROM pg_namespace n, pg_type at, pg_namespace nbt, pg_type bt,
2381          (
2382            /* columns */
2383            SELECT c.relnamespace, CAST(c.relname AS sql_identifier),
2384                   'TABLE'::text, a.attnum, a.atttypid
2385            FROM pg_class c, pg_attribute a
2386            WHERE c.oid = a.attrelid
2387                  AND c.relkind IN ('r', 'v', 'f')
2388                  AND attnum > 0 AND NOT attisdropped
2389
2390            UNION ALL
2391
2392            /* domains */
2393            SELECT t.typnamespace, CAST(t.typname AS sql_identifier),
2394                   'DOMAIN'::text, 1, t.typbasetype
2395            FROM pg_type t
2396            WHERE t.typtype = 'd'
2397
2398            UNION ALL
2399
2400            /* parameters */
2401            SELECT pronamespace, CAST(proname || '_' || CAST(oid AS text) AS sql_identifier),
2402                   'ROUTINE'::text, (ss.x).n, (ss.x).x
2403            FROM (SELECT p.pronamespace, p.proname, p.oid,
2404                         _pg_expandarray(coalesce(p.proallargtypes, p.proargtypes::oid[])) AS x
2405                  FROM pg_proc p) AS ss
2406
2407            UNION ALL
2408
2409            /* result types */
2410            SELECT p.pronamespace, CAST(p.proname || '_' || CAST(p.oid AS text) AS sql_identifier),
2411                   'ROUTINE'::text, 0, p.prorettype
2412            FROM pg_proc p
2413
2414          ) AS x (objschema, objname, objtype, objdtdid, objtypeid)
2415
2416     WHERE n.oid = x.objschema
2417           AND at.oid = x.objtypeid
2418           AND (at.typelem <> 0 AND at.typlen = -1)
2419           AND at.typelem = bt.oid
2420           AND nbt.oid = bt.typnamespace
2421
2422           AND (n.nspname, x.objname, x.objtype, CAST(x.objdtdid AS sql_identifier)) IN
2423               ( SELECT object_schema, object_name, object_type, dtd_identifier
2424                     FROM data_type_privileges );
2425
2426 GRANT SELECT ON element_types TO PUBLIC;
2427
2428
2429 -- SQL/MED views; these use section numbers from part 9 of the standard.
2430
2431 /* Base view for foreign-data wrappers */
2432 CREATE VIEW _pg_foreign_data_wrappers AS
2433     SELECT w.oid,
2434            w.fdwowner,
2435            w.fdwoptions,
2436            CAST(current_database() AS sql_identifier) AS foreign_data_wrapper_catalog,
2437            CAST(fdwname AS sql_identifier) AS foreign_data_wrapper_name,
2438            CAST(u.rolname AS sql_identifier) AS authorization_identifier,
2439            CAST('c' AS character_data) AS foreign_data_wrapper_language
2440     FROM pg_foreign_data_wrapper w, pg_authid u
2441     WHERE u.oid = w.fdwowner
2442           AND (pg_has_role(fdwowner, 'USAGE')
2443                OR has_foreign_data_wrapper_privilege(w.oid, 'USAGE'));
2444
2445
2446 /*
2447  * 24.4
2448  * FOREIGN_DATA_WRAPPER_OPTIONS view
2449  */
2450 CREATE VIEW foreign_data_wrapper_options AS
2451     SELECT foreign_data_wrapper_catalog,
2452            foreign_data_wrapper_name,
2453            CAST((pg_options_to_table(w.fdwoptions)).option_name AS sql_identifier) AS option_name,
2454            CAST((pg_options_to_table(w.fdwoptions)).option_value AS character_data) AS option_value
2455     FROM _pg_foreign_data_wrappers w;
2456
2457 GRANT SELECT ON foreign_data_wrapper_options TO PUBLIC;
2458
2459
2460 /*
2461  * 24.5
2462  * FOREIGN_DATA_WRAPPERS view
2463  */
2464 CREATE VIEW foreign_data_wrappers AS
2465     SELECT foreign_data_wrapper_catalog,
2466            foreign_data_wrapper_name,
2467            authorization_identifier,
2468            CAST(NULL AS character_data) AS library_name,
2469            foreign_data_wrapper_language
2470     FROM _pg_foreign_data_wrappers w;
2471
2472 GRANT SELECT ON foreign_data_wrappers TO PUBLIC;
2473
2474
2475 /* Base view for foreign servers */
2476 CREATE VIEW _pg_foreign_servers AS
2477     SELECT s.oid,
2478            s.srvoptions,
2479            CAST(current_database() AS sql_identifier) AS foreign_server_catalog,
2480            CAST(srvname AS sql_identifier) AS foreign_server_name,
2481            CAST(current_database() AS sql_identifier) AS foreign_data_wrapper_catalog,
2482            CAST(w.fdwname AS sql_identifier) AS foreign_data_wrapper_name,
2483            CAST(srvtype AS character_data) AS foreign_server_type,
2484            CAST(srvversion AS character_data) AS foreign_server_version,
2485            CAST(u.rolname AS sql_identifier) AS authorization_identifier
2486     FROM pg_foreign_server s, pg_foreign_data_wrapper w, pg_authid u
2487     WHERE w.oid = s.srvfdw
2488           AND u.oid = s.srvowner
2489           AND (pg_has_role(s.srvowner, 'USAGE')
2490                OR has_server_privilege(s.oid, 'USAGE'));
2491
2492
2493 /*
2494  * 24.6
2495  * FOREIGN_SERVER_OPTIONS view
2496  */
2497 CREATE VIEW foreign_server_options AS
2498     SELECT foreign_server_catalog,
2499            foreign_server_name,
2500            CAST((pg_options_to_table(s.srvoptions)).option_name AS sql_identifier) AS option_name,
2501            CAST((pg_options_to_table(s.srvoptions)).option_value AS character_data) AS option_value
2502     FROM _pg_foreign_servers s;
2503
2504 GRANT SELECT ON TABLE foreign_server_options TO PUBLIC;
2505
2506
2507 /*
2508  * 24.7
2509  * FOREIGN_SERVERS view
2510  */
2511 CREATE VIEW foreign_servers AS
2512     SELECT foreign_server_catalog,
2513            foreign_server_name,
2514            foreign_data_wrapper_catalog,
2515            foreign_data_wrapper_name,
2516            foreign_server_type,
2517            foreign_server_version,
2518            authorization_identifier
2519     FROM _pg_foreign_servers;
2520
2521 GRANT SELECT ON foreign_servers TO PUBLIC;
2522
2523
2524 /* Base view for foreign tables */
2525 CREATE VIEW _pg_foreign_tables AS
2526     SELECT
2527            CAST(current_database() AS sql_identifier) AS foreign_table_catalog,
2528            n.nspname AS foreign_table_schema,
2529            c.relname AS foreign_table_name,
2530            t.ftoptions AS ftoptions,
2531            CAST(current_database() AS sql_identifier) AS foreign_server_catalog,
2532            CAST(srvname AS sql_identifier) AS foreign_server_name,
2533            CAST(u.rolname AS sql_identifier) AS authorization_identifier
2534     FROM pg_foreign_table t, pg_foreign_server s, pg_foreign_data_wrapper w,
2535          pg_authid u, pg_namespace n, pg_class c
2536     WHERE w.oid = s.srvfdw
2537           AND u.oid = c.relowner
2538           AND (pg_has_role(c.relowner, 'USAGE')
2539                OR has_table_privilege(c.oid, 'SELECT')
2540                OR has_any_column_privilege(c.oid, 'SELECT'))
2541           AND n.oid = c.relnamespace
2542           AND c.oid = t.ftrelid
2543           AND c.relkind = 'f'
2544           AND s.oid = t.ftserver;
2545
2546
2547 /*
2548  * 24.8
2549  * FOREIGN_TABLE_OPTIONS view
2550  */
2551 CREATE VIEW foreign_table_options AS
2552     SELECT foreign_table_catalog,
2553            foreign_table_schema,
2554            foreign_table_name,
2555            CAST((pg_options_to_table(t.ftoptions)).option_name AS sql_identifier) AS option_name,
2556            CAST((pg_options_to_table(t.ftoptions)).option_value AS character_data) AS option_value
2557     FROM _pg_foreign_tables t;
2558
2559 GRANT SELECT ON TABLE foreign_table_options TO PUBLIC;
2560
2561
2562 /*
2563  * 24.9
2564  * FOREIGN_TABLES view
2565  */
2566 CREATE VIEW foreign_tables AS
2567     SELECT foreign_table_catalog,
2568            foreign_table_schema,
2569            foreign_table_name,
2570            foreign_server_catalog,
2571            foreign_server_name
2572     FROM _pg_foreign_tables;
2573
2574 GRANT SELECT ON foreign_tables TO PUBLIC;
2575
2576
2577
2578 /* Base view for user mappings */
2579 CREATE VIEW _pg_user_mappings AS
2580     SELECT um.oid,
2581            um.umoptions,
2582            um.umuser,
2583            CAST(COALESCE(u.rolname,'PUBLIC') AS sql_identifier ) AS authorization_identifier,
2584            s.foreign_server_catalog,
2585            s.foreign_server_name,
2586            s.authorization_identifier AS srvowner
2587     FROM pg_user_mapping um LEFT JOIN pg_authid u ON (u.oid = um.umuser),
2588          _pg_foreign_servers s
2589     WHERE s.oid = um.umserver;
2590
2591
2592 /*
2593  * 24.12
2594  * USER_MAPPING_OPTIONS view
2595  */
2596 CREATE VIEW user_mapping_options AS
2597     SELECT authorization_identifier,
2598            foreign_server_catalog,
2599            foreign_server_name,
2600            CAST((pg_options_to_table(um.umoptions)).option_name AS sql_identifier) AS option_name,
2601            CAST(CASE WHEN (umuser <> 0 AND authorization_identifier = current_user)
2602                        OR (umuser = 0 AND pg_has_role(srvowner, 'USAGE'))
2603                        OR (SELECT rolsuper FROM pg_authid WHERE rolname = current_user) THEN (pg_options_to_table(um.umoptions)).option_value
2604                      ELSE NULL END AS character_data) AS option_value
2605     FROM _pg_user_mappings um;
2606
2607 GRANT SELECT ON user_mapping_options TO PUBLIC;
2608
2609
2610 /*
2611  * 24.13
2612  * USER_MAPPINGS view
2613  */
2614 CREATE VIEW user_mappings AS
2615     SELECT authorization_identifier,
2616            foreign_server_catalog,
2617            foreign_server_name
2618     FROM _pg_user_mappings;
2619
2620 GRANT SELECT ON user_mappings TO PUBLIC;