Fix initdb's -c option to treat the GUC name case-insensitively.
authorTom Lane
Mon, 4 Mar 2024 17:00:39 +0000 (12:00 -0500)
committerTom Lane
Mon, 4 Mar 2024 17:00:39 +0000 (12:00 -0500)
The backend treats GUC names case-insensitively, so this code should
too.  This avoids ending up with a confusing set of redundant entries
in the generated postgresql.conf file.

Per report from Kyotaro Horiguchi.  Back-patch to v16 where this
feature was added (in commit 3e51b278d).

Discussion: https://postgr.es/m/20230928.164904.2153358973162534034[email protected]

src/bin/initdb/initdb.c
src/bin/initdb/t/001_initdb.pl

index 3afe14cb4b753d789d2e7bdaf6f449b2cda8e056..458dc1137a319b6963bc4755dee636c92b06a62c 100644 (file)
@@ -482,6 +482,7 @@ replace_guc_value(char **lines, const char *guc_name, const char *guc_value,
    for (i = 0; lines[i]; i++)
    {
        const char *where;
+       const char *namestart;
 
        /*
         * Look for a line assigning to guc_name.  Typically it will be
@@ -492,15 +493,19 @@ replace_guc_value(char **lines, const char *guc_name, const char *guc_value,
        where = lines[i];
        while (*where == '#' || isspace((unsigned char) *where))
            where++;
-       if (strncmp(where, guc_name, namelen) != 0)
+       if (pg_strncasecmp(where, guc_name, namelen) != 0)
            continue;
+       namestart = where;
        where += namelen;
        while (isspace((unsigned char) *where))
            where++;
        if (*where != '=')
            continue;
 
-       /* found it -- append the original comment if any */
+       /* found it -- let's use the canonical casing shown in the file */
+       memcpy(&newline->data[mark_as_comment ? 1 : 0], namestart, namelen);
+
+       /* now append the original comment if any */
        where = strrchr(where, '#');
        if (where)
        {
index 2d7469d2fc339a3b045be69a1012e3e74ed038da..0e4f0b5e644f1a96ea30131985660a5f1c3a9aae 100644 (file)
@@ -187,4 +187,18 @@ command_fails(
 command_fails([ 'initdb', '--no-sync', '--set', 'foo=bar', "$tempdir/dataX" ],
    'fails for invalid --set option');
 
+# Make sure multiple invocations of -c parameters are added case insensitive
+command_ok(
+   [
+       'initdb', '-cwork_mem=128',
+       '-cWork_Mem=256', '-cWORK_MEM=512',
+       "$tempdir/dataY"
+   ],
+   'multiple -c options with different case');
+
+my $conf = slurp_file("$tempdir/dataY/postgresql.conf");
+ok($conf !~ qr/^WORK_MEM = /m, "WORK_MEM should not be configured");
+ok($conf !~ qr/^Work_Mem = /m, "Work_Mem should not be configured");
+ok($conf =~ qr/^work_mem = 512/m, "work_mem should be in config");
+
 done_testing();