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