From ef81b21a49000666b29eba26518089da4dd53b31 Mon Sep 17 00:00:00 2001 From: Jason Petersen Date: Tue, 4 Apr 2017 15:36:19 -0600 Subject: [PATCH] Clean up ErrorIfUnstableCreateOrAlterExtensionStmt Swaps an Assert in for an ereport, and adds details and hints to the error message to help users with a possibly confusing scenario. --- .../distributed/executor/multi_utility.c | 62 ++++++++++++------- src/test/regress/expected/multi_extension.out | 4 +- 2 files changed, 43 insertions(+), 23 deletions(-) diff --git a/src/backend/distributed/executor/multi_utility.c b/src/backend/distributed/executor/multi_utility.c index 51c02ad11..8986d6a11 100644 --- a/src/backend/distributed/executor/multi_utility.c +++ b/src/backend/distributed/executor/multi_utility.c @@ -135,6 +135,7 @@ static bool OptionsSpecifyOwnedBy(List *optionList, Oid *ownedByTableId); static void ErrorIfDistributedRenameStmt(RenameStmt *renameStatement); /* Local functions forward declarations for helper functions */ +static char * ExtractNewExtensionVersion(Node *parsetree); static void CreateLocalTable(RangeVar *relation, char *nodeName, int32 nodePort); static bool IsAlterTableRenameStmt(RenameStmt *renameStatement); static void ExecuteDistributedDDLJob(DDLJob *ddlJob); @@ -1341,23 +1342,53 @@ DeparseVacuumColumnNames(List *columnNameList) static void ErrorIfUnstableCreateOrAlterExtensionStmt(Node *parsetree) { + char *newExtensionVersion = ExtractNewExtensionVersion(parsetree); + + if (newExtensionVersion != NULL) + { + /* explicit version provided in CREATE or ALTER EXTENSION UPDATE; verify */ + if (!MajorVersionsCompatible(newExtensionVersion, CITUS_EXTENSIONVERSION)) + { + ereport(ERROR, (errmsg("specified version incompatible with loaded " + "Citus library"), + errdetail("Loaded library requires %s, but %s was specified.", + CITUS_MAJORVERSION, newExtensionVersion), + errhint("If a newer library is present, restart the database " + "and try the command again."))); + } + } + else + { + /* + * No version was specified, so PostgreSQL will use the default_version + * from the citus.control file. In case a new default is available, we + * will force a compatibility check of the latest available version. + */ + availableExtensionVersion = NULL; + ErrorIfAvailableVersionMismatch(); + } +} + + +static char * +ExtractNewExtensionVersion(Node *parsetree) +{ + char *newVersion = NULL; List *optionsList = NIL; ListCell *optionsCell = NULL; if (IsA(parsetree, CreateExtensionStmt)) { - CreateExtensionStmt *createExtensionStmt = (CreateExtensionStmt *) parsetree; - optionsList = createExtensionStmt->options; + optionsList = ((CreateExtensionStmt *) parsetree)->options; } else if (IsA(parsetree, AlterExtensionStmt)) { - AlterExtensionStmt *alterExtensionStmt = (AlterExtensionStmt *) parsetree; - optionsList = alterExtensionStmt->options; + optionsList = ((AlterExtensionStmt *) parsetree)->options; } else { - ereport(ERROR, (errmsg("unsupported node type, create or alter extension " - "is expected"))); + /* input must be one of the two above types */ + Assert(false); } foreach(optionsCell, optionsList) @@ -1366,25 +1397,12 @@ ErrorIfUnstableCreateOrAlterExtensionStmt(Node *parsetree) if (strcmp(defElement->defname, "new_version") == 0) { - char *newVersion = strVal(defElement->arg); - - if (!MajorVersionsCompatible(newVersion, CITUS_EXTENSIONVERSION)) - { - ereport(ERROR, (errmsg("requested version is not compatible with " - "loaded Citus binaries."))); - } - - return; + newVersion = strVal(defElement->arg); + break; } } - /* - * new_version is not specified in ALTER EXTENSION statement, PostgreSQL will use - * default_version from citus.control file. We will flush availableExtensionVersion - * to re-check the available version from citus.control file. - */ - availableExtensionVersion = NULL; - ErrorIfAvailableVersionMismatch(); + return newVersion; } diff --git a/src/test/regress/expected/multi_extension.out b/src/test/regress/expected/multi_extension.out index 6448fdbda..c5a85b304 100644 --- a/src/test/regress/expected/multi_extension.out +++ b/src/test/regress/expected/multi_extension.out @@ -103,7 +103,9 @@ WHERE pgd.refclassid = 'pg_extension'::regclass AND DROP EXTENSION citus; \c CREATE EXTENSION citus VERSION '5.0'; -ERROR: requested version is not compatible with loaded Citus binaries. +ERROR: specified version incompatible with loaded Citus library +DETAIL: Loaded library requires 6.2, but 5.0 was specified. +HINT: If a newer library is present, restart the database and try the command again. -- re-create in newest version \c CREATE EXTENSION citus;