gen_guc_tables.pl: Validate required GUC fields before code generation

Started by Chao Li2 months ago11 messages
#1Chao Li
li.evan.chao@gmail.com
1 attachment(s)

Hi Hacker,

While working on the other patch and editing guc_parameters.dat, I
mistakenly deleted a “max” value line, then I got the following error
during build:

```
'/opt/homebrew/bin/perl' ../../../src/backend/utils/misc/gen_guc_tables.pl
../../../src/backend/utils/misc/guc_parameters.dat guc_tables.inc.c
Use of uninitialized value in printf at ../../../src/backend/utils/misc/
gen_guc_tables.pl line 78.
make[2]: *** [guc_tables.inc.c] Error 25
```

The error message is unclear and is not helpful to identify the real issue.

I am not an expert of perl, but I tried to make an enhancement that will
print an error message like:

```
'/opt/homebrew/bin/perl' ../../../src/backend/utils/misc/gen_guc_tables.pl
../../../src/backend/utils/misc/guc_parameters.dat guc_tables.inc.c
error: guc_parameters.data: 'max_index_keys' of type 'int' is missing
required field 'max'
```

I got the “required_common” and “required_by_type” by reading the function
“print_table”.

Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/

Attachments:

v1-0001-gen_guc_tables.pl-Validate-required-GUC-fields-be.patchapplication/octet-stream; name=v1-0001-gen_guc_tables.pl-Validate-required-GUC-fields-be.patchDownload
From b2636829133009eefecfdc9d01ca0d7285c00ca8 Mon Sep 17 00:00:00 2001
From: "Chao Li (Evan)" <lic@highgo.com>
Date: Mon, 10 Nov 2025 16:35:36 +0800
Subject: [PATCH v1] gen_guc_tables.pl: Validate required GUC fields before
 code generation

Previously, gen_guc_tables.pl would emit "Use of uninitialized value"
warnings if required fields were missing in guc_parameters.dat (for
example, when an integer or real GUC omitted the 'max' value).  The
resulting error messages were unclear and did not identify which GUC
entry was problematic.

Add explicit validation of required fields depending on the parameter
type, and fail with a clear and specific message such as:

    error: guc_parameters.data: 'max_index_keys' of type 'int' is missing required field 'max'

No functional changes to generated guc_tables.c.

Author: Chao Li <lic@highgo.com>
---
 src/backend/utils/misc/gen_guc_tables.pl | 36 ++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/src/backend/utils/misc/gen_guc_tables.pl b/src/backend/utils/misc/gen_guc_tables.pl
index 601c34ec30b..f46fe498603 100644
--- a/src/backend/utils/misc/gen_guc_tables.pl
+++ b/src/backend/utils/misc/gen_guc_tables.pl
@@ -38,6 +38,40 @@ sub dquote
 	return q{"} . $s =~ s/"/\\"/gr . q{"};
 }
 
+sub validate_guc_entry
+{
+    my ($entry) = @_;
+
+    my @required_common = qw(name type context group short_desc variable boot_val);
+
+    # Type-specific required fields
+    my %required_by_type = (
+        int  => [qw(min max)],
+        real => [qw(min max)],
+        enum => [qw(options)],
+        bool => [],   # no extra required fields
+        string => [], # no extra required fields
+    );
+
+    # Check common required fields
+    for my $f (@required_common) {
+        unless (defined $entry->{$f}) {
+            die sprintf("error: guc_parameters.data: '%s' is missing required field '%s'\n",
+                        $entry->{name} // '<unknown>', $f);
+        }
+    }
+
+    # Check type-specific fields
+    if (exists $required_by_type{$entry->{type}}) {
+        for my $f (@{ $required_by_type{$entry->{type}} }) {
+            unless (defined $entry->{$f}) {
+                die sprintf("error: guc_parameters.data: '%s' of type '%s' is missing required field '%s'\n",
+                            $entry->{name}, $entry->{type}, $f);
+            }
+        }
+    }
+}
+
 # Print GUC table.
 sub print_table
 {
@@ -50,6 +84,8 @@ sub print_table
 
 	foreach my $entry (@{$parse})
 	{
+		validate_guc_entry($entry);
+
 		if (defined($prev_name) && lc($prev_name) ge lc($entry->{name}))
 		{
 			die sprintf(
-- 
2.39.5 (Apple Git-154)

In reply to: Chao Li (#1)
Re: gen_guc_tables.pl: Validate required GUC fields before code generation

Chao Li <li.evan.chao@gmail.com> writes:

Hi Hacker,

While working on the other patch and editing guc_parameters.dat, I
mistakenly deleted a “max” value line, then I got the following error
during build:

```
'/opt/homebrew/bin/perl' ../../../src/backend/utils/misc/gen_guc_tables.pl
../../../src/backend/utils/misc/guc_parameters.dat guc_tables.inc.c
Use of uninitialized value in printf at ../../../src/backend/utils/misc/
gen_guc_tables.pl line 78.
make[2]: *** [guc_tables.inc.c] Error 25
```

Yeah, that's not a very helpful error.

The error message is unclear and is not helpful to identify the real issue.

I am not an expert of perl, but I tried to make an enhancement that will
print an error message like:

The patch looks good overall, but it could be made a bit more concise
(without sacrificing readability, IMO):

+sub validate_guc_entry
+{
+    my ($entry) = @_;
+
+    my @required_common = qw(name type context group short_desc variable boot_val);
+
+    # Type-specific required fields
+    my %required_by_type = (
+        int  => [qw(min max)],
+        real => [qw(min max)],
+        enum => [qw(options)],
+        bool => [],   # no extra required fields
+        string => [], # no extra required fields
+    );

Since we're checking if the key exists, there's no point in having these
empty arrays for types that don't have any extra fields.

+    # Check common required fields
+    for my $f (@required_common) {
+        unless (defined $entry->{$f}) {
+            die sprintf("error: guc_parameters.data: '%s' is missing required field '%s'\n",
+                        $entry->{name} // '<unknown>', $f);
+        }
+    }
+
+    # Check type-specific fields
+    if (exists $required_by_type{$entry->{type}}) {
+        for my $f (@{ $required_by_type{$entry->{type}} }) {
+            unless (defined $entry->{$f}) {
+                die sprintf("error: guc_parameters.data: '%s' of type '%s' is missing required field '%s'\n",
+                            $entry->{name}, $entry->{type}, $f);
+            }
+        }
+    }
+}

These two loops could be combined, with something like:

for my $f (@required_common, @{ $required_by_type{$entry->{type}} // [] }) {

The `// []` makes it default to an empty array for types that don't have
any extra fields, so we don't need to list them in the %required_by_type
hash. OTOH, we could instead throw an error if there's no entry, to
catch typos in the type field here, instead of only when we get around
to compiling the generated file. But that should IMO be done after the
checking for required fields, so we want the fallback here even if we
have the empty arrays.

There's no need for a `// ''` on the `->{type}` lookup, since it
would have died while checking the common fields if that were missing.

- ilmari
-- resident perl nitpicker

#3Álvaro Herrera
alvherre@kurilemu.de
In reply to: Chao Li (#1)
Re: gen_guc_tables.pl: Validate required GUC fields before code generation

On 2025-Nov-10, Chao Li wrote:

While working on the other patch and editing guc_parameters.dat, I
mistakenly deleted a “max” value line, then I got the following error
during build:

The error message is unclear and is not helpful to identify the real issue.

Funny -- I made a very similar mistake recently and was also going to
complain about the resulting error message, so +1 for getting it
improved along the lines you proposed, plus Ilmari's suggestions.

--
Álvaro Herrera 48°01'N 7°57'E — https://www.EnterpriseDB.com/
"Those who use electric razors are infidels destined to burn in hell while
we drink from rivers of beer, download free vids and mingle with naked
well shaved babes." (http://slashdot.org/comments.pl?sid=44793&amp;cid=4647152)

#4Chao Li
li.evan.chao@gmail.com
In reply to: Dagfinn Ilmari Mannsåker (#2)
1 attachment(s)
Re: gen_guc_tables.pl: Validate required GUC fields before code generation

On Mon, Nov 10, 2025 at 8:02 PM Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
wrote:

Chao Li <li.evan.chao@gmail.com> writes:

Hi Hacker,

While working on the other patch and editing guc_parameters.dat, I
mistakenly deleted a “max” value line, then I got the following error
during build:

```
'/opt/homebrew/bin/perl' ../../../src/backend/utils/misc/

gen_guc_tables.pl

../../../src/backend/utils/misc/guc_parameters.dat guc_tables.inc.c
Use of uninitialized value in printf at ../../../src/backend/utils/misc/
gen_guc_tables.pl line 78.
make[2]: *** [guc_tables.inc.c] Error 25
```

Yeah, that's not a very helpful error.

The error message is unclear and is not helpful to identify the real

issue.

I am not an expert of perl, but I tried to make an enhancement that will
print an error message like:

The patch looks good overall, but it could be made a bit more concise
(without sacrificing readability, IMO):

+sub validate_guc_entry
+{
+    my ($entry) = @_;
+
+    my @required_common = qw(name type context group short_desc

variable boot_val);

+
+    # Type-specific required fields
+    my %required_by_type = (
+        int  => [qw(min max)],
+        real => [qw(min max)],
+        enum => [qw(options)],
+        bool => [],   # no extra required fields
+        string => [], # no extra required fields
+    );

Since we're checking if the key exists, there's no point in having these
empty arrays for types that don't have any extra fields.

Deleted bool and string.

+    # Check common required fields
+    for my $f (@required_common) {
+        unless (defined $entry->{$f}) {
+            die sprintf("error: guc_parameters.data: '%s' is missing

required field '%s'\n",

+                        $entry->{name} // '<unknown>', $f);
+        }
+    }
+
+    # Check type-specific fields
+    if (exists $required_by_type{$entry->{type}}) {
+        for my $f (@{ $required_by_type{$entry->{type}} }) {
+            unless (defined $entry->{$f}) {
+                die sprintf("error: guc_parameters.data: '%s' of type

'%s' is missing required field '%s'\n",

+                            $entry->{name}, $entry->{type}, $f);
+            }
+        }
+    }
+}

These two loops could be combined, with something like:

for my $f (@required_common, @{ $required_by_type{$entry->{type}} //
[] }) {

The `// []` makes it default to an empty array for types that don't have
any extra fields, so we don't need to list them in the %required_by_type
hash. OTOH, we could instead throw an error if there's no entry, to
catch typos in the type field here, instead of only when we get around
to compiling the generated file. But that should IMO be done after the
checking for required fields, so we want the fallback here even if we
have the empty arrays.

Combined the two loops.

There's no need for a `// ''` on the `->{type}` lookup, since it
would have died while checking the common fields if that were missing.

Based on my test, a `// ''` on the `->{type}` lookup is still needed,
otherwise if I remove a "type" field, then I got:

```
'/opt/homebrew/bin/perl' ../../../src/backend/utils/misc/gen_guc_tables.pl
../../../src/backend/utils/misc/guc_parameters.dat guc_tables.inc.c
Use of uninitialized value in hash element at
../../../src/backend/utils/misc/gen_guc_tables.pl line 55.
```

In v2, I also added line number to the error message, because I found that
if "name" field is missing or typo on "name", then the error message
without a line number doesn't help either, like:
```
'/opt/homebrew/bin/perl' ../../../src/backend/utils/misc/gen_guc_tables.pl
../../../src/backend/utils/misc/guc_parameters.dat guc_tables.inc.c
error: guc_parameters.data: '<unknown>' of type 'int' is missing required
field 'name'
```

With a line number, we can easily identify the error place:
```
'/opt/homebrew/bin/perl' ../../../src/backend/utils/misc/gen_guc_tables.pl
../../../src/backend/utils/misc/guc_parameters.dat guc_tables.inc.c
error: guc_parameters.data line 1882: '<unknown>' of type 'int' is missing
required field 'name'
```

Best regards,
Chao Li (Evan)
---------------------
HighGo Software Co., Ltd.
https://www.highgo.com/

Attachments:

v2-0001-gen_guc_tables.pl-Validate-required-GUC-fields-be.patchapplication/octet-stream; name=v2-0001-gen_guc_tables.pl-Validate-required-GUC-fields-be.patchDownload
From edcda2c6c52c15607fcffd8bf3c8779d2b901b30 Mon Sep 17 00:00:00 2001
From: "Chao Li (Evan)" <lic@highgo.com>
Date: Mon, 10 Nov 2025 16:35:36 +0800
Subject: [PATCH v2] gen_guc_tables.pl: Validate required GUC fields before
 code generation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Previously, gen_guc_tables.pl would emit "Use of uninitialized value"
warnings if required fields were missing in guc_parameters.dat (for
example, when an integer or real GUC omitted the 'max' value).  The
resulting error messages were unclear and did not identify which GUC
entry was problematic.

Add explicit validation of required fields depending on the parameter
type, and fail with a clear and specific message such as:

    error: guc_parameters.data line 1909: 'max_index_keys' of type 'int' is missing required field 'max'

No functional changes to generated guc_tables.c.

Author: Chao Li <lic@highgo.com>
Reviewed-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Discussion: https://postgr.es/m/305B1E2D-3E35-410B-A840-53F62EDF5045@gmail.com
---
 src/backend/utils/misc/gen_guc_tables.pl | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/src/backend/utils/misc/gen_guc_tables.pl b/src/backend/utils/misc/gen_guc_tables.pl
index 601c34ec30b..cdcb4966a1f 100644
--- a/src/backend/utils/misc/gen_guc_tables.pl
+++ b/src/backend/utils/misc/gen_guc_tables.pl
@@ -38,6 +38,28 @@ sub dquote
 	return q{"} . $s =~ s/"/\\"/gr . q{"};
 }
 
+sub validate_guc_entry
+{
+    my ($entry) = @_;
+
+    my @required_common = qw(name type context group short_desc variable boot_val);
+
+    # Type-specific required fields
+    my %required_by_type = (
+        int  => [qw(min max)],
+        real => [qw(min max)],
+        enum => [qw(options)],
+    );
+
+    # Check common required fields
+	for my $f (@required_common, @{ $required_by_type{$entry->{type} // ''} // [] }) {
+        unless (defined $entry->{$f}) {
+            die sprintf("error: guc_parameters.data line %d: '%s' of type '%s' is missing required field '%s'\n",
+                        $entry->{line_number}, $entry->{name} // '<unknown>', $entry->{type} // '<unknown>', $f);
+        }
+    }
+}
+
 # Print GUC table.
 sub print_table
 {
@@ -50,6 +72,8 @@ sub print_table
 
 	foreach my $entry (@{$parse})
 	{
+		validate_guc_entry($entry);
+
 		if (defined($prev_name) && lc($prev_name) ge lc($entry->{name}))
 		{
 			die sprintf(
-- 
2.39.5 (Apple Git-154)

#5Chao Li
li.evan.chao@gmail.com
In reply to: Chao Li (#4)
Re: gen_guc_tables.pl: Validate required GUC fields before code generation

Added to CF: https://commitfest.postgresql.org/patch/6226/

On Nov 12, 2025, at 09:10, Chao Li <li.evan.chao@gmail.com> wrote:

On Mon, Nov 10, 2025 at 8:02 PM Dagfinn Ilmari Mannsåker <ilmari@ilmari.org> wrote:
Chao Li <li.evan.chao@gmail.com> writes:

Hi Hacker,

While working on the other patch and editing guc_parameters.dat, I
mistakenly deleted a “max” value line, then I got the following error
during build:

```
'/opt/homebrew/bin/perl' ../../../src/backend/utils/misc/gen_guc_tables.pl
../../../src/backend/utils/misc/guc_parameters.dat guc_tables.inc.c
Use of uninitialized value in printf at ../../../src/backend/utils/misc/
gen_guc_tables.pl line 78.
make[2]: *** [guc_tables.inc.c] Error 25
```

Yeah, that's not a very helpful error.

The error message is unclear and is not helpful to identify the real issue.

I am not an expert of perl, but I tried to make an enhancement that will
print an error message like:

The patch looks good overall, but it could be made a bit more concise
(without sacrificing readability, IMO):

+sub validate_guc_entry
+{
+    my ($entry) = @_;
+
+    my @required_common = qw(name type context group short_desc variable boot_val);
+
+    # Type-specific required fields
+    my %required_by_type = (
+        int  => [qw(min max)],
+        real => [qw(min max)],
+        enum => [qw(options)],
+        bool => [],   # no extra required fields
+        string => [], # no extra required fields
+    );

Since we're checking if the key exists, there's no point in having these
empty arrays for types that don't have any extra fields.

Deleted bool and string.

+    # Check common required fields
+    for my $f (@required_common) {
+        unless (defined $entry->{$f}) {
+            die sprintf("error: guc_parameters.data: '%s' is missing required field '%s'\n",
+                        $entry->{name} // '<unknown>', $f);
+        }
+    }
+
+    # Check type-specific fields
+    if (exists $required_by_type{$entry->{type}}) {
+        for my $f (@{ $required_by_type{$entry->{type}} }) {
+            unless (defined $entry->{$f}) {
+                die sprintf("error: guc_parameters.data: '%s' of type '%s' is missing required field '%s'\n",
+                            $entry->{name}, $entry->{type}, $f);
+            }
+        }
+    }
+}

These two loops could be combined, with something like:

for my $f (@required_common, @{ $required_by_type{$entry->{type}} // [] }) {

The `// []` makes it default to an empty array for types that don't have
any extra fields, so we don't need to list them in the %required_by_type
hash. OTOH, we could instead throw an error if there's no entry, to
catch typos in the type field here, instead of only when we get around
to compiling the generated file. But that should IMO be done after the
checking for required fields, so we want the fallback here even if we
have the empty arrays.

Combined the two loops.

There's no need for a `// ''` on the `->{type}` lookup, since it
would have died while checking the common fields if that were missing.

Based on my test, a `// ''` on the `->{type}` lookup is still needed, otherwise if I remove a "type" field, then I got:

```
'/opt/homebrew/bin/perl' ../../../src/backend/utils/misc/gen_guc_tables.pl ../../../src/backend/utils/misc/guc_parameters.dat guc_tables.inc.c
Use of uninitialized value in hash element at ../../../src/backend/utils/misc/gen_guc_tables.pl line 55.
```

In v2, I also added line number to the error message, because I found that if "name" field is missing or typo on "name", then the error message without a line number doesn't help either, like:
```
'/opt/homebrew/bin/perl' ../../../src/backend/utils/misc/gen_guc_tables.pl ../../../src/backend/utils/misc/guc_parameters.dat guc_tables.inc.c
error: guc_parameters.data: '<unknown>' of type 'int' is missing required field 'name'
```
With a line number, we can easily identify the error place:
```
'/opt/homebrew/bin/perl' ../../../src/backend/utils/misc/gen_guc_tables.pl ../../../src/backend/utils/misc/guc_parameters.dat guc_tables.inc.c
error: guc_parameters.data line 1882: '<unknown>' of type 'int' is missing required field 'name'
```

Best regards,
Chao Li (Evan)
---------------------
HighGo Software Co., Ltd.
https://www.highgo.com/
<v2-0001-gen_guc_tables.pl-Validate-required-GUC-fields-be.patch>

--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/

#6Mahmoud Ayman
mahmoud.ayman.fcai@gmail.com
In reply to: Chao Li (#5)
Re: gen_guc_tables.pl: Validate required GUC fields before code generation

The following review has been posted through the commitfest application:
make installcheck-world: not tested
Implements feature: not tested
Spec compliant: not tested
Documentation: not tested

I tested patch v2 on top of current master.

- The patch applies cleanly.
- Full build and regression tests pass (“All 231 tests passed.”).
- I tested the validation by removing the `max` field from an int GUC
(archive_timeout). The script now reports a clear error pointing to the
exact line and missing field, instead of Perl “uninitialized value” warnings.
- Verified that the generated guc_tables.c output is unchanged.
- The added validation code is small and straightforward, and integrates
cleanly into the existing script.

Everything works as described.
I think this patch is ready for committer.

Reviewed-by: Mahmoud Ayman

The new status of this patch is: Ready for Committer

#7Peter Eisentraut
peter@eisentraut.org
In reply to: Chao Li (#4)
Re: gen_guc_tables.pl: Validate required GUC fields before code generation

I find the data structures that you have constructed here barely
understandable:

my %required_by_type = (
int => [qw(min max)],
real => [qw(min max)],
enum => [qw(options)],
);

for my $f (@required_common, @{ $required_by_type{$entry->{type} //
''} // [] }) {

[qw(min max)] is an array inside an array reference? I think? Do we
need two levels of nesting?

I think this // notation is unnecessarily confusing, and why do we need
two of them. I thought your first patch

+        bool => [],   # no extra required fields
+        string => [], # no extra required fields

was clearer. And that way, we also check that the field type is one of
the ones we support.

#8Chao Li
li.evan.chao@gmail.com
In reply to: Peter Eisentraut (#7)
1 attachment(s)
Re: gen_guc_tables.pl: Validate required GUC fields before code generation

On Wed, Nov 19, 2025 at 4:33 PM Peter Eisentraut <peter@eisentraut.org>
wrote:

I find the data structures that you have constructed here barely
understandable:

my %required_by_type = (
int => [qw(min max)],
real => [qw(min max)],
enum => [qw(options)],
);

for my $f (@required_common, @{ $required_by_type{$entry->{type} //
''} // [] }) {

[qw(min max)] is an array inside an array reference? I think? Do we
need two levels of nesting?

I think this // notation is unnecessarily confusing, and why do we need
two of them. I thought your first patch

+        bool => [],   # no extra required fields
+        string => [], # no extra required fields

was clearer. And that way, we also check that the field type is one of
the ones we support.

Yeah, the two levels of nesting is not necessary. It was to address the
review comments of v1, I removed bool and string from required_by_type and
combined the two loops into one. Because bool and string don't exist in
required_by_type, so that $required_by_type{$entry->{type} needs a
fallback, why's why // was added.

v3 goes back to v1 plus I add a check for unknown field type per your
suggestion, for example:
```
error: guc_parameters.data line 2271: unknown GUC type 'intt'
```

Best regards,
Chao Li (Evan)
---------------------
HighGo Software Co., Ltd.
https://www.highgo.com/

Attachments:

v3-0001-gen_guc_tables.pl-Validate-required-GUC-fields-be.patchapplication/octet-stream; name=v3-0001-gen_guc_tables.pl-Validate-required-GUC-fields-be.patchDownload
From 394c9c3727388f48dea34daa376265e7bb805f14 Mon Sep 17 00:00:00 2001
From: "Chao Li (Evan)" <lic@highgo.com>
Date: Mon, 10 Nov 2025 16:35:36 +0800
Subject: [PATCH v3] gen_guc_tables.pl: Validate required GUC fields before
 code generation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Previously, gen_guc_tables.pl would emit "Use of uninitialized value"
warnings if required fields were missing in guc_parameters.dat (for
example, when an integer or real GUC omitted the 'max' value).  The
resulting error messages were unclear and did not identify which GUC
entry was problematic.

Add explicit validation of required fields depending on the parameter
type, and fail with a clear and specific message such as:

    error: guc_parameters.data line 1909: 'max_index_keys' of type 'int' is missing required field 'max'

No functional changes to generated guc_tables.c.

Author: Chao Li <lic@highgo.com>
Reviewed-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Reviewed-by: Peter Eisentraut <peter@eisentraut.org>
Discussion: https://postgr.es/m/305B1E2D-3E35-410B-A840-53F62EDF5045@gmail.com
---
 src/backend/utils/misc/gen_guc_tables.pl | 46 ++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/src/backend/utils/misc/gen_guc_tables.pl b/src/backend/utils/misc/gen_guc_tables.pl
index 601c34ec30b..0d6619d931b 100644
--- a/src/backend/utils/misc/gen_guc_tables.pl
+++ b/src/backend/utils/misc/gen_guc_tables.pl
@@ -38,6 +38,50 @@ sub dquote
 	return q{"} . $s =~ s/"/\\"/gr . q{"};
 }
 
+sub validate_guc_entry
+{
+	my ($entry) = @_;
+
+	my @required_common = qw(name type context group short_desc variable boot_val);
+
+	# Type-specific required fields
+	my %required_by_type = (
+		int    => [qw(min max)],
+		real   => [qw(min max)],
+		enum   => [qw(options)],
+		bool   => [],   # no extra required fields
+		string => [],   # no extra required fields
+	);
+
+	# Check common required fields
+	for my $f (@required_common) {
+		unless (defined $entry->{$f}) {
+			die sprintf(
+				"error: guc_parameters.data line %d: '%s' is missing required field '%s'\n",
+				$entry->{line_number}, $entry->{name} // '<unknown>', $f
+			);
+		}
+	}
+
+	# Check that the type is known and check type-specific fields
+	unless (exists $required_by_type{$entry->{type}}) {
+		die sprintf(
+			"error: guc_parameters.data line %d: unknown GUC type '%s'\n",
+			$entry->{line_number}, $entry->{type} // '<unknown>'
+		);
+	}
+
+	# Check per-type required fields
+	for my $f (@{ $required_by_type{$entry->{type}} }) {
+		unless (defined $entry->{$f}) {
+			die sprintf(
+				"error: guc_parameters.data line %d: '%s' of type '%s' is missing required field '%s'\n",
+				$entry->{line_number}, $entry->{name}, $entry->{type}, $f
+			);
+		}
+	}
+}
+
 # Print GUC table.
 sub print_table
 {
@@ -50,6 +94,8 @@ sub print_table
 
 	foreach my $entry (@{$parse})
 	{
+		validate_guc_entry($entry);
+
 		if (defined($prev_name) && lc($prev_name) ge lc($entry->{name}))
 		{
 			die sprintf(
-- 
2.39.5 (Apple Git-154)

In reply to: Chao Li (#8)
Re: gen_guc_tables.pl: Validate required GUC fields before code generation

Chao Li <li.evan.chao@gmail.com> writes:

On Wed, Nov 19, 2025 at 4:33 PM Peter Eisentraut <peter@eisentraut.org>
wrote:

I find the data structures that you have constructed here barely
understandable:

my %required_by_type = (
int => [qw(min max)],
real => [qw(min max)],
enum => [qw(options)],
);

for my $f (@required_common, @{ $required_by_type{$entry->{type} //
''} // [] }) {

[qw(min max)] is an array inside an array reference? I think? Do we
need two levels of nesting?

No there is no nesting. qw() is a quote operator ("quote words") that
returns a list of the words inside, and [] creates an array of the
elements of the list and returns a reference to it, So [qw(min max)] is
equivalent to ['min', 'max'].

I think this // notation is unnecessarily confusing, and why do we need
two of them. I thought your first patch

+        bool => [],   # no extra required fields
+        string => [], # no extra required fields

was clearer. And that way, we also check that the field type is one of
the ones we support.

Yeah, the two levels of nesting is not necessary. It was to address the
review comments of v1, I removed bool and string from required_by_type and
combined the two loops into one. Because bool and string don't exist in
required_by_type, so that $required_by_type{$entry->{type} needs a
fallback, why's why // was added.

The fallback was only necessary if we wanted to combine the two
originally-identical loops to check all the required fields in one go,
before checking that specfied type is known.

But now that we're checking the type between the check for the common
and typ-specific fields that's no longer relevant.

Personally, as a long-time Perl programmer I prefer the conciseness of
the combined loop, but I guess in a predominantly C codebase it makes
sense to keep things simpler and more explicitly spelled out.

v3 goes back to v1 plus I add a check for unknown field type per your
suggestion, for example:
```
error: guc_parameters.data line 2271: unknown GUC type 'intt'
```

We've already validated that the name field exists, so this error
message should include that, like the other ones do.

Otherwise, LGTM.

Show quoted text

Best regards,
Chao Li (Evan)
---------------------
HighGo Software Co., Ltd.
https://www.highgo.com/

#10Chao Li
li.evan.chao@gmail.com
In reply to: Dagfinn Ilmari Mannsåker (#9)
1 attachment(s)
Re: gen_guc_tables.pl: Validate required GUC fields before code generation

On Wed, Nov 19, 2025 at 7:56 PM Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
wrote:

v3 goes back to v1 plus I add a check for unknown field type per your
suggestion, for example:
```
error: guc_parameters.data line 2271: unknown GUC type 'intt'
```

We've already validated that the name field exists, so this error
message should include that, like the other ones do.

Make sense. I added field name to this error message in v4, now it looks
like:
```
error: guc_parameters.dat line 2278: 'primary_conninfo' has unknown GUC
type 'string1'
```

Chao Li (Evan)
---------------------
HighGo Software Co., Ltd.
https://www.highgo.com/

Attachments:

v4-0001-gen_guc_tables.pl-Validate-required-GUC-fields-be.patchapplication/octet-stream; name=v4-0001-gen_guc_tables.pl-Validate-required-GUC-fields-be.patchDownload
From 0e7c9d362e6a3c2e49ef614ff4cdd4fcb01e7494 Mon Sep 17 00:00:00 2001
From: "Chao Li (Evan)" <lic@highgo.com>
Date: Mon, 10 Nov 2025 16:35:36 +0800
Subject: [PATCH v4] gen_guc_tables.pl: Validate required GUC fields before
 code generation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Previously, gen_guc_tables.pl would emit "Use of uninitialized value"
warnings if required fields were missing in guc_parameters.dat (for
example, when an integer or real GUC omitted the 'max' value).  The
resulting error messages were unclear and did not identify which GUC
entry was problematic.

Add explicit validation of required fields depending on the parameter
type, and fail with a clear and specific message such as:

    error: guc_parameters.dat line 1909: 'max_index_keys' of type 'int' is missing required field 'max'

No functional changes to generated guc_tables.c.

Author: Chao Li <lic@highgo.com>
Reviewed-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Reviewed-by: Peter Eisentraut <peter@eisentraut.org>
Discussion: https://postgr.es/m/305B1E2D-3E35-410B-A840-53F62EDF5045@gmail.com
---
 src/backend/utils/misc/gen_guc_tables.pl | 46 ++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/src/backend/utils/misc/gen_guc_tables.pl b/src/backend/utils/misc/gen_guc_tables.pl
index 601c34ec30b..3930720dffd 100644
--- a/src/backend/utils/misc/gen_guc_tables.pl
+++ b/src/backend/utils/misc/gen_guc_tables.pl
@@ -38,6 +38,50 @@ sub dquote
 	return q{"} . $s =~ s/"/\\"/gr . q{"};
 }
 
+sub validate_guc_entry
+{
+	my ($entry) = @_;
+
+	my @required_common = qw(name type context group short_desc variable boot_val);
+
+	# Type-specific required fields
+	my %required_by_type = (
+		int    => [qw(min max)],
+		real   => [qw(min max)],
+		enum   => [qw(options)],
+		bool   => [],   # no extra required fields
+		string => [],   # no extra required fields
+	);
+
+	# Check common required fields
+	for my $f (@required_common) {
+		unless (defined $entry->{$f}) {
+			die sprintf(
+				"error: guc_parameters.dat line %d: '%s' is missing required field '%s'\n",
+				$entry->{line_number}, $entry->{name} // '<unknown>', $f
+			);
+		}
+	}
+
+	# Check that the type is known and check type-specific fields
+	unless (exists $required_by_type{$entry->{type}}) {
+		die sprintf(
+			"error: guc_parameters.dat line %d: '%s' has unknown GUC type '%s'\n",
+			$entry->{line_number}, $entry->{name}, $entry->{type} // '<unknown>'
+		);
+	}
+
+	# Check per-type required fields
+	for my $f (@{ $required_by_type{$entry->{type}} }) {
+		unless (defined $entry->{$f}) {
+			die sprintf(
+				"error: guc_parameters.dat line %d: '%s' of type '%s' is missing required field '%s'\n",
+				$entry->{line_number}, $entry->{name}, $entry->{type}, $f
+			);
+		}
+	}
+}
+
 # Print GUC table.
 sub print_table
 {
@@ -50,6 +94,8 @@ sub print_table
 
 	foreach my $entry (@{$parse})
 	{
+		validate_guc_entry($entry);
+
 		if (defined($prev_name) && lc($prev_name) ge lc($entry->{name}))
 		{
 			die sprintf(
-- 
2.39.5 (Apple Git-154)

#11Peter Eisentraut
peter@eisentraut.org
In reply to: Chao Li (#10)
Re: gen_guc_tables.pl: Validate required GUC fields before code generation

On 20.11.25 06:51, Chao Li wrote:

On Wed, Nov 19, 2025 at 7:56 PM Dagfinn Ilmari Mannsåker
<ilmari@ilmari.org <mailto:ilmari@ilmari.org>> wrote:

v3 goes back to v1 plus I add a check for unknown field type per your
suggestion, for example:
```
error: guc_parameters.data line 2271: unknown GUC type 'intt'
```

We've already validated that the name field exists, so this error
message should include that, like the other ones do.

Make sense. I added field name to this error message in v4, now it looks
like:
```
error: guc_parameters.dat line 2278: 'primary_conninfo' has unknown GUC
type 'string1'
```

Thanks, I committed this. I made some changes to the error message
format so that it matches the format recognized by editors, and to use
PostgreSQL quoting style (double quotes). I also removed some code
comments that just restated what was already obvious from the code.