From ce89d0570702c5581100ba16742cc0b6914db61b Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Tue, 4 Sep 2018 04:54:56 +1200 Subject: [PATCH 1/2] Add libc_collation_version_command GUC. --- src/backend/utils/adt/pg_locale.c | 50 +++++++++++++++++++++++++++++++ src/backend/utils/misc/guc.c | 13 ++++++++ src/include/utils/guc.h | 1 + 3 files changed, 64 insertions(+) diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index a3dc3be5a87..bb65c075676 100644 --- a/src/backend/utils/adt/pg_locale.c +++ b/src/backend/utils/adt/pg_locale.c @@ -56,7 +56,9 @@ #include "access/htup_details.h" #include "catalog/pg_collation.h" #include "catalog/pg_control.h" +#include "lib/stringinfo.h" #include "mb/pg_wchar.h" +#include "storage/fd.h" #include "utils/builtins.h" #include "utils/hsearch.h" #include "utils/lsyscache.h" @@ -1475,6 +1477,54 @@ get_collation_actual_version(char collprovider, const char *collcollate) } else #endif + if (libc_collation_version_command[0] != '\0') + { + char buffer[1024]; + StringInfoData output; + FILE *file; + size_t len; + const char *p; + +#define LC_COLLATE_TOKEN "@LC_COLLATE@" +#define LC_COLLATE_TOKEN_LEN (sizeof(LC_COLLATE_TOKEN) - 1) + + /* Build the complete command. */ + initStringInfo(&output); + p = libc_collation_version_command; + while (*p) + { + if (strncmp(p, LC_COLLATE_TOKEN, LC_COLLATE_TOKEN_LEN) == 0) + { + appendStringInfoString(&output, collcollate); + p += LC_COLLATE_TOKEN_LEN; + } + else + appendStringInfoChar(&output, *p++); + } + + /* Execute it and read one line. */ + file = OpenPipeStream(output.data, "r"); + if (!file) + ereport(ERROR, + (errmsg("could not run command \"%s\": %m", + output.data))); + if (!fgets(buffer, sizeof(buffer), file)) + { + ClosePipeStream(file); + ereport(ERROR, + (errmsg("could not read output from command \"%s\": %m", + output.data))); + } + ClosePipeStream(file); + pfree(output.data); + + /* Trim off newline. */ + len = strlen(buffer); + if (len > 0 && buffer[len - 1] == '\n') + buffer[len - 1] = '\0'; + collversion = pstrdup(buffer); + } + else collversion = NULL; return collversion; diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 0625eff2191..ed19a71f319 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -474,6 +474,7 @@ char *ConfigFileName; char *HbaFileName; char *IdentFileName; char *external_pid_file; +char *libc_collation_version_command; char *pgstat_temp_directory; @@ -3883,6 +3884,18 @@ static struct config_string ConfigureNamesString[] = check_cluster_name, NULL, NULL }, + { + {"libc_collation_version_command", PGC_POSTMASTER, PROCESS_TITLE, + gettext_noop("Command to obtain version strings for libc collations."), + NULL, + GUC_IS_NAME + }, + &libc_collation_version_command, + "", + NULL, NULL, NULL + }, + + { {"wal_consistency_checking", PGC_SUSET, DEVELOPER_OPTIONS, gettext_noop("Sets the WAL resource managers for which WAL consistency checks are done."), diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h index f462eabe594..7efbe033d22 100644 --- a/src/include/utils/guc.h +++ b/src/include/utils/guc.h @@ -262,6 +262,7 @@ extern PGDLLIMPORT char *ConfigFileName; extern char *HbaFileName; extern char *IdentFileName; extern char *external_pid_file; +extern char *libc_collation_version_command; extern PGDLLIMPORT char *application_name; -- 2.17.0