#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/objectaccess.h"
+#include "catalog/pg_aggregate.h"
+#include "catalog/pg_am.h"
#include "catalog/pg_authid.h"
+#include "catalog/pg_cast.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_conversion.h"
#include "catalog/pg_database.h"
#include "catalog/pg_type.h"
#include "catalog/pg_ts_config.h"
#include "catalog/pg_ts_dict.h"
+#include "catalog/pg_ts_parser.h"
+#include "catalog/pg_ts_template.h"
+#include "catalog/pg_transform.h"
#include "commands/dbcommands.h"
#include "commands/event_trigger.h"
#include "commands/extension.h"
Oid roleid, AclMode mask, AclMaskHow how);
static void recordExtensionInitPriv(Oid objoid, Oid classoid, int objsubid,
Acl *new_acl);
+static void recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid,
+ Acl *new_acl);
#ifdef ACLDEBUG
}
/*
- * Record initial ACL for an extension object
+ * Record initial privileges for the top-level object passed in.
*
- * This will perform a wholesale replacement of the entire ACL for the object
- * passed in, therefore be sure to pass in the complete new ACL to use.
+ * For the object passed in, this will record its ACL (if any) and the ACLs of
+ * any sub-objects (eg: columns) into pg_init_privs.
+ *
+ * Any new kinds of objects which have ACLs associated with them and can be
+ * added to an extension should be added to the if-else tree below.
+ */
+void
+recordExtObjInitPriv(Oid objoid, Oid classoid)
+{
+ /*
+ * pg_class / pg_attribute
+ *
+ * If this is a relation then we need to see if there are any sub-objects
+ * (eg: columns) for it and, if so, be sure to call
+ * recordExtensionInitPrivWorker() for each one.
+ */
+ if (classoid == RelationRelationId)
+ {
+ Form_pg_class pg_class_tuple;
+ Datum aclDatum;
+ bool isNull;
+ HeapTuple tuple;
+
+ tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(objoid));
+ if (!HeapTupleIsValid(tuple))
+ elog(ERROR, "cache lookup failed for relation %u", objoid);
+ pg_class_tuple = (Form_pg_class) GETSTRUCT(tuple);
+
+ /* Indexes don't have permissions */
+ if (pg_class_tuple->relkind == RELKIND_INDEX)
+ return;
+
+ /* Composite types don't have permissions either */
+ if (pg_class_tuple->relkind == RELKIND_COMPOSITE_TYPE)
+ return;
+
+ /*
+ * If this isn't a sequence, index, or composite type then it's
+ * possibly going to have columns associated with it that might have
+ * ACLs.
+ */
+ if (pg_class_tuple->relkind != RELKIND_SEQUENCE)
+ {
+ AttrNumber curr_att;
+ AttrNumber nattrs = pg_class_tuple->relnatts;
+
+ for (curr_att = 1; curr_att <= nattrs; curr_att++)
+ {
+ HeapTuple attTuple;
+ Datum attaclDatum;
+
+ attTuple = SearchSysCache2(ATTNUM,
+ ObjectIdGetDatum(objoid),
+ Int16GetDatum(curr_att));
+
+ if (!HeapTupleIsValid(attTuple))
+ continue;
+
+ /* ignore dropped columns */
+ if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
+ {
+ ReleaseSysCache(attTuple);
+ continue;
+ }
+
+ attaclDatum = SysCacheGetAttr(ATTNUM, attTuple,
+ Anum_pg_attribute_attacl,
+ &isNull);
+
+ /* no need to do anything for a NULL ACL */
+ if (isNull)
+ {
+ ReleaseSysCache(attTuple);
+ continue;
+ }
+
+ recordExtensionInitPrivWorker(objoid, classoid, curr_att,
+ DatumGetAclP(attaclDatum));
+
+ ReleaseSysCache(attTuple);
+ }
+ }
+
+ aclDatum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relacl,
+ &isNull);
+
+ /* Add the record, if any, for the top-level object */
+ if (!isNull)
+ recordExtensionInitPrivWorker(objoid, classoid, 0,
+ DatumGetAclP(aclDatum));
+
+ ReleaseSysCache(tuple);
+ }
+ /* pg_foreign_data_wrapper */
+ else if (classoid == ForeignDataWrapperRelationId)
+ {
+ Datum aclDatum;
+ bool isNull;
+ HeapTuple tuple;
+
+ tuple = SearchSysCache1(FOREIGNDATAWRAPPEROID,
+ ObjectIdGetDatum(objoid));
+ if (!HeapTupleIsValid(tuple))
+ elog(ERROR, "cache lookup failed for foreign data wrapper %u",
+ objoid);
+
+ aclDatum = SysCacheGetAttr(FOREIGNDATAWRAPPEROID, tuple,
+ Anum_pg_foreign_data_wrapper_fdwacl,
+ &isNull);
+
+ /* Add the record, if any, for the top-level object */
+ if (!isNull)
+ recordExtensionInitPrivWorker(objoid, classoid, 0,
+ DatumGetAclP(aclDatum));
+
+ ReleaseSysCache(tuple);
+ }
+ /* pg_foreign_server */
+ else if (classoid == ForeignServerRelationId)
+ {
+ Datum aclDatum;
+ bool isNull;
+ HeapTuple tuple;
+
+ tuple = SearchSysCache1(FOREIGNSERVEROID, ObjectIdGetDatum(objoid));
+ if (!HeapTupleIsValid(tuple))
+ elog(ERROR, "cache lookup failed for foreign data wrapper %u",
+ objoid);
+
+ aclDatum = SysCacheGetAttr(FOREIGNSERVEROID, tuple,
+ Anum_pg_foreign_server_srvacl,
+ &isNull);
+
+ /* Add the record, if any, for the top-level object */
+ if (!isNull)
+ recordExtensionInitPrivWorker(objoid, classoid, 0,
+ DatumGetAclP(aclDatum));
+
+ ReleaseSysCache(tuple);
+ }
+ /* pg_language */
+ else if (classoid == LanguageRelationId)
+ {
+ Datum aclDatum;
+ bool isNull;
+ HeapTuple tuple;
+
+ tuple = SearchSysCache1(LANGOID, ObjectIdGetDatum(objoid));
+ if (!HeapTupleIsValid(tuple))
+ elog(ERROR, "cache lookup failed for language %u", objoid);
+
+ aclDatum = SysCacheGetAttr(LANGOID, tuple, Anum_pg_language_lanacl,
+ &isNull);
+
+ /* Add the record, if any, for the top-level object */
+ if (!isNull)
+ recordExtensionInitPrivWorker(objoid, classoid, 0,
+ DatumGetAclP(aclDatum));
+
+ ReleaseSysCache(tuple);
+ }
+ /* pg_largeobject_metadata */
+ else if (classoid == LargeObjectMetadataRelationId)
+ {
+ Datum aclDatum;
+ bool isNull;
+ HeapTuple tuple;
+ ScanKeyData entry[1];
+ SysScanDesc scan;
+ Relation relation;
+
+ relation = heap_open(LargeObjectMetadataRelationId, RowExclusiveLock);
+
+ /* There's no syscache for pg_largeobject_metadata */
+ ScanKeyInit(&entry[0],
+ ObjectIdAttributeNumber,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(objoid));
+
+ scan = systable_beginscan(relation,
+ LargeObjectMetadataOidIndexId, true,
+ NULL, 1, entry);
+
+ tuple = systable_getnext(scan);
+ if (!HeapTupleIsValid(tuple))
+ elog(ERROR, "cache lookup failed for large object %u", objoid);
+
+ aclDatum = heap_getattr(tuple,
+ Anum_pg_largeobject_metadata_lomacl,
+ RelationGetDescr(relation), &isNull);
+
+ /* Add the record, if any, for the top-level object */
+ if (!isNull)
+ recordExtensionInitPrivWorker(objoid, classoid, 0,
+ DatumGetAclP(aclDatum));
+
+ systable_endscan(scan);
+ }
+ /* pg_namespace */
+ else if (classoid == NamespaceRelationId)
+ {
+ Datum aclDatum;
+ bool isNull;
+ HeapTuple tuple;
+
+ tuple = SearchSysCache1(NAMESPACEOID, ObjectIdGetDatum(objoid));
+ if (!HeapTupleIsValid(tuple))
+ elog(ERROR, "cache lookup failed for function %u", objoid);
+
+ aclDatum = SysCacheGetAttr(NAMESPACEOID, tuple,
+ Anum_pg_namespace_nspacl, &isNull);
+
+ /* Add the record, if any, for the top-level object */
+ if (!isNull)
+ recordExtensionInitPrivWorker(objoid, classoid, 0,
+ DatumGetAclP(aclDatum));
+
+ ReleaseSysCache(tuple);
+ }
+ /* pg_proc */
+ else if (classoid == ProcedureRelationId)
+ {
+ Datum aclDatum;
+ bool isNull;
+ HeapTuple tuple;
+
+ tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(objoid));
+ if (!HeapTupleIsValid(tuple))
+ elog(ERROR, "cache lookup failed for function %u", objoid);
+
+ aclDatum = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_proacl,
+ &isNull);
+
+ /* Add the record, if any, for the top-level object */
+ if (!isNull)
+ recordExtensionInitPrivWorker(objoid, classoid, 0,
+ DatumGetAclP(aclDatum));
+
+ ReleaseSysCache(tuple);
+ }
+ /* pg_type */
+ else if (classoid == TypeRelationId)
+ {
+ Datum aclDatum;
+ bool isNull;
+ HeapTuple tuple;
+
+ tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(objoid));
+ if (!HeapTupleIsValid(tuple))
+ elog(ERROR, "cache lookup failed for function %u", objoid);
+
+ aclDatum = SysCacheGetAttr(TYPEOID, tuple, Anum_pg_type_typacl,
+ &isNull);
+
+ /* Add the record, if any, for the top-level object */
+ if (!isNull)
+ recordExtensionInitPrivWorker(objoid, classoid, 0,
+ DatumGetAclP(aclDatum));
+
+ ReleaseSysCache(tuple);
+ }
+ else if (classoid == AccessMethodRelationId ||
+ classoid == AggregateRelationId ||
+ classoid == CastRelationId ||
+ classoid == CollationRelationId ||
+ classoid == ConversionRelationId ||
+ classoid == EventTriggerRelationId ||
+ classoid == OperatorRelationId ||
+ classoid == OperatorClassRelationId ||
+ classoid == OperatorFamilyRelationId ||
+ classoid == NamespaceRelationId ||
+ classoid == TSConfigRelationId ||
+ classoid == TSDictionaryRelationId ||
+ classoid == TSParserRelationId ||
+ classoid == TSTemplateRelationId ||
+ classoid == TransformRelationId
+ )
+ {
+ /* no ACL for these object types, so do nothing. */
+ }
+
+ /*
+ * complain if we are given a class OID for a class that extensions don't
+ * support or that we don't recognize.
+ */
+ else
+ {
+ elog(ERROR, "unrecognized or unsupported class OID: %u", classoid);
+ }
+}
+
+/*
+ * For the object passed in, remove its ACL and the ACLs of any object subIds
+ * from pg_init_privs (via recordExtensionInitPrivWorker()).
+ */
+void
+removeExtObjInitPriv(Oid objoid, Oid classoid)
+{
+ /*
+ * If this is a relation then we need to see if there are any sub-objects
+ * (eg: columns) for it and, if so, be sure to call
+ * recordExtensionInitPrivWorker() for each one.
+ */
+ if (classoid == RelationRelationId)
+ {
+ Form_pg_class pg_class_tuple;
+ HeapTuple tuple;
+
+ tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(objoid));
+ if (!HeapTupleIsValid(tuple))
+ elog(ERROR, "cache lookup failed for relation %u", objoid);
+ pg_class_tuple = (Form_pg_class) GETSTRUCT(tuple);
+
+ /* Indexes don't have permissions */
+ if (pg_class_tuple->relkind == RELKIND_INDEX)
+ return;
+
+ /* Composite types don't have permissions either */
+ if (pg_class_tuple->relkind == RELKIND_COMPOSITE_TYPE)
+ return;
+
+ /*
+ * If this isn't a sequence, index, or composite type then it's
+ * possibly going to have columns associated with it that might have
+ * ACLs.
+ */
+ if (pg_class_tuple->relkind != RELKIND_SEQUENCE)
+ {
+ AttrNumber curr_att;
+ AttrNumber nattrs = pg_class_tuple->relnatts;
+
+ for (curr_att = 1; curr_att <= nattrs; curr_att++)
+ {
+ HeapTuple attTuple;
+
+ attTuple = SearchSysCache2(ATTNUM,
+ ObjectIdGetDatum(objoid),
+ Int16GetDatum(curr_att));
+
+ if (!HeapTupleIsValid(attTuple))
+ continue;
+
+ /* when removing, remove all entires, even dropped columns */
+
+ recordExtensionInitPrivWorker(objoid, classoid, curr_att, NULL);
+
+ ReleaseSysCache(attTuple);
+ }
+ }
+
+ ReleaseSysCache(tuple);
+ }
+
+ /* Remove the record, if any, for the top-level object */
+ recordExtensionInitPrivWorker(objoid, classoid, 0, NULL);
+}
+
+/*
+ * Record initial ACL for an extension object
*
* Can be called at any time, we check if 'creating_extension' is set and, if
* not, exit immediately.
static void
recordExtensionInitPriv(Oid objoid, Oid classoid, int objsubid, Acl *new_acl)
{
- Relation relation;
- ScanKeyData key[3];
- SysScanDesc scan;
- HeapTuple tuple;
- HeapTuple oldtuple;
-
/*
* Generally, we only record the initial privileges when an extension is
* being created, but because we don't actually use CREATE EXTENSION
if (!creating_extension && !binary_upgrade_record_init_privs)
return;
+ recordExtensionInitPrivWorker(objoid, classoid, objsubid, new_acl);
+}
+
+/*
+ * Record initial ACL for an extension object, worker.
+ *
+ * This will perform a wholesale replacement of the entire ACL for the object
+ * passed in, therefore be sure to pass in the complete new ACL to use.
+ *
+ * Generally speaking, do *not* use this function directly but instead use
+ * recordExtensionInitPriv(), which checks if 'creating_extension' is set.
+ * This function does *not* check if 'creating_extension' is set as it is also
+ * used when an object is added to or removed from an extension via ALTER
+ * EXTENSION ... ADD/DROP.
+ */
+static void
+recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid, Acl *new_acl)
+{
+ Relation relation;
+ ScanKeyData key[3];
+ SysScanDesc scan;
+ HeapTuple tuple;
+ HeapTuple oldtuple;
+
relation = heap_open(InitPrivsRelationId, RowExclusiveLock);
ScanKeyInit(&key[0],
}
else
{
- /* No entry found, so add it. */
Datum values[Natts_pg_init_privs];
bool nulls[Natts_pg_init_privs];
- MemSet(nulls, false, sizeof(nulls));
+ /*
+ * Only add a new entry if the new ACL is non-NULL.
+ *
+ * If we are passed in a NULL ACL and no entry exists, we can just
+ * fall through and do nothing.
+ */
+ if (new_acl)
+ {
+ /* No entry found, so add it. */
+ MemSet(nulls, false, sizeof(nulls));
- values[Anum_pg_init_privs_objoid - 1] = ObjectIdGetDatum(objoid);
- values[Anum_pg_init_privs_classoid - 1] = ObjectIdGetDatum(classoid);
- values[Anum_pg_init_privs_objsubid - 1] = Int32GetDatum(objsubid);
+ values[Anum_pg_init_privs_objoid - 1] = ObjectIdGetDatum(objoid);
+ values[Anum_pg_init_privs_classoid - 1] = ObjectIdGetDatum(classoid);
+ values[Anum_pg_init_privs_objsubid - 1] = Int32GetDatum(objsubid);
- /* This function only handles initial privileges of extensions */
- values[Anum_pg_init_privs_privtype - 1] =
- CharGetDatum(INITPRIVS_EXTENSION);
+ /* This function only handles initial privileges of extensions */
+ values[Anum_pg_init_privs_privtype - 1] =
+ CharGetDatum(INITPRIVS_EXTENSION);
- values[Anum_pg_init_privs_privs - 1] = PointerGetDatum(new_acl);
+ values[Anum_pg_init_privs_privs - 1] = PointerGetDatum(new_acl);
- tuple = heap_form_tuple(RelationGetDescr(relation), values, nulls);
+ tuple = heap_form_tuple(RelationGetDescr(relation), values, nulls);
- simple_heap_insert(relation, tuple);
+ simple_heap_insert(relation, tuple);
- /* keep the catalog indexes up to date */
- CatalogUpdateIndexes(relation, tuple);
+ /* keep the catalog indexes up to date */
+ CatalogUpdateIndexes(relation, tuple);
+ }
}
systable_endscan(scan);
-SELECT 1;
- ?column?
-----------
- 1
-(1 row)
-
+CREATE ROLE regress_dump_test_role;
+CREATE EXTENSION test_pg_dump;
+ALTER EXTENSION test_pg_dump ADD DATABASE postgres; -- error
+ERROR: syntax error at or near "DATABASE"
+LINE 1: ALTER EXTENSION test_pg_dump ADD DATABASE postgres;
+ ^
+CREATE TABLE test_pg_dump_t1 (c1 int);
+CREATE VIEW test_pg_dump_v1 AS SELECT * FROM test_pg_dump_t1;
+CREATE MATERIALIZED VIEW test_pg_dump_mv1 AS SELECT * FROM test_pg_dump_t1;
+CREATE SCHEMA test_pg_dump_s1;
+CREATE TYPE test_pg_dump_e1 AS ENUM ('abc', 'def');
+CREATE AGGREGATE newavg (
+ sfunc = int4_avg_accum, basetype = int4, stype = _int8,
+ finalfunc = int8_avg,
+ initcond1 = '{0,0}'
+);
+CREATE FUNCTION test_pg_dump(int) RETURNS int AS $$
+BEGIN
+RETURN abs($1);
+END
+$$ LANGUAGE plpgsql IMMUTABLE;
+CREATE OPERATOR ==== (
+ LEFTARG = int,
+ RIGHTARG = int,
+ PROCEDURE = int4eq,
+ COMMUTATOR = ====
+);
+CREATE ACCESS METHOD gist2 TYPE INDEX HANDLER gisthandler;
+CREATE TYPE casttesttype;
+CREATE FUNCTION casttesttype_in(cstring)
+ RETURNS casttesttype
+ AS 'textin'
+ LANGUAGE internal STRICT IMMUTABLE;
+NOTICE: return type casttesttype is only a shell
+CREATE FUNCTION casttesttype_out(casttesttype)
+ RETURNS cstring
+ AS 'textout'
+ LANGUAGE internal STRICT IMMUTABLE;
+NOTICE: argument type casttesttype is only a shell
+CREATE TYPE casttesttype (
+ internallength = variable,
+ input = casttesttype_in,
+ output = casttesttype_out,
+ alignment = int4
+);
+CREATE CAST (text AS casttesttype) WITHOUT FUNCTION;
+CREATE FOREIGN DATA WRAPPER dummy;
+CREATE SERVER s0 FOREIGN DATA WRAPPER dummy;
+CREATE FOREIGN TABLE ft1 (
+ c1 integer OPTIONS ("param 1" 'val1') NOT NULL,
+ c2 text OPTIONS (param2 'val2', param3 'val3') CHECK (c2 <> ''),
+ c3 date,
+ CHECK (c3 BETWEEN '1994-01-01'::date AND '1994-01-31'::date)
+) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value');
+REVOKE EXECUTE ON FUNCTION test_pg_dump(int) FROM PUBLIC;
+GRANT EXECUTE ON FUNCTION test_pg_dump(int) TO regress_dump_test_role;
+GRANT SELECT (c1) ON test_pg_dump_t1 TO regress_dump_test_role;
+GRANT SELECT ON test_pg_dump_v1 TO regress_dump_test_role;
+GRANT USAGE ON FOREIGN DATA WRAPPER dummy TO regress_dump_test_role;
+GRANT USAGE ON FOREIGN SERVER s0 TO regress_dump_test_role;
+GRANT SELECT (c1) ON ft1 TO regress_dump_test_role;
+GRANT SELECT ON ft1 TO regress_dump_test_role;
+GRANT UPDATE ON test_pg_dump_mv1 TO regress_dump_test_role;
+GRANT USAGE ON SCHEMA test_pg_dump_s1 TO regress_dump_test_role;
+GRANT USAGE ON TYPE test_pg_dump_e1 TO regress_dump_test_role;
+ALTER EXTENSION test_pg_dump ADD ACCESS METHOD gist2;
+ALTER EXTENSION test_pg_dump ADD AGGREGATE newavg(int4);
+ALTER EXTENSION test_pg_dump ADD CAST (text AS casttesttype);
+ALTER EXTENSION test_pg_dump ADD FOREIGN DATA WRAPPER dummy;
+ALTER EXTENSION test_pg_dump ADD FOREIGN TABLE ft1;
+ALTER EXTENSION test_pg_dump ADD MATERIALIZED VIEW test_pg_dump_mv1;
+ALTER EXTENSION test_pg_dump ADD OPERATOR ==== (int, int);
+ALTER EXTENSION test_pg_dump ADD SCHEMA test_pg_dump_s1;
+ALTER EXTENSION test_pg_dump ADD SERVER s0;
+ALTER EXTENSION test_pg_dump ADD FUNCTION test_pg_dump(int);
+ALTER EXTENSION test_pg_dump ADD TABLE test_pg_dump_t1;
+ALTER EXTENSION test_pg_dump ADD TYPE test_pg_dump_e1;
+ALTER EXTENSION test_pg_dump ADD VIEW test_pg_dump_v1;
+REVOKE SELECT (c1) ON test_pg_dump_t1 FROM regress_dump_test_role;
+REVOKE SELECT ON test_pg_dump_v1 FROM regress_dump_test_role;
+REVOKE USAGE ON FOREIGN DATA WRAPPER dummy FROM regress_dump_test_role;
+ALTER EXTENSION test_pg_dump DROP ACCESS METHOD gist2;
+ALTER EXTENSION test_pg_dump DROP AGGREGATE newavg(int4);
+ALTER EXTENSION test_pg_dump DROP CAST (text AS casttesttype);
+ALTER EXTENSION test_pg_dump DROP FOREIGN DATA WRAPPER dummy;
+ALTER EXTENSION test_pg_dump DROP FOREIGN TABLE ft1;
+ALTER EXTENSION test_pg_dump DROP FUNCTION test_pg_dump(int);
+ALTER EXTENSION test_pg_dump DROP MATERIALIZED VIEW test_pg_dump_mv1;
+ALTER EXTENSION test_pg_dump DROP OPERATOR ==== (int, int);
+ALTER EXTENSION test_pg_dump DROP SCHEMA test_pg_dump_s1;
+ALTER EXTENSION test_pg_dump DROP SERVER s0;
+ALTER EXTENSION test_pg_dump DROP TABLE test_pg_dump_t1;
+ALTER EXTENSION test_pg_dump DROP TYPE test_pg_dump_e1;
+ALTER EXTENSION test_pg_dump DROP VIEW test_pg_dump_v1;
-SELECT 1;
+CREATE ROLE regress_dump_test_role;
+CREATE EXTENSION test_pg_dump;
+
+ALTER EXTENSION test_pg_dump ADD DATABASE postgres; -- error
+
+CREATE TABLE test_pg_dump_t1 (c1 int);
+CREATE VIEW test_pg_dump_v1 AS SELECT * FROM test_pg_dump_t1;
+CREATE MATERIALIZED VIEW test_pg_dump_mv1 AS SELECT * FROM test_pg_dump_t1;
+CREATE SCHEMA test_pg_dump_s1;
+CREATE TYPE test_pg_dump_e1 AS ENUM ('abc', 'def');
+
+CREATE AGGREGATE newavg (
+ sfunc = int4_avg_accum, basetype = int4, stype = _int8,
+ finalfunc = int8_avg,
+ initcond1 = '{0,0}'
+);
+
+CREATE FUNCTION test_pg_dump(int) RETURNS int AS $$
+BEGIN
+RETURN abs($1);
+END
+$$ LANGUAGE plpgsql IMMUTABLE;
+
+CREATE OPERATOR ==== (
+ LEFTARG = int,
+ RIGHTARG = int,
+ PROCEDURE = int4eq,
+ COMMUTATOR = ====
+);
+
+CREATE ACCESS METHOD gist2 TYPE INDEX HANDLER gisthandler;
+
+CREATE TYPE casttesttype;
+
+CREATE FUNCTION casttesttype_in(cstring)
+ RETURNS casttesttype
+ AS 'textin'
+ LANGUAGE internal STRICT IMMUTABLE;
+CREATE FUNCTION casttesttype_out(casttesttype)
+ RETURNS cstring
+ AS 'textout'
+ LANGUAGE internal STRICT IMMUTABLE;
+
+CREATE TYPE casttesttype (
+ internallength = variable,
+ input = casttesttype_in,
+ output = casttesttype_out,
+ alignment = int4
+);
+
+CREATE CAST (text AS casttesttype) WITHOUT FUNCTION;
+
+CREATE FOREIGN DATA WRAPPER dummy;
+
+CREATE SERVER s0 FOREIGN DATA WRAPPER dummy;
+
+CREATE FOREIGN TABLE ft1 (
+ c1 integer OPTIONS ("param 1" 'val1') NOT NULL,
+ c2 text OPTIONS (param2 'val2', param3 'val3') CHECK (c2 <> ''),
+ c3 date,
+ CHECK (c3 BETWEEN '1994-01-01'::date AND '1994-01-31'::date)
+) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value');
+
+REVOKE EXECUTE ON FUNCTION test_pg_dump(int) FROM PUBLIC;
+GRANT EXECUTE ON FUNCTION test_pg_dump(int) TO regress_dump_test_role;
+
+GRANT SELECT (c1) ON test_pg_dump_t1 TO regress_dump_test_role;
+GRANT SELECT ON test_pg_dump_v1 TO regress_dump_test_role;
+GRANT USAGE ON FOREIGN DATA WRAPPER dummy TO regress_dump_test_role;
+GRANT USAGE ON FOREIGN SERVER s0 TO regress_dump_test_role;
+GRANT SELECT (c1) ON ft1 TO regress_dump_test_role;
+GRANT SELECT ON ft1 TO regress_dump_test_role;
+GRANT UPDATE ON test_pg_dump_mv1 TO regress_dump_test_role;
+GRANT USAGE ON SCHEMA test_pg_dump_s1 TO regress_dump_test_role;
+GRANT USAGE ON TYPE test_pg_dump_e1 TO regress_dump_test_role;
+
+ALTER EXTENSION test_pg_dump ADD ACCESS METHOD gist2;
+ALTER EXTENSION test_pg_dump ADD AGGREGATE newavg(int4);
+ALTER EXTENSION test_pg_dump ADD CAST (text AS casttesttype);
+ALTER EXTENSION test_pg_dump ADD FOREIGN DATA WRAPPER dummy;
+ALTER EXTENSION test_pg_dump ADD FOREIGN TABLE ft1;
+ALTER EXTENSION test_pg_dump ADD MATERIALIZED VIEW test_pg_dump_mv1;
+ALTER EXTENSION test_pg_dump ADD OPERATOR ==== (int, int);
+ALTER EXTENSION test_pg_dump ADD SCHEMA test_pg_dump_s1;
+ALTER EXTENSION test_pg_dump ADD SERVER s0;
+ALTER EXTENSION test_pg_dump ADD FUNCTION test_pg_dump(int);
+ALTER EXTENSION test_pg_dump ADD TABLE test_pg_dump_t1;
+ALTER EXTENSION test_pg_dump ADD TYPE test_pg_dump_e1;
+ALTER EXTENSION test_pg_dump ADD VIEW test_pg_dump_v1;
+
+REVOKE SELECT (c1) ON test_pg_dump_t1 FROM regress_dump_test_role;
+REVOKE SELECT ON test_pg_dump_v1 FROM regress_dump_test_role;
+REVOKE USAGE ON FOREIGN DATA WRAPPER dummy FROM regress_dump_test_role;
+
+ALTER EXTENSION test_pg_dump DROP ACCESS METHOD gist2;
+ALTER EXTENSION test_pg_dump DROP AGGREGATE newavg(int4);
+ALTER EXTENSION test_pg_dump DROP CAST (text AS casttesttype);
+ALTER EXTENSION test_pg_dump DROP FOREIGN DATA WRAPPER dummy;
+ALTER EXTENSION test_pg_dump DROP FOREIGN TABLE ft1;
+ALTER EXTENSION test_pg_dump DROP FUNCTION test_pg_dump(int);
+ALTER EXTENSION test_pg_dump DROP MATERIALIZED VIEW test_pg_dump_mv1;
+ALTER EXTENSION test_pg_dump DROP OPERATOR ==== (int, int);
+ALTER EXTENSION test_pg_dump DROP SCHEMA test_pg_dump_s1;
+ALTER EXTENSION test_pg_dump DROP SERVER s0;
+ALTER EXTENSION test_pg_dump DROP TABLE test_pg_dump_t1;
+ALTER EXTENSION test_pg_dump DROP TYPE test_pg_dump_e1;
+ALTER EXTENSION test_pg_dump DROP VIEW test_pg_dump_v1;