postgres.git / summary / log / commit / refs

commit    8c239ee15a4b093523ebe30bdc9af186aaccebfd
Author:   Tomas Vondra <tomas.vondra@postgresql.org>
Date:     Sun Apr 21 19:21:26 2024 +0000
First released in: 17.0, 15.7, 16.3

    createdb: compare strategy case-insensitive
    
    When specifying the createdb strategy, the documentation suggests valid
    options are FILE_COPY and WAL_LOG, but the code does case-sensitive
    comparison and accepts only "file_copy" and "wal_log" as valid.
    
    Fixed by doing a case-insensitive comparison using pg_strcasecmp(), same
    as for other string parameters nearby.
    
    While at it, apply fmtId() to a nearby "locale_provider". This already
    did the comparison in case-insensitive way, but the value would not be
    double-quoted, confusing the parser and the error message.
    
    Backpatch to 15, where the strategy was introduced.
    
    Backpatch-through: 15
    Reviewed-by: Tom Lane
    Discussion: https://postgr.es/m/90c6913a-1dd2-42b4-8365-ce3b09c39b17@enterprisedb.com


src/backend/commands/dbcommands.c | 6 +++--- src/bin/scripts/createdb.c | 2 +- src/bin/scripts/t/020_createdb.pl | 10 ++++++++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index 8229dfa1f22..cd06d1270c5 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -1018,15 +1018,15 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt) char *strategy; strategy = defGetString(dstrategy); - if (strcmp(strategy, "wal_log") == 0) + if (pg_strcasecmp(strategy, "wal_log") == 0) dbstrategy = CREATEDB_WAL_LOG; - else if (strcmp(strategy, "file_copy") == 0) + else if (pg_strcasecmp(strategy, "file_copy") == 0) dbstrategy = CREATEDB_FILE_COPY; else ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("invalid create database strategy \"%s\"", strategy), - errhint("Valid strategies are \"wal_log\", and \"file_copy\"."))); + errhint("Valid strategies are \"wal_log\" and \"file_copy\"."))); } /* If encoding or locales are defaulted, use source's setting */ diff --git a/src/bin/scripts/createdb.c b/src/bin/scripts/createdb.c index 007061e756f..30426860efa 100644 --- a/src/bin/scripts/createdb.c +++ b/src/bin/scripts/createdb.c @@ -237,7 +237,7 @@ main(int argc, char *argv[]) appendStringLiteralConn(&sql, lc_ctype, conn); } if (locale_provider) - appendPQExpBuffer(&sql, " LOCALE_PROVIDER %s", locale_provider); + appendPQExpBuffer(&sql, " LOCALE_PROVIDER %s", fmtId(locale_provider)); if (icu_locale) { appendPQExpBufferStr(&sql, " ICU_LOCALE "); diff --git a/src/bin/scripts/t/020_createdb.pl b/src/bin/scripts/t/020_createdb.pl index 512b55c48a9..4a0e2c883a1 100644 --- a/src/bin/scripts/t/020_createdb.pl +++ b/src/bin/scripts/t/020_createdb.pl @@ -255,11 +255,21 @@ $node->issues_sql_like( qr/statement: CREATE DATABASE foobar6 STRATEGY wal_log TEMPLATE foobar2/, 'create database with WAL_LOG strategy'); +$node->issues_sql_like( + [ 'createdb', '-T', 'foobar2', '-S', 'WAL_LOG', 'foobar6s' ], + qr/statement: CREATE DATABASE foobar6s STRATEGY "WAL_LOG" TEMPLATE foobar2/, + 'create database with WAL_LOG strategy'); + $node->issues_sql_like( [ 'createdb', '-T', 'foobar2', '-S', 'file_copy', 'foobar7' ], qr/statement: CREATE DATABASE foobar7 STRATEGY file_copy TEMPLATE foobar2/, 'create database with FILE_COPY strategy'); +$node->issues_sql_like( + [ 'createdb', '-T', 'foobar2', '-S', 'FILE_COPY', 'foobar7s' ], + qr/statement: CREATE DATABASE foobar7s STRATEGY "FILE_COPY" TEMPLATE foobar2/, + 'create database with FILE_COPY strategy'); + # Create database owned by role_foobar. $node->issues_sql_like( [ 'createdb', '-T', 'foobar2', '-O', 'role_foobar', 'foobar8' ], [parent: a3021aafcecb]