Commit c5d94a34 authored by Bruce Momjian's avatar Bruce Momjian

Modify pg_upgrade to set/restore all environment variables related to

collation/encoding to match English when reading controldata.  This now
matches the English variable setting used by pg_regress.c.

Backpatch to 9.0.X.
parent a756f5ce
...@@ -4,13 +4,14 @@ ...@@ -4,13 +4,14 @@
* controldata functions * controldata functions
* *
* Copyright (c) 2010, PostgreSQL Global Development Group * Copyright (c) 2010, PostgreSQL Global Development Group
* $PostgreSQL: pgsql/contrib/pg_upgrade/controldata.c,v 1.9 2010/07/06 19:18:55 momjian Exp $ * $PostgreSQL: pgsql/contrib/pg_upgrade/controldata.c,v 1.10 2010/09/07 14:10:30 momjian Exp $
*/ */
#include "pg_upgrade.h" #include "pg_upgrade.h"
#include <ctype.h> #include <ctype.h>
static void putenv2(migratorContext *ctx, const char *var, const char *val);
/* /*
* get_control_data() * get_control_data()
...@@ -51,19 +52,55 @@ get_control_data(migratorContext *ctx, ClusterInfo *cluster, bool live_check) ...@@ -51,19 +52,55 @@ get_control_data(migratorContext *ctx, ClusterInfo *cluster, bool live_check)
bool got_toast = false; bool got_toast = false;
bool got_date_is_int = false; bool got_date_is_int = false;
bool got_float8_pass_by_value = false; bool got_float8_pass_by_value = false;
char *lc_collate = NULL;
char *lc_ctype = NULL;
char *lc_monetary = NULL;
char *lc_numeric = NULL;
char *lc_time = NULL;
char *lang = NULL; char *lang = NULL;
char *language = NULL;
char *lc_all = NULL;
char *lc_messages = NULL;
/* /*
* Because we test the pg_resetxlog output strings, it has to be in * Because we test the pg_resetxlog output as strings, it has to be in
* English. * English. Copied from pg_regress.c.
*/ */
if (getenv("LC_COLLATE"))
lc_collate = pg_strdup(ctx, getenv("LC_COLLATE"));
if (getenv("LC_CTYPE"))
lc_ctype = pg_strdup(ctx, getenv("LC_CTYPE"));
if (getenv("LC_MONETARY"))
lc_monetary = pg_strdup(ctx, getenv("LC_MONETARY"));
if (getenv("LC_NUMERIC"))
lc_numeric = pg_strdup(ctx, getenv("LC_NUMERIC"));
if (getenv("LC_TIME"))
lc_time = pg_strdup(ctx, getenv("LC_TIME"));
if (getenv("LANG")) if (getenv("LANG"))
lang = pg_strdup(ctx, getenv("LANG")); lang = pg_strdup(ctx, getenv("LANG"));
if (getenv("LANGUAGE"))
language = pg_strdup(ctx, getenv("LANGUAGE"));
if (getenv("LC_ALL"))
lc_all = pg_strdup(ctx, getenv("LC_ALL"));
if (getenv("LC_MESSAGES"))
lc_messages = pg_strdup(ctx, getenv("LC_MESSAGES"));
putenv2(ctx, "LC_COLLATE", NULL);
putenv2(ctx, "LC_CTYPE", NULL);
putenv2(ctx, "LC_MONETARY", NULL);
putenv2(ctx, "LC_NUMERIC", NULL);
putenv2(ctx, "LC_TIME", NULL);
putenv2(ctx, "LANG",
#ifndef WIN32 #ifndef WIN32
putenv(pg_strdup(ctx, "LANG=C")); NULL);
#else #else
SetEnvironmentVariableA("LANG", "C"); /* On Windows the default locale cannot be English, so force it */
"en");
#endif #endif
putenv2(ctx, "LANGUAGE", NULL);
putenv2(ctx, "LC_ALL", NULL);
putenv2(ctx, "LC_MESSAGES", "C");
snprintf(cmd, sizeof(cmd), SYSTEMQUOTE "\"%s/%s \"%s\"" SYSTEMQUOTE, snprintf(cmd, sizeof(cmd), SYSTEMQUOTE "\"%s/%s \"%s\"" SYSTEMQUOTE,
cluster->bindir, cluster->bindir,
live_check ? "pg_controldata\"" : "pg_resetxlog\" -n", live_check ? "pg_controldata\"" : "pg_resetxlog\" -n",
...@@ -334,28 +371,29 @@ get_control_data(migratorContext *ctx, ClusterInfo *cluster, bool live_check) ...@@ -334,28 +371,29 @@ get_control_data(migratorContext *ctx, ClusterInfo *cluster, bool live_check)
if (output) if (output)
pclose(output); pclose(output);
/* restore LANG */ /*
if (lang) * Restore environment variables
{ */
#ifndef WIN32 putenv2(ctx, "LC_COLLATE", lc_collate);
char *envstr = (char *) pg_malloc(ctx, strlen(lang) + 6); putenv2(ctx, "LC_CTYPE", lc_ctype);
putenv2(ctx, "LC_MONETARY", lc_monetary);
sprintf(envstr, "LANG=%s", lang); putenv2(ctx, "LC_NUMERIC", lc_numeric);
putenv(envstr); putenv2(ctx, "LC_TIME", lc_time);
#else putenv2(ctx, "LANG", lang);
SetEnvironmentVariableA("LANG", lang); putenv2(ctx, "LANGUAGE", language);
#endif putenv2(ctx, "LC_ALL", lc_all);
pg_free(lang); putenv2(ctx, "LC_MESSAGES", lc_messages);
}
else pg_free(lc_collate);
{ pg_free(lc_ctype);
#ifndef WIN32 pg_free(lc_monetary);
unsetenv("LANG"); pg_free(lc_numeric);
#else pg_free(lc_time);
SetEnvironmentVariableA("LANG", ""); pg_free(lang);
#endif pg_free(language);
} pg_free(lc_all);
pg_free(lc_messages);
/* verify that we got all the mandatory pg_control data */ /* verify that we got all the mandatory pg_control data */
if (!got_xid || !got_oid || if (!got_xid || !got_oid ||
(!live_check && !got_log_id) || (!live_check && !got_log_id) ||
...@@ -492,3 +530,39 @@ rename_old_pg_control(migratorContext *ctx) ...@@ -492,3 +530,39 @@ rename_old_pg_control(migratorContext *ctx)
pg_log(ctx, PG_FATAL, "Unable to rename %s to %s.\n", old_path, new_path); pg_log(ctx, PG_FATAL, "Unable to rename %s to %s.\n", old_path, new_path);
check_ok(ctx); check_ok(ctx);
} }
/*
* putenv2()
*
* This is like putenv(), but takes two arguments.
* It also does unsetenv() if val is NULL.
*/
static void
putenv2(migratorContext *ctx, const char *var, const char *val)
{
if (val)
{
#ifndef WIN32
char *envstr = (char *) pg_malloc(ctx, strlen(var) +
strlen(val) + 1);
sprintf(envstr, "%s=%s", var, val);
putenv(envstr);
/*
* Do not free envstr because it becomes part of the environment
* on some operating systems. See port/unsetenv.c::unsetenv.
*/
#else
SetEnvironmentVariableA(var, val);
#endif
}
else
{
#ifndef WIN32
unsetenv(var);
#else
SetEnvironmentVariableA(var, "");
#endif
}
}
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/port/unsetenv.c,v 1.11 2010/01/02 16:58:13 momjian Exp $ * $PostgreSQL: pgsql/src/port/unsetenv.c,v 1.12 2010/09/07 14:10:30 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -32,6 +32,7 @@ unsetenv(const char *name) ...@@ -32,6 +32,7 @@ unsetenv(const char *name)
* implementations (notably recent BSDs) that do not obey SUS but copy the * implementations (notably recent BSDs) that do not obey SUS but copy the
* presented string. This method fails on such platforms. Hopefully all * presented string. This method fails on such platforms. Hopefully all
* such platforms have unsetenv() and thus won't be using this hack. * such platforms have unsetenv() and thus won't be using this hack.
* See: http://www.greenend.org.uk/rjk/2008/putenv.html
* *
* Note that repeatedly setting and unsetting a var using this code will * Note that repeatedly setting and unsetting a var using this code will
* leak memory. * leak memory.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment