]> granicus.if.org Git - postgresql/blob - src/backend/commands/extension.c
be521484d0895ee56ab610636cd0fe34da9b77a8
[postgresql] / src / backend / commands / extension.c
1 /*-------------------------------------------------------------------------
2  *
3  * extension.c
4  *        Commands to manipulate extensions
5  *
6  * Extensions in PostgreSQL allow management of collections of SQL objects.
7  *
8  * All we need internally to manage an extension is an OID so that the
9  * dependent objects can be associated with it.  An extension is created by
10  * populating the pg_extension catalog from a "control" file.
11  * The extension control file is parsed with the same parser we use for
12  * postgresql.conf and recovery.conf.  An extension also has an installation
13  * script file, containing SQL commands to create the extension's objects.
14  *
15  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
16  * Portions Copyright (c) 1994, Regents of the University of California
17  *
18  *
19  * IDENTIFICATION
20  *        src/backend/commands/extension.c
21  *
22  *-------------------------------------------------------------------------
23  */
24 #include "postgres.h"
25
26 #include <dirent.h>
27 #include <limits.h>
28 #include <sys/file.h>
29 #include <sys/stat.h>
30 #include <unistd.h>
31
32 #include "access/htup_details.h"
33 #include "access/sysattr.h"
34 #include "access/xact.h"
35 #include "catalog/dependency.h"
36 #include "catalog/indexing.h"
37 #include "catalog/namespace.h"
38 #include "catalog/objectaccess.h"
39 #include "catalog/pg_collation.h"
40 #include "catalog/pg_depend.h"
41 #include "catalog/pg_extension.h"
42 #include "catalog/pg_namespace.h"
43 #include "catalog/pg_type.h"
44 #include "commands/alter.h"
45 #include "commands/comment.h"
46 #include "commands/defrem.h"
47 #include "commands/extension.h"
48 #include "commands/schemacmds.h"
49 #include "funcapi.h"
50 #include "mb/pg_wchar.h"
51 #include "miscadmin.h"
52 #include "nodes/makefuncs.h"
53 #include "storage/fd.h"
54 #include "tcop/utility.h"
55 #include "utils/builtins.h"
56 #include "utils/fmgroids.h"
57 #include "utils/lsyscache.h"
58 #include "utils/memutils.h"
59 #include "utils/rel.h"
60 #include "utils/snapmgr.h"
61 #include "utils/tqual.h"
62
63
64 /* Globally visible state variables */
65 bool            creating_extension = false;
66 Oid                     CurrentExtensionObject = InvalidOid;
67
68 /*
69  * Internal data structure to hold the results of parsing a control file
70  */
71 typedef struct ExtensionControlFile
72 {
73         char       *name;                       /* name of the extension */
74         char       *directory;          /* directory for script files */
75         char       *default_version;    /* default install target version, if any */
76         char       *module_pathname;    /* string to substitute for MODULE_PATHNAME */
77         char       *comment;            /* comment, if any */
78         char       *schema;                     /* target schema (allowed if !relocatable) */
79         bool            relocatable;    /* is ALTER EXTENSION SET SCHEMA supported? */
80         bool            superuser;              /* must be superuser to install? */
81         int                     encoding;               /* encoding of the script file, or -1 */
82         List       *requires;           /* names of prerequisite extensions */
83 } ExtensionControlFile;
84
85 /*
86  * Internal data structure for update path information
87  */
88 typedef struct ExtensionVersionInfo
89 {
90         char       *name;                       /* name of the starting version */
91         List       *reachable;          /* List of ExtensionVersionInfo's */
92         bool            installable;    /* does this version have an install script? */
93         /* working state for Dijkstra's algorithm: */
94         bool            distance_known; /* is distance from start known yet? */
95         int                     distance;               /* current worst-case distance estimate */
96         struct ExtensionVersionInfo *previous;          /* current best predecessor */
97 } ExtensionVersionInfo;
98
99 /* Local functions */
100 static List *find_update_path(List *evi_list,
101                                  ExtensionVersionInfo *evi_start,
102                                  ExtensionVersionInfo *evi_target,
103                                  bool reject_indirect,
104                                  bool reinitialize);
105 static Oid get_required_extension(char *reqExtensionName,
106                                            char *extensionName,
107                                            char *origSchemaName,
108                                            bool cascade,
109                                            List *parents,
110                                            bool is_create);
111 static void get_available_versions_for_extension(ExtensionControlFile *pcontrol,
112                                                                          Tuplestorestate *tupstore,
113                                                                          TupleDesc tupdesc);
114 static Datum convert_requires_to_datum(List *requires);
115 static void ApplyExtensionUpdates(Oid extensionOid,
116                                           ExtensionControlFile *pcontrol,
117                                           const char *initialVersion,
118                                           List *updateVersions,
119                                           char *origSchemaName,
120                                           bool cascade,
121                                           bool is_create);
122 static char *read_whole_file(const char *filename, int *length);
123
124
125 /*
126  * get_extension_oid - given an extension name, look up the OID
127  *
128  * If missing_ok is false, throw an error if extension name not found.  If
129  * true, just return InvalidOid.
130  */
131 Oid
132 get_extension_oid(const char *extname, bool missing_ok)
133 {
134         Oid                     result;
135         Relation        rel;
136         SysScanDesc scandesc;
137         HeapTuple       tuple;
138         ScanKeyData entry[1];
139
140         rel = heap_open(ExtensionRelationId, AccessShareLock);
141
142         ScanKeyInit(&entry[0],
143                                 Anum_pg_extension_extname,
144                                 BTEqualStrategyNumber, F_NAMEEQ,
145                                 CStringGetDatum(extname));
146
147         scandesc = systable_beginscan(rel, ExtensionNameIndexId, true,
148                                                                   NULL, 1, entry);
149
150         tuple = systable_getnext(scandesc);
151
152         /* We assume that there can be at most one matching tuple */
153         if (HeapTupleIsValid(tuple))
154                 result = HeapTupleGetOid(tuple);
155         else
156                 result = InvalidOid;
157
158         systable_endscan(scandesc);
159
160         heap_close(rel, AccessShareLock);
161
162         if (!OidIsValid(result) && !missing_ok)
163                 ereport(ERROR,
164                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
165                                  errmsg("extension \"%s\" does not exist",
166                                                 extname)));
167
168         return result;
169 }
170
171 /*
172  * get_extension_name - given an extension OID, look up the name
173  *
174  * Returns a palloc'd string, or NULL if no such extension.
175  */
176 char *
177 get_extension_name(Oid ext_oid)
178 {
179         char       *result;
180         Relation        rel;
181         SysScanDesc scandesc;
182         HeapTuple       tuple;
183         ScanKeyData entry[1];
184
185         rel = heap_open(ExtensionRelationId, AccessShareLock);
186
187         ScanKeyInit(&entry[0],
188                                 ObjectIdAttributeNumber,
189                                 BTEqualStrategyNumber, F_OIDEQ,
190                                 ObjectIdGetDatum(ext_oid));
191
192         scandesc = systable_beginscan(rel, ExtensionOidIndexId, true,
193                                                                   NULL, 1, entry);
194
195         tuple = systable_getnext(scandesc);
196
197         /* We assume that there can be at most one matching tuple */
198         if (HeapTupleIsValid(tuple))
199                 result = pstrdup(NameStr(((Form_pg_extension) GETSTRUCT(tuple))->extname));
200         else
201                 result = NULL;
202
203         systable_endscan(scandesc);
204
205         heap_close(rel, AccessShareLock);
206
207         return result;
208 }
209
210 /*
211  * get_extension_schema - given an extension OID, fetch its extnamespace
212  *
213  * Returns InvalidOid if no such extension.
214  */
215 static Oid
216 get_extension_schema(Oid ext_oid)
217 {
218         Oid                     result;
219         Relation        rel;
220         SysScanDesc scandesc;
221         HeapTuple       tuple;
222         ScanKeyData entry[1];
223
224         rel = heap_open(ExtensionRelationId, AccessShareLock);
225
226         ScanKeyInit(&entry[0],
227                                 ObjectIdAttributeNumber,
228                                 BTEqualStrategyNumber, F_OIDEQ,
229                                 ObjectIdGetDatum(ext_oid));
230
231         scandesc = systable_beginscan(rel, ExtensionOidIndexId, true,
232                                                                   NULL, 1, entry);
233
234         tuple = systable_getnext(scandesc);
235
236         /* We assume that there can be at most one matching tuple */
237         if (HeapTupleIsValid(tuple))
238                 result = ((Form_pg_extension) GETSTRUCT(tuple))->extnamespace;
239         else
240                 result = InvalidOid;
241
242         systable_endscan(scandesc);
243
244         heap_close(rel, AccessShareLock);
245
246         return result;
247 }
248
249 /*
250  * Utility functions to check validity of extension and version names
251  */
252 static void
253 check_valid_extension_name(const char *extensionname)
254 {
255         int                     namelen = strlen(extensionname);
256
257         /*
258          * Disallow empty names (the parser rejects empty identifiers anyway, but
259          * let's check).
260          */
261         if (namelen == 0)
262                 ereport(ERROR,
263                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
264                                  errmsg("invalid extension name: \"%s\"", extensionname),
265                                  errdetail("Extension names must not be empty.")));
266
267         /*
268          * No double dashes, since that would make script filenames ambiguous.
269          */
270         if (strstr(extensionname, "--"))
271                 ereport(ERROR,
272                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
273                                  errmsg("invalid extension name: \"%s\"", extensionname),
274                                  errdetail("Extension names must not contain \"--\".")));
275
276         /*
277          * No leading or trailing dash either.  (We could probably allow this, but
278          * it would require much care in filename parsing and would make filenames
279          * visually if not formally ambiguous.  Since there's no real-world use
280          * case, let's just forbid it.)
281          */
282         if (extensionname[0] == '-' || extensionname[namelen - 1] == '-')
283                 ereport(ERROR,
284                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
285                                  errmsg("invalid extension name: \"%s\"", extensionname),
286                         errdetail("Extension names must not begin or end with \"-\".")));
287
288         /*
289          * No directory separators either (this is sufficient to prevent ".."
290          * style attacks).
291          */
292         if (first_dir_separator(extensionname) != NULL)
293                 ereport(ERROR,
294                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
295                                  errmsg("invalid extension name: \"%s\"", extensionname),
296                                  errdetail("Extension names must not contain directory separator characters.")));
297 }
298
299 static void
300 check_valid_version_name(const char *versionname)
301 {
302         int                     namelen = strlen(versionname);
303
304         /*
305          * Disallow empty names (we could possibly allow this, but there seems
306          * little point).
307          */
308         if (namelen == 0)
309                 ereport(ERROR,
310                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
311                            errmsg("invalid extension version name: \"%s\"", versionname),
312                                  errdetail("Version names must not be empty.")));
313
314         /*
315          * No double dashes, since that would make script filenames ambiguous.
316          */
317         if (strstr(versionname, "--"))
318                 ereport(ERROR,
319                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
320                            errmsg("invalid extension version name: \"%s\"", versionname),
321                                  errdetail("Version names must not contain \"--\".")));
322
323         /*
324          * No leading or trailing dash either.
325          */
326         if (versionname[0] == '-' || versionname[namelen - 1] == '-')
327                 ereport(ERROR,
328                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
329                            errmsg("invalid extension version name: \"%s\"", versionname),
330                           errdetail("Version names must not begin or end with \"-\".")));
331
332         /*
333          * No directory separators either (this is sufficient to prevent ".."
334          * style attacks).
335          */
336         if (first_dir_separator(versionname) != NULL)
337                 ereport(ERROR,
338                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
339                            errmsg("invalid extension version name: \"%s\"", versionname),
340                                  errdetail("Version names must not contain directory separator characters.")));
341 }
342
343 /*
344  * Utility functions to handle extension-related path names
345  */
346 static bool
347 is_extension_control_filename(const char *filename)
348 {
349         const char *extension = strrchr(filename, '.');
350
351         return (extension != NULL) && (strcmp(extension, ".control") == 0);
352 }
353
354 static bool
355 is_extension_script_filename(const char *filename)
356 {
357         const char *extension = strrchr(filename, '.');
358
359         return (extension != NULL) && (strcmp(extension, ".sql") == 0);
360 }
361
362 static char *
363 get_extension_control_directory(void)
364 {
365         char            sharepath[MAXPGPATH];
366         char       *result;
367
368         get_share_path(my_exec_path, sharepath);
369         result = (char *) palloc(MAXPGPATH);
370         snprintf(result, MAXPGPATH, "%s/extension", sharepath);
371
372         return result;
373 }
374
375 static char *
376 get_extension_control_filename(const char *extname)
377 {
378         char            sharepath[MAXPGPATH];
379         char       *result;
380
381         get_share_path(my_exec_path, sharepath);
382         result = (char *) palloc(MAXPGPATH);
383         snprintf(result, MAXPGPATH, "%s/extension/%s.control",
384                          sharepath, extname);
385
386         return result;
387 }
388
389 static char *
390 get_extension_script_directory(ExtensionControlFile *control)
391 {
392         char            sharepath[MAXPGPATH];
393         char       *result;
394
395         /*
396          * The directory parameter can be omitted, absolute, or relative to the
397          * installation's share directory.
398          */
399         if (!control->directory)
400                 return get_extension_control_directory();
401
402         if (is_absolute_path(control->directory))
403                 return pstrdup(control->directory);
404
405         get_share_path(my_exec_path, sharepath);
406         result = (char *) palloc(MAXPGPATH);
407         snprintf(result, MAXPGPATH, "%s/%s", sharepath, control->directory);
408
409         return result;
410 }
411
412 static char *
413 get_extension_aux_control_filename(ExtensionControlFile *control,
414                                                                    const char *version)
415 {
416         char       *result;
417         char       *scriptdir;
418
419         scriptdir = get_extension_script_directory(control);
420
421         result = (char *) palloc(MAXPGPATH);
422         snprintf(result, MAXPGPATH, "%s/%s--%s.control",
423                          scriptdir, control->name, version);
424
425         pfree(scriptdir);
426
427         return result;
428 }
429
430 static char *
431 get_extension_script_filename(ExtensionControlFile *control,
432                                                           const char *from_version, const char *version)
433 {
434         char       *result;
435         char       *scriptdir;
436
437         scriptdir = get_extension_script_directory(control);
438
439         result = (char *) palloc(MAXPGPATH);
440         if (from_version)
441                 snprintf(result, MAXPGPATH, "%s/%s--%s--%s.sql",
442                                  scriptdir, control->name, from_version, version);
443         else
444                 snprintf(result, MAXPGPATH, "%s/%s--%s.sql",
445                                  scriptdir, control->name, version);
446
447         pfree(scriptdir);
448
449         return result;
450 }
451
452
453 /*
454  * Parse contents of primary or auxiliary control file, and fill in
455  * fields of *control.  We parse primary file if version == NULL,
456  * else the optional auxiliary file for that version.
457  *
458  * Control files are supposed to be very short, half a dozen lines,
459  * so we don't worry about memory allocation risks here.  Also we don't
460  * worry about what encoding it's in; all values are expected to be ASCII.
461  */
462 static void
463 parse_extension_control_file(ExtensionControlFile *control,
464                                                          const char *version)
465 {
466         char       *filename;
467         FILE       *file;
468         ConfigVariable *item,
469                            *head = NULL,
470                            *tail = NULL;
471
472         /*
473          * Locate the file to read.  Auxiliary files are optional.
474          */
475         if (version)
476                 filename = get_extension_aux_control_filename(control, version);
477         else
478                 filename = get_extension_control_filename(control->name);
479
480         if ((file = AllocateFile(filename, "r")) == NULL)
481         {
482                 if (version && errno == ENOENT)
483                 {
484                         /* no auxiliary file for this version */
485                         pfree(filename);
486                         return;
487                 }
488                 ereport(ERROR,
489                                 (errcode_for_file_access(),
490                                  errmsg("could not open extension control file \"%s\": %m",
491                                                 filename)));
492         }
493
494         /*
495          * Parse the file content, using GUC's file parsing code.  We need not
496          * check the return value since any errors will be thrown at ERROR level.
497          */
498         (void) ParseConfigFp(file, filename, 0, ERROR, &head, &tail);
499
500         FreeFile(file);
501
502         /*
503          * Convert the ConfigVariable list into ExtensionControlFile entries.
504          */
505         for (item = head; item != NULL; item = item->next)
506         {
507                 if (strcmp(item->name, "directory") == 0)
508                 {
509                         if (version)
510                                 ereport(ERROR,
511                                                 (errcode(ERRCODE_SYNTAX_ERROR),
512                                                  errmsg("parameter \"%s\" cannot be set in a secondary extension control file",
513                                                                 item->name)));
514
515                         control->directory = pstrdup(item->value);
516                 }
517                 else if (strcmp(item->name, "default_version") == 0)
518                 {
519                         if (version)
520                                 ereport(ERROR,
521                                                 (errcode(ERRCODE_SYNTAX_ERROR),
522                                                  errmsg("parameter \"%s\" cannot be set in a secondary extension control file",
523                                                                 item->name)));
524
525                         control->default_version = pstrdup(item->value);
526                 }
527                 else if (strcmp(item->name, "module_pathname") == 0)
528                 {
529                         control->module_pathname = pstrdup(item->value);
530                 }
531                 else if (strcmp(item->name, "comment") == 0)
532                 {
533                         control->comment = pstrdup(item->value);
534                 }
535                 else if (strcmp(item->name, "schema") == 0)
536                 {
537                         control->schema = pstrdup(item->value);
538                 }
539                 else if (strcmp(item->name, "relocatable") == 0)
540                 {
541                         if (!parse_bool(item->value, &control->relocatable))
542                                 ereport(ERROR,
543                                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
544                                                  errmsg("parameter \"%s\" requires a Boolean value",
545                                                                 item->name)));
546                 }
547                 else if (strcmp(item->name, "superuser") == 0)
548                 {
549                         if (!parse_bool(item->value, &control->superuser))
550                                 ereport(ERROR,
551                                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
552                                                  errmsg("parameter \"%s\" requires a Boolean value",
553                                                                 item->name)));
554                 }
555                 else if (strcmp(item->name, "encoding") == 0)
556                 {
557                         control->encoding = pg_valid_server_encoding(item->value);
558                         if (control->encoding < 0)
559                                 ereport(ERROR,
560                                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
561                                                  errmsg("\"%s\" is not a valid encoding name",
562                                                                 item->value)));
563                 }
564                 else if (strcmp(item->name, "requires") == 0)
565                 {
566                         /* Need a modifiable copy of string */
567                         char       *rawnames = pstrdup(item->value);
568
569                         /* Parse string into list of identifiers */
570                         if (!SplitIdentifierString(rawnames, ',', &control->requires))
571                         {
572                                 /* syntax error in name list */
573                                 ereport(ERROR,
574                                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
575                                  errmsg("parameter \"%s\" must be a list of extension names",
576                                                 item->name)));
577                         }
578                 }
579                 else
580                         ereport(ERROR,
581                                         (errcode(ERRCODE_SYNTAX_ERROR),
582                                          errmsg("unrecognized parameter \"%s\" in file \"%s\"",
583                                                         item->name, filename)));
584         }
585
586         FreeConfigVariables(head);
587
588         if (control->relocatable && control->schema != NULL)
589                 ereport(ERROR,
590                                 (errcode(ERRCODE_SYNTAX_ERROR),
591                                  errmsg("parameter \"schema\" cannot be specified when \"relocatable\" is true")));
592
593         pfree(filename);
594 }
595
596 /*
597  * Read the primary control file for the specified extension.
598  */
599 static ExtensionControlFile *
600 read_extension_control_file(const char *extname)
601 {
602         ExtensionControlFile *control;
603
604         /*
605          * Set up default values.  Pointer fields are initially null.
606          */
607         control = (ExtensionControlFile *) palloc0(sizeof(ExtensionControlFile));
608         control->name = pstrdup(extname);
609         control->relocatable = false;
610         control->superuser = true;
611         control->encoding = -1;
612
613         /*
614          * Parse the primary control file.
615          */
616         parse_extension_control_file(control, NULL);
617
618         return control;
619 }
620
621 /*
622  * Read the auxiliary control file for the specified extension and version.
623  *
624  * Returns a new modified ExtensionControlFile struct; the original struct
625  * (reflecting just the primary control file) is not modified.
626  */
627 static ExtensionControlFile *
628 read_extension_aux_control_file(const ExtensionControlFile *pcontrol,
629                                                                 const char *version)
630 {
631         ExtensionControlFile *acontrol;
632
633         /*
634          * Flat-copy the struct.  Pointer fields share values with original.
635          */
636         acontrol = (ExtensionControlFile *) palloc(sizeof(ExtensionControlFile));
637         memcpy(acontrol, pcontrol, sizeof(ExtensionControlFile));
638
639         /*
640          * Parse the auxiliary control file, overwriting struct fields
641          */
642         parse_extension_control_file(acontrol, version);
643
644         return acontrol;
645 }
646
647 /*
648  * Read an SQL script file into a string, and convert to database encoding
649  */
650 static char *
651 read_extension_script_file(const ExtensionControlFile *control,
652                                                    const char *filename)
653 {
654         int                     src_encoding;
655         char       *src_str;
656         char       *dest_str;
657         int                     len;
658
659         src_str = read_whole_file(filename, &len);
660
661         /* use database encoding if not given */
662         if (control->encoding < 0)
663                 src_encoding = GetDatabaseEncoding();
664         else
665                 src_encoding = control->encoding;
666
667         /* make sure that source string is valid in the expected encoding */
668         pg_verify_mbstr_len(src_encoding, src_str, len, false);
669
670         /*
671          * Convert the encoding to the database encoding. read_whole_file
672          * null-terminated the string, so if no conversion happens the string is
673          * valid as is.
674          */
675         dest_str = pg_any_to_server(src_str, len, src_encoding);
676
677         return dest_str;
678 }
679
680 /*
681  * Execute given SQL string.
682  *
683  * filename is used only to report errors.
684  *
685  * Note: it's tempting to just use SPI to execute the string, but that does
686  * not work very well.  The really serious problem is that SPI will parse,
687  * analyze, and plan the whole string before executing any of it; of course
688  * this fails if there are any plannable statements referring to objects
689  * created earlier in the script.  A lesser annoyance is that SPI insists
690  * on printing the whole string as errcontext in case of any error, and that
691  * could be very long.
692  */
693 static void
694 execute_sql_string(const char *sql, const char *filename)
695 {
696         List       *raw_parsetree_list;
697         DestReceiver *dest;
698         ListCell   *lc1;
699
700         /*
701          * Parse the SQL string into a list of raw parse trees.
702          */
703         raw_parsetree_list = pg_parse_query(sql);
704
705         /* All output from SELECTs goes to the bit bucket */
706         dest = CreateDestReceiver(DestNone);
707
708         /*
709          * Do parse analysis, rule rewrite, planning, and execution for each raw
710          * parsetree.  We must fully execute each query before beginning parse
711          * analysis on the next one, since there may be interdependencies.
712          */
713         foreach(lc1, raw_parsetree_list)
714         {
715                 Node       *parsetree = (Node *) lfirst(lc1);
716                 List       *stmt_list;
717                 ListCell   *lc2;
718
719                 stmt_list = pg_analyze_and_rewrite(parsetree,
720                                                                                    sql,
721                                                                                    NULL,
722                                                                                    0);
723                 stmt_list = pg_plan_queries(stmt_list, CURSOR_OPT_PARALLEL_OK, NULL);
724
725                 foreach(lc2, stmt_list)
726                 {
727                         Node       *stmt = (Node *) lfirst(lc2);
728
729                         if (IsA(stmt, TransactionStmt))
730                                 ereport(ERROR,
731                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
732                                                  errmsg("transaction control statements are not allowed within an extension script")));
733
734                         CommandCounterIncrement();
735
736                         PushActiveSnapshot(GetTransactionSnapshot());
737
738                         if (IsA(stmt, PlannedStmt) &&
739                                 ((PlannedStmt *) stmt)->utilityStmt == NULL)
740                         {
741                                 QueryDesc  *qdesc;
742
743                                 qdesc = CreateQueryDesc((PlannedStmt *) stmt,
744                                                                                 sql,
745                                                                                 GetActiveSnapshot(), NULL,
746                                                                                 dest, NULL, 0);
747
748                                 ExecutorStart(qdesc, 0);
749                                 ExecutorRun(qdesc, ForwardScanDirection, 0);
750                                 ExecutorFinish(qdesc);
751                                 ExecutorEnd(qdesc);
752
753                                 FreeQueryDesc(qdesc);
754                         }
755                         else
756                         {
757                                 ProcessUtility(stmt,
758                                                            sql,
759                                                            PROCESS_UTILITY_QUERY,
760                                                            NULL,
761                                                            dest,
762                                                            NULL);
763                         }
764
765                         PopActiveSnapshot();
766                 }
767         }
768
769         /* Be sure to advance the command counter after the last script command */
770         CommandCounterIncrement();
771 }
772
773 /*
774  * Execute the appropriate script file for installing or updating the extension
775  *
776  * If from_version isn't NULL, it's an update
777  */
778 static void
779 execute_extension_script(Oid extensionOid, ExtensionControlFile *control,
780                                                  const char *from_version,
781                                                  const char *version,
782                                                  List *requiredSchemas,
783                                                  const char *schemaName, Oid schemaOid)
784 {
785         char       *filename;
786         int                     save_nestlevel;
787         StringInfoData pathbuf;
788         ListCell   *lc;
789
790         /*
791          * Enforce superuser-ness if appropriate.  We postpone this check until
792          * here so that the flag is correctly associated with the right script(s)
793          * if it's set in secondary control files.
794          */
795         if (control->superuser && !superuser())
796         {
797                 if (from_version == NULL)
798                         ereport(ERROR,
799                                         (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
800                                          errmsg("permission denied to create extension \"%s\"",
801                                                         control->name),
802                                          errhint("Must be superuser to create this extension.")));
803                 else
804                         ereport(ERROR,
805                                         (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
806                                          errmsg("permission denied to update extension \"%s\"",
807                                                         control->name),
808                                          errhint("Must be superuser to update this extension.")));
809         }
810
811         filename = get_extension_script_filename(control, from_version, version);
812
813         /*
814          * Force client_min_messages and log_min_messages to be at least WARNING,
815          * so that we won't spam the user with useless NOTICE messages from common
816          * script actions like creating shell types.
817          *
818          * We use the equivalent of a function SET option to allow the setting to
819          * persist for exactly the duration of the script execution.  guc.c also
820          * takes care of undoing the setting on error.
821          */
822         save_nestlevel = NewGUCNestLevel();
823
824         if (client_min_messages < WARNING)
825                 (void) set_config_option("client_min_messages", "warning",
826                                                                  PGC_USERSET, PGC_S_SESSION,
827                                                                  GUC_ACTION_SAVE, true, 0, false);
828         if (log_min_messages < WARNING)
829                 (void) set_config_option("log_min_messages", "warning",
830                                                                  PGC_SUSET, PGC_S_SESSION,
831                                                                  GUC_ACTION_SAVE, true, 0, false);
832
833         /*
834          * Set up the search path to contain the target schema, then the schemas
835          * of any prerequisite extensions, and nothing else.  In particular this
836          * makes the target schema be the default creation target namespace.
837          *
838          * Note: it might look tempting to use PushOverrideSearchPath for this,
839          * but we cannot do that.  We have to actually set the search_path GUC in
840          * case the extension script examines or changes it.  In any case, the
841          * GUC_ACTION_SAVE method is just as convenient.
842          */
843         initStringInfo(&pathbuf);
844         appendStringInfoString(&pathbuf, quote_identifier(schemaName));
845         foreach(lc, requiredSchemas)
846         {
847                 Oid                     reqschema = lfirst_oid(lc);
848                 char       *reqname = get_namespace_name(reqschema);
849
850                 if (reqname)
851                         appendStringInfo(&pathbuf, ", %s", quote_identifier(reqname));
852         }
853
854         (void) set_config_option("search_path", pathbuf.data,
855                                                          PGC_USERSET, PGC_S_SESSION,
856                                                          GUC_ACTION_SAVE, true, 0, false);
857
858         /*
859          * Set creating_extension and related variables so that
860          * recordDependencyOnCurrentExtension and other functions do the right
861          * things.  On failure, ensure we reset these variables.
862          */
863         creating_extension = true;
864         CurrentExtensionObject = extensionOid;
865         PG_TRY();
866         {
867                 char       *c_sql = read_extension_script_file(control, filename);
868                 Datum           t_sql;
869
870                 /* We use various functions that want to operate on text datums */
871                 t_sql = CStringGetTextDatum(c_sql);
872
873                 /*
874                  * Reduce any lines beginning with "\echo" to empty.  This allows
875                  * scripts to contain messages telling people not to run them via
876                  * psql, which has been found to be necessary due to old habits.
877                  */
878                 t_sql = DirectFunctionCall4Coll(textregexreplace,
879                                                                                 C_COLLATION_OID,
880                                                                                 t_sql,
881                                                                                 CStringGetTextDatum("^\\\\echo.*$"),
882                                                                                 CStringGetTextDatum(""),
883                                                                                 CStringGetTextDatum("ng"));
884
885                 /*
886                  * If it's not relocatable, substitute the target schema name for
887                  * occurrences of @extschema@.
888                  *
889                  * For a relocatable extension, we needn't do this.  There cannot be
890                  * any need for @extschema@, else it wouldn't be relocatable.
891                  */
892                 if (!control->relocatable)
893                 {
894                         const char *qSchemaName = quote_identifier(schemaName);
895
896                         t_sql = DirectFunctionCall3(replace_text,
897                                                                                 t_sql,
898                                                                                 CStringGetTextDatum("@extschema@"),
899                                                                                 CStringGetTextDatum(qSchemaName));
900                 }
901
902                 /*
903                  * If module_pathname was set in the control file, substitute its
904                  * value for occurrences of MODULE_PATHNAME.
905                  */
906                 if (control->module_pathname)
907                 {
908                         t_sql = DirectFunctionCall3(replace_text,
909                                                                                 t_sql,
910                                                                           CStringGetTextDatum("MODULE_PATHNAME"),
911                                                           CStringGetTextDatum(control->module_pathname));
912                 }
913
914                 /* And now back to C string */
915                 c_sql = text_to_cstring(DatumGetTextPP(t_sql));
916
917                 execute_sql_string(c_sql, filename);
918         }
919         PG_CATCH();
920         {
921                 creating_extension = false;
922                 CurrentExtensionObject = InvalidOid;
923                 PG_RE_THROW();
924         }
925         PG_END_TRY();
926
927         creating_extension = false;
928         CurrentExtensionObject = InvalidOid;
929
930         /*
931          * Restore the GUC variables we set above.
932          */
933         AtEOXact_GUC(true, save_nestlevel);
934 }
935
936 /*
937  * Find or create an ExtensionVersionInfo for the specified version name
938  *
939  * Currently, we just use a List of the ExtensionVersionInfo's.  Searching
940  * for them therefore uses about O(N^2) time when there are N versions of
941  * the extension.  We could change the data structure to a hash table if
942  * this ever becomes a bottleneck.
943  */
944 static ExtensionVersionInfo *
945 get_ext_ver_info(const char *versionname, List **evi_list)
946 {
947         ExtensionVersionInfo *evi;
948         ListCell   *lc;
949
950         foreach(lc, *evi_list)
951         {
952                 evi = (ExtensionVersionInfo *) lfirst(lc);
953                 if (strcmp(evi->name, versionname) == 0)
954                         return evi;
955         }
956
957         evi = (ExtensionVersionInfo *) palloc(sizeof(ExtensionVersionInfo));
958         evi->name = pstrdup(versionname);
959         evi->reachable = NIL;
960         evi->installable = false;
961         /* initialize for later application of Dijkstra's algorithm */
962         evi->distance_known = false;
963         evi->distance = INT_MAX;
964         evi->previous = NULL;
965
966         *evi_list = lappend(*evi_list, evi);
967
968         return evi;
969 }
970
971 /*
972  * Locate the nearest unprocessed ExtensionVersionInfo
973  *
974  * This part of the algorithm is also about O(N^2).  A priority queue would
975  * make it much faster, but for now there's no need.
976  */
977 static ExtensionVersionInfo *
978 get_nearest_unprocessed_vertex(List *evi_list)
979 {
980         ExtensionVersionInfo *evi = NULL;
981         ListCell   *lc;
982
983         foreach(lc, evi_list)
984         {
985                 ExtensionVersionInfo *evi2 = (ExtensionVersionInfo *) lfirst(lc);
986
987                 /* only vertices whose distance is still uncertain are candidates */
988                 if (evi2->distance_known)
989                         continue;
990                 /* remember the closest such vertex */
991                 if (evi == NULL ||
992                         evi->distance > evi2->distance)
993                         evi = evi2;
994         }
995
996         return evi;
997 }
998
999 /*
1000  * Obtain information about the set of update scripts available for the
1001  * specified extension.  The result is a List of ExtensionVersionInfo
1002  * structs, each with a subsidiary list of the ExtensionVersionInfos for
1003  * the versions that can be reached in one step from that version.
1004  */
1005 static List *
1006 get_ext_ver_list(ExtensionControlFile *control)
1007 {
1008         List       *evi_list = NIL;
1009         int                     extnamelen = strlen(control->name);
1010         char       *location;
1011         DIR                *dir;
1012         struct dirent *de;
1013
1014         location = get_extension_script_directory(control);
1015         dir = AllocateDir(location);
1016         while ((de = ReadDir(dir, location)) != NULL)
1017         {
1018                 char       *vername;
1019                 char       *vername2;
1020                 ExtensionVersionInfo *evi;
1021                 ExtensionVersionInfo *evi2;
1022
1023                 /* must be a .sql file ... */
1024                 if (!is_extension_script_filename(de->d_name))
1025                         continue;
1026
1027                 /* ... matching extension name followed by separator */
1028                 if (strncmp(de->d_name, control->name, extnamelen) != 0 ||
1029                         de->d_name[extnamelen] != '-' ||
1030                         de->d_name[extnamelen + 1] != '-')
1031                         continue;
1032
1033                 /* extract version name(s) from 'extname--something.sql' filename */
1034                 vername = pstrdup(de->d_name + extnamelen + 2);
1035                 *strrchr(vername, '.') = '\0';
1036                 vername2 = strstr(vername, "--");
1037                 if (!vername2)
1038                 {
1039                         /* It's an install, not update, script; record its version name */
1040                         evi = get_ext_ver_info(vername, &evi_list);
1041                         evi->installable = true;
1042                         continue;
1043                 }
1044                 *vername2 = '\0';               /* terminate first version */
1045                 vername2 += 2;                  /* and point to second */
1046
1047                 /* if there's a third --, it's bogus, ignore it */
1048                 if (strstr(vername2, "--"))
1049                         continue;
1050
1051                 /* Create ExtensionVersionInfos and link them together */
1052                 evi = get_ext_ver_info(vername, &evi_list);
1053                 evi2 = get_ext_ver_info(vername2, &evi_list);
1054                 evi->reachable = lappend(evi->reachable, evi2);
1055         }
1056         FreeDir(dir);
1057
1058         return evi_list;
1059 }
1060
1061 /*
1062  * Given an initial and final version name, identify the sequence of update
1063  * scripts that have to be applied to perform that update.
1064  *
1065  * Result is a List of names of versions to transition through (the initial
1066  * version is *not* included).
1067  */
1068 static List *
1069 identify_update_path(ExtensionControlFile *control,
1070                                          const char *oldVersion, const char *newVersion)
1071 {
1072         List       *result;
1073         List       *evi_list;
1074         ExtensionVersionInfo *evi_start;
1075         ExtensionVersionInfo *evi_target;
1076
1077         /* Extract the version update graph from the script directory */
1078         evi_list = get_ext_ver_list(control);
1079
1080         /* Initialize start and end vertices */
1081         evi_start = get_ext_ver_info(oldVersion, &evi_list);
1082         evi_target = get_ext_ver_info(newVersion, &evi_list);
1083
1084         /* Find shortest path */
1085         result = find_update_path(evi_list, evi_start, evi_target, false, false);
1086
1087         if (result == NIL)
1088                 ereport(ERROR,
1089                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1090                                  errmsg("extension \"%s\" has no update path from version \"%s\" to version \"%s\"",
1091                                                 control->name, oldVersion, newVersion)));
1092
1093         return result;
1094 }
1095
1096 /*
1097  * Apply Dijkstra's algorithm to find the shortest path from evi_start to
1098  * evi_target.
1099  *
1100  * If reject_indirect is true, ignore paths that go through installable
1101  * versions.  This saves work when the caller will consider starting from
1102  * all installable versions anyway.
1103  *
1104  * If reinitialize is false, assume the ExtensionVersionInfo list has not
1105  * been used for this before, and the initialization done by get_ext_ver_info
1106  * is still good.  Otherwise, reinitialize all transient fields used here.
1107  *
1108  * Result is a List of names of versions to transition through (the initial
1109  * version is *not* included).  Returns NIL if no such path.
1110  */
1111 static List *
1112 find_update_path(List *evi_list,
1113                                  ExtensionVersionInfo *evi_start,
1114                                  ExtensionVersionInfo *evi_target,
1115                                  bool reject_indirect,
1116                                  bool reinitialize)
1117 {
1118         List       *result;
1119         ExtensionVersionInfo *evi;
1120         ListCell   *lc;
1121
1122         /* Caller error if start == target */
1123         Assert(evi_start != evi_target);
1124         /* Caller error if reject_indirect and target is installable */
1125         Assert(!(reject_indirect && evi_target->installable));
1126
1127         if (reinitialize)
1128         {
1129                 foreach(lc, evi_list)
1130                 {
1131                         evi = (ExtensionVersionInfo *) lfirst(lc);
1132                         evi->distance_known = false;
1133                         evi->distance = INT_MAX;
1134                         evi->previous = NULL;
1135                 }
1136         }
1137
1138         evi_start->distance = 0;
1139
1140         while ((evi = get_nearest_unprocessed_vertex(evi_list)) != NULL)
1141         {
1142                 if (evi->distance == INT_MAX)
1143                         break;                          /* all remaining vertices are unreachable */
1144                 evi->distance_known = true;
1145                 if (evi == evi_target)
1146                         break;                          /* found shortest path to target */
1147                 foreach(lc, evi->reachable)
1148                 {
1149                         ExtensionVersionInfo *evi2 = (ExtensionVersionInfo *) lfirst(lc);
1150                         int                     newdist;
1151
1152                         /* if reject_indirect, treat installable versions as unreachable */
1153                         if (reject_indirect && evi2->installable)
1154                                 continue;
1155                         newdist = evi->distance + 1;
1156                         if (newdist < evi2->distance)
1157                         {
1158                                 evi2->distance = newdist;
1159                                 evi2->previous = evi;
1160                         }
1161                         else if (newdist == evi2->distance &&
1162                                          evi2->previous != NULL &&
1163                                          strcmp(evi->name, evi2->previous->name) < 0)
1164                         {
1165                                 /*
1166                                  * Break ties in favor of the version name that comes first
1167                                  * according to strcmp().  This behavior is undocumented and
1168                                  * users shouldn't rely on it.  We do it just to ensure that
1169                                  * if there is a tie, the update path that is chosen does not
1170                                  * depend on random factors like the order in which directory
1171                                  * entries get visited.
1172                                  */
1173                                 evi2->previous = evi;
1174                         }
1175                 }
1176         }
1177
1178         /* Return NIL if target is not reachable from start */
1179         if (!evi_target->distance_known)
1180                 return NIL;
1181
1182         /* Build and return list of version names representing the update path */
1183         result = NIL;
1184         for (evi = evi_target; evi != evi_start; evi = evi->previous)
1185                 result = lcons(evi->name, result);
1186
1187         return result;
1188 }
1189
1190 /*
1191  * Given a target version that is not directly installable, find the
1192  * best installation sequence starting from a directly-installable version.
1193  *
1194  * evi_list: previously-collected version update graph
1195  * evi_target: member of that list that we want to reach
1196  *
1197  * Returns the best starting-point version, or NULL if there is none.
1198  * On success, *best_path is set to the path from the start point.
1199  *
1200  * If there's more than one possible start point, prefer shorter update paths,
1201  * and break any ties arbitrarily on the basis of strcmp'ing the starting
1202  * versions' names.
1203  */
1204 static ExtensionVersionInfo *
1205 find_install_path(List *evi_list, ExtensionVersionInfo *evi_target,
1206                                   List **best_path)
1207 {
1208         ExtensionVersionInfo *evi_start = NULL;
1209         ListCell   *lc;
1210
1211         *best_path = NIL;
1212
1213         /*
1214          * We don't expect to be called for an installable target, but if we are,
1215          * the answer is easy: just start from there, with an empty update path.
1216          */
1217         if (evi_target->installable)
1218                 return evi_target;
1219
1220         /* Consider all installable versions as start points */
1221         foreach(lc, evi_list)
1222         {
1223                 ExtensionVersionInfo *evi1 = (ExtensionVersionInfo *) lfirst(lc);
1224                 List       *path;
1225
1226                 if (!evi1->installable)
1227                         continue;
1228
1229                 /*
1230                  * Find shortest path from evi1 to evi_target; but no need to consider
1231                  * paths going through other installable versions.
1232                  */
1233                 path = find_update_path(evi_list, evi1, evi_target, true, true);
1234                 if (path == NIL)
1235                         continue;
1236
1237                 /* Remember best path */
1238                 if (evi_start == NULL ||
1239                         list_length(path) < list_length(*best_path) ||
1240                         (list_length(path) == list_length(*best_path) &&
1241                          strcmp(evi_start->name, evi1->name) < 0))
1242                 {
1243                         evi_start = evi1;
1244                         *best_path = path;
1245                 }
1246         }
1247
1248         return evi_start;
1249 }
1250
1251 /*
1252  * CREATE EXTENSION worker
1253  *
1254  * When CASCADE is specified, CreateExtensionInternal() recurses if required
1255  * extensions need to be installed.  To sanely handle cyclic dependencies,
1256  * the "parents" list contains a list of names of extensions already being
1257  * installed, allowing us to error out if we recurse to one of those.
1258  */
1259 static ObjectAddress
1260 CreateExtensionInternal(char *extensionName,
1261                                                 char *schemaName,
1262                                                 char *versionName,
1263                                                 char *oldVersionName,
1264                                                 bool cascade,
1265                                                 List *parents,
1266                                                 bool is_create)
1267 {
1268         char       *origSchemaName = schemaName;
1269         Oid                     schemaOid = InvalidOid;
1270         Oid                     extowner = GetUserId();
1271         ExtensionControlFile *pcontrol;
1272         ExtensionControlFile *control;
1273         List       *updateVersions;
1274         List       *requiredExtensions;
1275         List       *requiredSchemas;
1276         Oid                     extensionOid;
1277         ObjectAddress address;
1278         ListCell   *lc;
1279
1280         /*
1281          * Read the primary control file.  Note we assume that it does not contain
1282          * any non-ASCII data, so there is no need to worry about encoding at this
1283          * point.
1284          */
1285         pcontrol = read_extension_control_file(extensionName);
1286
1287         /*
1288          * Determine the version to install
1289          */
1290         if (versionName == NULL)
1291         {
1292                 if (pcontrol->default_version)
1293                         versionName = pcontrol->default_version;
1294                 else
1295                         ereport(ERROR,
1296                                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1297                                          errmsg("version to install must be specified")));
1298         }
1299         check_valid_version_name(versionName);
1300
1301         /*
1302          * Figure out which script(s) we need to run to install the desired
1303          * version of the extension.  If we do not have a script that directly
1304          * does what is needed, we try to find a sequence of update scripts that
1305          * will get us there.
1306          */
1307         if (oldVersionName)
1308         {
1309                 /*
1310                  * "FROM old_version" was specified, indicating that we're trying to
1311                  * update from some unpackaged version of the extension.  Locate a
1312                  * series of update scripts that will do it.
1313                  */
1314                 check_valid_version_name(oldVersionName);
1315
1316                 if (strcmp(oldVersionName, versionName) == 0)
1317                         ereport(ERROR,
1318                                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1319                                          errmsg("FROM version must be different from installation target version \"%s\"",
1320                                                         versionName)));
1321
1322                 updateVersions = identify_update_path(pcontrol,
1323                                                                                           oldVersionName,
1324                                                                                           versionName);
1325
1326                 if (list_length(updateVersions) == 1)
1327                 {
1328                         /*
1329                          * Simple case where there's just one update script to run. We
1330                          * will not need any follow-on update steps.
1331                          */
1332                         Assert(strcmp((char *) linitial(updateVersions), versionName) == 0);
1333                         updateVersions = NIL;
1334                 }
1335                 else
1336                 {
1337                         /*
1338                          * Multi-step sequence.  We treat this as installing the version
1339                          * that is the target of the first script, followed by successive
1340                          * updates to the later versions.
1341                          */
1342                         versionName = (char *) linitial(updateVersions);
1343                         updateVersions = list_delete_first(updateVersions);
1344                 }
1345         }
1346         else
1347         {
1348                 /*
1349                  * No FROM, so we're installing from scratch.  If there is an install
1350                  * script for the desired version, we only need to run that one.
1351                  */
1352                 char       *filename;
1353                 struct stat fst;
1354
1355                 oldVersionName = NULL;
1356
1357                 filename = get_extension_script_filename(pcontrol, NULL, versionName);
1358                 if (stat(filename, &fst) == 0)
1359                 {
1360                         /* Easy, no extra scripts */
1361                         updateVersions = NIL;
1362                 }
1363                 else
1364                 {
1365                         /* Look for best way to install this version */
1366                         List       *evi_list;
1367                         ExtensionVersionInfo *evi_start;
1368                         ExtensionVersionInfo *evi_target;
1369
1370                         /* Extract the version update graph from the script directory */
1371                         evi_list = get_ext_ver_list(pcontrol);
1372
1373                         /* Identify the target version */
1374                         evi_target = get_ext_ver_info(versionName, &evi_list);
1375
1376                         /* Identify best path to reach target */
1377                         evi_start = find_install_path(evi_list, evi_target,
1378                                                                                   &updateVersions);
1379
1380                         /* Fail if no path ... */
1381                         if (evi_start == NULL)
1382                                 ereport(ERROR,
1383                                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1384                                                  errmsg("extension \"%s\" has no installation script nor update path for version \"%s\"",
1385                                                                 pcontrol->name, versionName)));
1386
1387                         /* Otherwise, install best starting point and then upgrade */
1388                         versionName = evi_start->name;
1389                 }
1390         }
1391
1392         /*
1393          * Fetch control parameters for installation target version
1394          */
1395         control = read_extension_aux_control_file(pcontrol, versionName);
1396
1397         /*
1398          * Determine the target schema to install the extension into
1399          */
1400         if (schemaName)
1401         {
1402                 /* If the user is giving us the schema name, it must exist already. */
1403                 schemaOid = get_namespace_oid(schemaName, false);
1404         }
1405
1406         if (control->schema != NULL)
1407         {
1408                 /*
1409                  * The extension is not relocatable and the author gave us a schema
1410                  * for it.
1411                  *
1412                  * Unless CASCADE parameter was given, it's an error to give a schema
1413                  * different from control->schema if control->schema is specified.
1414                  */
1415                 if (schemaName && strcmp(control->schema, schemaName) != 0 &&
1416                         !cascade)
1417                         ereport(ERROR,
1418                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1419                                 errmsg("extension \"%s\" must be installed in schema \"%s\"",
1420                                            control->name,
1421                                            control->schema)));
1422
1423                 /* Always use the schema from control file for current extension. */
1424                 schemaName = control->schema;
1425
1426                 /* Find or create the schema in case it does not exist. */
1427                 schemaOid = get_namespace_oid(schemaName, true);
1428
1429                 if (!OidIsValid(schemaOid))
1430                 {
1431                         CreateSchemaStmt *csstmt = makeNode(CreateSchemaStmt);
1432
1433                         csstmt->schemaname = schemaName;
1434                         csstmt->authrole = NULL;        /* will be created by current user */
1435                         csstmt->schemaElts = NIL;
1436                         csstmt->if_not_exists = false;
1437                         CreateSchemaCommand(csstmt, NULL);
1438
1439                         /*
1440                          * CreateSchemaCommand includes CommandCounterIncrement, so new
1441                          * schema is now visible.
1442                          */
1443                         schemaOid = get_namespace_oid(schemaName, false);
1444                 }
1445         }
1446         else if (!OidIsValid(schemaOid))
1447         {
1448                 /*
1449                  * Neither user nor author of the extension specified schema; use the
1450                  * current default creation namespace, which is the first explicit
1451                  * entry in the search_path.
1452                  */
1453                 List       *search_path = fetch_search_path(false);
1454
1455                 if (search_path == NIL) /* nothing valid in search_path? */
1456                         ereport(ERROR,
1457                                         (errcode(ERRCODE_UNDEFINED_SCHEMA),
1458                                          errmsg("no schema has been selected to create in")));
1459                 schemaOid = linitial_oid(search_path);
1460                 schemaName = get_namespace_name(schemaOid);
1461                 if (schemaName == NULL) /* recently-deleted namespace? */
1462                         ereport(ERROR,
1463                                         (errcode(ERRCODE_UNDEFINED_SCHEMA),
1464                                          errmsg("no schema has been selected to create in")));
1465
1466                 list_free(search_path);
1467         }
1468
1469         /*
1470          * We don't check creation rights on the target namespace here.  If the
1471          * extension script actually creates any objects there, it will fail if
1472          * the user doesn't have such permissions.  But there are cases such as
1473          * procedural languages where it's convenient to set schema = pg_catalog
1474          * yet we don't want to restrict the command to users with ACL_CREATE for
1475          * pg_catalog.
1476          */
1477
1478         /*
1479          * Look up the prerequisite extensions, install them if necessary, and
1480          * build lists of their OIDs and the OIDs of their target schemas.
1481          */
1482         requiredExtensions = NIL;
1483         requiredSchemas = NIL;
1484         foreach(lc, control->requires)
1485         {
1486                 char       *curreq = (char *) lfirst(lc);
1487                 Oid                     reqext;
1488                 Oid                     reqschema;
1489
1490                 reqext = get_required_extension(curreq,
1491                                                                                 extensionName,
1492                                                                                 origSchemaName,
1493                                                                                 cascade,
1494                                                                                 parents,
1495                                                                                 is_create);
1496                 reqschema = get_extension_schema(reqext);
1497                 requiredExtensions = lappend_oid(requiredExtensions, reqext);
1498                 requiredSchemas = lappend_oid(requiredSchemas, reqschema);
1499         }
1500
1501         /*
1502          * Insert new tuple into pg_extension, and create dependency entries.
1503          */
1504         address = InsertExtensionTuple(control->name, extowner,
1505                                                                    schemaOid, control->relocatable,
1506                                                                    versionName,
1507                                                                    PointerGetDatum(NULL),
1508                                                                    PointerGetDatum(NULL),
1509                                                                    requiredExtensions);
1510         extensionOid = address.objectId;
1511
1512         /*
1513          * Apply any control-file comment on extension
1514          */
1515         if (control->comment != NULL)
1516                 CreateComments(extensionOid, ExtensionRelationId, 0, control->comment);
1517
1518         /*
1519          * Execute the installation script file
1520          */
1521         execute_extension_script(extensionOid, control,
1522                                                          oldVersionName, versionName,
1523                                                          requiredSchemas,
1524                                                          schemaName, schemaOid);
1525
1526         /*
1527          * If additional update scripts have to be executed, apply the updates as
1528          * though a series of ALTER EXTENSION UPDATE commands were given
1529          */
1530         ApplyExtensionUpdates(extensionOid, pcontrol,
1531                                                   versionName, updateVersions,
1532                                                   origSchemaName, cascade, is_create);
1533
1534         return address;
1535 }
1536
1537 /*
1538  * Get the OID of an extension listed in "requires", possibly creating it.
1539  */
1540 static Oid
1541 get_required_extension(char *reqExtensionName,
1542                                            char *extensionName,
1543                                            char *origSchemaName,
1544                                            bool cascade,
1545                                            List *parents,
1546                                            bool is_create)
1547 {
1548         Oid                     reqExtensionOid;
1549
1550         reqExtensionOid = get_extension_oid(reqExtensionName, true);
1551         if (!OidIsValid(reqExtensionOid))
1552         {
1553                 if (cascade)
1554                 {
1555                         /* Must install it. */
1556                         ObjectAddress addr;
1557                         List       *cascade_parents;
1558                         ListCell   *lc;
1559
1560                         /* Check extension name validity before trying to cascade. */
1561                         check_valid_extension_name(reqExtensionName);
1562
1563                         /* Check for cyclic dependency between extensions. */
1564                         foreach(lc, parents)
1565                         {
1566                                 char       *pname = (char *) lfirst(lc);
1567
1568                                 if (strcmp(pname, reqExtensionName) == 0)
1569                                         ereport(ERROR,
1570                                                         (errcode(ERRCODE_INVALID_RECURSION),
1571                                                          errmsg("cyclic dependency detected between extensions \"%s\" and \"%s\"",
1572                                                                         reqExtensionName, extensionName)));
1573                         }
1574
1575                         ereport(NOTICE,
1576                                         (errmsg("installing required extension \"%s\"",
1577                                                         reqExtensionName)));
1578
1579                         /* Add current extension to list of parents to pass down. */
1580                         cascade_parents = lappend(list_copy(parents), extensionName);
1581
1582                         /*
1583                          * Create the required extension.  We propagate the SCHEMA option
1584                          * if any, and CASCADE, but no other options.
1585                          */
1586                         addr = CreateExtensionInternal(reqExtensionName,
1587                                                                                    origSchemaName,
1588                                                                                    NULL,
1589                                                                                    NULL,
1590                                                                                    cascade,
1591                                                                                    cascade_parents,
1592                                                                                    is_create);
1593
1594                         /* Get its newly-assigned OID. */
1595                         reqExtensionOid = addr.objectId;
1596                 }
1597                 else
1598                         ereport(ERROR,
1599                                         (errcode(ERRCODE_UNDEFINED_OBJECT),
1600                                          errmsg("required extension \"%s\" is not installed",
1601                                                         reqExtensionName),
1602                                          is_create ?
1603                                          errhint("Use CREATE EXTENSION ... CASCADE to install required extensions too.") : 0));
1604         }
1605
1606         return reqExtensionOid;
1607 }
1608
1609 /*
1610  * CREATE EXTENSION
1611  */
1612 ObjectAddress
1613 CreateExtension(ParseState *pstate, CreateExtensionStmt *stmt)
1614 {
1615         DefElem    *d_schema = NULL;
1616         DefElem    *d_new_version = NULL;
1617         DefElem    *d_old_version = NULL;
1618         DefElem    *d_cascade = NULL;
1619         char       *schemaName = NULL;
1620         char       *versionName = NULL;
1621         char       *oldVersionName = NULL;
1622         bool            cascade = false;
1623         ListCell   *lc;
1624
1625         /* Check extension name validity before any filesystem access */
1626         check_valid_extension_name(stmt->extname);
1627
1628         /*
1629          * Check for duplicate extension name.  The unique index on
1630          * pg_extension.extname would catch this anyway, and serves as a backstop
1631          * in case of race conditions; but this is a friendlier error message, and
1632          * besides we need a check to support IF NOT EXISTS.
1633          */
1634         if (get_extension_oid(stmt->extname, true) != InvalidOid)
1635         {
1636                 if (stmt->if_not_exists)
1637                 {
1638                         ereport(NOTICE,
1639                                         (errcode(ERRCODE_DUPLICATE_OBJECT),
1640                                          errmsg("extension \"%s\" already exists, skipping",
1641                                                         stmt->extname)));
1642                         return InvalidObjectAddress;
1643                 }
1644                 else
1645                         ereport(ERROR,
1646                                         (errcode(ERRCODE_DUPLICATE_OBJECT),
1647                                          errmsg("extension \"%s\" already exists",
1648                                                         stmt->extname)));
1649         }
1650
1651         /*
1652          * We use global variables to track the extension being created, so we can
1653          * create only one extension at the same time.
1654          */
1655         if (creating_extension)
1656                 ereport(ERROR,
1657                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1658                                  errmsg("nested CREATE EXTENSION is not supported")));
1659
1660         /* Deconstruct the statement option list */
1661         foreach(lc, stmt->options)
1662         {
1663                 DefElem    *defel = (DefElem *) lfirst(lc);
1664
1665                 if (strcmp(defel->defname, "schema") == 0)
1666                 {
1667                         if (d_schema)
1668                                 ereport(ERROR,
1669                                                 (errcode(ERRCODE_SYNTAX_ERROR),
1670                                                  errmsg("conflicting or redundant options"),
1671                                                  parser_errposition(pstate, defel->location)));
1672                         d_schema = defel;
1673                         schemaName = defGetString(d_schema);
1674                 }
1675                 else if (strcmp(defel->defname, "new_version") == 0)
1676                 {
1677                         if (d_new_version)
1678                                 ereport(ERROR,
1679                                                 (errcode(ERRCODE_SYNTAX_ERROR),
1680                                                  errmsg("conflicting or redundant options"),
1681                                                  parser_errposition(pstate, defel->location)));
1682                         d_new_version = defel;
1683                         versionName = defGetString(d_new_version);
1684                 }
1685                 else if (strcmp(defel->defname, "old_version") == 0)
1686                 {
1687                         if (d_old_version)
1688                                 ereport(ERROR,
1689                                                 (errcode(ERRCODE_SYNTAX_ERROR),
1690                                                  errmsg("conflicting or redundant options"),
1691                                                  parser_errposition(pstate, defel->location)));
1692                         d_old_version = defel;
1693                         oldVersionName = defGetString(d_old_version);
1694                 }
1695                 else if (strcmp(defel->defname, "cascade") == 0)
1696                 {
1697                         if (d_cascade)
1698                                 ereport(ERROR,
1699                                                 (errcode(ERRCODE_SYNTAX_ERROR),
1700                                                  errmsg("conflicting or redundant options"),
1701                                                  parser_errposition(pstate, defel->location)));
1702                         d_cascade = defel;
1703                         cascade = defGetBoolean(d_cascade);
1704                 }
1705                 else
1706                         elog(ERROR, "unrecognized option: %s", defel->defname);
1707         }
1708
1709         /* Call CreateExtensionInternal to do the real work. */
1710         return CreateExtensionInternal(stmt->extname,
1711                                                                    schemaName,
1712                                                                    versionName,
1713                                                                    oldVersionName,
1714                                                                    cascade,
1715                                                                    NIL,
1716                                                                    true);
1717 }
1718
1719 /*
1720  * InsertExtensionTuple
1721  *
1722  * Insert the new pg_extension row, and create extension's dependency entries.
1723  * Return the OID assigned to the new row.
1724  *
1725  * This is exported for the benefit of pg_upgrade, which has to create a
1726  * pg_extension entry (and the extension-level dependencies) without
1727  * actually running the extension's script.
1728  *
1729  * extConfig and extCondition should be arrays or PointerGetDatum(NULL).
1730  * We declare them as plain Datum to avoid needing array.h in extension.h.
1731  */
1732 ObjectAddress
1733 InsertExtensionTuple(const char *extName, Oid extOwner,
1734                                          Oid schemaOid, bool relocatable, const char *extVersion,
1735                                          Datum extConfig, Datum extCondition,
1736                                          List *requiredExtensions)
1737 {
1738         Oid                     extensionOid;
1739         Relation        rel;
1740         Datum           values[Natts_pg_extension];
1741         bool            nulls[Natts_pg_extension];
1742         HeapTuple       tuple;
1743         ObjectAddress myself;
1744         ObjectAddress nsp;
1745         ListCell   *lc;
1746
1747         /*
1748          * Build and insert the pg_extension tuple
1749          */
1750         rel = heap_open(ExtensionRelationId, RowExclusiveLock);
1751
1752         memset(values, 0, sizeof(values));
1753         memset(nulls, 0, sizeof(nulls));
1754
1755         values[Anum_pg_extension_extname - 1] =
1756                 DirectFunctionCall1(namein, CStringGetDatum(extName));
1757         values[Anum_pg_extension_extowner - 1] = ObjectIdGetDatum(extOwner);
1758         values[Anum_pg_extension_extnamespace - 1] = ObjectIdGetDatum(schemaOid);
1759         values[Anum_pg_extension_extrelocatable - 1] = BoolGetDatum(relocatable);
1760         values[Anum_pg_extension_extversion - 1] = CStringGetTextDatum(extVersion);
1761
1762         if (extConfig == PointerGetDatum(NULL))
1763                 nulls[Anum_pg_extension_extconfig - 1] = true;
1764         else
1765                 values[Anum_pg_extension_extconfig - 1] = extConfig;
1766
1767         if (extCondition == PointerGetDatum(NULL))
1768                 nulls[Anum_pg_extension_extcondition - 1] = true;
1769         else
1770                 values[Anum_pg_extension_extcondition - 1] = extCondition;
1771
1772         tuple = heap_form_tuple(rel->rd_att, values, nulls);
1773
1774         extensionOid = simple_heap_insert(rel, tuple);
1775         CatalogUpdateIndexes(rel, tuple);
1776
1777         heap_freetuple(tuple);
1778         heap_close(rel, RowExclusiveLock);
1779
1780         /*
1781          * Record dependencies on owner, schema, and prerequisite extensions
1782          */
1783         recordDependencyOnOwner(ExtensionRelationId, extensionOid, extOwner);
1784
1785         myself.classId = ExtensionRelationId;
1786         myself.objectId = extensionOid;
1787         myself.objectSubId = 0;
1788
1789         nsp.classId = NamespaceRelationId;
1790         nsp.objectId = schemaOid;
1791         nsp.objectSubId = 0;
1792
1793         recordDependencyOn(&myself, &nsp, DEPENDENCY_NORMAL);
1794
1795         foreach(lc, requiredExtensions)
1796         {
1797                 Oid                     reqext = lfirst_oid(lc);
1798                 ObjectAddress otherext;
1799
1800                 otherext.classId = ExtensionRelationId;
1801                 otherext.objectId = reqext;
1802                 otherext.objectSubId = 0;
1803
1804                 recordDependencyOn(&myself, &otherext, DEPENDENCY_NORMAL);
1805         }
1806         /* Post creation hook for new extension */
1807         InvokeObjectPostCreateHook(ExtensionRelationId, extensionOid, 0);
1808
1809         return myself;
1810 }
1811
1812 /*
1813  * Guts of extension deletion.
1814  *
1815  * All we need do here is remove the pg_extension tuple itself.  Everything
1816  * else is taken care of by the dependency infrastructure.
1817  */
1818 void
1819 RemoveExtensionById(Oid extId)
1820 {
1821         Relation        rel;
1822         SysScanDesc scandesc;
1823         HeapTuple       tuple;
1824         ScanKeyData entry[1];
1825
1826         /*
1827          * Disallow deletion of any extension that's currently open for insertion;
1828          * else subsequent executions of recordDependencyOnCurrentExtension()
1829          * could create dangling pg_depend records that refer to a no-longer-valid
1830          * pg_extension OID.  This is needed not so much because we think people
1831          * might write "DROP EXTENSION foo" in foo's own script files, as because
1832          * errors in dependency management in extension script files could give
1833          * rise to cases where an extension is dropped as a result of recursing
1834          * from some contained object.  Because of that, we must test for the case
1835          * here, not at some higher level of the DROP EXTENSION command.
1836          */
1837         if (extId == CurrentExtensionObject)
1838                 ereport(ERROR,
1839                                 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1840                   errmsg("cannot drop extension \"%s\" because it is being modified",
1841                                  get_extension_name(extId))));
1842
1843         rel = heap_open(ExtensionRelationId, RowExclusiveLock);
1844
1845         ScanKeyInit(&entry[0],
1846                                 ObjectIdAttributeNumber,
1847                                 BTEqualStrategyNumber, F_OIDEQ,
1848                                 ObjectIdGetDatum(extId));
1849         scandesc = systable_beginscan(rel, ExtensionOidIndexId, true,
1850                                                                   NULL, 1, entry);
1851
1852         tuple = systable_getnext(scandesc);
1853
1854         /* We assume that there can be at most one matching tuple */
1855         if (HeapTupleIsValid(tuple))
1856                 simple_heap_delete(rel, &tuple->t_self);
1857
1858         systable_endscan(scandesc);
1859
1860         heap_close(rel, RowExclusiveLock);
1861 }
1862
1863 /*
1864  * This function lists the available extensions (one row per primary control
1865  * file in the control directory).  We parse each control file and report the
1866  * interesting fields.
1867  *
1868  * The system view pg_available_extensions provides a user interface to this
1869  * SRF, adding information about whether the extensions are installed in the
1870  * current DB.
1871  */
1872 Datum
1873 pg_available_extensions(PG_FUNCTION_ARGS)
1874 {
1875         ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
1876         TupleDesc       tupdesc;
1877         Tuplestorestate *tupstore;
1878         MemoryContext per_query_ctx;
1879         MemoryContext oldcontext;
1880         char       *location;
1881         DIR                *dir;
1882         struct dirent *de;
1883
1884         /* check to see if caller supports us returning a tuplestore */
1885         if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
1886                 ereport(ERROR,
1887                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1888                                  errmsg("set-valued function called in context that cannot accept a set")));
1889         if (!(rsinfo->allowedModes & SFRM_Materialize))
1890                 ereport(ERROR,
1891                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1892                                  errmsg("materialize mode required, but it is not " \
1893                                                 "allowed in this context")));
1894
1895         /* Build a tuple descriptor for our result type */
1896         if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
1897                 elog(ERROR, "return type must be a row type");
1898
1899         /* Build tuplestore to hold the result rows */
1900         per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
1901         oldcontext = MemoryContextSwitchTo(per_query_ctx);
1902
1903         tupstore = tuplestore_begin_heap(true, false, work_mem);
1904         rsinfo->returnMode = SFRM_Materialize;
1905         rsinfo->setResult = tupstore;
1906         rsinfo->setDesc = tupdesc;
1907
1908         MemoryContextSwitchTo(oldcontext);
1909
1910         location = get_extension_control_directory();
1911         dir = AllocateDir(location);
1912
1913         /*
1914          * If the control directory doesn't exist, we want to silently return an
1915          * empty set.  Any other error will be reported by ReadDir.
1916          */
1917         if (dir == NULL && errno == ENOENT)
1918         {
1919                 /* do nothing */
1920         }
1921         else
1922         {
1923                 while ((de = ReadDir(dir, location)) != NULL)
1924                 {
1925                         ExtensionControlFile *control;
1926                         char       *extname;
1927                         Datum           values[3];
1928                         bool            nulls[3];
1929
1930                         if (!is_extension_control_filename(de->d_name))
1931                                 continue;
1932
1933                         /* extract extension name from 'name.control' filename */
1934                         extname = pstrdup(de->d_name);
1935                         *strrchr(extname, '.') = '\0';
1936
1937                         /* ignore it if it's an auxiliary control file */
1938                         if (strstr(extname, "--"))
1939                                 continue;
1940
1941                         control = read_extension_control_file(extname);
1942
1943                         memset(values, 0, sizeof(values));
1944                         memset(nulls, 0, sizeof(nulls));
1945
1946                         /* name */
1947                         values[0] = DirectFunctionCall1(namein,
1948                                                                                         CStringGetDatum(control->name));
1949                         /* default_version */
1950                         if (control->default_version == NULL)
1951                                 nulls[1] = true;
1952                         else
1953                                 values[1] = CStringGetTextDatum(control->default_version);
1954                         /* comment */
1955                         if (control->comment == NULL)
1956                                 nulls[2] = true;
1957                         else
1958                                 values[2] = CStringGetTextDatum(control->comment);
1959
1960                         tuplestore_putvalues(tupstore, tupdesc, values, nulls);
1961                 }
1962
1963                 FreeDir(dir);
1964         }
1965
1966         /* clean up and return the tuplestore */
1967         tuplestore_donestoring(tupstore);
1968
1969         return (Datum) 0;
1970 }
1971
1972 /*
1973  * This function lists the available extension versions (one row per
1974  * extension installation script).  For each version, we parse the related
1975  * control file(s) and report the interesting fields.
1976  *
1977  * The system view pg_available_extension_versions provides a user interface
1978  * to this SRF, adding information about which versions are installed in the
1979  * current DB.
1980  */
1981 Datum
1982 pg_available_extension_versions(PG_FUNCTION_ARGS)
1983 {
1984         ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
1985         TupleDesc       tupdesc;
1986         Tuplestorestate *tupstore;
1987         MemoryContext per_query_ctx;
1988         MemoryContext oldcontext;
1989         char       *location;
1990         DIR                *dir;
1991         struct dirent *de;
1992
1993         /* check to see if caller supports us returning a tuplestore */
1994         if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
1995                 ereport(ERROR,
1996                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1997                                  errmsg("set-valued function called in context that cannot accept a set")));
1998         if (!(rsinfo->allowedModes & SFRM_Materialize))
1999                 ereport(ERROR,
2000                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2001                                  errmsg("materialize mode required, but it is not " \
2002                                                 "allowed in this context")));
2003
2004         /* Build a tuple descriptor for our result type */
2005         if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
2006                 elog(ERROR, "return type must be a row type");
2007
2008         /* Build tuplestore to hold the result rows */
2009         per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
2010         oldcontext = MemoryContextSwitchTo(per_query_ctx);
2011
2012         tupstore = tuplestore_begin_heap(true, false, work_mem);
2013         rsinfo->returnMode = SFRM_Materialize;
2014         rsinfo->setResult = tupstore;
2015         rsinfo->setDesc = tupdesc;
2016
2017         MemoryContextSwitchTo(oldcontext);
2018
2019         location = get_extension_control_directory();
2020         dir = AllocateDir(location);
2021
2022         /*
2023          * If the control directory doesn't exist, we want to silently return an
2024          * empty set.  Any other error will be reported by ReadDir.
2025          */
2026         if (dir == NULL && errno == ENOENT)
2027         {
2028                 /* do nothing */
2029         }
2030         else
2031         {
2032                 while ((de = ReadDir(dir, location)) != NULL)
2033                 {
2034                         ExtensionControlFile *control;
2035                         char       *extname;
2036
2037                         if (!is_extension_control_filename(de->d_name))
2038                                 continue;
2039
2040                         /* extract extension name from 'name.control' filename */
2041                         extname = pstrdup(de->d_name);
2042                         *strrchr(extname, '.') = '\0';
2043
2044                         /* ignore it if it's an auxiliary control file */
2045                         if (strstr(extname, "--"))
2046                                 continue;
2047
2048                         /* read the control file */
2049                         control = read_extension_control_file(extname);
2050
2051                         /* scan extension's script directory for install scripts */
2052                         get_available_versions_for_extension(control, tupstore, tupdesc);
2053                 }
2054
2055                 FreeDir(dir);
2056         }
2057
2058         /* clean up and return the tuplestore */
2059         tuplestore_donestoring(tupstore);
2060
2061         return (Datum) 0;
2062 }
2063
2064 /*
2065  * Inner loop for pg_available_extension_versions:
2066  *              read versions of one extension, add rows to tupstore
2067  */
2068 static void
2069 get_available_versions_for_extension(ExtensionControlFile *pcontrol,
2070                                                                          Tuplestorestate *tupstore,
2071                                                                          TupleDesc tupdesc)
2072 {
2073         List       *evi_list;
2074         ListCell   *lc;
2075
2076         /* Extract the version update graph from the script directory */
2077         evi_list = get_ext_ver_list(pcontrol);
2078
2079         /* For each installable version ... */
2080         foreach(lc, evi_list)
2081         {
2082                 ExtensionVersionInfo *evi = (ExtensionVersionInfo *) lfirst(lc);
2083                 ExtensionControlFile *control;
2084                 Datum           values[7];
2085                 bool            nulls[7];
2086                 ListCell   *lc2;
2087
2088                 if (!evi->installable)
2089                         continue;
2090
2091                 /*
2092                  * Fetch parameters for specific version (pcontrol is not changed)
2093                  */
2094                 control = read_extension_aux_control_file(pcontrol, evi->name);
2095
2096                 memset(values, 0, sizeof(values));
2097                 memset(nulls, 0, sizeof(nulls));
2098
2099                 /* name */
2100                 values[0] = DirectFunctionCall1(namein,
2101                                                                                 CStringGetDatum(control->name));
2102                 /* version */
2103                 values[1] = CStringGetTextDatum(evi->name);
2104                 /* superuser */
2105                 values[2] = BoolGetDatum(control->superuser);
2106                 /* relocatable */
2107                 values[3] = BoolGetDatum(control->relocatable);
2108                 /* schema */
2109                 if (control->schema == NULL)
2110                         nulls[4] = true;
2111                 else
2112                         values[4] = DirectFunctionCall1(namein,
2113                                                                                         CStringGetDatum(control->schema));
2114                 /* requires */
2115                 if (control->requires == NIL)
2116                         nulls[5] = true;
2117                 else
2118                         values[5] = convert_requires_to_datum(control->requires);
2119                 /* comment */
2120                 if (control->comment == NULL)
2121                         nulls[6] = true;
2122                 else
2123                         values[6] = CStringGetTextDatum(control->comment);
2124
2125                 tuplestore_putvalues(tupstore, tupdesc, values, nulls);
2126
2127                 /*
2128                  * Find all non-directly-installable versions that would be installed
2129                  * starting from this version, and report them, inheriting the
2130                  * parameters that aren't changed in updates from this version.
2131                  */
2132                 foreach(lc2, evi_list)
2133                 {
2134                         ExtensionVersionInfo *evi2 = (ExtensionVersionInfo *) lfirst(lc2);
2135                         List       *best_path;
2136
2137                         if (evi2->installable)
2138                                 continue;
2139                         if (find_install_path(evi_list, evi2, &best_path) == evi)
2140                         {
2141                                 /*
2142                                  * Fetch parameters for this version (pcontrol is not changed)
2143                                  */
2144                                 control = read_extension_aux_control_file(pcontrol, evi2->name);
2145
2146                                 /* name stays the same */
2147                                 /* version */
2148                                 values[1] = CStringGetTextDatum(evi2->name);
2149                                 /* superuser */
2150                                 values[2] = BoolGetDatum(control->superuser);
2151                                 /* relocatable */
2152                                 values[3] = BoolGetDatum(control->relocatable);
2153                                 /* schema stays the same */
2154                                 /* requires */
2155                                 if (control->requires == NIL)
2156                                         nulls[5] = true;
2157                                 else
2158                                 {
2159                                         values[5] = convert_requires_to_datum(control->requires);
2160                                         nulls[5] = false;
2161                                 }
2162                                 /* comment stays the same */
2163
2164                                 tuplestore_putvalues(tupstore, tupdesc, values, nulls);
2165                         }
2166                 }
2167         }
2168 }
2169
2170 /*
2171  * Convert a list of extension names to a name[] Datum
2172  */
2173 static Datum
2174 convert_requires_to_datum(List *requires)
2175 {
2176         Datum      *datums;
2177         int                     ndatums;
2178         ArrayType  *a;
2179         ListCell   *lc;
2180
2181         ndatums = list_length(requires);
2182         datums = (Datum *) palloc(ndatums * sizeof(Datum));
2183         ndatums = 0;
2184         foreach(lc, requires)
2185         {
2186                 char       *curreq = (char *) lfirst(lc);
2187
2188                 datums[ndatums++] =
2189                         DirectFunctionCall1(namein, CStringGetDatum(curreq));
2190         }
2191         a = construct_array(datums, ndatums,
2192                                                 NAMEOID,
2193                                                 NAMEDATALEN, false, 'c');
2194         return PointerGetDatum(a);
2195 }
2196
2197 /*
2198  * This function reports the version update paths that exist for the
2199  * specified extension.
2200  */
2201 Datum
2202 pg_extension_update_paths(PG_FUNCTION_ARGS)
2203 {
2204         Name            extname = PG_GETARG_NAME(0);
2205         ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
2206         TupleDesc       tupdesc;
2207         Tuplestorestate *tupstore;
2208         MemoryContext per_query_ctx;
2209         MemoryContext oldcontext;
2210         List       *evi_list;
2211         ExtensionControlFile *control;
2212         ListCell   *lc1;
2213
2214         /* Check extension name validity before any filesystem access */
2215         check_valid_extension_name(NameStr(*extname));
2216
2217         /* check to see if caller supports us returning a tuplestore */
2218         if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
2219                 ereport(ERROR,
2220                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2221                                  errmsg("set-valued function called in context that cannot accept a set")));
2222         if (!(rsinfo->allowedModes & SFRM_Materialize))
2223                 ereport(ERROR,
2224                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2225                                  errmsg("materialize mode required, but it is not " \
2226                                                 "allowed in this context")));
2227
2228         /* Build a tuple descriptor for our result type */
2229         if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
2230                 elog(ERROR, "return type must be a row type");
2231
2232         /* Build tuplestore to hold the result rows */
2233         per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
2234         oldcontext = MemoryContextSwitchTo(per_query_ctx);
2235
2236         tupstore = tuplestore_begin_heap(true, false, work_mem);
2237         rsinfo->returnMode = SFRM_Materialize;
2238         rsinfo->setResult = tupstore;
2239         rsinfo->setDesc = tupdesc;
2240
2241         MemoryContextSwitchTo(oldcontext);
2242
2243         /* Read the extension's control file */
2244         control = read_extension_control_file(NameStr(*extname));
2245
2246         /* Extract the version update graph from the script directory */
2247         evi_list = get_ext_ver_list(control);
2248
2249         /* Iterate over all pairs of versions */
2250         foreach(lc1, evi_list)
2251         {
2252                 ExtensionVersionInfo *evi1 = (ExtensionVersionInfo *) lfirst(lc1);
2253                 ListCell   *lc2;
2254
2255                 foreach(lc2, evi_list)
2256                 {
2257                         ExtensionVersionInfo *evi2 = (ExtensionVersionInfo *) lfirst(lc2);
2258                         List       *path;
2259                         Datum           values[3];
2260                         bool            nulls[3];
2261
2262                         if (evi1 == evi2)
2263                                 continue;
2264
2265                         /* Find shortest path from evi1 to evi2 */
2266                         path = find_update_path(evi_list, evi1, evi2, false, true);
2267
2268                         /* Emit result row */
2269                         memset(values, 0, sizeof(values));
2270                         memset(nulls, 0, sizeof(nulls));
2271
2272                         /* source */
2273                         values[0] = CStringGetTextDatum(evi1->name);
2274                         /* target */
2275                         values[1] = CStringGetTextDatum(evi2->name);
2276                         /* path */
2277                         if (path == NIL)
2278                                 nulls[2] = true;
2279                         else
2280                         {
2281                                 StringInfoData pathbuf;
2282                                 ListCell   *lcv;
2283
2284                                 initStringInfo(&pathbuf);
2285                                 /* The path doesn't include start vertex, but show it */
2286                                 appendStringInfoString(&pathbuf, evi1->name);
2287                                 foreach(lcv, path)
2288                                 {
2289                                         char       *versionName = (char *) lfirst(lcv);
2290
2291                                         appendStringInfoString(&pathbuf, "--");
2292                                         appendStringInfoString(&pathbuf, versionName);
2293                                 }
2294                                 values[2] = CStringGetTextDatum(pathbuf.data);
2295                                 pfree(pathbuf.data);
2296                         }
2297
2298                         tuplestore_putvalues(tupstore, tupdesc, values, nulls);
2299                 }
2300         }
2301
2302         /* clean up and return the tuplestore */
2303         tuplestore_donestoring(tupstore);
2304
2305         return (Datum) 0;
2306 }
2307
2308 /*
2309  * pg_extension_config_dump
2310  *
2311  * Record information about a configuration table that belongs to an
2312  * extension being created, but whose contents should be dumped in whole
2313  * or in part during pg_dump.
2314  */
2315 Datum
2316 pg_extension_config_dump(PG_FUNCTION_ARGS)
2317 {
2318         Oid                     tableoid = PG_GETARG_OID(0);
2319         text       *wherecond = PG_GETARG_TEXT_P(1);
2320         char       *tablename;
2321         Relation        extRel;
2322         ScanKeyData key[1];
2323         SysScanDesc extScan;
2324         HeapTuple       extTup;
2325         Datum           arrayDatum;
2326         Datum           elementDatum;
2327         int                     arrayLength;
2328         int                     arrayIndex;
2329         bool            isnull;
2330         Datum           repl_val[Natts_pg_extension];
2331         bool            repl_null[Natts_pg_extension];
2332         bool            repl_repl[Natts_pg_extension];
2333         ArrayType  *a;
2334
2335         /*
2336          * We only allow this to be called from an extension's SQL script. We
2337          * shouldn't need any permissions check beyond that.
2338          */
2339         if (!creating_extension)
2340                 ereport(ERROR,
2341                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2342                                  errmsg("pg_extension_config_dump() can only be called "
2343                                                 "from an SQL script executed by CREATE EXTENSION")));
2344
2345         /*
2346          * Check that the table exists and is a member of the extension being
2347          * created.  This ensures that we don't need to register an additional
2348          * dependency to protect the extconfig entry.
2349          */
2350         tablename = get_rel_name(tableoid);
2351         if (tablename == NULL)
2352                 ereport(ERROR,
2353                                 (errcode(ERRCODE_UNDEFINED_TABLE),
2354                                  errmsg("OID %u does not refer to a table", tableoid)));
2355         if (getExtensionOfObject(RelationRelationId, tableoid) !=
2356                 CurrentExtensionObject)
2357                 ereport(ERROR,
2358                                 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
2359                 errmsg("table \"%s\" is not a member of the extension being created",
2360                            tablename)));
2361
2362         /*
2363          * Add the table OID and WHERE condition to the extension's extconfig and
2364          * extcondition arrays.
2365          *
2366          * If the table is already in extconfig, treat this as an update of the
2367          * WHERE condition.
2368          */
2369
2370         /* Find the pg_extension tuple */
2371         extRel = heap_open(ExtensionRelationId, RowExclusiveLock);
2372
2373         ScanKeyInit(&key[0],
2374                                 ObjectIdAttributeNumber,
2375                                 BTEqualStrategyNumber, F_OIDEQ,
2376                                 ObjectIdGetDatum(CurrentExtensionObject));
2377
2378         extScan = systable_beginscan(extRel, ExtensionOidIndexId, true,
2379                                                                  NULL, 1, key);
2380
2381         extTup = systable_getnext(extScan);
2382
2383         if (!HeapTupleIsValid(extTup))          /* should not happen */
2384                 elog(ERROR, "extension with oid %u does not exist",
2385                          CurrentExtensionObject);
2386
2387         memset(repl_val, 0, sizeof(repl_val));
2388         memset(repl_null, false, sizeof(repl_null));
2389         memset(repl_repl, false, sizeof(repl_repl));
2390
2391         /* Build or modify the extconfig value */
2392         elementDatum = ObjectIdGetDatum(tableoid);
2393
2394         arrayDatum = heap_getattr(extTup, Anum_pg_extension_extconfig,
2395                                                           RelationGetDescr(extRel), &isnull);
2396         if (isnull)
2397         {
2398                 /* Previously empty extconfig, so build 1-element array */
2399                 arrayLength = 0;
2400                 arrayIndex = 1;
2401
2402                 a = construct_array(&elementDatum, 1,
2403                                                         OIDOID,
2404                                                         sizeof(Oid), true, 'i');
2405         }
2406         else
2407         {
2408                 /* Modify or extend existing extconfig array */
2409                 Oid                *arrayData;
2410                 int                     i;
2411
2412                 a = DatumGetArrayTypeP(arrayDatum);
2413
2414                 arrayLength = ARR_DIMS(a)[0];
2415                 if (ARR_NDIM(a) != 1 ||
2416                         ARR_LBOUND(a)[0] != 1 ||
2417                         arrayLength < 0 ||
2418                         ARR_HASNULL(a) ||
2419                         ARR_ELEMTYPE(a) != OIDOID)
2420                         elog(ERROR, "extconfig is not a 1-D Oid array");
2421                 arrayData = (Oid *) ARR_DATA_PTR(a);
2422
2423                 arrayIndex = arrayLength + 1;   /* set up to add after end */
2424
2425                 for (i = 0; i < arrayLength; i++)
2426                 {
2427                         if (arrayData[i] == tableoid)
2428                         {
2429                                 arrayIndex = i + 1;             /* replace this element instead */
2430                                 break;
2431                         }
2432                 }
2433
2434                 a = array_set(a, 1, &arrayIndex,
2435                                           elementDatum,
2436                                           false,
2437                                           -1 /* varlena array */ ,
2438                                           sizeof(Oid) /* OID's typlen */ ,
2439                                           true /* OID's typbyval */ ,
2440                                           'i' /* OID's typalign */ );
2441         }
2442         repl_val[Anum_pg_extension_extconfig - 1] = PointerGetDatum(a);
2443         repl_repl[Anum_pg_extension_extconfig - 1] = true;
2444
2445         /* Build or modify the extcondition value */
2446         elementDatum = PointerGetDatum(wherecond);
2447
2448         arrayDatum = heap_getattr(extTup, Anum_pg_extension_extcondition,
2449                                                           RelationGetDescr(extRel), &isnull);
2450         if (isnull)
2451         {
2452                 if (arrayLength != 0)
2453                         elog(ERROR, "extconfig and extcondition arrays do not match");
2454
2455                 a = construct_array(&elementDatum, 1,
2456                                                         TEXTOID,
2457                                                         -1, false, 'i');
2458         }
2459         else
2460         {
2461                 a = DatumGetArrayTypeP(arrayDatum);
2462
2463                 if (ARR_NDIM(a) != 1 ||
2464                         ARR_LBOUND(a)[0] != 1 ||
2465                         ARR_HASNULL(a) ||
2466                         ARR_ELEMTYPE(a) != TEXTOID)
2467                         elog(ERROR, "extcondition is not a 1-D text array");
2468                 if (ARR_DIMS(a)[0] != arrayLength)
2469                         elog(ERROR, "extconfig and extcondition arrays do not match");
2470
2471                 /* Add or replace at same index as in extconfig */
2472                 a = array_set(a, 1, &arrayIndex,
2473                                           elementDatum,
2474                                           false,
2475                                           -1 /* varlena array */ ,
2476                                           -1 /* TEXT's typlen */ ,
2477                                           false /* TEXT's typbyval */ ,
2478                                           'i' /* TEXT's typalign */ );
2479         }
2480         repl_val[Anum_pg_extension_extcondition - 1] = PointerGetDatum(a);
2481         repl_repl[Anum_pg_extension_extcondition - 1] = true;
2482
2483         extTup = heap_modify_tuple(extTup, RelationGetDescr(extRel),
2484                                                            repl_val, repl_null, repl_repl);
2485
2486         simple_heap_update(extRel, &extTup->t_self, extTup);
2487         CatalogUpdateIndexes(extRel, extTup);
2488
2489         systable_endscan(extScan);
2490
2491         heap_close(extRel, RowExclusiveLock);
2492
2493         PG_RETURN_VOID();
2494 }
2495
2496 /*
2497  * extension_config_remove
2498  *
2499  * Remove the specified table OID from extension's extconfig, if present.
2500  * This is not currently exposed as a function, but it could be;
2501  * for now, we just invoke it from ALTER EXTENSION DROP.
2502  */
2503 static void
2504 extension_config_remove(Oid extensionoid, Oid tableoid)
2505 {
2506         Relation        extRel;
2507         ScanKeyData key[1];
2508         SysScanDesc extScan;
2509         HeapTuple       extTup;
2510         Datum           arrayDatum;
2511         int                     arrayLength;
2512         int                     arrayIndex;
2513         bool            isnull;
2514         Datum           repl_val[Natts_pg_extension];
2515         bool            repl_null[Natts_pg_extension];
2516         bool            repl_repl[Natts_pg_extension];
2517         ArrayType  *a;
2518
2519         /* Find the pg_extension tuple */
2520         extRel = heap_open(ExtensionRelationId, RowExclusiveLock);
2521
2522         ScanKeyInit(&key[0],
2523                                 ObjectIdAttributeNumber,
2524                                 BTEqualStrategyNumber, F_OIDEQ,
2525                                 ObjectIdGetDatum(extensionoid));
2526
2527         extScan = systable_beginscan(extRel, ExtensionOidIndexId, true,
2528                                                                  NULL, 1, key);
2529
2530         extTup = systable_getnext(extScan);
2531
2532         if (!HeapTupleIsValid(extTup))          /* should not happen */
2533                 elog(ERROR, "extension with oid %u does not exist",
2534                          extensionoid);
2535
2536         /* Search extconfig for the tableoid */
2537         arrayDatum = heap_getattr(extTup, Anum_pg_extension_extconfig,
2538                                                           RelationGetDescr(extRel), &isnull);
2539         if (isnull)
2540         {
2541                 /* nothing to do */
2542                 a = NULL;
2543                 arrayLength = 0;
2544                 arrayIndex = -1;
2545         }
2546         else
2547         {
2548                 Oid                *arrayData;
2549                 int                     i;
2550
2551                 a = DatumGetArrayTypeP(arrayDatum);
2552
2553                 arrayLength = ARR_DIMS(a)[0];
2554                 if (ARR_NDIM(a) != 1 ||
2555                         ARR_LBOUND(a)[0] != 1 ||
2556                         arrayLength < 0 ||
2557                         ARR_HASNULL(a) ||
2558                         ARR_ELEMTYPE(a) != OIDOID)
2559                         elog(ERROR, "extconfig is not a 1-D Oid array");
2560                 arrayData = (Oid *) ARR_DATA_PTR(a);
2561
2562                 arrayIndex = -1;                /* flag for no deletion needed */
2563
2564                 for (i = 0; i < arrayLength; i++)
2565                 {
2566                         if (arrayData[i] == tableoid)
2567                         {
2568                                 arrayIndex = i; /* index to remove */
2569                                 break;
2570                         }
2571                 }
2572         }
2573
2574         /* If tableoid is not in extconfig, nothing to do */
2575         if (arrayIndex < 0)
2576         {
2577                 systable_endscan(extScan);
2578                 heap_close(extRel, RowExclusiveLock);
2579                 return;
2580         }
2581
2582         /* Modify or delete the extconfig value */
2583         memset(repl_val, 0, sizeof(repl_val));
2584         memset(repl_null, false, sizeof(repl_null));
2585         memset(repl_repl, false, sizeof(repl_repl));
2586
2587         if (arrayLength <= 1)
2588         {
2589                 /* removing only element, just set array to null */
2590                 repl_null[Anum_pg_extension_extconfig - 1] = true;
2591         }
2592         else
2593         {
2594                 /* squeeze out the target element */
2595                 Datum      *dvalues;
2596                 bool       *dnulls;
2597                 int                     nelems;
2598                 int                     i;
2599
2600                 deconstruct_array(a, OIDOID, sizeof(Oid), true, 'i',
2601                                                   &dvalues, &dnulls, &nelems);
2602
2603                 /* We already checked there are no nulls, so ignore dnulls */
2604                 for (i = arrayIndex; i < arrayLength - 1; i++)
2605                         dvalues[i] = dvalues[i + 1];
2606
2607                 a = construct_array(dvalues, arrayLength - 1,
2608                                                         OIDOID, sizeof(Oid), true, 'i');
2609
2610                 repl_val[Anum_pg_extension_extconfig - 1] = PointerGetDatum(a);
2611         }
2612         repl_repl[Anum_pg_extension_extconfig - 1] = true;
2613
2614         /* Modify or delete the extcondition value */
2615         arrayDatum = heap_getattr(extTup, Anum_pg_extension_extcondition,
2616                                                           RelationGetDescr(extRel), &isnull);
2617         if (isnull)
2618         {
2619                 elog(ERROR, "extconfig and extcondition arrays do not match");
2620         }
2621         else
2622         {
2623                 a = DatumGetArrayTypeP(arrayDatum);
2624
2625                 if (ARR_NDIM(a) != 1 ||
2626                         ARR_LBOUND(a)[0] != 1 ||
2627                         ARR_HASNULL(a) ||
2628                         ARR_ELEMTYPE(a) != TEXTOID)
2629                         elog(ERROR, "extcondition is not a 1-D text array");
2630                 if (ARR_DIMS(a)[0] != arrayLength)
2631                         elog(ERROR, "extconfig and extcondition arrays do not match");
2632         }
2633
2634         if (arrayLength <= 1)
2635         {
2636                 /* removing only element, just set array to null */
2637                 repl_null[Anum_pg_extension_extcondition - 1] = true;
2638         }
2639         else
2640         {
2641                 /* squeeze out the target element */
2642                 Datum      *dvalues;
2643                 bool       *dnulls;
2644                 int                     nelems;
2645                 int                     i;
2646
2647                 deconstruct_array(a, TEXTOID, -1, false, 'i',
2648                                                   &dvalues, &dnulls, &nelems);
2649
2650                 /* We already checked there are no nulls, so ignore dnulls */
2651                 for (i = arrayIndex; i < arrayLength - 1; i++)
2652                         dvalues[i] = dvalues[i + 1];
2653
2654                 a = construct_array(dvalues, arrayLength - 1,
2655                                                         TEXTOID, -1, false, 'i');
2656
2657                 repl_val[Anum_pg_extension_extcondition - 1] = PointerGetDatum(a);
2658         }
2659         repl_repl[Anum_pg_extension_extcondition - 1] = true;
2660
2661         extTup = heap_modify_tuple(extTup, RelationGetDescr(extRel),
2662                                                            repl_val, repl_null, repl_repl);
2663
2664         simple_heap_update(extRel, &extTup->t_self, extTup);
2665         CatalogUpdateIndexes(extRel, extTup);
2666
2667         systable_endscan(extScan);
2668
2669         heap_close(extRel, RowExclusiveLock);
2670 }
2671
2672 /*
2673  * Execute ALTER EXTENSION SET SCHEMA
2674  */
2675 ObjectAddress
2676 AlterExtensionNamespace(List *names, const char *newschema, Oid *oldschema)
2677 {
2678         char       *extensionName;
2679         Oid                     extensionOid;
2680         Oid                     nspOid;
2681         Oid                     oldNspOid = InvalidOid;
2682         AclResult       aclresult;
2683         Relation        extRel;
2684         ScanKeyData key[2];
2685         SysScanDesc extScan;
2686         HeapTuple       extTup;
2687         Form_pg_extension extForm;
2688         Relation        depRel;
2689         SysScanDesc depScan;
2690         HeapTuple       depTup;
2691         ObjectAddresses *objsMoved;
2692         ObjectAddress extAddr;
2693
2694         if (list_length(names) != 1)
2695                 ereport(ERROR,
2696                                 (errcode(ERRCODE_SYNTAX_ERROR),
2697                                  errmsg("extension name cannot be qualified")));
2698         extensionName = strVal(linitial(names));
2699
2700         extensionOid = get_extension_oid(extensionName, false);
2701
2702         nspOid = LookupCreationNamespace(newschema);
2703
2704         /*
2705          * Permission check: must own extension.  Note that we don't bother to
2706          * check ownership of the individual member objects ...
2707          */
2708         if (!pg_extension_ownercheck(extensionOid, GetUserId()))
2709                 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_EXTENSION,
2710                                            extensionName);
2711
2712         /* Permission check: must have creation rights in target namespace */
2713         aclresult = pg_namespace_aclcheck(nspOid, GetUserId(), ACL_CREATE);
2714         if (aclresult != ACLCHECK_OK)
2715                 aclcheck_error(aclresult, ACL_KIND_NAMESPACE, newschema);
2716
2717         /*
2718          * If the schema is currently a member of the extension, disallow moving
2719          * the extension into the schema.  That would create a dependency loop.
2720          */
2721         if (getExtensionOfObject(NamespaceRelationId, nspOid) == extensionOid)
2722                 ereport(ERROR,
2723                                 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
2724                                  errmsg("cannot move extension \"%s\" into schema \"%s\" "
2725                                                 "because the extension contains the schema",
2726                                                 extensionName, newschema)));
2727
2728         /* Locate the pg_extension tuple */
2729         extRel = heap_open(ExtensionRelationId, RowExclusiveLock);
2730
2731         ScanKeyInit(&key[0],
2732                                 ObjectIdAttributeNumber,
2733                                 BTEqualStrategyNumber, F_OIDEQ,
2734                                 ObjectIdGetDatum(extensionOid));
2735
2736         extScan = systable_beginscan(extRel, ExtensionOidIndexId, true,
2737                                                                  NULL, 1, key);
2738
2739         extTup = systable_getnext(extScan);
2740
2741         if (!HeapTupleIsValid(extTup))          /* should not happen */
2742                 elog(ERROR, "extension with oid %u does not exist", extensionOid);
2743
2744         /* Copy tuple so we can modify it below */
2745         extTup = heap_copytuple(extTup);
2746         extForm = (Form_pg_extension) GETSTRUCT(extTup);
2747
2748         systable_endscan(extScan);
2749
2750         /*
2751          * If the extension is already in the target schema, just silently do
2752          * nothing.
2753          */
2754         if (extForm->extnamespace == nspOid)
2755         {
2756                 heap_close(extRel, RowExclusiveLock);
2757                 return InvalidObjectAddress;
2758         }
2759
2760         /* Check extension is supposed to be relocatable */
2761         if (!extForm->extrelocatable)
2762                 ereport(ERROR,
2763                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2764                                  errmsg("extension \"%s\" does not support SET SCHEMA",
2765                                                 NameStr(extForm->extname))));
2766
2767         objsMoved = new_object_addresses();
2768
2769         /*
2770          * Scan pg_depend to find objects that depend directly on the extension,
2771          * and alter each one's schema.
2772          */
2773         depRel = heap_open(DependRelationId, AccessShareLock);
2774
2775         ScanKeyInit(&key[0],
2776                                 Anum_pg_depend_refclassid,
2777                                 BTEqualStrategyNumber, F_OIDEQ,
2778                                 ObjectIdGetDatum(ExtensionRelationId));
2779         ScanKeyInit(&key[1],
2780                                 Anum_pg_depend_refobjid,
2781                                 BTEqualStrategyNumber, F_OIDEQ,
2782                                 ObjectIdGetDatum(extensionOid));
2783
2784         depScan = systable_beginscan(depRel, DependReferenceIndexId, true,
2785                                                                  NULL, 2, key);
2786
2787         while (HeapTupleIsValid(depTup = systable_getnext(depScan)))
2788         {
2789                 Form_pg_depend pg_depend = (Form_pg_depend) GETSTRUCT(depTup);
2790                 ObjectAddress dep;
2791                 Oid                     dep_oldNspOid;
2792
2793                 /*
2794                  * Ignore non-membership dependencies.  (Currently, the only other
2795                  * case we could see here is a normal dependency from another
2796                  * extension.)
2797                  */
2798                 if (pg_depend->deptype != DEPENDENCY_EXTENSION)
2799                         continue;
2800
2801                 dep.classId = pg_depend->classid;
2802                 dep.objectId = pg_depend->objid;
2803                 dep.objectSubId = pg_depend->objsubid;
2804
2805                 if (dep.objectSubId != 0)               /* should not happen */
2806                         elog(ERROR, "extension should not have a sub-object dependency");
2807
2808                 /* Relocate the object */
2809                 dep_oldNspOid = AlterObjectNamespace_oid(dep.classId,
2810                                                                                                  dep.objectId,
2811                                                                                                  nspOid,
2812                                                                                                  objsMoved);
2813
2814                 /*
2815                  * Remember previous namespace of first object that has one
2816                  */
2817                 if (oldNspOid == InvalidOid && dep_oldNspOid != InvalidOid)
2818                         oldNspOid = dep_oldNspOid;
2819
2820                 /*
2821                  * If not all the objects had the same old namespace (ignoring any
2822                  * that are not in namespaces), complain.
2823                  */
2824                 if (dep_oldNspOid != InvalidOid && dep_oldNspOid != oldNspOid)
2825                         ereport(ERROR,
2826                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2827                                          errmsg("extension \"%s\" does not support SET SCHEMA",
2828                                                         NameStr(extForm->extname)),
2829                                          errdetail("%s is not in the extension's schema \"%s\"",
2830                                                            getObjectDescription(&dep),
2831                                                            get_namespace_name(oldNspOid))));
2832         }
2833
2834         /* report old schema, if caller wants it */
2835         if (oldschema)
2836                 *oldschema = oldNspOid;
2837
2838         systable_endscan(depScan);
2839
2840         relation_close(depRel, AccessShareLock);
2841
2842         /* Now adjust pg_extension.extnamespace */
2843         extForm->extnamespace = nspOid;
2844
2845         simple_heap_update(extRel, &extTup->t_self, extTup);
2846         CatalogUpdateIndexes(extRel, extTup);
2847
2848         heap_close(extRel, RowExclusiveLock);
2849
2850         /* update dependencies to point to the new schema */
2851         changeDependencyFor(ExtensionRelationId, extensionOid,
2852                                                 NamespaceRelationId, oldNspOid, nspOid);
2853
2854         InvokeObjectPostAlterHook(ExtensionRelationId, extensionOid, 0);
2855
2856         ObjectAddressSet(extAddr, ExtensionRelationId, extensionOid);
2857
2858         return extAddr;
2859 }
2860
2861 /*
2862  * Execute ALTER EXTENSION UPDATE
2863  */
2864 ObjectAddress
2865 ExecAlterExtensionStmt(ParseState *pstate, AlterExtensionStmt *stmt)
2866 {
2867         DefElem    *d_new_version = NULL;
2868         char       *versionName;
2869         char       *oldVersionName;
2870         ExtensionControlFile *control;
2871         Oid                     extensionOid;
2872         Relation        extRel;
2873         ScanKeyData key[1];
2874         SysScanDesc extScan;
2875         HeapTuple       extTup;
2876         List       *updateVersions;
2877         Datum           datum;
2878         bool            isnull;
2879         ListCell   *lc;
2880         ObjectAddress address;
2881
2882         /*
2883          * We use global variables to track the extension being created, so we can
2884          * create/update only one extension at the same time.
2885          */
2886         if (creating_extension)
2887                 ereport(ERROR,
2888                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2889                                  errmsg("nested ALTER EXTENSION is not supported")));
2890
2891         /*
2892          * Look up the extension --- it must already exist in pg_extension
2893          */
2894         extRel = heap_open(ExtensionRelationId, AccessShareLock);
2895
2896         ScanKeyInit(&key[0],
2897                                 Anum_pg_extension_extname,
2898                                 BTEqualStrategyNumber, F_NAMEEQ,
2899                                 CStringGetDatum(stmt->extname));
2900
2901         extScan = systable_beginscan(extRel, ExtensionNameIndexId, true,
2902                                                                  NULL, 1, key);
2903
2904         extTup = systable_getnext(extScan);
2905
2906         if (!HeapTupleIsValid(extTup))
2907                 ereport(ERROR,
2908                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
2909                                  errmsg("extension \"%s\" does not exist",
2910                                                 stmt->extname)));
2911
2912         extensionOid = HeapTupleGetOid(extTup);
2913
2914         /*
2915          * Determine the existing version we are updating from
2916          */
2917         datum = heap_getattr(extTup, Anum_pg_extension_extversion,
2918                                                  RelationGetDescr(extRel), &isnull);
2919         if (isnull)
2920                 elog(ERROR, "extversion is null");
2921         oldVersionName = text_to_cstring(DatumGetTextPP(datum));
2922
2923         systable_endscan(extScan);
2924
2925         heap_close(extRel, AccessShareLock);
2926
2927         /* Permission check: must own extension */
2928         if (!pg_extension_ownercheck(extensionOid, GetUserId()))
2929                 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_EXTENSION,
2930                                            stmt->extname);
2931
2932         /*
2933          * Read the primary control file.  Note we assume that it does not contain
2934          * any non-ASCII data, so there is no need to worry about encoding at this
2935          * point.
2936          */
2937         control = read_extension_control_file(stmt->extname);
2938
2939         /*
2940          * Read the statement option list
2941          */
2942         foreach(lc, stmt->options)
2943         {
2944                 DefElem    *defel = (DefElem *) lfirst(lc);
2945
2946                 if (strcmp(defel->defname, "new_version") == 0)
2947                 {
2948                         if (d_new_version)
2949                                 ereport(ERROR,
2950                                                 (errcode(ERRCODE_SYNTAX_ERROR),
2951                                                  errmsg("conflicting or redundant options"),
2952                                                  parser_errposition(pstate, defel->location)));
2953                         d_new_version = defel;
2954                 }
2955                 else
2956                         elog(ERROR, "unrecognized option: %s", defel->defname);
2957         }
2958
2959         /*
2960          * Determine the version to update to
2961          */
2962         if (d_new_version && d_new_version->arg)
2963                 versionName = strVal(d_new_version->arg);
2964         else if (control->default_version)
2965                 versionName = control->default_version;
2966         else
2967         {
2968                 ereport(ERROR,
2969                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2970                                  errmsg("version to install must be specified")));
2971                 versionName = NULL;             /* keep compiler quiet */
2972         }
2973         check_valid_version_name(versionName);
2974
2975         /*
2976          * If we're already at that version, just say so
2977          */
2978         if (strcmp(oldVersionName, versionName) == 0)
2979         {
2980                 ereport(NOTICE,
2981                    (errmsg("version \"%s\" of extension \"%s\" is already installed",
2982                                    versionName, stmt->extname)));
2983                 return InvalidObjectAddress;
2984         }
2985
2986         /*
2987          * Identify the series of update script files we need to execute
2988          */
2989         updateVersions = identify_update_path(control,
2990                                                                                   oldVersionName,
2991                                                                                   versionName);
2992
2993         /*
2994          * Update the pg_extension row and execute the update scripts, one at a
2995          * time
2996          */
2997         ApplyExtensionUpdates(extensionOid, control,
2998                                                   oldVersionName, updateVersions,
2999                                                   NULL, false, false);
3000
3001         ObjectAddressSet(address, ExtensionRelationId, extensionOid);
3002
3003         return address;
3004 }
3005
3006 /*
3007  * Apply a series of update scripts as though individual ALTER EXTENSION
3008  * UPDATE commands had been given, including altering the pg_extension row
3009  * and dependencies each time.
3010  *
3011  * This might be more work than necessary, but it ensures that old update
3012  * scripts don't break if newer versions have different control parameters.
3013  */
3014 static void
3015 ApplyExtensionUpdates(Oid extensionOid,
3016                                           ExtensionControlFile *pcontrol,
3017                                           const char *initialVersion,
3018                                           List *updateVersions,
3019                                           char *origSchemaName,
3020                                           bool cascade,
3021                                           bool is_create)
3022 {
3023         const char *oldVersionName = initialVersion;
3024         ListCell   *lcv;
3025
3026         foreach(lcv, updateVersions)
3027         {
3028                 char       *versionName = (char *) lfirst(lcv);
3029                 ExtensionControlFile *control;
3030                 char       *schemaName;
3031                 Oid                     schemaOid;
3032                 List       *requiredExtensions;
3033                 List       *requiredSchemas;
3034                 Relation        extRel;
3035                 ScanKeyData key[1];
3036                 SysScanDesc extScan;
3037                 HeapTuple       extTup;
3038                 Form_pg_extension extForm;
3039                 Datum           values[Natts_pg_extension];
3040                 bool            nulls[Natts_pg_extension];
3041                 bool            repl[Natts_pg_extension];
3042                 ObjectAddress myself;
3043                 ListCell   *lc;
3044
3045                 /*
3046                  * Fetch parameters for specific version (pcontrol is not changed)
3047                  */
3048                 control = read_extension_aux_control_file(pcontrol, versionName);
3049
3050                 /* Find the pg_extension tuple */
3051                 extRel = heap_open(ExtensionRelationId, RowExclusiveLock);
3052
3053                 ScanKeyInit(&key[0],
3054                                         ObjectIdAttributeNumber,
3055                                         BTEqualStrategyNumber, F_OIDEQ,
3056                                         ObjectIdGetDatum(extensionOid));
3057
3058                 extScan = systable_beginscan(extRel, ExtensionOidIndexId, true,
3059                                                                          NULL, 1, key);
3060
3061                 extTup = systable_getnext(extScan);
3062
3063                 if (!HeapTupleIsValid(extTup))  /* should not happen */
3064                         elog(ERROR, "extension with oid %u does not exist",
3065                                  extensionOid);
3066
3067                 extForm = (Form_pg_extension) GETSTRUCT(extTup);
3068
3069                 /*
3070                  * Determine the target schema (set by original install)
3071                  */
3072                 schemaOid = extForm->extnamespace;
3073                 schemaName = get_namespace_name(schemaOid);
3074
3075                 /*
3076                  * Modify extrelocatable and extversion in the pg_extension tuple
3077                  */
3078                 memset(values, 0, sizeof(values));
3079                 memset(nulls, 0, sizeof(nulls));
3080                 memset(repl, 0, sizeof(repl));
3081
3082                 values[Anum_pg_extension_extrelocatable - 1] =
3083                         BoolGetDatum(control->relocatable);
3084                 repl[Anum_pg_extension_extrelocatable - 1] = true;
3085                 values[Anum_pg_extension_extversion - 1] =
3086                         CStringGetTextDatum(versionName);
3087                 repl[Anum_pg_extension_extversion - 1] = true;
3088
3089                 extTup = heap_modify_tuple(extTup, RelationGetDescr(extRel),
3090                                                                    values, nulls, repl);
3091
3092                 simple_heap_update(extRel, &extTup->t_self, extTup);
3093                 CatalogUpdateIndexes(extRel, extTup);
3094
3095                 systable_endscan(extScan);
3096
3097                 heap_close(extRel, RowExclusiveLock);
3098
3099                 /*
3100                  * Look up the prerequisite extensions for this version, install them
3101                  * if necessary, and build lists of their OIDs and the OIDs of their
3102                  * target schemas.
3103                  */
3104                 requiredExtensions = NIL;
3105                 requiredSchemas = NIL;
3106                 foreach(lc, control->requires)
3107                 {
3108                         char       *curreq = (char *) lfirst(lc);
3109                         Oid                     reqext;
3110                         Oid                     reqschema;
3111
3112                         reqext = get_required_extension(curreq,
3113                                                                                         control->name,
3114                                                                                         origSchemaName,
3115                                                                                         cascade,
3116                                                                                         NIL,
3117                                                                                         is_create);
3118                         reqschema = get_extension_schema(reqext);
3119                         requiredExtensions = lappend_oid(requiredExtensions, reqext);
3120                         requiredSchemas = lappend_oid(requiredSchemas, reqschema);
3121                 }
3122
3123                 /*
3124                  * Remove and recreate dependencies on prerequisite extensions
3125                  */
3126                 deleteDependencyRecordsForClass(ExtensionRelationId, extensionOid,
3127                                                                                 ExtensionRelationId,
3128                                                                                 DEPENDENCY_NORMAL);
3129
3130                 myself.classId = ExtensionRelationId;
3131                 myself.objectId = extensionOid;
3132                 myself.objectSubId = 0;
3133
3134                 foreach(lc, requiredExtensions)
3135                 {
3136                         Oid                     reqext = lfirst_oid(lc);
3137                         ObjectAddress otherext;
3138
3139                         otherext.classId = ExtensionRelationId;
3140                         otherext.objectId = reqext;
3141                         otherext.objectSubId = 0;
3142
3143                         recordDependencyOn(&myself, &otherext, DEPENDENCY_NORMAL);
3144                 }
3145
3146                 InvokeObjectPostAlterHook(ExtensionRelationId, extensionOid, 0);
3147
3148                 /*
3149                  * Finally, execute the update script file
3150                  */
3151                 execute_extension_script(extensionOid, control,
3152                                                                  oldVersionName, versionName,
3153                                                                  requiredSchemas,
3154                                                                  schemaName, schemaOid);
3155
3156                 /*
3157                  * Update prior-version name and loop around.  Since
3158                  * execute_sql_string did a final CommandCounterIncrement, we can
3159                  * update the pg_extension row again.
3160                  */
3161                 oldVersionName = versionName;
3162         }
3163 }
3164
3165 /*
3166  * Execute ALTER EXTENSION ADD/DROP
3167  *
3168  * Return value is the address of the altered extension.
3169  *
3170  * objAddr is an output argument which, if not NULL, is set to the address of
3171  * the added/dropped object.
3172  */
3173 ObjectAddress
3174 ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt,
3175                                                            ObjectAddress *objAddr)
3176 {
3177         ObjectAddress extension;
3178         ObjectAddress object;
3179         Relation        relation;
3180         Oid                     oldExtension;
3181
3182         extension.classId = ExtensionRelationId;
3183         extension.objectId = get_extension_oid(stmt->extname, false);
3184         extension.objectSubId = 0;
3185
3186         /* Permission check: must own extension */
3187         if (!pg_extension_ownercheck(extension.objectId, GetUserId()))
3188                 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_EXTENSION,
3189                                            stmt->extname);
3190
3191         /*
3192          * Translate the parser representation that identifies the object into an
3193          * ObjectAddress.  get_object_address() will throw an error if the object
3194          * does not exist, and will also acquire a lock on the object to guard
3195          * against concurrent DROP and ALTER EXTENSION ADD/DROP operations.
3196          */
3197         object = get_object_address(stmt->objtype, stmt->objname, stmt->objargs,
3198                                                                 &relation, ShareUpdateExclusiveLock, false);
3199
3200         Assert(object.objectSubId == 0);
3201         if (objAddr)
3202                 *objAddr = object;
3203
3204         /* Permission check: must own target object, too */
3205         check_object_ownership(GetUserId(), stmt->objtype, object,
3206                                                    stmt->objname, stmt->objargs, relation);
3207
3208         /*
3209          * Check existing extension membership.
3210          */
3211         oldExtension = getExtensionOfObject(object.classId, object.objectId);
3212
3213         if (stmt->action > 0)
3214         {
3215                 /*
3216                  * ADD, so complain if object is already attached to some extension.
3217                  */
3218                 if (OidIsValid(oldExtension))
3219                         ereport(ERROR,
3220                                         (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3221                                          errmsg("%s is already a member of extension \"%s\"",
3222                                                         getObjectDescription(&object),
3223                                                         get_extension_name(oldExtension))));
3224
3225                 /*
3226                  * Prevent a schema from being added to an extension if the schema
3227                  * contains the extension.  That would create a dependency loop.
3228                  */
3229                 if (object.classId == NamespaceRelationId &&
3230                         object.objectId == get_extension_schema(extension.objectId))
3231                         ereport(ERROR,
3232                                         (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3233                                          errmsg("cannot add schema \"%s\" to extension \"%s\" "
3234                                                         "because the schema contains the extension",
3235                                                         get_namespace_name(object.objectId),
3236                                                         stmt->extname)));
3237
3238                 /*
3239                  * OK, add the dependency.
3240                  */
3241                 recordDependencyOn(&object, &extension, DEPENDENCY_EXTENSION);
3242         }
3243         else
3244         {
3245                 /*
3246                  * DROP, so complain if it's not a member.
3247                  */
3248                 if (oldExtension != extension.objectId)
3249                         ereport(ERROR,
3250                                         (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3251                                          errmsg("%s is not a member of extension \"%s\"",
3252                                                         getObjectDescription(&object),
3253                                                         stmt->extname)));
3254
3255                 /*
3256                  * OK, drop the dependency.
3257                  */
3258                 if (deleteDependencyRecordsForClass(object.classId, object.objectId,
3259                                                                                         ExtensionRelationId,
3260                                                                                         DEPENDENCY_EXTENSION) != 1)
3261                         elog(ERROR, "unexpected number of extension dependency records");
3262
3263                 /*
3264                  * If it's a relation, it might have an entry in the extension's
3265                  * extconfig array, which we must remove.
3266                  */
3267                 if (object.classId == RelationRelationId)
3268                         extension_config_remove(extension.objectId, object.objectId);
3269         }
3270
3271         InvokeObjectPostAlterHook(ExtensionRelationId, extension.objectId, 0);
3272
3273         /*
3274          * If get_object_address() opened the relation for us, we close it to keep
3275          * the reference count correct - but we retain any locks acquired by
3276          * get_object_address() until commit time, to guard against concurrent
3277          * activity.
3278          */
3279         if (relation != NULL)
3280                 relation_close(relation, NoLock);
3281
3282         return extension;
3283 }
3284
3285 /*
3286  * Read the whole of file into memory.
3287  *
3288  * The file contents are returned as a single palloc'd chunk. For convenience
3289  * of the callers, an extra \0 byte is added to the end.
3290  */
3291 static char *
3292 read_whole_file(const char *filename, int *length)
3293 {
3294         char       *buf;
3295         FILE       *file;
3296         size_t          bytes_to_read;
3297         struct stat fst;
3298
3299         if (stat(filename, &fst) < 0)
3300                 ereport(ERROR,
3301                                 (errcode_for_file_access(),
3302                                  errmsg("could not stat file \"%s\": %m", filename)));
3303
3304         if (fst.st_size > (MaxAllocSize - 1))
3305                 ereport(ERROR,
3306                                 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3307                                  errmsg("file \"%s\" is too large", filename)));
3308         bytes_to_read = (size_t) fst.st_size;
3309
3310         if ((file = AllocateFile(filename, PG_BINARY_R)) == NULL)
3311                 ereport(ERROR,
3312                                 (errcode_for_file_access(),
3313                                  errmsg("could not open file \"%s\" for reading: %m",
3314                                                 filename)));
3315
3316         buf = (char *) palloc(bytes_to_read + 1);
3317
3318         *length = fread(buf, 1, bytes_to_read, file);
3319
3320         if (ferror(file))
3321                 ereport(ERROR,
3322                                 (errcode_for_file_access(),
3323                                  errmsg("could not read file \"%s\": %m", filename)));
3324
3325         FreeFile(file);
3326
3327         buf[*length] = '\0';
3328         return buf;
3329 }