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