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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy