Re: initdb's -c option behaves wrong way?

Поиск
Список
Период
Сортировка
От Tom Lane
Тема Re: initdb's -c option behaves wrong way?
Дата
Msg-id 2629788.1705682037@sss.pgh.pa.us
обсуждение исходный текст
Ответ на Re: initdb's -c option behaves wrong way?  (Daniel Gustafsson <daniel@yesql.se>)
Ответы Re: initdb's -c option behaves wrong way?
Список pgsql-hackers
Daniel Gustafsson <daniel@yesql.se> writes:
> I'll give some more time for opinions, then I'll go ahead with one of the
> patches with a backpatch to v16.

OK, I take back my previous complaint that just using strncasecmp
would be enough --- I was misremembering how the code worked, and
you're right that it would use the spelling from the command line
rather than that from the file.

However, the v3 patch is flat broken.  You can't assume you have
found a match until you've verified that whitespace and '='
appear next --- otherwise, you'll be fooled by a guc_name that
is a prefix of one that appears in the file.  I think the simplest
change that does it correctly is as attached.

Now, since I was the one who wrote the existing code, I freely
concede that I may have too high an opinion of its readability.
Maybe some larger refactoring is appropriate.  But I didn't
find that what you'd done improved the readability.  I'd still
rather keep the newline-assembly code together as much as possible.
Maybe we should do the search part before we build any of newline?

            regards, tom lane

diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index ac409b0006..6a620c9d5f 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -484,6 +484,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
@@ -494,15 +495,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 (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)
         {
diff --git a/src/bin/initdb/t/001_initdb.pl b/src/bin/initdb/t/001_initdb.pl
index 03376cc0f7..413a5eca67 100644
--- a/src/bin/initdb/t/001_initdb.pl
+++ b/src/bin/initdb/t/001_initdb.pl
@@ -199,4 +199,17 @@ 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();

В списке pgsql-hackers по дате отправления:

Предыдущее
От: Konstantin Knizhnik
Дата:
Сообщение: Re: index prefetching
Следующее
От: Heikki Linnakangas
Дата:
Сообщение: Re: Change GUC hashtable to use simplehash?