From 625d4b38e0311fa5d281624d05f6cf7db46c98bb Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Fri, 9 Dec 2005 15:51:14 +0000 Subject: [PATCH] Let initdb detect the date order of the lc_time locale and initialize the datestyle parameter of the new cluster accordingly. --- doc/TODO | 2 +- doc/src/sgml/config.sgml | 9 +++-- src/bin/initdb/initdb.c | 73 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 79 insertions(+), 5 deletions(-) diff --git a/doc/TODO b/doc/TODO index 5e8c8ebff3..a18f2e67e4 100644 --- a/doc/TODO +++ b/doc/TODO @@ -566,7 +566,7 @@ SQL Commands Clients ======= -* Have initdb set the input DateStyle (MDY or DMY) based on locale? +* -Have initdb set the input DateStyle (MDY or DMY) based on locale * Have pg_ctl look at PGHOST in case it is a socket directory? * Allow pg_ctl to work properly with configuration files located outside the PGDATA directory diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 89dc122327..2d1e508183 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -1,5 +1,5 @@ Server Configuration @@ -32,7 +32,7 @@ $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.37 2005/11/17 22:14:50 tgl Exp $ One way to set these parameters is to edit the file postgresql.confpostgresql.conf, - which is normally kept in the data directory. (initdb + which is normally kept in the data directory. (initdb installs a default copy there.) An example of what this file might look like is: @@ -3300,7 +3300,10 @@ SELECT * FROM parent WHERE key = 2400; keywords US, NonEuro, and NonEuropean are synonyms for MDY. See for more information. The - default is ISO, MDY. + built-in default is ISO, MDY, but + initdb will initialize the + configuration file with a setting that corresponds to the + behavior of the chosen lc_time locale. diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index ad9e4b6027..4188518413 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -42,7 +42,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * Portions taken from FreeBSD. * - * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.100 2005/11/22 18:17:28 momjian Exp $ + * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.101 2005/12/09 15:51:14 petere Exp $ * *------------------------------------------------------------------------- */ @@ -57,11 +57,13 @@ #ifdef HAVE_LANGINFO_H #include #endif +#include #include "libpq/pqsignal.h" #include "mb/pg_wchar.h" #include "getaddrinfo.h" #include "getopt_long.h" +#include "miscadmin.h" #ifndef HAVE_INT_OPTRESET int optreset; @@ -186,6 +188,7 @@ static void make_postgres(void); static void trapsig(int signum); static void check_ok(void); static char *escape_quotes(const char *src); +static int locale_date_order(const char *locale); static bool chklocale(const char *locale); static void setlocales(void); static void usage(const char *progname); @@ -1195,6 +1198,20 @@ setup_config(void) snprintf(repltok, sizeof(repltok), "lc_time = '%s'", lc_time); conflines = replace_token(conflines, "#lc_time = 'C'", repltok); + switch (locale_date_order(lc_time)) { + case DATEORDER_YMD: + strcpy(repltok, "datestyle = 'iso, ymd'"); + break; + case DATEORDER_DMY: + strcpy(repltok, "datestyle = 'iso, dmy'"); + break; + case DATEORDER_MDY: + default: + strcpy(repltok, "datestyle = 'iso, mdy'"); + break; + } + conflines = replace_token(conflines, "#datestyle = 'iso, mdy'", repltok); + snprintf(path, sizeof(path), "%s/postgresql.conf", pg_data); writefile(path, conflines); @@ -2052,6 +2069,60 @@ escape_quotes(const char *src) return result; } +/* + * Determine likely date order from locale + */ +static int +locale_date_order(const char *locale) +{ + struct tm testtime; + char buf[128]; + char *posD; + char *posM; + char *posY; + char *save; + size_t res; + int result; + + result = DATEORDER_MDY; /* default */ + + save = setlocale(LC_TIME, NULL); + if (!save) + return result; + save = xstrdup(save); + + setlocale(LC_TIME, locale); + + memset(&testtime, 0, sizeof(testtime)); + testtime.tm_mday = 22; + testtime.tm_mon = 10; /* November, should come out as "11" */ + testtime.tm_year = 133; /* 2033 */ + + res = strftime(buf, sizeof(buf), "%x", &testtime); + + setlocale(LC_TIME, save); + free(save); + + if (res == 0) + return result; + + posM = strstr(buf, "11"); + posD = strstr(buf, "22"); + posY = strstr(buf, "33"); + + if (!posM || !posD || !posY) + return result; + + if (posY < posM && posM < posD) + result = DATEORDER_YMD; + else if (posD < posM) + result = DATEORDER_DMY; + else + result = DATEORDER_MDY; + + return result; +} + /* * check if given string is a valid locale specifier */