Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit c5d94a3

Browse files
committed
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.
1 parent a756f5c commit c5d94a3

File tree

2 files changed

+103
-28
lines changed

2 files changed

+103
-28
lines changed

contrib/pg_upgrade/controldata.c

Lines changed: 101 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@
44
* controldata functions
55
*
66
* Copyright (c) 2010, PostgreSQL Global Development Group
7-
* $PostgreSQL: pgsql/contrib/pg_upgrade/controldata.c,v 1.9 2010/07/06 19:18:55 momjian Exp $
7+
* $PostgreSQL: pgsql/contrib/pg_upgrade/controldata.c,v 1.10 2010/09/07 14:10:30 momjian Exp $
88
*/
99

1010
#include "pg_upgrade.h"
1111

1212
#include <ctype.h>
1313

14+
static void putenv2(migratorContext *ctx, const char *var, const char *val);
1415

1516
/*
1617
* get_control_data()
@@ -51,19 +52,55 @@ get_control_data(migratorContext *ctx, ClusterInfo *cluster, bool live_check)
5152
bool got_toast = false;
5253
bool got_date_is_int = false;
5354
bool got_float8_pass_by_value = false;
55+
char *lc_collate = NULL;
56+
char *lc_ctype = NULL;
57+
char *lc_monetary = NULL;
58+
char *lc_numeric = NULL;
59+
char *lc_time = NULL;
5460
char *lang = NULL;
61+
char *language = NULL;
62+
char *lc_all = NULL;
63+
char *lc_messages = NULL;
5564

5665
/*
57-
* Because we test the pg_resetxlog output strings, it has to be in
58-
* English.
66+
* Because we test the pg_resetxlog output as strings, it has to be in
67+
* English. Copied from pg_regress.c.
5968
*/
69+
if (getenv("LC_COLLATE"))
70+
lc_collate = pg_strdup(ctx, getenv("LC_COLLATE"));
71+
if (getenv("LC_CTYPE"))
72+
lc_ctype = pg_strdup(ctx, getenv("LC_CTYPE"));
73+
if (getenv("LC_MONETARY"))
74+
lc_monetary = pg_strdup(ctx, getenv("LC_MONETARY"));
75+
if (getenv("LC_NUMERIC"))
76+
lc_numeric = pg_strdup(ctx, getenv("LC_NUMERIC"));
77+
if (getenv("LC_TIME"))
78+
lc_time = pg_strdup(ctx, getenv("LC_TIME"));
6079
if (getenv("LANG"))
6180
lang = pg_strdup(ctx, getenv("LANG"));
81+
if (getenv("LANGUAGE"))
82+
language = pg_strdup(ctx, getenv("LANGUAGE"));
83+
if (getenv("LC_ALL"))
84+
lc_all = pg_strdup(ctx, getenv("LC_ALL"));
85+
if (getenv("LC_MESSAGES"))
86+
lc_messages = pg_strdup(ctx, getenv("LC_MESSAGES"));
87+
88+
putenv2(ctx, "LC_COLLATE", NULL);
89+
putenv2(ctx, "LC_CTYPE", NULL);
90+
putenv2(ctx, "LC_MONETARY", NULL);
91+
putenv2(ctx, "LC_NUMERIC", NULL);
92+
putenv2(ctx, "LC_TIME", NULL);
93+
putenv2(ctx, "LANG",
6294
#ifndef WIN32
63-
putenv(pg_strdup(ctx, "LANG=C"));
95+
NULL);
6496
#else
65-
SetEnvironmentVariableA("LANG", "C");
97+
/* On Windows the default locale cannot be English, so force it */
98+
"en");
6699
#endif
100+
putenv2(ctx, "LANGUAGE", NULL);
101+
putenv2(ctx, "LC_ALL", NULL);
102+
putenv2(ctx, "LC_MESSAGES", "C");
103+
67104
snprintf(cmd, sizeof(cmd), SYSTEMQUOTE "\"%s/%s \"%s\"" SYSTEMQUOTE,
68105
cluster->bindir,
69106
live_check ? "pg_controldata\"" : "pg_resetxlog\" -n",
@@ -334,28 +371,29 @@ get_control_data(migratorContext *ctx, ClusterInfo *cluster, bool live_check)
334371
if (output)
335372
pclose(output);
336373

337-
/* restore LANG */
338-
if (lang)
339-
{
340-
#ifndef WIN32
341-
char *envstr = (char *) pg_malloc(ctx, strlen(lang) + 6);
342-
343-
sprintf(envstr, "LANG=%s", lang);
344-
putenv(envstr);
345-
#else
346-
SetEnvironmentVariableA("LANG", lang);
347-
#endif
348-
pg_free(lang);
349-
}
350-
else
351-
{
352-
#ifndef WIN32
353-
unsetenv("LANG");
354-
#else
355-
SetEnvironmentVariableA("LANG", "");
356-
#endif
357-
}
358-
374+
/*
375+
* Restore environment variables
376+
*/
377+
putenv2(ctx, "LC_COLLATE", lc_collate);
378+
putenv2(ctx, "LC_CTYPE", lc_ctype);
379+
putenv2(ctx, "LC_MONETARY", lc_monetary);
380+
putenv2(ctx, "LC_NUMERIC", lc_numeric);
381+
putenv2(ctx, "LC_TIME", lc_time);
382+
putenv2(ctx, "LANG", lang);
383+
putenv2(ctx, "LANGUAGE", language);
384+
putenv2(ctx, "LC_ALL", lc_all);
385+
putenv2(ctx, "LC_MESSAGES", lc_messages);
386+
387+
pg_free(lc_collate);
388+
pg_free(lc_ctype);
389+
pg_free(lc_monetary);
390+
pg_free(lc_numeric);
391+
pg_free(lc_time);
392+
pg_free(lang);
393+
pg_free(language);
394+
pg_free(lc_all);
395+
pg_free(lc_messages);
396+
359397
/* verify that we got all the mandatory pg_control data */
360398
if (!got_xid || !got_oid ||
361399
(!live_check && !got_log_id) ||
@@ -492,3 +530,39 @@ rename_old_pg_control(migratorContext *ctx)
492530
pg_log(ctx, PG_FATAL, "Unable to rename %s to %s.\n", old_path, new_path);
493531
check_ok(ctx);
494532
}
533+
534+
535+
/*
536+
* putenv2()
537+
*
538+
* This is like putenv(), but takes two arguments.
539+
* It also does unsetenv() if val is NULL.
540+
*/
541+
static void
542+
putenv2(migratorContext *ctx, const char *var, const char *val)
543+
{
544+
if (val)
545+
{
546+
#ifndef WIN32
547+
char *envstr = (char *) pg_malloc(ctx, strlen(var) +
548+
strlen(val) + 1);
549+
550+
sprintf(envstr, "%s=%s", var, val);
551+
putenv(envstr);
552+
/*
553+
* Do not free envstr because it becomes part of the environment
554+
* on some operating systems. See port/unsetenv.c::unsetenv.
555+
*/
556+
#else
557+
SetEnvironmentVariableA(var, val);
558+
#endif
559+
}
560+
else
561+
{
562+
#ifndef WIN32
563+
unsetenv(var);
564+
#else
565+
SetEnvironmentVariableA(var, "");
566+
#endif
567+
}
568+
}

src/port/unsetenv.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/port/unsetenv.c,v 1.11 2010/01/02 16:58:13 momjian Exp $
11+
* $PostgreSQL: pgsql/src/port/unsetenv.c,v 1.12 2010/09/07 14:10:30 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -32,6 +32,7 @@ unsetenv(const char *name)
3232
* implementations (notably recent BSDs) that do not obey SUS but copy the
3333
* presented string. This method fails on such platforms. Hopefully all
3434
* such platforms have unsetenv() and thus won't be using this hack.
35+
* See: http://www.greenend.org.uk/rjk/2008/putenv.html
3536
*
3637
* Note that repeatedly setting and unsetting a var using this code will
3738
* leak memory.

0 commit comments

Comments
 (0)