2 36.17. Packaging Related Objects into an Extension #
4 36.17.1. Extension Files
5 36.17.2. Extension Relocatability
6 36.17.3. Extension Configuration Tables
7 36.17.4. Extension Updates
8 36.17.5. Installing Extensions Using Update Scripts
9 36.17.6. Security Considerations for Extensions
10 36.17.7. Extension Example
12 A useful extension to PostgreSQL typically includes multiple SQL
13 objects; for example, a new data type will require new functions, new
14 operators, and probably new index operator classes. It is helpful to
15 collect all these objects into a single package to simplify database
16 management. PostgreSQL calls such a package an extension. To define an
17 extension, you need at least a script file that contains the SQL
18 commands to create the extension's objects, and a control file that
19 specifies a few basic properties of the extension itself. If the
20 extension includes C code, there will typically also be a shared
21 library file into which the C code has been built. Once you have these
22 files, a simple CREATE EXTENSION command loads the objects into your
25 The main advantage of using an extension, rather than just running the
26 SQL script to load a bunch of “loose” objects into your database, is
27 that PostgreSQL will then understand that the objects of the extension
28 go together. You can drop all the objects with a single DROP EXTENSION
29 command (no need to maintain a separate “uninstall” script). Even more
30 useful, pg_dump knows that it should not dump the individual member
31 objects of the extension — it will just include a CREATE EXTENSION
32 command in dumps, instead. This vastly simplifies migration to a new
33 version of the extension that might contain more or different objects
34 than the old version. Note however that you must have the extension's
35 control, script, and other files available when loading such a dump
38 PostgreSQL will not let you drop an individual object contained in an
39 extension, except by dropping the whole extension. Also, while you can
40 change the definition of an extension member object (for example, via
41 CREATE OR REPLACE FUNCTION for a function), bear in mind that the
42 modified definition will not be dumped by pg_dump. Such a change is
43 usually only sensible if you concurrently make the same change in the
44 extension's script file. (But there are special provisions for tables
45 containing configuration data; see Section 36.17.3.) In production
46 situations, it's generally better to create an extension update script
47 to perform changes to extension member objects.
49 The extension script may set privileges on objects that are part of the
50 extension, using GRANT and REVOKE statements. The final set of
51 privileges for each object (if any are set) will be stored in the
52 pg_init_privs system catalog. When pg_dump is used, the CREATE
53 EXTENSION command will be included in the dump, followed by the set of
54 GRANT and REVOKE statements necessary to set the privileges on the
55 objects to what they were at the time the dump was taken.
57 PostgreSQL does not currently support extension scripts issuing CREATE
58 POLICY or SECURITY LABEL statements. These are expected to be set after
59 the extension has been created. All RLS policies and security labels on
60 extension objects will be included in dumps created by pg_dump.
62 The extension mechanism also has provisions for packaging modification
63 scripts that adjust the definitions of the SQL objects contained in an
64 extension. For example, if version 1.1 of an extension adds one
65 function and changes the body of another function compared to 1.0, the
66 extension author can provide an update script that makes just those two
67 changes. The ALTER EXTENSION UPDATE command can then be used to apply
68 these changes and track which version of the extension is actually
69 installed in a given database.
71 The kinds of SQL objects that can be members of an extension are shown
72 in the description of ALTER EXTENSION. Notably, objects that are
73 database-cluster-wide, such as databases, roles, and tablespaces,
74 cannot be extension members since an extension is only known within one
75 database. (Although an extension script is not prohibited from creating
76 such objects, if it does so they will not be tracked as part of the
77 extension.) Also notice that while a table can be a member of an
78 extension, its subsidiary objects such as indexes are not directly
79 considered members of the extension. Another important point is that
80 schemas can belong to extensions, but not vice versa: an extension as
81 such has an unqualified name and does not exist “within” any schema.
82 The extension's member objects, however, will belong to schemas
83 whenever appropriate for their object types. It may or may not be
84 appropriate for an extension to own the schema(s) its member objects
87 If an extension's script creates any temporary objects (such as temp
88 tables), those objects are treated as extension members for the
89 remainder of the current session, but are automatically dropped at
90 session end, as any temporary object would be. This is an exception to
91 the rule that extension member objects cannot be dropped without
92 dropping the whole extension.
94 36.17.1. Extension Files #
96 The CREATE EXTENSION command relies on a control file for each
97 extension, which must be named the same as the extension with a suffix
98 of .control, and must be placed in the installation's
99 SHAREDIR/extension directory. There must also be at least one SQL
100 script file, which follows the naming pattern extension--version.sql
101 (for example, foo--1.0.sql for version 1.0 of extension foo). By
102 default, the script file(s) are also placed in the SHAREDIR/extension
103 directory; but the control file can specify a different directory for
106 Additional locations for extension control files can be configured
107 using the parameter extension_control_path.
109 The file format for an extension control file is the same as for the
110 postgresql.conf file, namely a list of parameter_name = value
111 assignments, one per line. Blank lines and comments introduced by # are
112 allowed. Be sure to quote any value that is not a single word or
115 A control file can set the following parameters:
118 The directory containing the extension's SQL script file(s).
119 Unless an absolute path is given, the name is relative to the
120 directory where the control file was found. By default, the
121 script files are looked for in the same directory where the
122 control file was found.
124 default_version (string) #
125 The default version of the extension (the one that will be
126 installed if no version is specified in CREATE EXTENSION).
127 Although this can be omitted, that will result in CREATE
128 EXTENSION failing if no VERSION option appears, so you generally
129 don't want to do that.
132 A comment (any string) about the extension. The comment is
133 applied when initially creating an extension, but not during
134 extension updates (since that might override user-added
135 comments). Alternatively, the extension's comment can be set by
136 writing a COMMENT command in the script file.
139 The character set encoding used by the script file(s). This
140 should be specified if the script files contain any non-ASCII
141 characters. Otherwise the files will be assumed to be in the
144 module_pathname (string) #
145 The value of this parameter will be substituted for each
146 occurrence of MODULE_PATHNAME in the script file(s). If it is
147 not set, no substitution is made. Typically, this is set to just
148 shared_library_name and then MODULE_PATHNAME is used in CREATE
149 FUNCTION commands for C-language functions, so that the script
150 files do not need to hard-wire the name of the shared library.
153 A list of names of extensions that this extension depends on,
154 for example requires = 'foo, bar'. Those extensions must be
155 installed before this one can be installed.
157 no_relocate (string) #
158 A list of names of extensions that this extension depends on
159 that should be barred from changing their schemas via ALTER
160 EXTENSION ... SET SCHEMA. This is needed if this extension's
161 script references the name of a required extension's schema
162 (using the @extschema:name@ syntax) in a way that cannot track
165 superuser (boolean) #
166 If this parameter is true (which is the default), only
167 superusers can create the extension or update it to a new
168 version (but see also trusted, below). If it is set to false,
169 just the privileges required to execute the commands in the
170 installation or update script are required. This should normally
171 be set to true if any of the script commands require superuser
172 privileges. (Such commands would fail anyway, but it's more
173 user-friendly to give the error up front.)
176 This parameter, if set to true (which is not the default),
177 allows some non-superusers to install an extension that has
178 superuser set to true. Specifically, installation will be
179 permitted for anyone who has CREATE privilege on the current
180 database. When the user executing CREATE EXTENSION is not a
181 superuser but is allowed to install by virtue of this parameter,
182 then the installation or update script is run as the bootstrap
183 superuser, not as the calling user. This parameter is irrelevant
184 if superuser is false. Generally, this should not be set true
185 for extensions that could allow access to
186 otherwise-superuser-only abilities, such as file system access.
187 Also, marking an extension trusted requires significant extra
188 effort to write the extension's installation and update
189 script(s) securely; see Section 36.17.6.
191 relocatable (boolean) #
192 An extension is relocatable if it is possible to move its
193 contained objects into a different schema after initial creation
194 of the extension. The default is false, i.e., the extension is
195 not relocatable. See Section 36.17.2 for more information.
198 This parameter can only be set for non-relocatable extensions.
199 It forces the extension to be loaded into exactly the named
200 schema and not any other. The schema parameter is consulted only
201 when initially creating an extension, not during extension
202 updates. See Section 36.17.2 for more information.
204 In addition to the primary control file extension.control, an extension
205 can have secondary control files named in the style
206 extension--version.control. If supplied, these must be located in the
207 script file directory. Secondary control files follow the same format
208 as the primary control file. Any parameters set in a secondary control
209 file override the primary control file when installing or updating to
210 that version of the extension. However, the parameters directory and
211 default_version cannot be set in a secondary control file.
213 An extension's SQL script files can contain any SQL commands, except
214 for transaction control commands (BEGIN, COMMIT, etc.) and commands
215 that cannot be executed inside a transaction block (such as VACUUM).
216 This is because the script files are implicitly executed within a
219 An extension's SQL script files can also contain lines beginning with
220 \echo, which will be ignored (treated as comments) by the extension
221 mechanism. This provision is commonly used to throw an error if the
222 script file is fed to psql rather than being loaded via CREATE
223 EXTENSION (see example script in Section 36.17.7). Without that, users
224 might accidentally load the extension's contents as “loose” objects
225 rather than as an extension, a state of affairs that's a bit tedious to
228 If the extension script contains the string @extowner@, that string is
229 replaced with the (suitably quoted) name of the user calling CREATE
230 EXTENSION or ALTER EXTENSION. Typically this feature is used by
231 extensions that are marked trusted to assign ownership of selected
232 objects to the calling user rather than the bootstrap superuser. (One
233 should be careful about doing so, however. For example, assigning
234 ownership of a C-language function to a non-superuser would create a
235 privilege escalation path for that user.)
237 While the script files can contain any characters allowed by the
238 specified encoding, control files should contain only plain ASCII,
239 because there is no way for PostgreSQL to know what encoding a control
240 file is in. In practice this is only an issue if you want to use
241 non-ASCII characters in the extension's comment. Recommended practice
242 in that case is to not use the control file comment parameter, but
243 instead use COMMENT ON EXTENSION within a script file to set the
246 36.17.2. Extension Relocatability #
248 Users often wish to load the objects contained in an extension into a
249 different schema than the extension's author had in mind. There are
250 three supported levels of relocatability:
251 * A fully relocatable extension can be moved into another schema at
252 any time, even after it's been loaded into a database. This is done
253 with the ALTER EXTENSION SET SCHEMA command, which automatically
254 renames all the member objects into the new schema. Normally, this
255 is only possible if the extension contains no internal assumptions
256 about what schema any of its objects are in. Also, the extension's
257 objects must all be in one schema to begin with (ignoring objects
258 that do not belong to any schema, such as procedural languages).
259 Mark a fully relocatable extension by setting relocatable = true in
261 * An extension might be relocatable during installation but not
262 afterwards. This is typically the case if the extension's script
263 file needs to reference the target schema explicitly, for example
264 in setting search_path properties for SQL functions. For such an
265 extension, set relocatable = false in its control file, and use
266 @extschema@ to refer to the target schema in the script file. All
267 occurrences of this string will be replaced by the actual target
268 schema's name (double-quoted if necessary) before the script is
269 executed. The user can set the target schema using the SCHEMA
270 option of CREATE EXTENSION.
271 * If the extension does not support relocation at all, set
272 relocatable = false in its control file, and also set schema to the
273 name of the intended target schema. This will prevent use of the
274 SCHEMA option of CREATE EXTENSION, unless it specifies the same
275 schema named in the control file. This choice is typically
276 necessary if the extension contains internal assumptions about its
277 schema name that can't be replaced by uses of @extschema@. The
278 @extschema@ substitution mechanism is available in this case too,
279 although it is of limited use since the schema name is determined
282 In all cases, the script file will be executed with search_path
283 initially set to point to the target schema; that is, CREATE EXTENSION
284 does the equivalent of this:
285 SET LOCAL search_path TO @extschema@, pg_temp;
287 This allows the objects created by the script file to go into the
288 target schema. The script file can change search_path if it wishes, but
289 that is generally undesirable. search_path is restored to its previous
290 setting upon completion of CREATE EXTENSION.
292 The target schema is determined by the schema parameter in the control
293 file if that is given, otherwise by the SCHEMA option of CREATE
294 EXTENSION if that is given, otherwise the current default object
295 creation schema (the first one in the caller's search_path). When the
296 control file schema parameter is used, the target schema will be
297 created if it doesn't already exist, but in the other two cases it must
300 If any prerequisite extensions are listed in requires in the control
301 file, their target schemas are added to the initial setting of
302 search_path, following the new extension's target schema. This allows
303 their objects to be visible to the new extension's script file.
305 For security, pg_temp is automatically appended to the end of
306 search_path in all cases.
308 Although a non-relocatable extension can contain objects spread across
309 multiple schemas, it is usually desirable to place all the objects
310 meant for external use into a single schema, which is considered the
311 extension's target schema. Such an arrangement works conveniently with
312 the default setting of search_path during creation of dependent
315 If an extension references objects belonging to another extension, it
316 is recommended to schema-qualify those references. To do that, write
317 @extschema:name@ in the extension's script file, where name is the name
318 of the other extension (which must be listed in this extension's
319 requires list). This string will be replaced by the name (double-quoted
320 if necessary) of that extension's target schema. Although this notation
321 avoids the need to make hard-wired assumptions about schema names in
322 the extension's script file, its use may embed the other extension's
323 schema name into the installed objects of this extension. (Typically,
324 that happens when @extschema:name@ is used inside a string literal,
325 such as a function body or a search_path setting. In other cases, the
326 object reference is reduced to an OID during parsing and does not
327 require subsequent lookups.) If the other extension's schema name is so
328 embedded, you should prevent the other extension from being relocated
329 after yours is installed, by adding the name of the other extension to
330 this one's no_relocate list.
332 36.17.3. Extension Configuration Tables #
334 Some extensions include configuration tables, which contain data that
335 might be added or changed by the user after installation of the
336 extension. Ordinarily, if a table is part of an extension, neither the
337 table's definition nor its content will be dumped by pg_dump. But that
338 behavior is undesirable for a configuration table; any data changes
339 made by the user need to be included in dumps, or the extension will
340 behave differently after a dump and restore.
342 To solve this problem, an extension's script file can mark a table or a
343 sequence it has created as a configuration relation, which will cause
344 pg_dump to include the table's or the sequence's contents (not its
345 definition) in dumps. To do that, call the function
346 pg_extension_config_dump(regclass, text) after creating the table or
347 the sequence, for example
348 CREATE TABLE my_config (key text, value text);
349 CREATE SEQUENCE my_config_seq;
351 SELECT pg_catalog.pg_extension_config_dump('my_config', '');
352 SELECT pg_catalog.pg_extension_config_dump('my_config_seq', '');
354 Any number of tables or sequences can be marked this way. Sequences
355 associated with serial or bigserial columns can be marked as well.
357 When the second argument of pg_extension_config_dump is an empty
358 string, the entire contents of the table are dumped by pg_dump. This is
359 usually only correct if the table is initially empty as created by the
360 extension script. If there is a mixture of initial data and
361 user-provided data in the table, the second argument of
362 pg_extension_config_dump provides a WHERE condition that selects the
363 data to be dumped. For example, you might do
364 CREATE TABLE my_config (key text, value text, standard_entry boolean);
366 SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr
369 and then make sure that standard_entry is true only in the rows created
370 by the extension's script.
372 For sequences, the second argument of pg_extension_config_dump has no
375 More complicated situations, such as initially-provided rows that might
376 be modified by users, can be handled by creating triggers on the
377 configuration table to ensure that modified rows are marked correctly.
379 You can alter the filter condition associated with a configuration
380 table by calling pg_extension_config_dump again. (This would typically
381 be useful in an extension update script.) The only way to mark a table
382 as no longer a configuration table is to dissociate it from the
383 extension with ALTER EXTENSION ... DROP TABLE.
385 Note that foreign key relationships between these tables will dictate
386 the order in which the tables are dumped out by pg_dump. Specifically,
387 pg_dump will attempt to dump the referenced-by table before the
388 referencing table. As the foreign key relationships are set up at
389 CREATE EXTENSION time (prior to data being loaded into the tables)
390 circular dependencies are not supported. When circular dependencies
391 exist, the data will still be dumped out but the dump will not be able
392 to be restored directly and user intervention will be required.
394 Sequences associated with serial or bigserial columns need to be
395 directly marked to dump their state. Marking their parent relation is
396 not enough for this purpose.
398 36.17.4. Extension Updates #
400 One advantage of the extension mechanism is that it provides convenient
401 ways to manage updates to the SQL commands that define an extension's
402 objects. This is done by associating a version name or number with each
403 released version of the extension's installation script. In addition,
404 if you want users to be able to update their databases dynamically from
405 one version to the next, you should provide update scripts that make
406 the necessary changes to go from one version to the next. Update
407 scripts have names following the pattern
408 extension--old_version--target_version.sql (for example,
409 foo--1.0--1.1.sql contains the commands to modify version 1.0 of
410 extension foo into version 1.1).
412 Given that a suitable update script is available, the command ALTER
413 EXTENSION UPDATE will update an installed extension to the specified
414 new version. The update script is run in the same environment that
415 CREATE EXTENSION provides for installation scripts: in particular,
416 search_path is set up in the same way, and any new objects created by
417 the script are automatically added to the extension. Also, if the
418 script chooses to drop extension member objects, they are automatically
419 dissociated from the extension.
421 If an extension has secondary control files, the control parameters
422 that are used for an update script are those associated with the
423 script's target (new) version.
425 ALTER EXTENSION is able to execute sequences of update script files to
426 achieve a requested update. For example, if only foo--1.0--1.1.sql and
427 foo--1.1--2.0.sql are available, ALTER EXTENSION will apply them in
428 sequence if an update to version 2.0 is requested when 1.0 is currently
431 PostgreSQL doesn't assume anything about the properties of version
432 names: for example, it does not know whether 1.1 follows 1.0. It just
433 matches up the available version names and follows the path that
434 requires applying the fewest update scripts. (A version name can
435 actually be any string that doesn't contain -- or leading or trailing
438 Sometimes it is useful to provide “downgrade” scripts, for example
439 foo--1.1--1.0.sql to allow reverting the changes associated with
440 version 1.1. If you do that, be careful of the possibility that a
441 downgrade script might unexpectedly get applied because it yields a
442 shorter path. The risky case is where there is a “fast path” update
443 script that jumps ahead several versions as well as a downgrade script
444 to the fast path's start point. It might take fewer steps to apply the
445 downgrade and then the fast path than to move ahead one version at a
446 time. If the downgrade script drops any irreplaceable objects, this
447 will yield undesirable results.
449 To check for unexpected update paths, use this command:
450 SELECT * FROM pg_extension_update_paths('extension_name');
452 This shows each pair of distinct known version names for the specified
453 extension, together with the update path sequence that would be taken
454 to get from the source version to the target version, or NULL if there
455 is no available update path. The path is shown in textual form with --
456 separators. You can use regexp_split_to_array(path,'--') if you prefer
459 36.17.5. Installing Extensions Using Update Scripts #
461 An extension that has been around for awhile will probably exist in
462 several versions, for which the author will need to write update
463 scripts. For example, if you have released a foo extension in versions
464 1.0, 1.1, and 1.2, there should be update scripts foo--1.0--1.1.sql and
465 foo--1.1--1.2.sql. Before PostgreSQL 10, it was necessary to also
466 create new script files foo--1.1.sql and foo--1.2.sql that directly
467 build the newer extension versions, or else the newer versions could
468 not be installed directly, only by installing 1.0 and then updating.
469 That was tedious and duplicative, but now it's unnecessary, because
470 CREATE EXTENSION can follow update chains automatically. For example,
471 if only the script files foo--1.0.sql, foo--1.0--1.1.sql, and
472 foo--1.1--1.2.sql are available then a request to install version 1.2
473 is honored by running those three scripts in sequence. The processing
474 is the same as if you'd first installed 1.0 and then updated to 1.2.
475 (As with ALTER EXTENSION UPDATE, if multiple pathways are available
476 then the shortest is preferred.) Arranging an extension's script files
477 in this style can reduce the amount of maintenance effort needed to
478 produce small updates.
480 If you use secondary (version-specific) control files with an extension
481 maintained in this style, keep in mind that each version needs a
482 control file even if it has no stand-alone installation script, as that
483 control file will determine how the implicit update to that version is
484 performed. For example, if foo--1.0.control specifies requires = 'bar'
485 but foo's other control files do not, the extension's dependency on bar
486 will be dropped when updating from 1.0 to another version.
488 36.17.6. Security Considerations for Extensions #
490 Widely-distributed extensions should assume little about the database
491 they occupy. Therefore, it's appropriate to write functions provided by
492 an extension in a secure style that cannot be compromised by
493 search-path-based attacks.
495 An extension that has the superuser property set to true must also
496 consider security hazards for the actions taken within its installation
497 and update scripts. It is not terribly difficult for a malicious user
498 to create trojan-horse objects that will compromise later execution of
499 a carelessly-written extension script, allowing that user to acquire
500 superuser privileges.
502 If an extension is marked trusted, then its installation schema can be
503 selected by the installing user, who might intentionally use an
504 insecure schema in hopes of gaining superuser privileges. Therefore, a
505 trusted extension is extremely exposed from a security standpoint, and
506 all its script commands must be carefully examined to ensure that no
507 compromise is possible.
509 Advice about writing functions securely is provided in
510 Section 36.17.6.1 below, and advice about writing installation scripts
511 securely is provided in Section 36.17.6.2.
513 36.17.6.1. Security Considerations for Extension Functions #
515 SQL-language and PL-language functions provided by extensions are at
516 risk of search-path-based attacks when they are executed, since parsing
517 of these functions occurs at execution time not creation time.
519 The CREATE FUNCTION reference page contains advice about writing
520 SECURITY DEFINER functions safely. It's good practice to apply those
521 techniques for any function provided by an extension, since the
522 function might be called by a high-privilege user.
524 If you cannot set the search_path to contain only secure schemas,
525 assume that each unqualified name could resolve to an object that a
526 malicious user has defined. Beware of constructs that depend on
527 search_path implicitly; for example, IN and CASE expression WHEN always
528 select an operator using the search path. In their place, use
529 OPERATOR(schema.=) ANY and CASE WHEN expression.
531 A general-purpose extension usually should not assume that it's been
532 installed into a secure schema, which means that even schema-qualified
533 references to its own objects are not entirely risk-free. For example,
534 if the extension has defined a function myschema.myfunc(bigint) then a
535 call such as myschema.myfunc(42) could be captured by a hostile
536 function myschema.myfunc(integer). Be careful that the data types of
537 function and operator parameters exactly match the declared argument
538 types, using explicit casts where necessary.
540 36.17.6.2. Security Considerations for Extension Scripts #
542 An extension installation or update script should be written to guard
543 against search-path-based attacks occurring when the script executes.
544 If an object reference in the script can be made to resolve to some
545 other object than the script author intended, then a compromise might
546 occur immediately, or later when the mis-defined extension object is
549 DDL commands such as CREATE FUNCTION and CREATE OPERATOR CLASS are
550 generally secure, but beware of any command having a general-purpose
551 expression as a component. For example, CREATE VIEW needs to be vetted,
552 as does a DEFAULT expression in CREATE FUNCTION.
554 Sometimes an extension script might need to execute general-purpose
555 SQL, for example to make catalog adjustments that aren't possible via
556 DDL. Be careful to execute such commands with a secure search_path; do
557 not trust the path provided by CREATE/ALTER EXTENSION to be secure.
558 Best practice is to temporarily set search_path to pg_catalog, pg_temp
559 and insert references to the extension's installation schema explicitly
560 where needed. (This practice might also be helpful for creating views.)
561 Examples can be found in the contrib modules in the PostgreSQL source
564 Secure cross-extension references typically require
565 schema-qualification of the names of the other extension's objects,
566 using the @extschema:name@ syntax, in addition to careful matching of
567 argument types for functions and operators.
569 36.17.7. Extension Example #
571 Here is a complete example of an SQL-only extension, a two-element
572 composite type that can store any type of value in its slots, which are
573 named “k” and “v”. Non-text values are automatically coerced to text
576 The script file pair--1.0.sql looks like this:
577 -- complain if script is sourced in psql, rather than via CREATE EXTENSION
578 \echo Use "CREATE EXTENSION pair" to load this file. \quit
580 CREATE TYPE pair AS ( k text, v text );
582 CREATE FUNCTION pair(text, text)
583 RETURNS pair LANGUAGE SQL AS 'SELECT ROW($1, $2)::@extschema@.pair;';
585 CREATE OPERATOR ~> (LEFTARG = text, RIGHTARG = text, FUNCTION = pair);
587 -- "SET search_path" is easy to get right, but qualified names perform better.
588 CREATE FUNCTION lower(pair)
589 RETURNS pair LANGUAGE SQL
590 AS 'SELECT ROW(lower($1.k), lower($1.v))::@extschema@.pair;'
591 SET search_path = pg_temp;
593 CREATE FUNCTION pair_concat(pair, pair)
594 RETURNS pair LANGUAGE SQL
595 AS 'SELECT ROW($1.k OPERATOR(pg_catalog.||) $2.k,
596 $1.v OPERATOR(pg_catalog.||) $2.v)::@extschema@.pair;';
599 The control file pair.control looks like this:
601 comment = 'A key/value pair data type'
602 default_version = '1.0'
603 # cannot be relocatable because of use of @extschema@
606 While you hardly need a makefile to install these two files into the
607 correct directory, you could use a Makefile containing this:
611 PG_CONFIG = pg_config
612 PGXS := $(shell $(PG_CONFIG) --pgxs)
615 This makefile relies on PGXS, which is described in Section 36.18. The
616 command make install will install the control and script files into the
617 correct directory as reported by pg_config.
619 Once the files are installed, use the CREATE EXTENSION command to load
620 the objects into any particular database.