]> granicus.if.org Git - postgresql/blob - src/backend/catalog/information_schema.sql
Update information schema for SQL:2003 and new PostgreSQL features.
[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.33 2006/04/02 17:38:13 petere 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
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            CAST(null AS cardinal_number) AS position_in_unique_constraint  -- FIXME
925     FROM pg_attribute a,
926          (SELECT r.oid, nc.nspname AS nc_nspname, c.conname,
927                  nr.nspname AS nr_nspname, r.relname,
928                 _pg_expandarray(c.conkey) AS x
929           FROM pg_namespace nr, pg_class r, pg_namespace nc,
930                pg_constraint c
931           WHERE nr.oid = r.relnamespace
932                 AND r.oid = c.conrelid
933                 AND nc.oid = c.connamespace
934                 AND c.contype IN ('p', 'u', 'f')
935                 AND r.relkind = 'r'
936                 AND (pg_has_role(r.relowner, 'USAGE')
937                      OR has_table_privilege(c.oid, 'SELECT')
938                      OR has_table_privilege(c.oid, 'INSERT')
939                      OR has_table_privilege(c.oid, 'UPDATE')
940                      OR has_table_privilege(c.oid, 'REFERENCES')) ) AS ss
941     WHERE ss.oid = a.attrelid
942           AND a.attnum = (ss.x).x
943           AND NOT a.attisdropped;
944
945 GRANT SELECT ON key_column_usage TO PUBLIC;
946
947
948 /*
949  * 5.32
950  * METHOD_SPECIFICATION_PARAMETERS view
951  */
952
953 -- feature not supported
954
955
956 /*
957  * 5.33
958  * METHOD_SPECIFICATIONS view
959  */
960
961 -- feature not supported
962
963
964 /*
965  * 5.34
966  * PARAMETERS view
967  */
968
969 CREATE VIEW parameters AS
970     SELECT CAST(current_database() AS sql_identifier) AS specific_catalog,
971            CAST(n_nspname AS sql_identifier) AS specific_schema,
972            CAST(proname || '_' || CAST(p_oid AS text) AS sql_identifier) AS specific_name,
973            CAST((ss.x).n AS cardinal_number) AS ordinal_position,
974            CAST(
975              CASE WHEN proargmodes IS NULL THEN 'IN'
976                 WHEN proargmodes[(ss.x).n] = 'i' THEN 'IN'
977                 WHEN proargmodes[(ss.x).n] = 'o' THEN 'OUT'
978                 WHEN proargmodes[(ss.x).n] = 'b' THEN 'INOUT'
979              END AS character_data) AS parameter_mode,
980            CAST('NO' AS character_data) AS is_result,
981            CAST('NO' AS character_data) AS as_locator,
982            CAST(NULLIF(proargnames[(ss.x).n], '') AS sql_identifier) AS parameter_name,
983            CAST(
984              CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'ARRAY'
985                   WHEN nt.nspname = 'pg_catalog' THEN format_type(t.oid, null)
986                   ELSE 'USER-DEFINED' END AS character_data)
987              AS data_type,
988            CAST(null AS cardinal_number) AS character_maximum_length,
989            CAST(null AS cardinal_number) AS character_octet_length,
990            CAST(null AS sql_identifier) AS character_set_catalog,
991            CAST(null AS sql_identifier) AS character_set_schema,
992            CAST(null AS sql_identifier) AS character_set_name,
993            CAST(null AS sql_identifier) AS collation_catalog,
994            CAST(null AS sql_identifier) AS collation_schema,
995            CAST(null AS sql_identifier) AS collation_name,
996            CAST(null AS cardinal_number) AS numeric_precision,
997            CAST(null AS cardinal_number) AS numeric_precision_radix,
998            CAST(null AS cardinal_number) AS numeric_scale,
999            CAST(null AS cardinal_number) AS datetime_precision,
1000            CAST(null AS character_data) AS interval_type,
1001            CAST(null AS character_data) AS interval_precision,
1002            CAST(current_database() AS sql_identifier) AS udt_catalog,
1003            CAST(nt.nspname AS sql_identifier) AS udt_schema,
1004            CAST(t.typname AS sql_identifier) AS udt_name,
1005            CAST(null AS sql_identifier) AS scope_catalog,
1006            CAST(null AS sql_identifier) AS scope_schema,
1007            CAST(null AS sql_identifier) AS scope_name,
1008            CAST(null AS cardinal_number) AS maximum_cardinality,
1009            CAST((ss.x).n AS sql_identifier) AS dtd_identifier
1010
1011     FROM pg_type t, pg_namespace nt,
1012          (SELECT n.nspname AS n_nspname, p.proname, p.oid AS p_oid,
1013                  p.proargnames, p.proargmodes,
1014                  _pg_expandarray(coalesce(p.proallargtypes, p.proargtypes::oid[])) AS x
1015           FROM pg_namespace n, pg_proc p
1016           WHERE n.oid = p.pronamespace
1017                 AND (pg_has_role(p.proowner, 'USAGE') OR
1018                      has_function_privilege(p.oid, 'EXECUTE'))) AS ss
1019     WHERE t.oid = (ss.x).x AND t.typnamespace = nt.oid;
1020
1021 GRANT SELECT ON parameters TO PUBLIC;
1022
1023
1024 /*
1025  * 5.35
1026  * REFERENCED_TYPES view
1027  */
1028
1029 -- feature not supported
1030
1031
1032 /*
1033  * 5.36
1034  * REFERENTIAL_CONSTRAINTS view
1035  */
1036
1037 CREATE VIEW referential_constraints AS
1038     SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog,
1039            CAST(ncon.nspname AS sql_identifier) AS constraint_schema,
1040            CAST(con.conname AS sql_identifier) AS constraint_name,
1041            CAST(
1042              CASE WHEN npkc.nspname IS NULL THEN NULL
1043                   ELSE current_database() END
1044              AS sql_identifier) AS unique_constraint_catalog,
1045            CAST(npkc.nspname AS sql_identifier) AS unique_constraint_schema,
1046            CAST(pkc.conname AS sql_identifier) AS unique_constraint_name,
1047
1048            CAST(
1049              CASE con.confmatchtype WHEN 'f' THEN 'FULL'
1050                                     WHEN 'p' THEN 'PARTIAL'
1051                                     WHEN 'u' THEN 'NONE' END
1052              AS character_data) AS match_option,
1053
1054            CAST(
1055              CASE con.confupdtype WHEN 'c' THEN 'CASCADE'
1056                                   WHEN 'n' THEN 'SET NULL'
1057                                   WHEN 'd' THEN 'SET DEFAULT'
1058                                   WHEN 'r' THEN 'RESTRICT'
1059                                   WHEN 'a' THEN 'NO ACTION' END
1060              AS character_data) AS update_rule,
1061
1062            CAST(
1063              CASE con.confdeltype 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 delete_rule
1069
1070     FROM (pg_namespace ncon
1071           INNER JOIN pg_constraint con ON ncon.oid = con.connamespace
1072           INNER JOIN pg_class c ON con.conrelid = c.oid)
1073          LEFT JOIN
1074          (pg_constraint pkc
1075           INNER JOIN pg_namespace npkc ON pkc.connamespace = npkc.oid)
1076          ON con.confrelid = pkc.conrelid
1077             AND _pg_keysequal(con.confkey, pkc.conkey)
1078
1079     WHERE c.relkind = 'r'
1080           AND con.contype = 'f'
1081           AND (pkc.contype IN ('p', 'u') OR pkc.contype IS NULL)
1082           AND pg_has_role(c.relowner, 'USAGE');
1083
1084 GRANT SELECT ON referential_constraints TO PUBLIC;
1085
1086
1087 /*
1088  * 5.37
1089  * ROLE_COLUMN_GRANTS view
1090  */
1091
1092 CREATE VIEW role_column_grants AS
1093     SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor,
1094            CAST(g_grantee.rolname AS sql_identifier) AS grantee,
1095            CAST(current_database() AS sql_identifier) AS table_catalog,
1096            CAST(nc.nspname AS sql_identifier) AS table_schema,
1097            CAST(c.relname AS sql_identifier) AS table_name,
1098            CAST(a.attname AS sql_identifier) AS column_name,
1099            CAST(pr.type AS character_data) AS privilege_type,
1100            CAST(
1101              CASE WHEN aclcontains(c.relacl,
1102                                    makeaclitem(g_grantee.oid, u_grantor.oid, pr.type, true))
1103                   THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable
1104
1105     FROM pg_attribute a,
1106          pg_class c,
1107          pg_namespace nc,
1108          pg_authid u_grantor,
1109          pg_authid g_grantee,
1110          (SELECT 'SELECT' UNION ALL
1111           SELECT 'INSERT' UNION ALL
1112           SELECT 'UPDATE' UNION ALL
1113           SELECT 'REFERENCES') AS pr (type)
1114
1115     WHERE a.attrelid = c.oid
1116           AND c.relnamespace = nc.oid
1117           AND a.attnum > 0
1118           AND NOT a.attisdropped
1119           AND c.relkind IN ('r', 'v')
1120           AND aclcontains(c.relacl,
1121                           makeaclitem(g_grantee.oid, u_grantor.oid, pr.type, false))
1122           AND (u_grantor.rolname IN (SELECT role_name FROM enabled_roles)
1123                OR g_grantee.rolname IN (SELECT role_name FROM enabled_roles));
1124
1125 GRANT SELECT ON role_column_grants TO PUBLIC;
1126
1127
1128 /*
1129  * 5.38
1130  * ROLE_ROUTINE_GRANTS view
1131  */
1132
1133 CREATE VIEW role_routine_grants AS
1134     SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor,
1135            CAST(g_grantee.rolname AS sql_identifier) AS grantee,
1136            CAST(current_database() AS sql_identifier) AS specific_catalog,
1137            CAST(n.nspname AS sql_identifier) AS specific_schema,
1138            CAST(p.proname || '_' || CAST(p.oid AS text) AS sql_identifier) AS specific_name,
1139            CAST(current_database() AS sql_identifier) AS routine_catalog,
1140            CAST(n.nspname AS sql_identifier) AS routine_schema,
1141            CAST(p.proname AS sql_identifier) AS routine_name,
1142            CAST('EXECUTE' AS character_data) AS privilege_type,
1143            CAST(
1144              CASE WHEN aclcontains(p.proacl,
1145                                    makeaclitem(g_grantee.oid, u_grantor.oid, 'EXECUTE', true))
1146                   THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable
1147
1148     FROM pg_proc p,
1149          pg_namespace n,
1150          pg_authid u_grantor,
1151          pg_authid g_grantee
1152
1153     WHERE p.pronamespace = n.oid
1154           AND aclcontains(p.proacl,
1155                           makeaclitem(g_grantee.oid, u_grantor.oid, 'EXECUTE', false))
1156           AND (u_grantor.rolname IN (SELECT role_name FROM enabled_roles)
1157                OR g_grantee.rolname IN (SELECT role_name FROM enabled_roles));
1158
1159 GRANT SELECT ON role_routine_grants TO PUBLIC;
1160
1161
1162 /*
1163  * 5.39
1164  * ROLE_TABLE_GRANTS view
1165  */
1166
1167 CREATE VIEW role_table_grants AS
1168     SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor,
1169            CAST(g_grantee.rolname AS sql_identifier) AS grantee,
1170            CAST(current_database() AS sql_identifier) AS table_catalog,
1171            CAST(nc.nspname AS sql_identifier) AS table_schema,
1172            CAST(c.relname AS sql_identifier) AS table_name,
1173            CAST(pr.type AS character_data) AS privilege_type,
1174            CAST(
1175              CASE WHEN aclcontains(c.relacl,
1176                                    makeaclitem(g_grantee.oid, u_grantor.oid, pr.type, true))
1177                   THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable,
1178            CAST('NO' AS character_data) AS with_hierarchy
1179
1180     FROM pg_class c,
1181          pg_namespace nc,
1182          pg_authid u_grantor,
1183          pg_authid g_grantee,
1184          (SELECT 'SELECT' UNION ALL
1185           SELECT 'DELETE' UNION ALL
1186           SELECT 'INSERT' UNION ALL
1187           SELECT 'UPDATE' UNION ALL
1188           SELECT 'REFERENCES' UNION ALL
1189           SELECT 'RULE' UNION ALL
1190           SELECT 'TRIGGER') AS pr (type)
1191
1192     WHERE c.relnamespace = nc.oid
1193           AND c.relkind IN ('r', 'v')
1194           AND aclcontains(c.relacl,
1195                           makeaclitem(g_grantee.oid, u_grantor.oid, pr.type, false))
1196           AND (u_grantor.rolname IN (SELECT role_name FROM enabled_roles)
1197                OR g_grantee.rolname IN (SELECT role_name FROM enabled_roles));
1198
1199 GRANT SELECT ON role_table_grants TO PUBLIC;
1200
1201
1202 /*
1203  * 5.40
1204  * ROLE_TABLE_METHOD_GRANTS view
1205  */
1206
1207 -- feature not supported
1208
1209
1210 /*
1211  * 5.41
1212  * ROLE_USAGE_GRANTS view
1213  */
1214
1215 -- See USAGE_PRIVILEGES.
1216
1217 CREATE VIEW role_usage_grants AS
1218     SELECT CAST(null AS sql_identifier) AS grantor,
1219            CAST(null AS sql_identifier) AS grantee,
1220            CAST(current_database() AS sql_identifier) AS object_catalog,
1221            CAST(null AS sql_identifier) AS object_schema,
1222            CAST(null AS sql_identifier) AS object_name,
1223            CAST(null AS character_data) AS object_type,
1224            CAST('USAGE' AS character_data) AS privilege_type,
1225            CAST(null AS character_data) AS is_grantable
1226
1227     WHERE false;
1228
1229 GRANT SELECT ON role_usage_grants TO PUBLIC;
1230
1231
1232 /*
1233  * 5.42
1234  * ROLE_UDT_GRANTS view
1235  */
1236
1237 -- feature not supported
1238
1239
1240 /*
1241  * 5.43
1242  * ROUTINE_COLUMN_USAGE view
1243  */
1244
1245 -- not tracked by PostgreSQL
1246
1247
1248 /*
1249  * 5.44
1250  * ROUTINE_PRIVILEGES view
1251  */
1252
1253 CREATE VIEW routine_privileges AS
1254     SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor,
1255            CAST(grantee.rolname AS sql_identifier) AS grantee,
1256            CAST(current_database() AS sql_identifier) AS specific_catalog,
1257            CAST(n.nspname AS sql_identifier) AS specific_schema,
1258            CAST(p.proname || '_' || CAST(p.oid AS text) AS sql_identifier) AS specific_name,
1259            CAST(current_database() AS sql_identifier) AS routine_catalog,
1260            CAST(n.nspname AS sql_identifier) AS routine_schema,
1261            CAST(p.proname AS sql_identifier) AS routine_name,
1262            CAST('EXECUTE' AS character_data) AS privilege_type,
1263            CAST(
1264              CASE WHEN aclcontains(p.proacl,
1265                                    makeaclitem(grantee.oid, u_grantor.oid, 'EXECUTE', true))
1266                   THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable
1267
1268     FROM pg_proc p,
1269          pg_namespace n,
1270          pg_authid u_grantor,
1271          (
1272            SELECT oid, rolname FROM pg_authid
1273            UNION ALL
1274            SELECT 0::oid, 'PUBLIC'
1275          ) AS grantee (oid, rolname)
1276
1277     WHERE p.pronamespace = n.oid
1278           AND aclcontains(p.proacl,
1279                           makeaclitem(grantee.oid, u_grantor.oid, 'EXECUTE', false))
1280           AND (pg_has_role(u_grantor.oid, 'USAGE')
1281                OR pg_has_role(grantee.oid, 'USAGE')
1282                OR grantee.rolname = 'PUBLIC');
1283
1284 GRANT SELECT ON routine_privileges TO PUBLIC;
1285
1286
1287 /*
1288  * 5.45
1289  * ROUTINE_ROUTINE_USAGE view
1290  */
1291
1292 -- not tracked by PostgreSQL
1293
1294
1295 /* 
1296  * 5.46
1297  * ROUTINE_SEQUENCE_USAGE view
1298  */
1299
1300 -- not tracked by PostgreSQL
1301
1302
1303 /*
1304  * 5.47
1305  * ROUTINE_TABLE_USAGE view
1306  */
1307
1308 -- not tracked by PostgreSQL
1309
1310
1311 /*
1312  * 5.48
1313  * ROUTINES view
1314  */
1315
1316 CREATE VIEW routines AS
1317     SELECT CAST(current_database() AS sql_identifier) AS specific_catalog,
1318            CAST(n.nspname AS sql_identifier) AS specific_schema,
1319            CAST(p.proname || '_' || CAST(p.oid AS text) AS sql_identifier) AS specific_name,
1320            CAST(current_database() AS sql_identifier) AS routine_catalog,
1321            CAST(n.nspname AS sql_identifier) AS routine_schema,
1322            CAST(p.proname AS sql_identifier) AS routine_name,
1323            CAST('FUNCTION' AS character_data) AS routine_type,
1324            CAST(null AS sql_identifier) AS module_catalog,
1325            CAST(null AS sql_identifier) AS module_schema,
1326            CAST(null AS sql_identifier) AS module_name,
1327            CAST(null AS sql_identifier) AS udt_catalog,
1328            CAST(null AS sql_identifier) AS udt_schema,
1329            CAST(null AS sql_identifier) AS udt_name,
1330
1331            CAST(
1332              CASE WHEN t.typelem <> 0 AND t.typlen = -1 THEN 'ARRAY'
1333                   WHEN nt.nspname = 'pg_catalog' THEN format_type(t.oid, null)
1334                   ELSE 'USER-DEFINED' END AS character_data)
1335              AS data_type,
1336            CAST(null AS cardinal_number) AS character_maximum_length,
1337            CAST(null AS cardinal_number) AS character_octet_length,
1338            CAST(null AS sql_identifier) AS character_set_catalog,
1339            CAST(null AS sql_identifier) AS character_set_schema,
1340            CAST(null AS sql_identifier) AS character_set_name,
1341            CAST(null AS sql_identifier) AS collation_catalog,
1342            CAST(null AS sql_identifier) AS collation_schema,
1343            CAST(null AS sql_identifier) AS collation_name,
1344            CAST(null AS cardinal_number) AS numeric_precision,
1345            CAST(null AS cardinal_number) AS numeric_precision_radix,
1346            CAST(null AS cardinal_number) AS numeric_scale,
1347            CAST(null AS cardinal_number) AS datetime_precision,
1348            CAST(null AS character_data) AS interval_type,
1349            CAST(null AS character_data) AS interval_precision,
1350            CAST(current_database() AS sql_identifier) AS type_udt_catalog,
1351            CAST(nt.nspname AS sql_identifier) AS type_udt_schema,
1352            CAST(t.typname AS sql_identifier) AS type_udt_name,
1353            CAST(null AS sql_identifier) AS scope_catalog,
1354            CAST(null AS sql_identifier) AS scope_schema,
1355            CAST(null AS sql_identifier) AS scope_name,
1356            CAST(null AS cardinal_number) AS maximum_cardinality,
1357            CAST(0 AS sql_identifier) AS dtd_identifier,
1358
1359            CAST(CASE WHEN l.lanname = 'sql' THEN 'SQL' ELSE 'EXTERNAL' END AS character_data)
1360              AS routine_body,
1361            CAST(
1362              CASE WHEN pg_has_role(p.proowner, 'USAGE') THEN p.prosrc ELSE null END
1363              AS character_data) AS routine_definition,
1364            CAST(
1365              CASE WHEN l.lanname = 'c' THEN p.prosrc ELSE null END
1366              AS character_data) AS external_name,
1367            CAST(upper(l.lanname) AS character_data) AS external_language,
1368
1369            CAST('GENERAL' AS character_data) AS parameter_style,
1370            CAST(CASE WHEN p.provolatile = 'i' THEN 'YES' ELSE 'NO' END AS character_data) AS is_deterministic,
1371            CAST('MODIFIES' AS character_data) AS sql_data_access,
1372            CAST(CASE WHEN p.proisstrict THEN 'YES' ELSE 'NO' END AS character_data) AS is_null_call,
1373            CAST(null AS character_data) AS sql_path,
1374            CAST('YES' AS character_data) AS schema_level_routine,
1375            CAST(0 AS cardinal_number) AS max_dynamic_result_sets,
1376            CAST(null AS character_data) AS is_user_defined_cast,
1377            CAST(null AS character_data) AS is_implicitly_invocable,
1378            CAST(CASE WHEN p.prosecdef THEN 'DEFINER' ELSE 'INVOKER' END AS character_data) AS security_type,
1379            CAST(null AS sql_identifier) AS to_sql_specific_catalog,
1380            CAST(null AS sql_identifier) AS to_sql_specific_schema,
1381            CAST(null AS sql_identifier) AS to_sql_specific_name,
1382            CAST('NO' AS character_data) AS as_locator,
1383            CAST(null AS time_stamp) AS created,
1384            CAST(null AS time_stamp) AS last_altered,
1385            CAST(null AS character_data) AS new_savepoint_level,
1386            CAST('YES' AS character_data) AS is_udt_dependent, -- FIXME?
1387
1388            CAST(null AS character_data) AS result_cast_from_data_type,
1389            CAST(null AS character_data) AS result_cast_as_locator,
1390            CAST(null AS cardinal_number) AS result_cast_char_max_length,
1391            CAST(null AS cardinal_number) AS result_cast_char_octet_length,
1392            CAST(null AS sql_identifier) AS result_cast_char_set_catalog,
1393            CAST(null AS sql_identifier) AS result_cast_char_set_schema,
1394            CAST(null AS sql_identifier) AS result_cast_character_set_name,
1395            CAST(null AS sql_identifier) AS result_cast_collation_catalog,
1396            CAST(null AS sql_identifier) AS result_cast_collation_schema,
1397            CAST(null AS sql_identifier) AS result_cast_collation_name,
1398            CAST(null AS cardinal_number) AS result_cast_numeric_precision,
1399            CAST(null AS cardinal_number) AS result_cast_numeric_precision_radix,
1400            CAST(null AS cardinal_number) AS result_cast_numeric_scale,
1401            CAST(null AS cardinal_number) AS result_cast_datetime_precision,
1402            CAST(null AS character_data) AS result_cast_interval_type,
1403            CAST(null AS character_data) AS result_cast_interval_precision,
1404            CAST(null AS sql_identifier) AS result_cast_type_udt_catalog,
1405            CAST(null AS sql_identifier) AS result_cast_type_udt_schema,
1406            CAST(null AS sql_identifier) AS result_cast_type_udt_name,
1407            CAST(null AS sql_identifier) AS result_cast_scope_catalog,
1408            CAST(null AS sql_identifier) AS result_cast_scope_schema,
1409            CAST(null AS sql_identifier) AS result_cast_scope_name,
1410            CAST(null AS cardinal_number) AS result_cast_maximum_cardinality,
1411            CAST(null AS sql_identifier) AS result_cast_dtd_identifier           
1412
1413     FROM pg_namespace n, pg_proc p, pg_language l,
1414          pg_type t, pg_namespace nt
1415
1416     WHERE n.oid = p.pronamespace AND p.prolang = l.oid
1417           AND p.prorettype = t.oid AND t.typnamespace = nt.oid
1418           AND (pg_has_role(p.proowner, 'USAGE')
1419                OR has_function_privilege(p.oid, 'EXECUTE'));
1420
1421 GRANT SELECT ON routines TO PUBLIC;
1422
1423
1424 /*
1425  * 5.49
1426  * SCHEMATA view
1427  */
1428
1429 CREATE VIEW schemata AS
1430     SELECT CAST(current_database() AS sql_identifier) AS catalog_name,
1431            CAST(n.nspname AS sql_identifier) AS schema_name,
1432            CAST(u.rolname AS sql_identifier) AS schema_owner,
1433            CAST(null AS sql_identifier) AS default_character_set_catalog,
1434            CAST(null AS sql_identifier) AS default_character_set_schema,
1435            CAST(null AS sql_identifier) AS default_character_set_name,
1436            CAST(null AS character_data) AS sql_path
1437     FROM pg_namespace n, pg_authid u
1438     WHERE n.nspowner = u.oid AND pg_has_role(n.nspowner, 'USAGE');
1439
1440 GRANT SELECT ON schemata TO PUBLIC;
1441
1442
1443 /*
1444  * 5.50
1445  * SEQUENCES view
1446  */
1447
1448 CREATE VIEW sequences AS
1449     SELECT CAST(current_database() AS sql_identifier) AS sequence_catalog,
1450            CAST(nc.nspname AS sql_identifier) AS sequence_schema,
1451            CAST(c.relname AS sql_identifier) AS sequence_name,
1452            CAST('bigint' AS character_data) AS data_type,
1453            CAST(64 AS cardinal_number) AS numeric_precision,
1454            CAST(2 AS cardinal_number) AS numeric_precision_radix,
1455            CAST(0 AS cardinal_number) AS numeric_scale,
1456            CAST(null AS cardinal_number) AS maximum_value, -- FIXME
1457            CAST(null AS cardinal_number) AS minimum_value, -- FIXME
1458            CAST(null AS cardinal_number) AS increment,     -- FIXME
1459            CAST(null AS character_data) AS cycle_option    -- FIXME
1460     FROM pg_namespace nc, pg_class c
1461     WHERE c.relnamespace = nc.oid
1462           AND c.relkind = 's'
1463           AND (pg_has_role(c.relowner, 'USAGE')
1464                OR has_table_privilege(c.oid, 'SELECT')
1465                OR has_table_privilege(c.oid, 'UPDATE') );
1466
1467 GRANT SELECT ON sequences TO PUBLIC;
1468
1469
1470 /*
1471  * 5.51
1472  * SQL_FEATURES table
1473  */
1474
1475 CREATE TABLE sql_features (
1476     feature_id          character_data,
1477     feature_name        character_data,
1478     sub_feature_id      character_data,
1479     sub_feature_name    character_data,
1480     is_supported        character_data,
1481     is_verified_by      character_data,
1482     comments            character_data
1483 ) WITHOUT OIDS;
1484
1485 -- Will be filled with external data by initdb.
1486
1487 GRANT SELECT ON sql_features TO PUBLIC;
1488
1489
1490 /*
1491  * 5.52
1492  * SQL_IMPLEMENTATION_INFO table
1493  */
1494
1495 -- Note: Implementation information items are defined in ISO/IEC 9075-3:2003,
1496 -- clause 7.1.
1497
1498 CREATE TABLE sql_implementation_info (
1499     implementation_info_id      character_data,
1500     implementation_info_name    character_data,
1501     integer_value               cardinal_number,
1502     character_value             character_data,
1503     comments                    character_data
1504 ) WITHOUT OIDS;
1505
1506 INSERT INTO sql_implementation_info VALUES ('10003', 'CATALOG NAME', NULL, 'Y', NULL);
1507 INSERT INTO sql_implementation_info VALUES ('10004', 'COLLATING SEQUENCE', NULL, '', 'not supported');
1508 INSERT INTO sql_implementation_info VALUES ('23',    'CURSOR COMMIT BEHAVIOR', 1, NULL, 'close cursors and retain prepared statements');
1509 INSERT INTO sql_implementation_info VALUES ('2',     'DATA SOURCE NAME', NULL, '', NULL);
1510 INSERT INTO sql_implementation_info VALUES ('17',    'DBMS NAME', NULL, (select trim(trailing ' ' from substring(version() from '^[^0-9]*'))), NULL);
1511 INSERT INTO sql_implementation_info VALUES ('18',    'DBMS VERSION', NULL, '???', NULL); -- filled by initdb
1512 INSERT INTO sql_implementation_info VALUES ('26',    'DEFAULT TRANSACTION ISOLATION', 2, NULL, 'READ COMMITTED; user-settable');
1513 INSERT INTO sql_implementation_info VALUES ('28',    'IDENTIFIER CASE', 3, NULL, 'stored in mixed case - case sensitive');
1514 INSERT INTO sql_implementation_info VALUES ('85',    'NULL COLLATION', 0, NULL, 'nulls higher than non-nulls');
1515 INSERT INTO sql_implementation_info VALUES ('13',    'SERVER NAME', NULL, '', NULL);
1516 INSERT INTO sql_implementation_info VALUES ('94',    'SPECIAL CHARACTERS', NULL, '', 'all non-ASCII characters allowed');
1517 INSERT INTO sql_implementation_info VALUES ('46',    'TRANSACTION CAPABLE', 2, NULL, 'both DML and DDL');
1518
1519 GRANT SELECT ON sql_implementation_info TO PUBLIC;
1520
1521
1522 /*
1523  * 5.53
1524  * SQL_LANGUAGES table
1525  */
1526
1527 CREATE TABLE sql_languages (
1528     sql_language_source         character_data,
1529     sql_language_year           character_data,
1530     sql_language_conformance    character_data,
1531     sql_language_integrity      character_data,
1532     sql_language_implementation character_data,
1533     sql_language_binding_style  character_data,
1534     sql_language_programming_language character_data
1535 ) WITHOUT OIDS;
1536
1537 INSERT INTO sql_languages VALUES ('ISO 9075', '1999', 'CORE', NULL, NULL, 'DIRECT', NULL);
1538 INSERT INTO sql_languages VALUES ('ISO 9075', '1999', 'CORE', NULL, NULL, 'EMBEDDED', 'C');
1539 INSERT INTO sql_languages VALUES ('ISO 9075', '2003', 'CORE', NULL, NULL, 'DIRECT', NULL);
1540 INSERT INTO sql_languages VALUES ('ISO 9075', '2003', 'CORE', NULL, NULL, 'EMBEDDED', 'C');
1541
1542 GRANT SELECT ON sql_languages TO PUBLIC;
1543
1544
1545 /*
1546  * 5.54
1547  * SQL_PACKAGES table
1548  */
1549
1550 CREATE TABLE sql_packages (
1551     feature_id      character_data,
1552     feature_name    character_data,
1553     is_supported    character_data,
1554     is_verified_by  character_data,
1555     comments        character_data
1556 ) WITHOUT OIDS;
1557
1558 INSERT INTO sql_packages VALUES ('PKG000', 'Core', 'NO', NULL, '');
1559 INSERT INTO sql_packages VALUES ('PKG001', 'Enhanced datetime facilities', 'YES', NULL, '');
1560 INSERT INTO sql_packages VALUES ('PKG002', 'Enhanced integrity management', 'NO', NULL, '');
1561 INSERT INTO sql_packages VALUES ('PKG003', 'OLAP facilities', 'NO', NULL, '');
1562 INSERT INTO sql_packages VALUES ('PKG004', 'PSM', 'NO', NULL, 'PL/pgSQL is similar.');
1563 INSERT INTO sql_packages VALUES ('PKG005', 'CLI', 'NO', NULL, 'ODBC is similar.');
1564 INSERT INTO sql_packages VALUES ('PKG006', 'Basic object support', 'NO', NULL, '');
1565 INSERT INTO sql_packages VALUES ('PKG007', 'Enhanced object support', 'NO', NULL, '');
1566 INSERT INTO sql_packages VALUES ('PKG008', 'Active database', 'NO', NULL, '');
1567 INSERT INTO sql_packages VALUES ('PKG010', 'OLAP', 'NO', NULL, 'NO');
1568
1569 GRANT SELECT ON sql_packages TO PUBLIC;
1570
1571
1572 /*
1573  * 5.55
1574  * SQL_PARTS table
1575  */
1576
1577 CREATE TABLE sql_parts (
1578     feature_id      character_data,
1579     feature_name    character_data,
1580     is_supported    character_data,
1581     is_verified_by  character_data,
1582     comments        character_data
1583 ) WITHOUT OIDS;
1584
1585 INSERT INTO sql_parts VALUES ('1', 'Framework (SQL/Framework)', 'NO', NULL, '');
1586 INSERT INTO sql_parts VALUES ('2', 'Foundation (SQL/Foundation)', 'NO', NULL, '');
1587 INSERT INTO sql_parts VALUES ('3', 'Call-Level Interface (SQL/CLI)', 'NO', NULL, '');
1588 INSERT INTO sql_parts VALUES ('4', 'Persistent Stored Modules (SQL/PSM)', NULL, '');
1589 INSERT INTO sql_parts VALUES ('9', 'Management of External Data (SQL/MED)', NULL, '');
1590 INSERT INTO sql_parts VALUES ('10', 'Object Language Bindings (SQL/OLB)', NULL, '');
1591 INSERT INTO sql_parts VALUES ('11', 'Information and Definition Schema (SQL/Schemata)', NULL, '');
1592 INSERT INTO sql_parts VALUES ('13', 'Routines and Types Using the Java Programming Language (SQL/JRT)', NULL, '');
1593 INSERT INTO sql_parts VALUES ('14', 'XML-Related Specifications (SQL/XML)', NULL, '');
1594
1595
1596 /*
1597  * 5.56
1598  * SQL_SIZING table
1599  */
1600
1601 -- Note: Sizing items are defined in ISO/IEC 9075-3:2003, clause 7.2.
1602
1603 CREATE TABLE sql_sizing (
1604     sizing_id       cardinal_number,
1605     sizing_name     character_data,
1606     supported_value cardinal_number,
1607     comments        character_data
1608 ) WITHOUT OIDS;
1609
1610 INSERT INTO sql_sizing VALUES (34,    'MAXIMUM CATALOG NAME LENGTH', 63, NULL);
1611 INSERT INTO sql_sizing VALUES (30,    'MAXIMUM COLUMN NAME LENGTH', 63, NULL);
1612 INSERT INTO sql_sizing VALUES (97,    'MAXIMUM COLUMNS IN GROUP BY', 0, NULL);
1613 INSERT INTO sql_sizing VALUES (99,    'MAXIMUM COLUMNS IN ORDER BY', 0, NULL);
1614 INSERT INTO sql_sizing VALUES (100,   'MAXIMUM COLUMNS IN SELECT', 1664, NULL); -- match MaxTupleAttributeNumber
1615 INSERT INTO sql_sizing VALUES (101,   'MAXIMUM COLUMNS IN TABLE', 1600, NULL); -- match MaxHeapAttributeNumber
1616 INSERT INTO sql_sizing VALUES (1,     'MAXIMUM CONCURRENT ACTIVITIES', 0, NULL);
1617 INSERT INTO sql_sizing VALUES (31,    'MAXIMUM CURSOR NAME LENGTH', 63, NULL);
1618 INSERT INTO sql_sizing VALUES (0,     'MAXIMUM DRIVER CONNECTIONS', NULL, NULL);
1619 INSERT INTO sql_sizing VALUES (10005, 'MAXIMUM IDENTIFIER LENGTH', 63, NULL);
1620 INSERT INTO sql_sizing VALUES (32,    'MAXIMUM SCHEMA NAME LENGTH', 63, NULL);
1621 INSERT INTO sql_sizing VALUES (20000, 'MAXIMUM STATEMENT OCTETS', 0, NULL);
1622 INSERT INTO sql_sizing VALUES (20001, 'MAXIMUM STATEMENT OCTETS DATA', 0, NULL);
1623 INSERT INTO sql_sizing VALUES (20002, 'MAXIMUM STATEMENT OCTETS SCHEMA', 0, NULL);
1624 INSERT INTO sql_sizing VALUES (35,    'MAXIMUM TABLE NAME LENGTH', 63, NULL);
1625 INSERT INTO sql_sizing VALUES (106,   'MAXIMUM TABLES IN SELECT', 0, NULL);
1626 INSERT INTO sql_sizing VALUES (107,   'MAXIMUM USER NAME LENGTH', 63, NULL);
1627 INSERT INTO sql_sizing VALUES (25000, 'MAXIMUM CURRENT DEFAULT TRANSFORM GROUP LENGTH', NULL, NULL);
1628 INSERT INTO sql_sizing VALUES (25001, 'MAXIMUM CURRENT TRANSFORM GROUP LENGTH', NULL, NULL);
1629 INSERT INTO sql_sizing VALUES (25002, 'MAXIMUM CURRENT PATH LENGTH', 0, NULL);
1630 INSERT INTO sql_sizing VALUES (25003, 'MAXIMUM CURRENT ROLE LENGTH', NULL, NULL);
1631 INSERT INTO sql_sizing VALUES (25004, 'MAXIMUM SESSION USER LENGTH', 63, NULL);
1632 INSERT INTO sql_sizing VALUES (25005, 'MAXIMUM SYSTEM USER LENGTH', 63, NULL);
1633
1634 UPDATE sql_sizing
1635     SET supported_value = (SELECT typlen-1 FROM pg_catalog.pg_type WHERE typname = 'name'),
1636         comments = 'Might be less, depending on character set.'
1637     WHERE supported_value = 63;
1638
1639 GRANT SELECT ON sql_sizing TO PUBLIC;
1640
1641
1642 /*
1643  * 5.57
1644  * SQL_SIZING_PROFILES table
1645  */
1646
1647 -- The data in this table are defined by various profiles of SQL.
1648 -- Since we don't have any information about such profiles, we provide
1649 -- an empty table.
1650
1651 CREATE TABLE sql_sizing_profiles (
1652     sizing_id       cardinal_number,
1653     sizing_name     character_data,
1654     profile_id      character_data,
1655     required_value  cardinal_number,
1656     comments        character_data
1657 ) WITHOUT OIDS;
1658
1659 GRANT SELECT ON sql_sizing_profiles TO PUBLIC;
1660
1661
1662 /*
1663  * 5.58
1664  * TABLE_CONSTRAINTS view
1665  */
1666
1667 CREATE VIEW table_constraints AS
1668     SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog,
1669            CAST(nc.nspname AS sql_identifier) AS constraint_schema,
1670            CAST(c.conname AS sql_identifier) AS constraint_name,
1671            CAST(current_database() AS sql_identifier) AS table_catalog,
1672            CAST(nr.nspname AS sql_identifier) AS table_schema,
1673            CAST(r.relname AS sql_identifier) AS table_name,
1674            CAST(
1675              CASE c.contype WHEN 'c' THEN 'CHECK'
1676                             WHEN 'f' THEN 'FOREIGN KEY'
1677                             WHEN 'p' THEN 'PRIMARY KEY'
1678                             WHEN 'u' THEN 'UNIQUE' END
1679              AS character_data) AS constraint_type,
1680            CAST(CASE WHEN c.condeferrable THEN 'YES' ELSE 'NO' END AS character_data)
1681              AS is_deferrable,
1682            CAST(CASE WHEN c.condeferred THEN 'YES' ELSE 'NO' END AS character_data)
1683              AS initially_deferred
1684
1685     FROM pg_namespace nc,
1686          pg_namespace nr,
1687          pg_constraint c,
1688          pg_class r
1689
1690     WHERE nc.oid = c.connamespace AND nr.oid = r.relnamespace
1691           AND c.conrelid = r.oid
1692           AND r.relkind = 'r'
1693           AND (pg_has_role(r.relowner, 'USAGE')
1694                -- SELECT privilege omitted, per SQL standard
1695                OR has_table_privilege(r.oid, 'INSERT')
1696                OR has_table_privilege(r.oid, 'UPDATE')
1697                OR has_table_privilege(r.oid, 'DELETE')
1698                OR has_table_privilege(r.oid, 'RULE')
1699                OR has_table_privilege(r.oid, 'REFERENCES')
1700                OR has_table_privilege(r.oid, 'TRIGGER') )
1701
1702     UNION
1703
1704     -- not-null constraints
1705
1706     SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog,
1707            CAST(nr.nspname AS sql_identifier) AS constraint_schema,
1708            CAST(nr.oid || '_' || r.oid || '_' || a.attnum || '_not_null' AS sql_identifier) AS constraint_name, -- XXX
1709            CAST(current_database() AS sql_identifier) AS table_catalog,
1710            CAST(nr.nspname AS sql_identifier) AS table_schema,
1711            CAST(r.relname AS sql_identifier) AS table_name,
1712            CAST('CHECK' AS character_data) AS constraint_type,
1713            CAST('NO' AS character_data) AS is_deferrable,
1714            CAST('NO' AS character_data) AS initially_deferred
1715
1716     FROM pg_namespace nr,
1717          pg_class r,
1718          pg_attribute a
1719
1720     WHERE nr.oid = r.relnamespace
1721           AND r.oid = a.attrelid
1722           AND a.attnotnull
1723           AND a.attnum > 0
1724           AND NOT a.attisdropped
1725           AND r.relkind = 'r'
1726           AND (pg_has_role(r.relowner, 'USAGE')
1727                OR has_table_privilege(r.oid, 'SELECT')
1728                OR has_table_privilege(r.oid, 'INSERT')
1729                OR has_table_privilege(r.oid, 'UPDATE')
1730                OR has_table_privilege(r.oid, 'DELETE')
1731                OR has_table_privilege(r.oid, 'RULE')
1732                OR has_table_privilege(r.oid, 'REFERENCES')
1733                OR has_table_privilege(r.oid, 'TRIGGER') );
1734
1735 GRANT SELECT ON table_constraints TO PUBLIC;
1736
1737
1738 /*
1739  * 5.59
1740  * TABLE_METHOD_PRIVILEGES view
1741  */
1742
1743 -- feature not supported
1744
1745
1746 /*
1747  * 5.60
1748  * TABLE_PRIVILEGES view
1749  */
1750
1751 CREATE VIEW table_privileges AS
1752     SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor,
1753            CAST(grantee.rolname AS sql_identifier) AS grantee,
1754            CAST(current_database() AS sql_identifier) AS table_catalog,
1755            CAST(nc.nspname AS sql_identifier) AS table_schema,
1756            CAST(c.relname AS sql_identifier) AS table_name,
1757            CAST(pr.type AS character_data) AS privilege_type,
1758            CAST(
1759              CASE WHEN aclcontains(c.relacl,
1760                                    makeaclitem(grantee.oid, u_grantor.oid, pr.type, true))
1761                   THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable,
1762            CAST('NO' AS character_data) AS with_hierarchy
1763
1764     FROM pg_class c,
1765          pg_namespace nc,
1766          pg_authid u_grantor,
1767          (
1768            SELECT oid, rolname FROM pg_authid
1769            UNION ALL
1770            SELECT 0::oid, 'PUBLIC'
1771          ) AS grantee (oid, rolname),
1772          (SELECT 'SELECT' UNION ALL
1773           SELECT 'DELETE' UNION ALL
1774           SELECT 'INSERT' UNION ALL
1775           SELECT 'UPDATE' UNION ALL
1776           SELECT 'REFERENCES' UNION ALL
1777           SELECT 'RULE' UNION ALL
1778           SELECT 'TRIGGER') AS pr (type)
1779
1780     WHERE c.relnamespace = nc.oid
1781           AND c.relkind IN ('r', 'v')
1782           AND aclcontains(c.relacl,
1783                           makeaclitem(grantee.oid, u_grantor.oid, pr.type, false))
1784           AND (pg_has_role(u_grantor.oid, 'USAGE')
1785                OR pg_has_role(grantee.oid, 'USAGE')
1786                OR grantee.rolname = 'PUBLIC');
1787
1788 GRANT SELECT ON table_privileges TO PUBLIC;
1789
1790
1791 /*
1792  * 5.61
1793  * TABLES view
1794  */
1795
1796 CREATE VIEW tables AS
1797     SELECT CAST(current_database() AS sql_identifier) AS table_catalog,
1798            CAST(nc.nspname AS sql_identifier) AS table_schema,
1799            CAST(c.relname AS sql_identifier) AS table_name,
1800
1801            CAST(
1802              CASE WHEN nc.nspname LIKE 'pg!_temp!_%' ESCAPE '!' THEN 'LOCAL TEMPORARY'
1803                   WHEN c.relkind = 'r' THEN 'BASE TABLE'
1804                   WHEN c.relkind = 'v' THEN 'VIEW'
1805                   ELSE null END
1806              AS character_data) AS table_type,
1807
1808            CAST(null AS sql_identifier) AS self_referencing_column_name,
1809            CAST(null AS character_data) AS reference_generation,
1810
1811            CAST(null AS sql_identifier) AS user_defined_type_catalog,
1812            CAST(null AS sql_identifier) AS user_defined_type_schema,
1813            CAST(null AS sql_identifier) AS user_defined_type_name,
1814
1815            CAST(CASE WHEN c.relkind = 'r'
1816                 THEN 'YES' ELSE 'NO' END AS character_data) AS is_insertable_into,
1817            CAST('NO' AS character_data) AS is_typed,
1818            CAST(
1819              CASE WHEN nc.nspname LIKE 'pg!_temp!_%' ESCAPE '!' THEN 'PRESERVE'
1820                   ELSE null END
1821              AS character_data) AS commit_action
1822
1823     FROM pg_namespace nc, pg_class c
1824
1825     WHERE c.relnamespace = nc.oid
1826           AND c.relkind IN ('r', 'v')
1827           AND (pg_has_role(c.relowner, 'USAGE')
1828                OR has_table_privilege(c.oid, 'SELECT')
1829                OR has_table_privilege(c.oid, 'INSERT')
1830                OR has_table_privilege(c.oid, 'UPDATE')
1831                OR has_table_privilege(c.oid, 'DELETE')
1832                OR has_table_privilege(c.oid, 'RULE')
1833                OR has_table_privilege(c.oid, 'REFERENCES')
1834                OR has_table_privilege(c.oid, 'TRIGGER') );
1835
1836 GRANT SELECT ON tables TO PUBLIC;
1837
1838
1839 /*
1840  * 5.62
1841  * TRANSFORMS view
1842  */
1843
1844 -- feature not supported
1845
1846
1847 /*
1848  * 5.63
1849  * TRANSLATIONS view
1850  */
1851
1852 -- feature not supported
1853
1854
1855 /*
1856  * 5.64
1857  * TRIGGERED_UPDATE_COLUMNS view
1858  */
1859
1860 -- PostgreSQL doesn't allow the specification of individual triggered
1861 -- update columns, so this view is empty.
1862
1863 CREATE VIEW triggered_update_columns AS
1864     SELECT CAST(current_database() AS sql_identifier) AS trigger_catalog,
1865            CAST(null AS sql_identifier) AS trigger_schema,
1866            CAST(null AS sql_identifier) AS trigger_name,
1867            CAST(current_database() AS sql_identifier) AS event_object_catalog,
1868            CAST(null AS sql_identifier) AS event_object_schema,
1869            CAST(null AS sql_identifier) AS event_object_table,
1870            CAST(null AS sql_identifier) AS event_object_column
1871     WHERE false;
1872
1873 GRANT SELECT ON triggered_update_columns TO PUBLIC;
1874
1875
1876 /*
1877  * 5.65
1878  * TRIGGER_COLUMN_USAGE view
1879  */
1880
1881 -- not tracked by PostgreSQL
1882
1883
1884 /*
1885  * 5.66
1886  * TRIGGER_ROUTINE_USAGE view
1887  */
1888
1889 -- not tracked by PostgreSQL
1890
1891
1892 /*
1893  * 5.67
1894  * TRIGGER_SEQUENCE_USAGE view
1895  */
1896
1897 -- not tracked by PostgreSQL
1898
1899
1900 /*
1901  * 5.68
1902  * TRIGGER_TABLE_USAGE view
1903  */
1904
1905 -- not tracked by PostgreSQL
1906
1907
1908 /*
1909  * 5.69
1910  * TRIGGERS view
1911  */
1912
1913 CREATE VIEW triggers AS
1914     SELECT CAST(current_database() AS sql_identifier) AS trigger_catalog,
1915            CAST(n.nspname AS sql_identifier) AS trigger_schema,
1916            CAST(t.tgname AS sql_identifier) AS trigger_name,
1917            CAST(em.text AS character_data) AS event_manipulation,
1918            CAST(current_database() AS sql_identifier) AS event_object_catalog,
1919            CAST(n.nspname AS sql_identifier) AS event_object_schema,
1920            CAST(c.relname AS sql_identifier) AS event_object_table,
1921            CAST(null AS cardinal_number) AS action_order,
1922            CAST(null AS character_data) AS action_condition,
1923            CAST(
1924              substring(pg_get_triggerdef(t.oid) from
1925                        position('EXECUTE PROCEDURE' in substring(pg_get_triggerdef(t.oid) from 48)) + 47)
1926              AS character_data) AS action_statement,
1927            CAST(
1928              CASE WHEN t.tgtype & 1 = 1 THEN 'ROW' ELSE 'STATEMENT' END
1929              AS character_data) AS action_orientation,
1930            CAST(
1931              CASE WHEN t.tgtype & 2 = 2 THEN 'BEFORE' ELSE 'AFTER' END
1932              AS character_data) AS condition_timing,
1933            CAST(null AS sql_identifier) AS condition_reference_old_table,
1934            CAST(null AS sql_identifier) AS condition_reference_new_table,
1935            CAST(null AS sql_identifier) AS condition_reference_old_row,
1936            CAST(null AS sql_identifier) AS condition_reference_new_row,
1937            CAST(null AS time_stamp) AS created
1938
1939     FROM pg_namespace n, pg_class c, pg_trigger t,
1940          (SELECT 4, 'INSERT' UNION ALL
1941           SELECT 8, 'DELETE' UNION ALL
1942           SELECT 16, 'UPDATE') AS em (num, text)
1943
1944     WHERE n.oid = c.relnamespace
1945           AND c.oid = t.tgrelid
1946           AND t.tgtype & em.num <> 0
1947           AND NOT t.tgisconstraint
1948           AND (pg_has_role(c.relowner, 'USAGE')
1949                -- SELECT privilege omitted, per SQL standard
1950                OR has_table_privilege(c.oid, 'INSERT')
1951                OR has_table_privilege(c.oid, 'UPDATE')
1952                OR has_table_privilege(c.oid, 'DELETE')
1953                OR has_table_privilege(c.oid, 'RULE')
1954                OR has_table_privilege(c.oid, 'REFERENCES')
1955                OR has_table_privilege(c.oid, 'TRIGGER') );
1956
1957 GRANT SELECT ON triggers TO PUBLIC;
1958
1959
1960 /*
1961  * 5.70
1962  * UDT_PRIVILEGES view
1963  */
1964
1965 -- feature not supported
1966
1967
1968 /*
1969  * 5.71
1970  * USAGE_PRIVILEGES view
1971  */
1972
1973 -- Of the things currently implemented in PostgreSQL, usage privileges
1974 -- apply only to domains.  Since domains have no real privileges, we
1975 -- represent all domains with implicit usage privilege here.
1976
1977 CREATE VIEW usage_privileges AS
1978     SELECT CAST(u.rolname AS sql_identifier) AS grantor,
1979            CAST('PUBLIC' AS sql_identifier) AS grantee,
1980            CAST(current_database() AS sql_identifier) AS object_catalog,
1981            CAST(n.nspname AS sql_identifier) AS object_schema,
1982            CAST(t.typname AS sql_identifier) AS object_name,
1983            CAST('DOMAIN' AS character_data) AS object_type,
1984            CAST('USAGE' AS character_data) AS privilege_type,
1985            CAST('NO' AS character_data) AS is_grantable
1986
1987     FROM pg_authid u,
1988          pg_namespace n,
1989          pg_type t
1990
1991     WHERE u.oid = t.typowner
1992           AND t.typnamespace = n.oid
1993           AND t.typtype = 'd';
1994
1995 GRANT SELECT ON usage_privileges TO PUBLIC;
1996
1997
1998 /*
1999  * 5.72
2000  * USER_DEFINED_TYPES view
2001  */
2002
2003 -- feature not supported
2004
2005
2006 /*
2007  * 5.73
2008  * VIEW_COLUMN_USAGE
2009  */
2010
2011 CREATE VIEW view_column_usage AS
2012     SELECT DISTINCT
2013            CAST(current_database() AS sql_identifier) AS view_catalog,
2014            CAST(nv.nspname AS sql_identifier) AS view_schema,
2015            CAST(v.relname AS sql_identifier) AS view_name,
2016            CAST(current_database() AS sql_identifier) AS table_catalog,
2017            CAST(nt.nspname AS sql_identifier) AS table_schema,
2018            CAST(t.relname AS sql_identifier) AS table_name,
2019            CAST(a.attname AS sql_identifier) AS column_name
2020
2021     FROM pg_namespace nv, pg_class v, pg_depend dv,
2022          pg_depend dt, pg_class t, pg_namespace nt,
2023          pg_attribute a
2024
2025     WHERE nv.oid = v.relnamespace
2026           AND v.relkind = 'v'
2027           AND v.oid = dv.refobjid
2028           AND dv.refclassid = 'pg_catalog.pg_class'::regclass
2029           AND dv.classid = 'pg_catalog.pg_rewrite'::regclass
2030           AND dv.deptype = 'i'
2031           AND dv.objid = dt.objid
2032           AND dv.refobjid <> dt.refobjid
2033           AND dt.classid = 'pg_catalog.pg_rewrite'::regclass
2034           AND dt.refclassid = 'pg_catalog.pg_class'::regclass
2035           AND dt.refobjid = t.oid
2036           AND t.relnamespace = nt.oid
2037           AND t.relkind IN ('r', 'v')
2038           AND t.oid = a.attrelid
2039           AND dt.refobjsubid = a.attnum
2040           AND pg_has_role(t.relowner, 'USAGE');
2041
2042 GRANT SELECT ON view_column_usage TO PUBLIC;
2043
2044
2045 /*
2046  * 5.74
2047  * VIEW_ROUTINE_USAGE
2048  */
2049
2050 CREATE VIEW view_routine_usage AS
2051     SELECT DISTINCT
2052            CAST(current_database() AS sql_identifier) AS table_catalog,
2053            CAST(nv.nspname AS sql_identifier) AS table_schema,
2054            CAST(v.relname AS sql_identifier) AS table_name,
2055            CAST(current_database() AS sql_identifier) AS specific_catalog,
2056            CAST(np.nspname AS sql_identifier) AS specific_schema,
2057            CAST(p.proname || '_' || CAST(p.oid AS text)  AS sql_identifier) AS specific_name
2058
2059     FROM pg_namespace nv, pg_class v, pg_depend dv,
2060          pg_depend dp, pg_proc p, pg_namespace np
2061
2062     WHERE nv.oid = v.relnamespace
2063           AND v.relkind = 'v'
2064           AND v.oid = dv.refobjid
2065           AND dv.refclassid = 'pg_catalog.pg_class'::regclass
2066           AND dv.classid = 'pg_catalog.pg_rewrite'::regclass
2067           AND dv.deptype = 'i'
2068           AND dv.objid = dp.objid
2069           AND dp.classid = 'pg_catalog.pg_rewrite'::regclass
2070           AND dp.refclassid = 'pg_catalog.pg_proc'::regclass
2071           AND dp.refobjid = p.oid
2072           AND p.pronamespace = np.oid
2073           AND pg_has_role(p.proowner, 'USAGE');
2074
2075 GRANT SELECT ON view_routine_usage TO PUBLIC;
2076
2077
2078 /*
2079  * 5.75
2080  * VIEW_TABLE_USAGE
2081  */
2082
2083 CREATE VIEW view_table_usage AS
2084     SELECT DISTINCT
2085            CAST(current_database() AS sql_identifier) AS view_catalog,
2086            CAST(nv.nspname AS sql_identifier) AS view_schema,
2087            CAST(v.relname AS sql_identifier) AS view_name,
2088            CAST(current_database() AS sql_identifier) AS table_catalog,
2089            CAST(nt.nspname AS sql_identifier) AS table_schema,
2090            CAST(t.relname AS sql_identifier) AS table_name
2091
2092     FROM pg_namespace nv, pg_class v, pg_depend dv,
2093          pg_depend dt, pg_class t, pg_namespace nt
2094
2095     WHERE nv.oid = v.relnamespace
2096           AND v.relkind = 'v'
2097           AND v.oid = dv.refobjid
2098           AND dv.refclassid = 'pg_catalog.pg_class'::regclass
2099           AND dv.classid = 'pg_catalog.pg_rewrite'::regclass
2100           AND dv.deptype = 'i'
2101           AND dv.objid = dt.objid
2102           AND dv.refobjid <> dt.refobjid
2103           AND dt.classid = 'pg_catalog.pg_rewrite'::regclass
2104           AND dt.refclassid = 'pg_catalog.pg_class'::regclass
2105           AND dt.refobjid = t.oid
2106           AND t.relnamespace = nt.oid
2107           AND t.relkind IN ('r', 'v')
2108           AND pg_has_role(t.relowner, 'USAGE');
2109
2110 GRANT SELECT ON view_table_usage TO PUBLIC;
2111
2112
2113 /*
2114  * 5.76
2115  * VIEWS view
2116  */
2117
2118 CREATE VIEW views AS
2119     SELECT CAST(current_database() AS sql_identifier) AS table_catalog,
2120            CAST(nc.nspname AS sql_identifier) AS table_schema,
2121            CAST(c.relname AS sql_identifier) AS table_name,
2122
2123            CAST(
2124              CASE WHEN pg_has_role(c.relowner, 'USAGE')
2125                   THEN pg_get_viewdef(c.oid)
2126                   ELSE null END
2127              AS character_data) AS view_definition,
2128
2129            CAST('NONE' AS character_data) AS check_option,
2130
2131            CAST(
2132              CASE WHEN EXISTS (SELECT 1 FROM pg_rewrite WHERE ev_class = c.oid AND ev_type = 2 AND is_instead)
2133                    AND EXISTS (SELECT 1 FROM pg_rewrite WHERE ev_class = c.oid AND ev_type = 4 AND is_instead)
2134                   THEN 'YES' ELSE 'NO' END
2135              AS character_data) AS is_updatable,
2136
2137            CAST(
2138              CASE WHEN EXISTS (SELECT 1 FROM pg_rewrite WHERE ev_class = c.oid AND ev_type = 3 AND is_instead)
2139                   THEN 'YES' ELSE 'NO' END
2140              AS character_data) AS is_insertable_into
2141
2142     FROM pg_namespace nc, pg_class c
2143
2144     WHERE c.relnamespace = nc.oid
2145           AND c.relkind = 'v'
2146           AND (pg_has_role(c.relowner, 'USAGE')
2147                OR has_table_privilege(c.oid, 'SELECT')
2148                OR has_table_privilege(c.oid, 'INSERT')
2149                OR has_table_privilege(c.oid, 'UPDATE')
2150                OR has_table_privilege(c.oid, 'DELETE')
2151                OR has_table_privilege(c.oid, 'RULE')
2152                OR has_table_privilege(c.oid, 'REFERENCES')
2153                OR has_table_privilege(c.oid, 'TRIGGER') );
2154
2155 GRANT SELECT ON views TO PUBLIC;
2156
2157
2158 -- The following views have dependencies that force them to appear out of order.
2159
2160 /*
2161  * 5.23
2162  * DATA_TYPE_PRIVILEGES view
2163  */
2164
2165 CREATE VIEW data_type_privileges AS
2166     SELECT CAST(current_database() AS sql_identifier) AS object_catalog,
2167            CAST(x.objschema AS sql_identifier) AS object_schema,
2168            CAST(x.objname AS sql_identifier) AS object_name,
2169            CAST(x.objtype AS character_data) AS object_type,
2170            CAST(x.objdtdid AS sql_identifier) AS dtd_identifier
2171
2172     FROM
2173       (
2174         SELECT udt_schema, udt_name, 'USER-DEFINED TYPE'::text, dtd_identifier FROM attributes
2175         UNION ALL
2176         SELECT table_schema, table_name, 'TABLE'::text, dtd_identifier FROM columns
2177         UNION ALL
2178         SELECT domain_schema, domain_name, 'DOMAIN'::text, dtd_identifier FROM domains
2179         UNION ALL
2180         SELECT specific_schema, specific_name, 'ROUTINE'::text, dtd_identifier FROM parameters
2181         UNION ALL
2182         SELECT specific_schema, specific_name, 'ROUTINE'::text, dtd_identifier FROM routines
2183       ) AS x (objschema, objname, objtype, objdtdid);
2184
2185 GRANT SELECT ON data_type_privileges TO PUBLIC;
2186
2187
2188 /*
2189  * 5.28
2190  * ELEMENT_TYPES view
2191  */
2192
2193 CREATE VIEW element_types AS
2194     SELECT CAST(current_database() AS sql_identifier) AS object_catalog,
2195            CAST(n.nspname AS sql_identifier) AS object_schema,
2196            CAST(x.objname AS sql_identifier) AS object_name,
2197            CAST(x.objtype AS character_data) AS object_type,
2198            CAST(x.objdtdid AS sql_identifier) AS collection_type_identifier,
2199            CAST(
2200              CASE WHEN nbt.nspname = 'pg_catalog' THEN format_type(bt.oid, null)
2201                   ELSE 'USER-DEFINED' END AS character_data) AS data_type,
2202
2203            CAST(null AS cardinal_number) AS character_maximum_length,
2204            CAST(null AS cardinal_number) AS character_octet_length,
2205            CAST(null AS sql_identifier) AS character_set_catalog,
2206            CAST(null AS sql_identifier) AS character_set_schema,
2207            CAST(null AS sql_identifier) AS character_set_name,
2208            CAST(null AS sql_identifier) AS collation_catalog,
2209            CAST(null AS sql_identifier) AS collation_schema,
2210            CAST(null AS sql_identifier) AS collation_name,
2211            CAST(null AS cardinal_number) AS numeric_precision,
2212            CAST(null AS cardinal_number) AS numeric_precision_radix,
2213            CAST(null AS cardinal_number) AS numeric_scale,
2214            CAST(null AS cardinal_number) AS datetime_precision,
2215            CAST(null AS character_data) AS interval_type,
2216            CAST(null AS character_data) AS interval_precision,
2217            
2218            CAST(null AS character_data) AS domain_default, -- XXX maybe a bug in the standard
2219
2220            CAST(current_database() AS sql_identifier) AS udt_catalog,
2221            CAST(nbt.nspname AS sql_identifier) AS udt_schema,
2222            CAST(bt.typname AS sql_identifier) AS udt_name,
2223
2224            CAST(null AS sql_identifier) AS scope_catalog,
2225            CAST(null AS sql_identifier) AS scope_schema,
2226            CAST(null AS sql_identifier) AS scope_name,
2227
2228            CAST(null AS cardinal_number) AS maximum_cardinality,
2229            CAST('a' || x.objdtdid AS sql_identifier) AS dtd_identifier
2230
2231     FROM pg_namespace n, pg_type at, pg_namespace nbt, pg_type bt,
2232          (
2233            /* columns */
2234            SELECT c.relnamespace, CAST(c.relname AS sql_identifier),
2235                   'TABLE'::text, a.attnum, a.atttypid
2236            FROM pg_class c, pg_attribute a
2237            WHERE c.oid = a.attrelid
2238                  AND c.relkind IN ('r', 'v')
2239                  AND attnum > 0 AND NOT attisdropped
2240
2241            UNION ALL
2242
2243            /* domains */
2244            SELECT t.typnamespace, CAST(t.typname AS sql_identifier),
2245                   'DOMAIN'::text, 1, t.typbasetype
2246            FROM pg_type t
2247            WHERE t.typtype = 'd'
2248
2249            UNION ALL
2250
2251            /* parameters */
2252            SELECT pronamespace, CAST(proname || '_' || CAST(oid AS text) AS sql_identifier),
2253                   'ROUTINE'::text, (ss.x).n, (ss.x).x
2254            FROM (SELECT p.pronamespace, p.proname, p.oid,
2255                         _pg_expandarray(coalesce(p.proallargtypes, p.proargtypes::oid[])) AS x
2256                  FROM pg_proc p) AS ss
2257
2258            UNION ALL
2259
2260            /* result types */
2261            SELECT p.pronamespace, CAST(p.proname || '_' || CAST(p.oid AS text) AS sql_identifier),
2262                   'ROUTINE'::text, 0, p.prorettype
2263            FROM pg_proc p
2264
2265          ) AS x (objschema, objname, objtype, objdtdid, objtypeid)
2266
2267     WHERE n.oid = x.objschema
2268           AND at.oid = x.objtypeid
2269           AND (at.typelem <> 0 AND at.typlen = -1)
2270           AND at.typelem = bt.oid
2271           AND nbt.oid = bt.typnamespace
2272
2273           AND (n.nspname, x.objname, x.objtype, x.objdtdid) IN
2274               ( SELECT object_schema, object_name, object_type, dtd_identifier
2275                     FROM data_type_privileges );
2276
2277 GRANT SELECT ON element_types TO PUBLIC;