63 #include "utils/fmgroids.h"
126 bool reject_indirect,
130 char *origSchemaName,
140 const char *initialVersion,
141 List *updateVersions,
142 char *origSchemaName,
167 (
errcode(ERRCODE_UNDEFINED_OBJECT),
168 errmsg(
"extension \"%s\" does not exist",
224 int namelen = strlen(extensionname);
232 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
233 errmsg(
"invalid extension name: \"%s\"", extensionname),
234 errdetail(
"Extension names must not be empty.")));
239 if (strstr(extensionname,
"--"))
241 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
242 errmsg(
"invalid extension name: \"%s\"", extensionname),
243 errdetail(
"Extension names must not contain \"--\".")));
251 if (extensionname[0] ==
'-' || extensionname[namelen - 1] ==
'-')
253 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
254 errmsg(
"invalid extension name: \"%s\"", extensionname),
255 errdetail(
"Extension names must not begin or end with \"-\".")));
263 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
264 errmsg(
"invalid extension name: \"%s\"", extensionname),
265 errdetail(
"Extension names must not contain directory separator characters.")));
271 int namelen = strlen(versionname);
279 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
280 errmsg(
"invalid extension version name: \"%s\"", versionname),
281 errdetail(
"Version names must not be empty.")));
286 if (strstr(versionname,
"--"))
288 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
289 errmsg(
"invalid extension version name: \"%s\"", versionname),
290 errdetail(
"Version names must not contain \"--\".")));
295 if (versionname[0] ==
'-' || versionname[namelen - 1] ==
'-')
297 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
298 errmsg(
"invalid extension version name: \"%s\"", versionname),
299 errdetail(
"Version names must not begin or end with \"-\".")));
307 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
308 errmsg(
"invalid extension version name: \"%s\"", versionname),
309 errdetail(
"Version names must not contain directory separator characters.")));
318 const char *extension = strrchr(
filename,
'.');
320 return (extension != NULL) && (strcmp(extension,
".control") == 0);
326 const char *extension = strrchr(
filename,
'.');
328 return (extension != NULL) && (strcmp(extension,
".sql") == 0);
392 scriptdir, control->
name, version);
401 const char *from_version,
const char *version)
411 scriptdir, control->
name, from_version, version);
414 scriptdir, control->
name, version);
462 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
463 errmsg(
"extension \"%s\" is not available", control->
name),
464 errdetail(
"Could not open extension control file \"%s\": %m.",
466 errhint(
"The extension must first be installed on the system where PostgreSQL is running.")));
470 errmsg(
"could not open extension control file \"%s\": %m",
486 for (item = head; item != NULL; item = item->
next)
488 if (strcmp(item->
name,
"directory") == 0)
492 (
errcode(ERRCODE_SYNTAX_ERROR),
493 errmsg(
"parameter \"%s\" cannot be set in a secondary extension control file",
498 else if (strcmp(item->
name,
"default_version") == 0)
502 (
errcode(ERRCODE_SYNTAX_ERROR),
503 errmsg(
"parameter \"%s\" cannot be set in a secondary extension control file",
508 else if (strcmp(item->
name,
"module_pathname") == 0)
512 else if (strcmp(item->
name,
"comment") == 0)
516 else if (strcmp(item->
name,
"schema") == 0)
520 else if (strcmp(item->
name,
"relocatable") == 0)
524 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
525 errmsg(
"parameter \"%s\" requires a Boolean value",
528 else if (strcmp(item->
name,
"superuser") == 0)
532 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
533 errmsg(
"parameter \"%s\" requires a Boolean value",
536 else if (strcmp(item->
name,
"trusted") == 0)
540 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
541 errmsg(
"parameter \"%s\" requires a Boolean value",
544 else if (strcmp(item->
name,
"encoding") == 0)
549 (
errcode(ERRCODE_UNDEFINED_OBJECT),
550 errmsg(
"\"%s\" is not a valid encoding name",
553 else if (strcmp(item->
name,
"requires") == 0)
563 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
564 errmsg(
"parameter \"%s\" must be a list of extension names",
568 else if (strcmp(item->
name,
"no_relocate") == 0)
578 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
579 errmsg(
"parameter \"%s\" must be a list of extension names",
585 (
errcode(ERRCODE_SYNTAX_ERROR),
586 errmsg(
"unrecognized parameter \"%s\" in file \"%s\"",
594 (
errcode(ERRCODE_SYNTAX_ERROR),
595 errmsg(
"parameter \"schema\" cannot be specified when \"relocatable\" is true")));
692 const char *query = callback_arg->
sql;
695 int syntaxerrposition;
696 const char *lastslash;
708 if (syntaxerrposition > 0)
717 if (location < 0 || syntaxerrposition < location ||
718 (
len > 0 && syntaxerrposition > location +
len))
732 int slen = strlen(query);
735 for (
int loc = 0; loc < slen; loc++)
737 if (query[loc] !=
';')
739 if (query[loc + 1] ==
'\r')
741 if (query[loc + 1] ==
'\n')
745 if (bkpt < syntaxerrposition)
747 else if (bkpt > syntaxerrposition)
749 len = bkpt - location;
763 syntaxerrposition -= location;
764 if (syntaxerrposition < 0)
765 syntaxerrposition = 0;
766 else if (syntaxerrposition >
len)
767 syntaxerrposition =
len;
774 else if (location >= 0)
789 lastslash = strrchr(callback_arg->
filename,
'/');
803 for (query = callback_arg->
sql; *query; query++)
810 errcontext(
"extension script file \"%s\", near line %d",
811 lastslash, linenumber);
814 errcontext(
"extension script file \"%s\"", lastslash);
835 List *raw_parsetree_list;
842 callback_arg.
sql = sql;
848 scripterrcontext.
arg = (
void *) &callback_arg;
865 foreach(lc1, raw_parsetree_list)
881 per_parsetree_context =
883 "execute_sql_string per-statement context",
897 foreach(lc2, stmt_list)
905 if (
stmt->utilityStmt == NULL)
912 dest, NULL, NULL, 0);
925 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
926 errmsg(
"transaction control statements are not allowed within an extension script")));
982 const char *from_version,
984 List *requiredSchemas,
985 const char *schemaName,
Oid schemaOid)
987 bool switch_to_superuser =
false;
990 int save_sec_context = 0;
1004 switch_to_superuser =
true;
1005 else if (from_version == NULL)
1007 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1008 errmsg(
"permission denied to create extension \"%s\"",
1011 ?
errhint(
"Must have CREATE privilege on current database to create this extension.")
1012 :
errhint(
"Must be superuser to create this extension.")));
1015 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1016 errmsg(
"permission denied to update extension \"%s\"",
1019 ?
errhint(
"Must have CREATE privilege on current database to update this extension.")
1020 :
errhint(
"Must be superuser to update this extension.")));
1025 if (from_version == NULL)
1026 elog(
DEBUG1,
"executing extension script for \"%s\" version '%s'", control->
name, version);
1028 elog(
DEBUG1,
"executing extension script for \"%s\" update from version '%s' to '%s'", control->
name, from_version, version);
1035 if (switch_to_superuser)
1063 BOOTSTRAP_SUPERUSERID,
1085 foreach(lc, requiredSchemas)
1090 if (reqname && strcmp(reqname,
"pg_catalog") != 0)
1119 const char *quoting_relevant_chars =
"\"$'\\";
1139 if (strstr(c_sql,
"@extowner@"))
1141 Oid uid = switch_to_superuser ? save_userid :
GetUserId();
1150 if (strpbrk(userName, quoting_relevant_chars))
1152 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1153 errmsg(
"invalid character in extension owner: must not contain any of \"%s\"",
1154 quoting_relevant_chars)));
1174 if (t_sql != old && strpbrk(schemaName, quoting_relevant_chars))
1176 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1177 errmsg(
"invalid character in extension \"%s\" schema: must not contain any of \"%s\"",
1178 control->
name, quoting_relevant_chars)));
1189 char *reqextname = (
char *)
lfirst(lc);
1195 repltoken =
psprintf(
"@extschema:%s@", reqextname);
1201 if (t_sql != old && strpbrk(schemaName, quoting_relevant_chars))
1203 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1204 errmsg(
"invalid character in extension \"%s\" schema: must not contain any of \"%s\"",
1205 reqextname, quoting_relevant_chars)));
1241 if (switch_to_superuser)
1259 foreach(lc, *evi_list)
1262 if (strcmp(evi->
name, versionname) == 0)
1275 *evi_list =
lappend(*evi_list, evi);
1292 foreach(lc, evi_list)
1318 int extnamelen = strlen(control->
name);
1325 while ((de =
ReadDir(dir, location)) != NULL)
1337 if (strncmp(de->
d_name, control->
name, extnamelen) != 0 ||
1338 de->
d_name[extnamelen] !=
'-' ||
1339 de->
d_name[extnamelen + 1] !=
'-')
1344 *strrchr(vername,
'.') =
'\0';
1345 vername2 = strstr(vername,
"--");
1357 if (strstr(vername2,
"--"))
1379 const char *oldVersion,
const char *newVersion)
1398 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1399 errmsg(
"extension \"%s\" has no update path from version \"%s\" to version \"%s\"",
1400 control->
name, oldVersion, newVersion)));
1424 bool reject_indirect,
1432 Assert(evi_start != evi_target);
1438 foreach(lc, evi_list)
1454 if (evi == evi_target)
1465 if (newdist < evi2->distance)
1470 else if (newdist == evi2->
distance &&
1493 for (evi = evi_target; evi != evi_start; evi = evi->
previous)
1530 foreach(lc, evi_list)
1547 if (evi_start == NULL ||
1550 strcmp(evi_start->
name, evi1->
name) < 0))
1571 const char *versionName,
1576 char *origSchemaName = schemaName;
1583 List *updateVersions;
1584 List *requiredExtensions;
1585 List *requiredSchemas;
1600 if (versionName == NULL)
1606 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1607 errmsg(
"version to install must be specified")));
1621 updateVersions =
NIL;
1641 if (evi_start == NULL)
1643 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1644 errmsg(
"extension \"%s\" has no installation script nor update path for version \"%s\"",
1645 pcontrol->
name, versionName)));
1648 versionName = evi_start->
name;
1665 if (control->
schema != NULL)
1674 if (schemaName && strcmp(control->
schema, schemaName) != 0 &&
1677 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1678 errmsg(
"extension \"%s\" must be installed in schema \"%s\"",
1683 schemaName = control->
schema;
1715 if (search_path ==
NIL)
1717 (
errcode(ERRCODE_UNDEFINED_SCHEMA),
1718 errmsg(
"no schema has been selected to create in")));
1721 if (schemaName == NULL)
1723 (
errcode(ERRCODE_UNDEFINED_SCHEMA),
1724 errmsg(
"no schema has been selected to create in")));
1749 requiredExtensions =
NIL;
1750 requiredSchemas =
NIL;
1753 char *curreq = (
char *)
lfirst(lc);
1764 requiredExtensions =
lappend_oid(requiredExtensions, reqext);
1765 requiredSchemas =
lappend_oid(requiredSchemas, reqschema);
1776 requiredExtensions);
1791 schemaName, schemaOid);
1798 versionName, updateVersions,
1799 origSchemaName, cascade, is_create);
1809 char *extensionName,
1810 char *origSchemaName,
1815 Oid reqExtensionOid;
1824 List *cascade_parents;
1831 foreach(lc, parents)
1833 char *pname = (
char *)
lfirst(lc);
1835 if (strcmp(pname, reqExtensionName) == 0)
1837 (
errcode(ERRCODE_INVALID_RECURSION),
1838 errmsg(
"cyclic dependency detected between extensions \"%s\" and \"%s\"",
1839 reqExtensionName, extensionName)));
1843 (
errmsg(
"installing required extension \"%s\"",
1844 reqExtensionName)));
1865 (
errcode(ERRCODE_UNDEFINED_OBJECT),
1866 errmsg(
"required extension \"%s\" is not installed",
1869 errhint(
"Use CREATE EXTENSION ... CASCADE to install required extensions too.") : 0));
1872 return reqExtensionOid;
1882 DefElem *d_new_version = NULL;
1884 char *schemaName = NULL;
1885 char *versionName = NULL;
1886 bool cascade =
false;
1900 if (
stmt->if_not_exists)
1904 errmsg(
"extension \"%s\" already exists, skipping",
1911 errmsg(
"extension \"%s\" already exists",
1921 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1922 errmsg(
"nested CREATE EXTENSION is not supported")));
1925 foreach(lc,
stmt->options)
1929 if (strcmp(defel->
defname,
"schema") == 0)
1936 else if (strcmp(defel->
defname,
"new_version") == 0)
1940 d_new_version = defel;
1943 else if (strcmp(defel->
defname,
"cascade") == 0)
1978 Oid schemaOid,
bool relocatable,
const char *extVersion,
1980 List *requiredExtensions)
1985 bool nulls[Natts_pg_extension];
1998 memset(nulls, 0,
sizeof(nulls));
2001 Anum_pg_extension_oid);
2003 values[Anum_pg_extension_extname - 1] =
2011 nulls[Anum_pg_extension_extconfig - 1] =
true;
2013 values[Anum_pg_extension_extconfig - 1] = extConfig;
2016 nulls[Anum_pg_extension_extcondition - 1] =
true;
2018 values[Anum_pg_extension_extcondition - 1] = extCondition;
2039 foreach(lc, requiredExtensions)
2085 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
2086 errmsg(
"cannot drop extension \"%s\" because it is being modified",
2092 Anum_pg_extension_oid,
2136 if (dir == NULL && errno == ENOENT)
2142 while ((de =
ReadDir(dir, location)) != NULL)
2153 extname =
pstrdup(de->d_name);
2154 *strrchr(extname,
'.') =
'\0';
2157 if (strstr(extname,
"--"))
2163 memset(nulls, 0,
sizeof(nulls));
2216 if (dir == NULL && errno == ENOENT)
2222 while ((de =
ReadDir(dir, location)) != NULL)
2231 extname =
pstrdup(de->d_name);
2232 *strrchr(extname,
'.') =
'\0';
2235 if (strstr(extname,
"--"))
2268 foreach(lc, evi_list)
2285 memset(nulls, 0,
sizeof(nulls));
2299 if (control->
schema == NULL)
2322 foreach(lc2, evi_list)
2373 bool result =
false;
2385 if (dir == NULL && errno == ENOENT)
2391 while ((de =
ReadDir(dir, location)) != NULL)
2400 *strrchr(extname,
'.') =
'\0';
2403 if (strstr(extname,
"--"))
2407 if (strcmp(extname, extensionName) == 0)
2434 foreach(lc, requires)
2436 char *curreq = (
char *)
lfirst(lc);
2471 foreach(lc1, evi_list)
2476 foreach(lc2, evi_list)
2491 memset(nulls, 0,
sizeof(nulls));
2510 char *versionName = (
char *)
lfirst(lcv);
2549 Datum repl_val[Natts_pg_extension];
2550 bool repl_null[Natts_pg_extension];
2551 bool repl_repl[Natts_pg_extension];
2560 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2561 errmsg(
"%s can only be called from an SQL script executed by CREATE EXTENSION",
2562 "pg_extension_config_dump()")));
2570 if (tablename == NULL)
2573 errmsg(
"OID %u does not refer to a table", tableoid)));
2577 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
2578 errmsg(
"table \"%s\" is not a member of the extension being created",
2593 Anum_pg_extension_oid,
2603 elog(
ERROR,
"could not find tuple for extension %u",
2606 memset(repl_val, 0,
sizeof(repl_val));
2607 memset(repl_null,
false,
sizeof(repl_null));
2608 memset(repl_repl,
false,
sizeof(repl_repl));
2613 arrayDatum =
heap_getattr(extTup, Anum_pg_extension_extconfig,
2637 elog(
ERROR,
"extconfig is not a 1-D Oid array");
2640 arrayIndex = arrayLength + 1;
2642 for (
i = 0;
i < arrayLength;
i++)
2644 if (arrayData[
i] == tableoid)
2660 repl_repl[Anum_pg_extension_extconfig - 1] =
true;
2665 arrayDatum =
heap_getattr(extTup, Anum_pg_extension_extcondition,
2669 if (arrayLength != 0)
2670 elog(
ERROR,
"extconfig and extcondition arrays do not match");
2682 elog(
ERROR,
"extcondition is not a 1-D text array");
2684 elog(
ERROR,
"extconfig and extcondition arrays do not match");
2696 repl_repl[Anum_pg_extension_extcondition - 1] =
true;
2699 repl_val, repl_null, repl_repl);
2728 Datum repl_val[Natts_pg_extension];
2729 bool repl_null[Natts_pg_extension];
2730 bool repl_repl[Natts_pg_extension];
2737 Anum_pg_extension_oid,
2747 elog(
ERROR,
"could not find tuple for extension %u",
2751 arrayDatum =
heap_getattr(extTup, Anum_pg_extension_extconfig,
2773 elog(
ERROR,
"extconfig is not a 1-D Oid array");
2778 for (
i = 0;
i < arrayLength;
i++)
2780 if (arrayData[
i] == tableoid)
2797 memset(repl_val, 0,
sizeof(repl_val));
2798 memset(repl_null,
false,
sizeof(repl_null));
2799 memset(repl_repl,
false,
sizeof(repl_repl));
2801 if (arrayLength <= 1)
2804 repl_null[Anum_pg_extension_extconfig - 1] =
true;
2816 for (
i = arrayIndex;
i < arrayLength - 1;
i++)
2817 dvalues[
i] = dvalues[
i + 1];
2823 repl_repl[Anum_pg_extension_extconfig - 1] =
true;
2826 arrayDatum =
heap_getattr(extTup, Anum_pg_extension_extcondition,
2830 elog(
ERROR,
"extconfig and extcondition arrays do not match");
2840 elog(
ERROR,
"extcondition is not a 1-D text array");
2842 elog(
ERROR,
"extconfig and extcondition arrays do not match");
2845 if (arrayLength <= 1)
2848 repl_null[Anum_pg_extension_extcondition - 1] =
true;
2860 for (
i = arrayIndex;
i < arrayLength - 1;
i++)
2861 dvalues[
i] = dvalues[
i + 1];
2867 repl_repl[Anum_pg_extension_extcondition - 1] =
true;
2870 repl_val, repl_null, repl_repl);
2923 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
2924 errmsg(
"cannot move extension \"%s\" into schema \"%s\" "
2925 "because the extension contains the schema",
2926 extensionName, newschema)));
2932 Anum_pg_extension_oid,
2942 elog(
ERROR,
"could not find tuple for extension %u",
2955 if (extForm->extnamespace == nspOid)
2962 if (!extForm->extrelocatable)
2964 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2965 errmsg(
"extension \"%s\" does not support SET SCHEMA",
2971 oldNspOid = extForm->extnamespace;
2980 Anum_pg_depend_refclassid,
2984 Anum_pg_depend_refobjid,
3007 pg_depend->classid == ExtensionRelationId)
3016 char *nrextname = (
char *)
lfirst(lc);
3018 if (strcmp(nrextname,
NameStr(extForm->extname)) == 0)
3021 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3022 errmsg(
"cannot SET SCHEMA of extension \"%s\" because other extensions prevent it",
3024 errdetail(
"Extension \"%s\" requests no relocation of extension \"%s\".",
3039 dep.
classId = pg_depend->classid;
3044 elog(
ERROR,
"extension should not have a sub-object dependency");
3056 if (dep_oldNspOid !=
InvalidOid && dep_oldNspOid != oldNspOid)
3058 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3059 errmsg(
"extension \"%s\" does not support SET SCHEMA",
3061 errdetail(
"%s is not in the extension's schema \"%s\"",
3068 *oldschema = oldNspOid;
3075 extForm->extnamespace = nspOid;
3083 NamespaceRelationId, oldNspOid, nspOid) != 1)
3084 elog(
ERROR,
"could not change schema dependency for extension %s",
3100 DefElem *d_new_version = NULL;
3102 char *oldVersionName;
3109 List *updateVersions;
3121 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3122 errmsg(
"nested ALTER EXTENSION is not supported")));
3130 Anum_pg_extension_extname,
3141 (
errcode(ERRCODE_UNDEFINED_OBJECT),
3142 errmsg(
"extension \"%s\" does not exist",
3150 datum =
heap_getattr(extTup, Anum_pg_extension_extversion,
3175 foreach(lc,
stmt->options)
3179 if (strcmp(defel->
defname,
"new_version") == 0)
3183 d_new_version = defel;
3192 if (d_new_version && d_new_version->
arg)
3193 versionName =
strVal(d_new_version->
arg);
3199 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3200 errmsg(
"version to install must be specified")));
3208 if (strcmp(oldVersionName, versionName) == 0)
3211 (
errmsg(
"version \"%s\" of extension \"%s\" is already installed",
3212 versionName,
stmt->extname)));
3228 oldVersionName, updateVersions,
3229 NULL,
false,
false);
3247 const char *initialVersion,
3248 List *updateVersions,
3249 char *origSchemaName,
3253 const char *oldVersionName = initialVersion;
3256 foreach(lcv, updateVersions)
3258 char *versionName = (
char *)
lfirst(lcv);
3262 List *requiredExtensions;
3263 List *requiredSchemas;
3270 bool nulls[Natts_pg_extension];
3271 bool repl[Natts_pg_extension];
3284 Anum_pg_extension_oid,
3294 elog(
ERROR,
"could not find tuple for extension %u",
3302 schemaOid = extForm->extnamespace;
3309 memset(nulls, 0,
sizeof(nulls));
3310 memset(repl, 0,
sizeof(repl));
3312 values[Anum_pg_extension_extrelocatable - 1] =
3314 repl[Anum_pg_extension_extrelocatable - 1] =
true;
3315 values[Anum_pg_extension_extversion - 1] =
3317 repl[Anum_pg_extension_extversion - 1] =
true;
3333 requiredExtensions =
NIL;
3334 requiredSchemas =
NIL;
3337 char *curreq = (
char *)
lfirst(lc);
3348 requiredExtensions =
lappend_oid(requiredExtensions, reqext);
3349 requiredSchemas =
lappend_oid(requiredSchemas, reqschema);
3356 ExtensionRelationId,
3359 myself.
classId = ExtensionRelationId;
3363 foreach(lc, requiredExtensions)
3368 otherext.
classId = ExtensionRelationId;
3381 oldVersionName, versionName,
3383 schemaName, schemaOid);
3390 oldVersionName = versionName;
3410 switch (
stmt->objtype)
3421 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
3422 errmsg(
"cannot add an object of this type to an extension")));
3455 Assert(
object.objectSubId == 0);
3461 stmt->object, relation);
3475 if (relation != NULL)
3500 if (
stmt->action > 0)
3507 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3508 errmsg(
"%s is already a member of extension \"%s\"",
3516 if (
object.classId == NamespaceRelationId &&
3519 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3520 errmsg(
"cannot add schema \"%s\" to extension \"%s\" "
3521 "because the schema contains the extension",
3545 if (oldExtension != extension.
objectId)
3547 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3548 errmsg(
"%s is not a member of extension \"%s\"",
3556 ExtensionRelationId,
3558 elog(
ERROR,
"unexpected number of extension dependency records");
3564 if (
object.classId == RelationRelationId)
3583 if (
object.classId == TypeRelationId)
3587 depobject.
classId = TypeRelationId;
3601 (
errcode(ERRCODE_UNDEFINED_OBJECT),
3602 errmsg(
"could not find multirange type for data type %s",
3607 if (
object.classId == RelationRelationId)
3611 depobject.
classId = TypeRelationId;
3633 size_t bytes_to_read;
3643 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3645 bytes_to_read = (size_t) fst.
st_size;
3650 errmsg(
"could not open file \"%s\" for reading: %m",
3653 buf = (
char *)
palloc(bytes_to_read + 1);
3655 bytes_to_read = fread(
buf, 1, bytes_to_read, file);
3664 buf[bytes_to_read] =
'\0';
3679 for (s = d =
buf; *s; s++)
3681 if (!(*s ==
'\r' && s[1] ==
'\n'))
3685 bytes_to_read = d -
buf;
3689 *length = bytes_to_read;
void recordExtObjInitPriv(Oid objoid, Oid classoid)
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
void removeExtObjInitPriv(Oid objoid, Oid classoid)
Oid AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid, ObjectAddresses *objsMoved)
#define DatumGetArrayTypeP(X)
ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
ArrayType * array_set(ArrayType *array, int nSubscripts, int *indx, Datum dataValue, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign)
void deconstruct_array_builtin(ArrayType *array, Oid elmtype, Datum **elemsp, bool **nullsp, int *nelemsp)
bool parse_bool(const char *value, bool *result)
static Datum values[MAXATTR]
#define CStringGetTextDatum(s)
#define Assert(condition)
#define OidIsValid(objectId)
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
#define CONF_FILE_START_DEPTH
bool defGetBoolean(DefElem *def)
char * defGetString(DefElem *def)
void errorConflictingDefElem(DefElem *defel, ParseState *pstate)
void record_object_address_dependencies(const ObjectAddress *depender, ObjectAddresses *referenced, DependencyType behavior)
ObjectAddresses * new_object_addresses(void)
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
void free_object_addresses(ObjectAddresses *addrs)
DestReceiver * CreateDestReceiver(CommandDest dest)
int internalerrquery(const char *query)
int internalerrposition(int cursorpos)
int errcode_for_file_access(void)
int errdetail(const char *fmt,...)
ErrorContextCallback * error_context_stack
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
int errposition(int cursorpos)
#define ereport(elevel,...)
void ExecutorEnd(QueryDesc *queryDesc)
void ExecutorFinish(QueryDesc *queryDesc)
void ExecutorStart(QueryDesc *queryDesc, int eflags)
void ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count, bool execute_once)
static ExtensionVersionInfo * get_ext_ver_info(const char *versionname, List **evi_list)
Oid get_extension_schema(Oid ext_oid)
static bool is_extension_script_filename(const char *filename)
static char * read_whole_file(const char *filename, int *length)
ObjectAddress InsertExtensionTuple(const char *extName, Oid extOwner, Oid schemaOid, bool relocatable, const char *extVersion, Datum extConfig, Datum extCondition, List *requiredExtensions)
static void check_valid_extension_name(const char *extensionname)
static char * read_extension_script_file(const ExtensionControlFile *control, const char *filename)
static List * identify_update_path(ExtensionControlFile *control, const char *oldVersion, const char *newVersion)
struct ExtensionVersionInfo ExtensionVersionInfo
ObjectAddress CreateExtension(ParseState *pstate, CreateExtensionStmt *stmt)
static void check_valid_version_name(const char *versionname)
static bool is_extension_control_filename(const char *filename)
static Oid get_required_extension(char *reqExtensionName, char *extensionName, char *origSchemaName, bool cascade, List *parents, bool is_create)
static void script_error_callback(void *arg)
static char * get_extension_script_filename(ExtensionControlFile *control, const char *from_version, const char *version)
static List * get_ext_ver_list(ExtensionControlFile *control)
static void execute_extension_script(Oid extensionOid, ExtensionControlFile *control, const char *from_version, const char *version, List *requiredSchemas, const char *schemaName, Oid schemaOid)
static void parse_extension_control_file(ExtensionControlFile *control, const char *version)
Datum pg_available_extension_versions(PG_FUNCTION_ARGS)
static void extension_config_remove(Oid extensionoid, Oid tableoid)
static void execute_sql_string(const char *sql, const char *filename)
static ExtensionVersionInfo * get_nearest_unprocessed_vertex(List *evi_list)
ObjectAddress AlterExtensionNamespace(const char *extensionName, const char *newschema, Oid *oldschema)
static char * get_extension_control_directory(void)
static char * get_extension_script_directory(ExtensionControlFile *control)
static ExtensionControlFile * read_extension_control_file(const char *extname)
ObjectAddress ExecAlterExtensionStmt(ParseState *pstate, AlterExtensionStmt *stmt)
Oid CurrentExtensionObject
ObjectAddress ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt, ObjectAddress *objAddr)
Datum pg_extension_update_paths(PG_FUNCTION_ARGS)
static void ExecAlterExtensionContentsRecurse(AlterExtensionContentsStmt *stmt, ObjectAddress extension, ObjectAddress object)
Oid get_extension_oid(const char *extname, bool missing_ok)
Datum pg_available_extensions(PG_FUNCTION_ARGS)
Datum pg_extension_config_dump(PG_FUNCTION_ARGS)
static ExtensionVersionInfo * find_install_path(List *evi_list, ExtensionVersionInfo *evi_target, List **best_path)
static Datum convert_requires_to_datum(List *requires)
static char * get_extension_control_filename(const char *extname)
static ExtensionControlFile * read_extension_aux_control_file(const ExtensionControlFile *pcontrol, const char *version)
struct ExtensionControlFile ExtensionControlFile
char * get_extension_name(Oid ext_oid)
void RemoveExtensionById(Oid extId)
static void get_available_versions_for_extension(ExtensionControlFile *pcontrol, Tuplestorestate *tupstore, TupleDesc tupdesc)
static List * find_update_path(List *evi_list, ExtensionVersionInfo *evi_start, ExtensionVersionInfo *evi_target, bool reject_indirect, bool reinitialize)
bool extension_file_exists(const char *extensionName)
static bool extension_is_trusted(ExtensionControlFile *control)
static void ApplyExtensionUpdates(Oid extensionOid, ExtensionControlFile *pcontrol, const char *initialVersion, List *updateVersions, char *origSchemaName, bool cascade, bool is_create)
static ObjectAddress CreateExtensionInternal(char *extensionName, char *schemaName, const char *versionName, bool cascade, List *parents, bool is_create)
static char * get_extension_aux_control_filename(ExtensionControlFile *control, const char *version)
struct dirent * ReadDir(DIR *dir, const char *dirname)
FILE * AllocateFile(const char *name, const char *mode)
DIR * AllocateDir(const char *dirname)
Datum DirectFunctionCall4Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4)
Datum DirectFunctionCall3Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2, Datum arg3)
#define PG_GETARG_TEXT_PP(n)
#define DatumGetTextPP(X)
#define DirectFunctionCall1(func, arg1)
#define PG_GETARG_NAME(n)
void InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags)
void systable_endscan(SysScanDesc sysscan)
HeapTuple systable_getnext(SysScanDesc sysscan)
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
char my_exec_path[MAXPGPATH]
int set_config_option_ext(const char *name, const char *value, GucContext context, GucSource source, Oid srole, GucAction action, bool changeVal, int elevel, bool is_reload)
int NewGUCNestLevel(void)
void AtEOXact_GUC(bool isCommit, int nestLevel)
int set_config_option(const char *name, const char *value, GucContext context, GucSource source, GucAction action, bool changeVal, int elevel, bool is_reload)
void FreeConfigVariables(ConfigVariable *list)
bool ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel, ConfigVariable **head_p, ConfigVariable **tail_p)
bool check_function_bodies
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
HeapTuple heap_copytuple(HeapTuple tuple)
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
void heap_freetuple(HeapTuple htup)
#define HeapTupleIsValid(tuple)
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
if(TABLE==NULL||TABLE_index==NULL)
List * lappend(List *list, void *datum)
List * lappend_oid(List *list, Oid datum)
List * list_copy(const List *oldlist)
void list_free(List *list)
List * lcons(void *datum, List *list)
#define ShareUpdateExclusiveLock
bool type_is_range(Oid typid)
char * get_namespace_name(Oid nspid)
Oid get_rel_type_id(Oid relid)
char * get_rel_name(Oid relid)
Oid get_range_multirange(Oid rangeOid)
Oid get_array_type(Oid typid)
char * pg_any_to_server(const char *s, int len, int encoding)
int GetDatabaseEncoding(void)
bool pg_verify_mbstr(int encoding, const char *mbstr, int len, bool noError)
char * pnstrdup(const char *in, Size len)
char * pstrdup(const char *in)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
void MemoryContextDelete(MemoryContext context)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define SECURITY_LOCAL_USERID_CHANGE
char * GetUserNameFromId(Oid roleid, bool noerr)
void GetUserIdAndSecContext(Oid *userid, int *sec_context)
void SetUserIdAndSecContext(Oid userid, int sec_context)
Datum namein(PG_FUNCTION_ARGS)
bool isTempNamespace(Oid namespaceId)
Oid LookupCreationNamespace(const char *nspname)
List * fetch_search_path(bool includeImplicit)
Oid get_namespace_oid(const char *nspname, bool missing_ok)
#define IsA(nodeptr, _type_)
#define InvokeObjectPostCreateHook(classId, objectId, subId)
#define InvokeObjectPostAlterHook(classId, objectId, subId)
char * getObjectDescription(const ObjectAddress *object, bool missing_ok)
void check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address, Node *object, Relation relation)
const ObjectAddress InvalidObjectAddress
ObjectAddress get_object_address(ObjectType objtype, Node *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
#define ObjectAddressSet(addr, class_id, object_id)
#define CURSOR_OPT_PARALLEL_OK
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
long changeDependencyFor(Oid classId, Oid objectId, Oid refClassId, Oid oldRefObjectId, Oid newRefObjectId)
long deleteDependencyRecordsForClass(Oid classId, Oid objectId, Oid refclassId, char deptype)
Oid getExtensionOfObject(Oid classId, Oid objectId)
FormData_pg_depend * Form_pg_depend
FormData_pg_extension * Form_pg_extension
#define lfirst_node(type, lc)
static int list_length(const List *l)
#define forboth(cell1, list1, cell2, list2)
void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)
#define pg_valid_server_encoding
#define ERRCODE_UNDEFINED_TABLE
void get_share_path(const char *my_exec_path, char *ret_path)
#define is_absolute_path(filename)
char * first_dir_separator(const char *filename)
List * pg_parse_query(const char *query_string)
List * pg_analyze_and_rewrite_fixedparams(RawStmt *parsetree, const char *query_string, const Oid *paramTypes, int numParams, QueryEnvironment *queryEnv)
List * pg_plan_queries(List *querytrees, const char *query_string, int cursorOptions, ParamListInfo boundParams)
static Datum PointerGetDatum(const void *X)
static Datum BoolGetDatum(bool X)
static Datum ObjectIdGetDatum(Oid X)
static Datum CStringGetDatum(const char *X)
void FreeQueryDesc(QueryDesc *qdesc)
QueryDesc * CreateQueryDesc(PlannedStmt *plannedstmt, const char *sourceText, Snapshot snapshot, Snapshot crosscheck_snapshot, DestReceiver *dest, ParamListInfo params, QueryEnvironment *queryEnv, int instrument_options)
char * psprintf(const char *fmt,...)
const char * CleanQuerytext(const char *query, int *location, int *len)
MemoryContextSwitchTo(old_ctx)
Datum textregexreplace(PG_FUNCTION_ARGS)
#define RelationGetDescr(relation)
const char * quote_identifier(const char *ident)
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Oid CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString, int stmt_location, int stmt_len)
Snapshot GetTransactionSnapshot(void)
void PushActiveSnapshot(Snapshot snapshot)
void PopActiveSnapshot(void)
Snapshot GetActiveSnapshot(void)
void relation_close(Relation relation, LOCKMODE lockmode)
#define BTEqualStrategyNumber
#define ERRCODE_DUPLICATE_OBJECT
void appendStringInfo(StringInfo str, const char *fmt,...)
void appendStringInfoString(StringInfo str, const char *s)
void initStringInfo(StringInfo str)
struct ConfigVariable * next
struct ErrorContextCallback * previous
void(* callback)(void *arg)
struct ExtensionVersionInfo * previous
Tuplestorestate * setResult
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
#define GetSysCacheOid1(cacheId, oidcol, key1)
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const bool *isnull)
void ProcessUtility(PlannedStmt *pstmt, const char *queryString, bool readOnlyTree, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletion *qc)
String * makeString(char *str)
char * text_to_cstring(const text *t)
bool SplitIdentifierString(char *rawstring, char separator, List **namelist)
Datum replace_text(PG_FUNCTION_ARGS)
void CommandCounterIncrement(void)
#define XACT_FLAGS_ACCESSEDTEMPNAMESPACE