diff options
author | Tom Lane | 2011-02-08 21:08:41 +0000 |
---|---|---|
committer | Tom Lane | 2011-02-08 21:13:22 +0000 |
commit | d9572c4e3b474031060189050e14ef384b94e001 (patch) | |
tree | 07646762f4086b94a69b9fc215734d2bccade5db /src/include | |
parent | 414c5a2ea65cbd38d79ffdf9b1fde7cc75c134e0 (diff) |
Core support for "extensions", which are packages of SQL objects.
This patch adds the server infrastructure to support extensions.
There is still one significant loose end, namely how to make it play nice
with pg_upgrade, so I am not yet committing the changes that would make
all the contrib modules depend on this feature.
In passing, fix a disturbingly large amount of breakage in
AlterObjectNamespace() and callers.
Dimitri Fontaine, reviewed by Anssi Kääriäinen,
Itagaki Takahiro, Tom Lane, and numerous others
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/catalog/catversion.h | 2 | ||||
-rw-r--r-- | src/include/catalog/dependency.h | 16 | ||||
-rw-r--r-- | src/include/catalog/indexing.h | 6 | ||||
-rw-r--r-- | src/include/catalog/pg_extension.h | 72 | ||||
-rw-r--r-- | src/include/catalog/pg_proc.h | 6 | ||||
-rw-r--r-- | src/include/commands/alter.h | 10 | ||||
-rw-r--r-- | src/include/commands/conversioncmds.h | 1 | ||||
-rw-r--r-- | src/include/commands/defrem.h | 8 | ||||
-rw-r--r-- | src/include/commands/extension.h | 40 | ||||
-rw-r--r-- | src/include/commands/typecmds.h | 3 | ||||
-rw-r--r-- | src/include/nodes/nodes.h | 1 | ||||
-rw-r--r-- | src/include/nodes/parsenodes.h | 13 | ||||
-rw-r--r-- | src/include/parser/kwlist.h | 1 | ||||
-rw-r--r-- | src/include/utils/builtins.h | 6 |
14 files changed, 176 insertions, 9 deletions
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 3defe0641f2..019cd8fab5a 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 201102083 +#define CATALOG_VERSION_NO 201102084 #endif diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h index c6ab313edf8..4d7ff8853d1 100644 --- a/src/include/catalog/dependency.h +++ b/src/include/catalog/dependency.h @@ -50,6 +50,12 @@ * Example: a trigger that's created to enforce a foreign-key constraint * is made internally dependent on the constraint's pg_constraint entry. * + * DEPENDENCY_EXTENSION ('e'): the dependent object is a member of the + * extension that is the referenced object. The dependent object can be + * dropped only via DROP EXTENSION on the referenced object. Functionally + * this dependency type acts the same as an internal dependency, but it's + * kept separate for clarity and to simplify pg_dump. + * * DEPENDENCY_PIN ('p'): there is no dependent object; this type of entry * is a signal that the system itself depends on the referenced object, * and so that object must never be deleted. Entries of this type are @@ -64,6 +70,7 @@ typedef enum DependencyType DEPENDENCY_NORMAL = 'n', DEPENDENCY_AUTO = 'a', DEPENDENCY_INTERNAL = 'i', + DEPENDENCY_EXTENSION = 'e', DEPENDENCY_PIN = 'p' } DependencyType; @@ -137,8 +144,8 @@ typedef enum ObjectClass OCLASS_FDW, /* pg_foreign_data_wrapper */ OCLASS_FOREIGN_SERVER, /* pg_foreign_server */ OCLASS_USER_MAPPING, /* pg_user_mapping */ - OCLASS_FOREIGN_TABLE, /* pg_foreign_table */ OCLASS_DEFACL, /* pg_default_acl */ + OCLASS_EXTENSION, /* pg_extension */ MAX_OCLASS /* MUST BE LAST */ } ObjectClass; @@ -193,12 +200,17 @@ extern void recordMultipleDependencies(const ObjectAddress *depender, int nreferenced, DependencyType behavior); -extern long deleteDependencyRecordsFor(Oid classId, Oid objectId); +extern void recordDependencyOnCurrentExtension(const ObjectAddress *object); + +extern long deleteDependencyRecordsFor(Oid classId, Oid objectId, + bool skipExtensionDeps); extern long changeDependencyFor(Oid classId, Oid objectId, Oid refClassId, Oid oldRefObjectId, Oid newRefObjectId); +extern Oid getExtensionOfObject(Oid classId, Oid objectId); + extern bool sequenceIsOwned(Oid seqId, Oid *tableId, int32 *colId); extern void markSequenceUnowned(Oid seqId); diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h index 866942cf9a3..4118e645424 100644 --- a/src/include/catalog/indexing.h +++ b/src/include/catalog/indexing.h @@ -294,6 +294,12 @@ DECLARE_UNIQUE_INDEX(pg_db_role_setting_databaseid_rol_index, 2965, on pg_db_rol DECLARE_UNIQUE_INDEX(pg_seclabel_object_index, 3597, on pg_seclabel using btree(objoid oid_ops, classoid oid_ops, objsubid int4_ops, provider text_ops)); #define SecLabelObjectIndexId 3597 +DECLARE_UNIQUE_INDEX(pg_extension_oid_index, 3080, on pg_extension using btree(oid oid_ops)); +#define ExtensionOidIndexId 3080 + +DECLARE_UNIQUE_INDEX(pg_extension_name_index, 3081, on pg_extension using btree(extname name_ops)); +#define ExtensionNameIndexId 3081 + /* last step of initialization script: build the indexes declared above */ BUILD_INDICES diff --git a/src/include/catalog/pg_extension.h b/src/include/catalog/pg_extension.h new file mode 100644 index 00000000000..0ad47b01a4b --- /dev/null +++ b/src/include/catalog/pg_extension.h @@ -0,0 +1,72 @@ +/*------------------------------------------------------------------------- + * + * pg_extension.h + * definition of the system "extension" relation (pg_extension) + * along with the relation's initial contents. + * + * + * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_extension.h + * + * NOTES + * the genbki.pl script reads this file and generates .bki + * information from the DATA() statements. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_EXTENSION_H +#define PG_EXTENSION_H + +#include "catalog/genbki.h" + +/* ---------------- + * pg_extension definition. cpp turns this into + * typedef struct FormData_pg_extension + * ---------------- + */ +#define ExtensionRelationId 3079 + +CATALOG(pg_extension,3079) +{ + NameData extname; /* extension name */ + Oid extowner; /* extension owner */ + Oid extnamespace; /* namespace of contained objects */ + bool extrelocatable; /* if true, allow ALTER EXTENSION SET SCHEMA */ + + /* + * VARIABLE LENGTH FIELDS start here. These fields may be NULL, too. + */ + text extversion; /* extension version ID, if any */ + Oid extconfig[1]; /* dumpable configuration tables */ + text extcondition[1]; /* WHERE clauses for config tables */ +} FormData_pg_extension; + +/* ---------------- + * Form_pg_extension corresponds to a pointer to a tuple with + * the format of pg_extension relation. + * ---------------- + */ +typedef FormData_pg_extension *Form_pg_extension; + +/* ---------------- + * compiler constants for pg_extension + * ---------------- + */ + +#define Natts_pg_extension 7 +#define Anum_pg_extension_extname 1 +#define Anum_pg_extension_extowner 2 +#define Anum_pg_extension_extnamespace 3 +#define Anum_pg_extension_extrelocatable 4 +#define Anum_pg_extension_extversion 5 +#define Anum_pg_extension_extconfig 6 +#define Anum_pg_extension_extcondition 7 + +/* ---------------- + * pg_extension has no initial contents + * ---------------- + */ + +#endif /* PG_EXTENSION_H */ diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 836574355cd..9e6ec3dda50 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -4873,6 +4873,12 @@ DESCR("record greater than or equal"); DATA(insert OID = 2987 ( btrecordcmp PGNSP PGUID 12 1 0 0 f f f t f i 2 0 23 "2249 2249" _null_ _null_ _null_ _null_ btrecordcmp _null_ _null_ _null_ )); DESCR("btree less-equal-greater"); +/* Extensions */ +DATA(insert OID = 3082 ( pg_available_extensions PGNSP PGUID 12 10 100 0 f f f t t s 0 0 2249 "" "{19,25,16,25}" "{o,o,o,o}" "{name,version,relocatable,comment}" _null_ pg_available_extensions _null_ _null_ _null_ )); +DESCR("list available extensions"); +DATA(insert OID = 3083 ( pg_extension_config_dump PGNSP PGUID 12 1 0 0 f f f t f v 2 0 2278 "2205 25" _null_ _null_ _null_ _null_ pg_extension_config_dump _null_ _null_ _null_ )); +DESCR("flag an extension's table contents to be emitted by pg_dump"); + /* SQL-spec window functions */ DATA(insert OID = 3100 ( row_number PGNSP PGUID 12 1 0 0 f t f f f i 0 0 20 "" _null_ _null_ _null_ _null_ window_row_number _null_ _null_ _null_ )); DESCR("row number within partition"); diff --git a/src/include/commands/alter.h b/src/include/commands/alter.h index 74d5132636c..21731685f5c 100644 --- a/src/include/commands/alter.h +++ b/src/include/commands/alter.h @@ -20,11 +20,11 @@ extern void ExecRenameStmt(RenameStmt *stmt); extern void ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt); -extern void AlterObjectNamespace(Relation rel, int cacheId, - Oid classId, Oid objid, Oid nspId, - int Anum_name, int Anum_namespace, int Anum_owner, - AclObjectKind acl_kind, - bool superuser_only); +extern Oid AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid); +extern Oid AlterObjectNamespace(Relation rel, int oidCacheId, int nameCacheId, + Oid objid, Oid nspOid, + int Anum_name, int Anum_namespace, int Anum_owner, + AclObjectKind acl_kind); extern void ExecAlterOwnerStmt(AlterOwnerStmt *stmt); #endif /* ALTER_H */ diff --git a/src/include/commands/conversioncmds.h b/src/include/commands/conversioncmds.h index 6156c4a94e6..f77023ffe32 100644 --- a/src/include/commands/conversioncmds.h +++ b/src/include/commands/conversioncmds.h @@ -23,5 +23,6 @@ extern void RenameConversion(List *name, const char *newname); extern void AlterConversionOwner(List *name, Oid newOwnerId); extern void AlterConversionOwner_oid(Oid conversionOid, Oid newOwnerId); extern void AlterConversionNamespace(List *name, const char *newschema); +extern Oid AlterConversionNamespace_oid(Oid convOid, Oid newNspOid); #endif /* CONVERSIONCMDS_H */ diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h index 01f271bff43..157ee394614 100644 --- a/src/include/commands/defrem.h +++ b/src/include/commands/defrem.h @@ -66,6 +66,7 @@ extern void DropCast(DropCastStmt *stmt); extern void DropCastById(Oid castOid); extern void AlterFunctionNamespace(List *name, List *argtypes, bool isagg, const char *newschema); +extern Oid AlterFunctionNamespace_oid(Oid procOid, Oid nspOid); extern void ExecuteDoStmt(DoStmt *stmt); extern Oid get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok); @@ -77,6 +78,7 @@ extern void AlterOperatorOwner(List *name, TypeName *typeName1, TypeName *typename2, Oid newOwnerId); extern void AlterOperatorOwner_oid(Oid operOid, Oid newOwnerId); extern void AlterOperatorNamespace(List *names, List *argtypes, const char *newschema); +extern Oid AlterOperatorNamespace_oid(Oid operOid, Oid newNspOid); /* commands/aggregatecmds.c */ extern void DefineAggregate(List *name, List *args, bool oldstyle, @@ -100,9 +102,11 @@ extern void RenameOpFamily(List *name, const char *access_method, const char *ne extern void AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId); extern void AlterOpClassOwner_oid(Oid opclassOid, Oid newOwnerId); extern void AlterOpClassNamespace(List *name, char *access_method, const char *newschema); +extern Oid AlterOpClassNamespace_oid(Oid opclassOid, Oid newNspOid); extern void AlterOpFamilyOwner(List *name, const char *access_method, Oid newOwnerId); extern void AlterOpFamilyOwner_oid(Oid opfamilyOid, Oid newOwnerId); extern void AlterOpFamilyNamespace(List *name, char *access_method, const char *newschema); +extern Oid AlterOpFamilyNamespace_oid(Oid opfamilyOid, Oid newNspOid); extern Oid get_am_oid(const char *amname, bool missing_ok); extern Oid get_opclass_oid(Oid amID, List *opclassname, bool missing_ok); extern Oid get_opfamily_oid(Oid amID, List *opfamilyname, bool missing_ok); @@ -111,6 +115,7 @@ extern Oid get_opfamily_oid(Oid amID, List *opfamilyname, bool missing_ok); extern void DefineTSParser(List *names, List *parameters); extern void RenameTSParser(List *oldname, const char *newname); extern void AlterTSParserNamespace(List *name, const char *newschema); +extern Oid AlterTSParserNamespace_oid(Oid prsId, Oid newNspOid); extern void RemoveTSParsers(DropStmt *drop); extern void RemoveTSParserById(Oid prsId); @@ -121,10 +126,12 @@ extern void RemoveTSDictionaryById(Oid dictId); extern void AlterTSDictionary(AlterTSDictionaryStmt *stmt); extern void AlterTSDictionaryOwner(List *name, Oid newOwnerId); extern void AlterTSDictionaryNamespace(List *name, const char *newschema); +extern Oid AlterTSDictionaryNamespace_oid(Oid dictId, Oid newNspOid); extern void DefineTSTemplate(List *names, List *parameters); extern void RenameTSTemplate(List *oldname, const char *newname); extern void AlterTSTemplateNamespace(List *name, const char *newschema); +extern Oid AlterTSTemplateNamespace_oid(Oid tmplId, Oid newNspOid); extern void RemoveTSTemplates(DropStmt *stmt); extern void RemoveTSTemplateById(Oid tmplId); @@ -135,6 +142,7 @@ extern void RemoveTSConfigurationById(Oid cfgId); extern void AlterTSConfiguration(AlterTSConfigurationStmt *stmt); extern void AlterTSConfigurationOwner(List *name, Oid newOwnerId); extern void AlterTSConfigurationNamespace(List *name, const char *newschema); +extern Oid AlterTSConfigurationNamespace_oid(Oid cfgId, Oid newNspOid); extern text *serialize_deflist(List *deflist); extern List *deserialize_deflist(Datum txt); diff --git a/src/include/commands/extension.h b/src/include/commands/extension.h new file mode 100644 index 00000000000..10d08935a00 --- /dev/null +++ b/src/include/commands/extension.h @@ -0,0 +1,40 @@ +/*------------------------------------------------------------------------- + * + * extension.h + * Extension management commands (create/drop extension). + * + * + * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/extension.h + * + *------------------------------------------------------------------------- + */ +#ifndef EXTENSION_H +#define EXTENSION_H + +#include "nodes/parsenodes.h" + + +/* + * creating_extension is only true while running a CREATE EXTENSION command. + * It instructs recordDependencyOnCurrentExtension() to register a dependency + * on the current pg_extension object for each SQL object created by its + * installation script. + */ +extern bool creating_extension; +extern Oid CurrentExtensionObject; + + +extern void CreateExtension(CreateExtensionStmt *stmt); + +extern void RemoveExtensions(DropStmt *stmt); +extern void RemoveExtensionById(Oid extId); + +extern Oid get_extension_oid(const char *extname, bool missing_ok); +extern char *get_extension_name(Oid ext_oid); + +extern void AlterExtensionNamespace(List *names, const char *newschema); + +#endif /* EXTENSION_H */ diff --git a/src/include/commands/typecmds.h b/src/include/commands/typecmds.h index b13363aaf7e..1b20296934f 100644 --- a/src/include/commands/typecmds.h +++ b/src/include/commands/typecmds.h @@ -41,7 +41,8 @@ extern void AlterTypeOwner(List *names, Oid newOwnerId); extern void AlterTypeOwnerInternal(Oid typeOid, Oid newOwnerId, bool hasDependEntry); extern void AlterTypeNamespace(List *names, const char *newschema); -extern void AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid, +extern Oid AlterTypeNamespace_oid(Oid typeOid, Oid nspOid); +extern Oid AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid, bool isImplicitArray, bool errorOnTableType); diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index 63b9dd80be9..1ca5f1ef9a1 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -355,6 +355,7 @@ typedef enum NodeTag T_AlterTableSpaceOptionsStmt, T_SecLabelStmt, T_CreateForeignTableStmt, + T_CreateExtensionStmt, /* * TAGS FOR PARSE TREE NODES (parsenodes.h) diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index b68fe10990a..5de4dbd5ec1 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -1073,6 +1073,7 @@ typedef enum ObjectType OBJECT_CONVERSION, OBJECT_DATABASE, OBJECT_DOMAIN, + OBJECT_EXTENSION, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FOREIGN_TABLE, @@ -1534,6 +1535,18 @@ typedef struct AlterTableSpaceOptionsStmt } AlterTableSpaceOptionsStmt; /* ---------------------- + * Create Extension Statement + * ---------------------- + */ + +typedef struct CreateExtensionStmt +{ + NodeTag type; + char *extname; + List *options; /* List of DefElem nodes */ +} CreateExtensionStmt; + +/* ---------------------- * Create/Drop FOREIGN DATA WRAPPER Statements * ---------------------- */ diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h index 7dad00197eb..4939b493bc2 100644 --- a/src/include/parser/kwlist.h +++ b/src/include/parser/kwlist.h @@ -150,6 +150,7 @@ PG_KEYWORD("exclusive", EXCLUSIVE, UNRESERVED_KEYWORD) PG_KEYWORD("execute", EXECUTE, UNRESERVED_KEYWORD) PG_KEYWORD("exists", EXISTS, COL_NAME_KEYWORD) PG_KEYWORD("explain", EXPLAIN, UNRESERVED_KEYWORD) +PG_KEYWORD("extension", EXTENSION, UNRESERVED_KEYWORD) PG_KEYWORD("external", EXTERNAL, UNRESERVED_KEYWORD) PG_KEYWORD("extract", EXTRACT, COL_NAME_KEYWORD) PG_KEYWORD("false", FALSE_P, RESERVED_KEYWORD) diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index 540d16b844a..d17eb67b1be 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -440,6 +440,8 @@ extern Datum pg_relation_filenode(PG_FUNCTION_ARGS); extern Datum pg_relation_filepath(PG_FUNCTION_ARGS); /* genfile.c */ +extern bytea *read_binary_file(const char *filename, + int64 seek_offset, int64 bytes_to_read); extern Datum pg_stat_file(PG_FUNCTION_ARGS); extern Datum pg_read_file(PG_FUNCTION_ARGS); extern Datum pg_read_file_all(PG_FUNCTION_ARGS); @@ -1063,6 +1065,10 @@ extern Datum pg_describe_object(PG_FUNCTION_ARGS); /* commands/constraint.c */ extern Datum unique_key_recheck(PG_FUNCTION_ARGS); +/* commands/extension.c */ +extern Datum pg_available_extensions(PG_FUNCTION_ARGS); +extern Datum pg_extension_config_dump(PG_FUNCTION_ARGS); + /* commands/prepare.c */ extern Datum pg_prepared_statement(PG_FUNCTION_ARGS); |