diff options
Diffstat (limited to 'src/bin/initdb/initdb.c')
-rw-r--r-- | src/bin/initdb/initdb.c | 166 |
1 files changed, 2 insertions, 164 deletions
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index 1e7d6772447..eb1be100c85 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -1608,178 +1608,16 @@ setup_description(FILE *cmdfd) PG_CMD_PUTS("DROP TABLE tmp_pg_shdescription;\n\n"); } -#ifdef HAVE_LOCALE_T -/* - * "Normalize" a locale name, stripping off encoding tags such as - * ".utf8" (e.g., "en_US.utf8" -> "en_US", but "br_FR.iso885915@euro" - * -> "br_FR@euro"). Return true if a new, different name was - * generated. - */ -static bool -normalize_locale_name(char *new, const char *old) -{ - char *n = new; - const char *o = old; - bool changed = false; - - while (*o) - { - if (*o == '.') - { - /* skip over encoding tag such as ".utf8" or ".UTF-8" */ - o++; - while ((*o >= 'A' && *o <= 'Z') - || (*o >= 'a' && *o <= 'z') - || (*o >= '0' && *o <= '9') - || (*o == '-')) - o++; - changed = true; - } - else - *n++ = *o++; - } - *n = '\0'; - - return changed; -} -#endif /* HAVE_LOCALE_T */ - /* * populate pg_collation */ static void setup_collation(FILE *cmdfd) { -#if defined(HAVE_LOCALE_T) && !defined(WIN32) - int i; - FILE *locale_a_handle; - char localebuf[NAMEDATALEN]; /* we assume ASCII so this is fine */ - int count = 0; - - locale_a_handle = popen_check("locale -a", "r"); - if (!locale_a_handle) - return; /* complaint already printed */ - - PG_CMD_PUTS("CREATE TEMP TABLE tmp_pg_collation ( " - " collname name, " - " locale name, " - " encoding int) WITHOUT OIDS;\n\n"); - - while (fgets(localebuf, sizeof(localebuf), locale_a_handle)) - { - size_t len; - int enc; - bool skip; - char *quoted_locale; - char alias[NAMEDATALEN]; - - len = strlen(localebuf); - - if (len == 0 || localebuf[len - 1] != '\n') - { - if (debug) - fprintf(stderr, _("%s: locale name too long, skipped: \"%s\"\n"), - progname, localebuf); - continue; - } - localebuf[len - 1] = '\0'; - - /* - * Some systems have locale names that don't consist entirely of ASCII - * letters (such as "bokmål" or "français"). This is - * pretty silly, since we need the locale itself to interpret the - * non-ASCII characters. We can't do much with those, so we filter - * them out. - */ - skip = false; - for (i = 0; i < len; i++) - { - if (IS_HIGHBIT_SET(localebuf[i])) - { - skip = true; - break; - } - } - if (skip) - { - if (debug) - fprintf(stderr, _("%s: locale name has non-ASCII characters, skipped: \"%s\"\n"), - progname, localebuf); - continue; - } - - enc = pg_get_encoding_from_locale(localebuf, debug); - if (enc < 0) - { - /* error message printed by pg_get_encoding_from_locale() */ - continue; - } - if (!PG_VALID_BE_ENCODING(enc)) - continue; /* ignore locales for client-only encodings */ - if (enc == PG_SQL_ASCII) - continue; /* C/POSIX are already in the catalog */ - - count++; - - quoted_locale = escape_quotes(localebuf); - - PG_CMD_PRINTF3("INSERT INTO tmp_pg_collation VALUES (E'%s', E'%s', %d);\n\n", - quoted_locale, quoted_locale, enc); - - /* - * Generate aliases such as "en_US" in addition to "en_US.utf8" for - * ease of use. Note that collation names are unique per encoding - * only, so this doesn't clash with "en_US" for LATIN1, say. - */ - if (normalize_locale_name(alias, localebuf)) - { - char *quoted_alias = escape_quotes(alias); - - PG_CMD_PRINTF3("INSERT INTO tmp_pg_collation VALUES (E'%s', E'%s', %d);\n\n", - quoted_alias, quoted_locale, enc); - free(quoted_alias); - } - free(quoted_locale); - } + PG_CMD_PUTS("SELECT pg_import_system_collations(if_not_exists => false, schema => 'pg_catalog');\n\n"); /* Add an SQL-standard name */ - PG_CMD_PRINTF1("INSERT INTO tmp_pg_collation VALUES ('ucs_basic', 'C', %d);\n\n", PG_UTF8); - - /* - * When copying collations to the final location, eliminate aliases that - * conflict with an existing locale name for the same encoding. For - * example, "br_FR.iso88591" is normalized to "br_FR", both for encoding - * LATIN1. But the unnormalized locale "br_FR" already exists for LATIN1. - * Prefer the alias that matches the OS locale name, else the first locale - * name by sort order (arbitrary choice to be deterministic). - * - * Also, eliminate any aliases that conflict with pg_collation's - * hard-wired entries for "C" etc. - */ - PG_CMD_PUTS("INSERT INTO pg_collation (collname, collnamespace, collowner, collencoding, collcollate, collctype) " - " SELECT DISTINCT ON (collname, encoding)" - " collname, " - " (SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog') AS collnamespace, " - " (SELECT relowner FROM pg_class WHERE relname = 'pg_collation') AS collowner, " - " encoding, locale, locale " - " FROM tmp_pg_collation" - " WHERE NOT EXISTS (SELECT 1 FROM pg_collation WHERE collname = tmp_pg_collation.collname)" - " ORDER BY collname, encoding, (collname = locale) DESC, locale;\n\n"); - - /* - * Even though the table is temp, drop it explicitly so it doesn't get - * copied into template0/postgres databases. - */ - PG_CMD_PUTS("DROP TABLE tmp_pg_collation;\n\n"); - - pclose(locale_a_handle); - - if (count == 0 && !debug) - { - printf(_("No usable system locales were found.\n")); - printf(_("Use the option \"--debug\" to see details.\n")); - } -#endif /* not HAVE_LOCALE_T && not WIN32 */ + PG_CMD_PRINTF2("INSERT INTO pg_collation (collname, collnamespace, collowner, collencoding, collcollate, collctype) VALUES ('ucs_basic', 'pg_catalog'::regnamespace, '%s'::regrole, %d, 'C', 'C');\n\n", escape_quotes(username), PG_UTF8); } /* |