From 72c580c6ec1e8e5bc29c6edfb11afb8e062de2b5 Mon Sep 17 00:00:00 2001
From: Jelte Fennema-Nio <postgres@jeltef.nl>
Date: Mon, 6 Apr 2026 17:05:27 +0200
Subject: [PATCH v5] Use named arguments for pg_get_*_ddl() functions

In 4881981f92024 some infrastructure was introduced to allow optional
key-value pairs as arguments. This removes that infrastructure in favor
of named arguments. No custom parsing and typechecking logic is needed
this way.
---
 doc/src/sgml/func/func-info.sgml             |  53 ++--
 src/backend/utils/adt/ddlutils.c             | 256 ++-----------------
 src/include/catalog/pg_proc.dat              |  36 ++-
 src/test/regress/expected/database_ddl.out   |  10 +-
 src/test/regress/expected/role_ddl.out       |   4 +-
 src/test/regress/expected/tablespace_ddl.out |   4 +-
 src/test/regress/sql/database_ddl.sql        |   9 +-
 src/test/regress/sql/role_ddl.sql            |   4 +-
 src/test/regress/sql/tablespace_ddl.sql      |   4 +-
 src/tools/pgindent/typedefs.list             |   2 -
 10 files changed, 76 insertions(+), 306 deletions(-)

diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml
index 80cf11083d6..adf2bb93c0e 100644
--- a/doc/src/sgml/func/func-info.sgml
+++ b/doc/src/sgml/func/func-info.sgml
@@ -3895,8 +3895,10 @@ acl      | {postgres=arwdDxtm/postgres,foo=r/postgres}
         </indexterm>
         <function>pg_get_role_ddl</function>
         ( <parameter>role</parameter> <type>regrole</type>
-        <optional>, <literal>VARIADIC</literal> <parameter>options</parameter>
-        <type>text</type> </optional> )
+        <optional>, <parameter>pretty</parameter> <type>boolean</type>
+        <literal>DEFAULT false</literal> </optional>
+        <optional>, <parameter>memberships</parameter> <type>boolean</type>
+        <literal>DEFAULT true</literal> </optional> )
         <returnvalue>setof text</returnvalue>
        </para>
        <para>
@@ -3904,10 +3906,11 @@ acl      | {postgres=arwdDxtm/postgres,foo=r/postgres}
         <command>ALTER ROLE ... SET</command> statements for the given role.
         Each statement is returned as a separate row.
         Password information is never included in the output.
-        The following options are supported: <literal>pretty</literal> (boolean)
-        for pretty-printed output and <literal>memberships</literal> (boolean,
-        default true) to include <command>GRANT</command> statements for
-        role memberships and their options.
+        If <parameter>pretty</parameter> is true, the output is formatted with
+        newlines and indentation.
+        If <parameter>memberships</parameter> is true (the default),
+        <command>GRANT</command> statements for role memberships and their
+        options are included.
        </para></entry>
       </row>
       <row>
@@ -3917,15 +3920,19 @@ acl      | {postgres=arwdDxtm/postgres,foo=r/postgres}
         </indexterm>
         <function>pg_get_tablespace_ddl</function>
         ( <parameter>tablespace</parameter> <type>oid</type>
-        <optional>, <literal>VARIADIC</literal> <parameter>options</parameter>
-        <type>text</type> </optional> )
+        <optional>, <parameter>pretty</parameter> <type>boolean</type>
+        <literal>DEFAULT false</literal> </optional>
+        <optional>, <parameter>owner</parameter> <type>boolean</type>
+        <literal>DEFAULT true</literal> </optional> )
         <returnvalue>setof text</returnvalue>
        </para>
        <para>
         <function>pg_get_tablespace_ddl</function>
         ( <parameter>tablespace</parameter> <type>name</type>
-        <optional>, <literal>VARIADIC</literal> <parameter>options</parameter>
-        <type>text</type> </optional> )
+        <optional>, <parameter>pretty</parameter> <type>boolean</type>
+        <literal>DEFAULT false</literal> </optional>
+        <optional>, <parameter>owner</parameter> <type>boolean</type>
+        <literal>DEFAULT true</literal> </optional> )
         <returnvalue>setof text</returnvalue>
        </para>
        <para>
@@ -3933,9 +3940,10 @@ acl      | {postgres=arwdDxtm/postgres,foo=r/postgres}
         the specified tablespace (by OID or name).  If the tablespace has
         options set, an <command>ALTER TABLESPACE ... SET</command> statement
         is also returned.  Each statement is returned as a separate row.
-        The following options are supported: <literal>pretty</literal> (boolean)
-        for formatted output and <literal>owner</literal> (boolean) to include
-        <literal>OWNER</literal>.
+        If <parameter>pretty</parameter> is true, the output is formatted with
+        newlines and indentation.
+        If <parameter>owner</parameter> is true (the default), an
+        <literal>OWNER</literal> clause is included.
        </para></entry>
       </row>
       <row>
@@ -3945,8 +3953,12 @@ acl      | {postgres=arwdDxtm/postgres,foo=r/postgres}
         </indexterm>
         <function>pg_get_database_ddl</function>
         ( <parameter>database</parameter> <type>regdatabase</type>
-        <optional>, <literal>VARIADIC</literal> <parameter>options</parameter>
-        <type>text</type> </optional> )
+        <optional>, <parameter>pretty</parameter> <type>boolean</type>
+        <literal>DEFAULT false</literal> </optional>
+        <optional>, <parameter>owner</parameter> <type>boolean</type>
+        <literal>DEFAULT true</literal> </optional>
+        <optional>, <parameter>tablespace</parameter> <type>boolean</type>
+        <literal>DEFAULT true</literal> </optional> )
         <returnvalue>setof text</returnvalue>
        </para>
        <para>
@@ -3954,11 +3966,12 @@ acl      | {postgres=arwdDxtm/postgres,foo=r/postgres}
         specified database, followed by <command>ALTER DATABASE</command>
         statements for connection limit, template status, and configuration
         settings.  Each statement is returned as a separate row.
-        The following options are supported:
-        <literal>pretty</literal> (boolean) for formatted output,
-        <literal>owner</literal> (boolean) to include <literal>OWNER</literal>,
-        and <literal>tablespace</literal> (boolean) to include
-        <literal>TABLESPACE</literal>.
+        If <parameter>pretty</parameter> is true, the output is formatted with
+        newlines and indentation.
+        If <parameter>owner</parameter> is true (the default), an
+        <literal>OWNER</literal> clause is included.
+        If <parameter>tablespace</parameter> is true (the default), a
+        <literal>TABLESPACE</literal> clause is included.
        </para></entry>
       </row>
      </tbody>
diff --git a/src/backend/utils/adt/ddlutils.c b/src/backend/utils/adt/ddlutils.c
index b16c277d000..f19901d7523 100644
--- a/src/backend/utils/adt/ddlutils.c
+++ b/src/backend/utils/adt/ddlutils.c
@@ -39,42 +39,12 @@
 #include "utils/fmgroids.h"
 #include "utils/guc.h"
 #include "utils/lsyscache.h"
-#include "utils/pg_locale.h"
 #include "utils/rel.h"
 #include "utils/ruleutils.h"
 #include "utils/syscache.h"
 #include "utils/timestamp.h"
 #include "utils/varlena.h"
 
-/* Option value types for DDL option parsing */
-typedef enum
-{
-	DDL_OPT_BOOL,
-	DDL_OPT_TEXT,
-	DDL_OPT_INT,
-} DdlOptType;
-
-/*
- * A single DDL option descriptor: caller fills in name and type,
- * parse_ddl_options fills in isset + the appropriate value field.
- */
-typedef struct DdlOption
-{
-	const char *name;			/* option name (case-insensitive match) */
-	DdlOptType	type;			/* expected value type */
-	bool		isset;			/* true if caller supplied this option */
-	/* fields for specific option types */
-	union
-	{
-		bool		boolval;	/* filled in for DDL_OPT_BOOL */
-		char	   *textval;	/* filled in for DDL_OPT_TEXT (palloc'd) */
-		int			intval;		/* filled in for DDL_OPT_INT */
-	};
-} DdlOption;
-
-
-static void parse_ddl_options(FunctionCallInfo fcinfo, int variadic_start,
-							  DdlOption *opts, int nopts);
 static void append_ddl_option(StringInfo buf, bool pretty, int indent,
 							  const char *fmt,...)
 			pg_attribute_printf(4, 5);
@@ -83,150 +53,11 @@ static void append_guc_value(StringInfo buf, const char *name,
 static List *pg_get_role_ddl_internal(Oid roleid, bool pretty,
 									  bool memberships);
 static List *pg_get_tablespace_ddl_internal(Oid tsid, bool pretty, bool no_owner);
-static Datum pg_get_tablespace_ddl_srf(FunctionCallInfo fcinfo, Oid tsid, bool isnull);
+static Datum pg_get_tablespace_ddl_srf(FunctionCallInfo fcinfo, Oid tsid);
 static List *pg_get_database_ddl_internal(Oid dbid, bool pretty,
 										  bool no_owner, bool no_tablespace);
 
 
-/*
- * parse_ddl_options
- * 		Parse variadic name/value option pairs
- *
- * Options are passed as alternating key/value text pairs.  The caller
- * provides an array of DdlOption descriptors specifying the accepted
- * option names and their types; this function matches each supplied
- * pair against the array, validates the value, and fills in the
- * result fields.
- */
-static void
-parse_ddl_options(FunctionCallInfo fcinfo, int variadic_start,
-				  DdlOption *opts, int nopts)
-{
-	Datum	   *args;
-	bool	   *nulls;
-	Oid		   *types;
-	int			nargs;
-
-	/* Clear all output fields */
-	for (int i = 0; i < nopts; i++)
-	{
-		opts[i].isset = false;
-		switch (opts[i].type)
-		{
-			case DDL_OPT_BOOL:
-				opts[i].boolval = false;
-				break;
-			case DDL_OPT_TEXT:
-				opts[i].textval = NULL;
-				break;
-			case DDL_OPT_INT:
-				opts[i].intval = 0;
-				break;
-		}
-	}
-
-	nargs = extract_variadic_args(fcinfo, variadic_start, true,
-								  &args, &types, &nulls);
-
-	if (nargs <= 0)
-		return;
-
-	/* Handle DEFAULT NULL case */
-	if (nargs == 1 && nulls[0])
-		return;
-
-	if (nargs % 2 != 0)
-		ereport(ERROR,
-				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-				 errmsg("variadic arguments must be name/value pairs"),
-				 errhint("Provide an even number of variadic arguments that can be divided into pairs.")));
-
-	/*
-	 * For each option name/value pair, find corresponding positional option
-	 * for the option name, and assign the option value.
-	 */
-	for (int i = 0; i < nargs; i += 2)
-	{
-		char	   *name;
-		char	   *valstr;
-		DdlOption  *opt = NULL;
-
-		if (nulls[i])
-			ereport(ERROR,
-					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-					 errmsg("option name at variadic position %d is null", i + 1)));
-
-		name = TextDatumGetCString(args[i]);
-
-		if (nulls[i + 1])
-			ereport(ERROR,
-					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-					 errmsg("value for option \"%s\" must not be null", name)));
-
-		/* Find matching option descriptor */
-		for (int j = 0; j < nopts; j++)
-		{
-			if (pg_strcasecmp(name, opts[j].name) == 0)
-			{
-				opt = &opts[j];
-				break;
-			}
-		}
-
-		if (opt == NULL)
-			ereport(ERROR,
-					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-					 errmsg("unrecognized option: \"%s\"", name)));
-
-		if (opt->isset)
-			ereport(ERROR,
-					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-					 errmsg("option \"%s\" is specified more than once",
-							name)));
-
-		valstr = TextDatumGetCString(args[i + 1]);
-
-		switch (opt->type)
-		{
-			case DDL_OPT_BOOL:
-				if (!parse_bool(valstr, &opt->boolval))
-					ereport(ERROR,
-							(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-							 errmsg("invalid value for boolean option \"%s\": %s",
-									name, valstr)));
-				break;
-
-			case DDL_OPT_TEXT:
-				opt->textval = valstr;
-				valstr = NULL;	/* don't pfree below */
-				break;
-
-			case DDL_OPT_INT:
-				{
-					char	   *endp;
-					long		val;
-
-					errno = 0;
-					val = strtol(valstr, &endp, 10);
-					if (*endp != '\0' || errno == ERANGE ||
-						val < PG_INT32_MIN || val > PG_INT32_MAX)
-						ereport(ERROR,
-								(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-								 errmsg("invalid value for integer option \"%s\": %s",
-										name, valstr)));
-					opt->intval = (int) val;
-				}
-				break;
-		}
-
-		opt->isset = true;
-
-		if (valstr)
-			pfree(valstr);
-		pfree(name);
-	}
-}
-
 /*
  * Helper to append a formatted string with optional pretty-printing.
  */
@@ -601,27 +432,13 @@ pg_get_role_ddl(PG_FUNCTION_ARGS)
 	if (SRF_IS_FIRSTCALL())
 	{
 		MemoryContext oldcontext;
-		Oid			roleid;
-		DdlOption	opts[] = {
-			{"pretty", DDL_OPT_BOOL},
-			{"memberships", DDL_OPT_BOOL},
-		};
 
 		funcctx = SRF_FIRSTCALL_INIT();
 		oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
 
-		if (PG_ARGISNULL(0))
-		{
-			MemoryContextSwitchTo(oldcontext);
-			SRF_RETURN_DONE(funcctx);
-		}
-
-		roleid = PG_GETARG_OID(0);
-		parse_ddl_options(fcinfo, 1, opts, lengthof(opts));
-
-		statements = pg_get_role_ddl_internal(roleid,
-											  opts[0].isset && opts[0].boolval,
-											  !opts[1].isset || opts[1].boolval);
+		statements = pg_get_role_ddl_internal(PG_GETARG_OID(0),
+											  PG_GETARG_BOOL(1),
+											  PG_GETARG_BOOL(2));
 		funcctx->user_fctx = statements;
 		funcctx->max_calls = list_length(statements);
 
@@ -755,7 +572,7 @@ pg_get_tablespace_ddl_internal(Oid tsid, bool pretty, bool no_owner)
  * pg_get_tablespace_ddl_srf - common SRF logic for tablespace DDL
  */
 static Datum
-pg_get_tablespace_ddl_srf(FunctionCallInfo fcinfo, Oid tsid, bool isnull)
+pg_get_tablespace_ddl_srf(FunctionCallInfo fcinfo, Oid tsid)
 {
 	FuncCallContext *funcctx;
 	List	   *statements;
@@ -763,25 +580,13 @@ pg_get_tablespace_ddl_srf(FunctionCallInfo fcinfo, Oid tsid, bool isnull)
 	if (SRF_IS_FIRSTCALL())
 	{
 		MemoryContext oldcontext;
-		DdlOption	opts[] = {
-			{"pretty", DDL_OPT_BOOL},
-			{"owner", DDL_OPT_BOOL},
-		};
 
 		funcctx = SRF_FIRSTCALL_INIT();
 		oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
 
-		if (isnull)
-		{
-			MemoryContextSwitchTo(oldcontext);
-			SRF_RETURN_DONE(funcctx);
-		}
-
-		parse_ddl_options(fcinfo, 1, opts, lengthof(opts));
-
 		statements = pg_get_tablespace_ddl_internal(tsid,
-													opts[0].isset && opts[0].boolval,
-													opts[1].isset && !opts[1].boolval);
+													PG_GETARG_BOOL(1),
+													!PG_GETARG_BOOL(2));
 		funcctx->user_fctx = statements;
 		funcctx->max_calls = list_length(statements);
 
@@ -813,14 +618,7 @@ pg_get_tablespace_ddl_srf(FunctionCallInfo fcinfo, Oid tsid, bool isnull)
 Datum
 pg_get_tablespace_ddl_oid(PG_FUNCTION_ARGS)
 {
-	Oid			tsid = InvalidOid;
-	bool		isnull;
-
-	isnull = PG_ARGISNULL(0);
-	if (!isnull)
-		tsid = PG_GETARG_OID(0);
-
-	return pg_get_tablespace_ddl_srf(fcinfo, tsid, isnull);
+	return pg_get_tablespace_ddl_srf(fcinfo, PG_GETARG_OID(0));
 }
 
 /*
@@ -830,19 +628,10 @@ pg_get_tablespace_ddl_oid(PG_FUNCTION_ARGS)
 Datum
 pg_get_tablespace_ddl_name(PG_FUNCTION_ARGS)
 {
-	Oid			tsid = InvalidOid;
-	Name		tspname;
-	bool		isnull;
+	Name		tspname = PG_GETARG_NAME(0);
 
-	isnull = PG_ARGISNULL(0);
-
-	if (!isnull)
-	{
-		tspname = PG_GETARG_NAME(0);
-		tsid = get_tablespace_oid(NameStr(*tspname), false);
-	}
-
-	return pg_get_tablespace_ddl_srf(fcinfo, tsid, isnull);
+	return pg_get_tablespace_ddl_srf(fcinfo,
+									 get_tablespace_oid(NameStr(*tspname), false));
 }
 
 /*
@@ -1122,29 +911,14 @@ pg_get_database_ddl(PG_FUNCTION_ARGS)
 	if (SRF_IS_FIRSTCALL())
 	{
 		MemoryContext oldcontext;
-		Oid			dbid;
-		DdlOption	opts[] = {
-			{"pretty", DDL_OPT_BOOL},
-			{"owner", DDL_OPT_BOOL},
-			{"tablespace", DDL_OPT_BOOL},
-		};
 
 		funcctx = SRF_FIRSTCALL_INIT();
 		oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
 
-		if (PG_ARGISNULL(0))
-		{
-			MemoryContextSwitchTo(oldcontext);
-			SRF_RETURN_DONE(funcctx);
-		}
-
-		dbid = PG_GETARG_OID(0);
-		parse_ddl_options(fcinfo, 1, opts, lengthof(opts));
-
-		statements = pg_get_database_ddl_internal(dbid,
-												  opts[0].isset && opts[0].boolval,
-												  opts[1].isset && !opts[1].boolval,
-												  opts[2].isset && !opts[2].boolval);
+		statements = pg_get_database_ddl_internal(PG_GETARG_OID(0),
+												  PG_GETARG_BOOL(1),
+												  !PG_GETARG_BOOL(2),
+												  !PG_GETARG_BOOL(3));
 		funcctx->user_fctx = statements;
 		funcctx->max_calls = list_length(statements);
 
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 3ea17fc5629..1b5b6a683d3 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -8610,36 +8610,32 @@
   proname => 'pg_get_constraintdef', provolatile => 's', prorettype => 'text',
   proargtypes => 'oid bool', prosrc => 'pg_get_constraintdef_ext' },
 { oid => '8760', descr => 'get DDL to recreate a role',
-  proname => 'pg_get_role_ddl', provariadic => 'text', proisstrict => 'f',
+  proname => 'pg_get_role_ddl',
   provolatile => 's', proretset => 't', prorows => '10', prorettype => 'text',
-  proargtypes => 'regrole text',
-  proargmodes => '{i,v}',
-  proallargtypes => '{regrole,text}',
-  pronargdefaults => '1', proargdefaults => '{NULL}',
+  proargtypes => 'regrole bool bool',
+  proargnames => '{roleid,pretty,memberships}',
+  pronargdefaults => '2', proargdefaults => '{false,true}',
   prosrc => 'pg_get_role_ddl' },
 { oid => '8758', descr => 'get DDL to recreate a tablespace',
-  proname => 'pg_get_tablespace_ddl', provariadic => 'text', proisstrict => 'f',
+  proname => 'pg_get_tablespace_ddl',
   provolatile => 's', proretset => 't', prorows => '10', prorettype => 'text',
-  proargtypes => 'oid text',
-  proargmodes => '{i,v}',
-  proallargtypes => '{oid,text}',
-  pronargdefaults => '1', proargdefaults => '{NULL}',
+  proargtypes => 'oid bool bool',
+  proargnames => '{tablespace_oid,pretty,owner}',
+  pronargdefaults => '2', proargdefaults => '{false,true}',
   prosrc => 'pg_get_tablespace_ddl_oid' },
 { oid => '8759', descr => 'get DDL to recreate a tablespace',
-  proname => 'pg_get_tablespace_ddl', provariadic => 'text', proisstrict => 'f',
+  proname => 'pg_get_tablespace_ddl',
   provolatile => 's', proretset => 't', prorows => '10', prorettype => 'text',
-  proargtypes => 'name text',
-  proargmodes => '{i,v}',
-  proallargtypes => '{name,text}',
-  pronargdefaults => '1', proargdefaults => '{NULL}',
+  proargtypes => 'name bool bool',
+  proargnames => '{tablespace_name,pretty,owner}',
+  pronargdefaults => '2', proargdefaults => '{false,true}',
   prosrc => 'pg_get_tablespace_ddl_name' },
 { oid => '8762', descr => 'get DDL to recreate a database',
-  proname => 'pg_get_database_ddl', provariadic => 'text', proisstrict => 'f',
+  proname => 'pg_get_database_ddl',
   provolatile => 's', proretset => 't', prorows => '10', prorettype => 'text',
-  proargtypes => 'regdatabase text',
-  proargmodes => '{i,v}',
-  proallargtypes => '{regdatabase,text}',
-  pronargdefaults => '1', proargdefaults => '{NULL}',
+  proargtypes => 'regdatabase bool bool bool',
+  proargnames => '{database,pretty,owner,tablespace}',
+  pronargdefaults => '3', proargdefaults => '{false,true,true}',
   prosrc => 'pg_get_database_ddl' },
 { oid => '2509',
   descr => 'deparse an encoded expression with pretty-print option',
diff --git a/src/test/regress/expected/database_ddl.out b/src/test/regress/expected/database_ddl.out
index 97657e52cfa..67332212f56 100644
--- a/src/test/regress/expected/database_ddl.out
+++ b/src/test/regress/expected/database_ddl.out
@@ -36,12 +36,6 @@ SELECT * FROM pg_get_database_ddl(NULL);
 ---------------------
 (0 rows)
 
--- Invalid option value (should error)
-SELECT * FROM pg_get_database_ddl('regression_database_ddl', 'owner', 'invalid');
-ERROR:  invalid value for boolean option "owner": invalid
--- Duplicate option (should error)
-SELECT * FROM pg_get_database_ddl('regression_database_ddl', 'owner', 'false', 'owner', 'true');
-ERROR:  option "owner" is specified more than once
 -- Without options
 SELECT ddl_filter(pg_get_database_ddl) FROM pg_get_database_ddl('regression_database_ddl');
                                       ddl_filter                                      
@@ -53,7 +47,7 @@ SELECT ddl_filter(pg_get_database_ddl) FROM pg_get_database_ddl('regression_data
 (4 rows)
 
 -- With owner
-SELECT ddl_filter(pg_get_database_ddl) FROM pg_get_database_ddl('regression_database_ddl', 'owner', 'true');
+SELECT ddl_filter(pg_get_database_ddl) FROM pg_get_database_ddl('regression_database_ddl', owner => true);
                                       ddl_filter                                      
 --------------------------------------------------------------------------------------
  CREATE DATABASE regression_database_ddl WITH TEMPLATE = template0 ENCODING = 'UTF8';
@@ -64,7 +58,7 @@ SELECT ddl_filter(pg_get_database_ddl) FROM pg_get_database_ddl('regression_data
 
 -- Pretty-printed output
 \pset format unaligned
-SELECT ddl_filter(pg_get_database_ddl) FROM pg_get_database_ddl('regression_database_ddl', 'pretty', 'true', 'tablespace', 'false');
+SELECT ddl_filter(pg_get_database_ddl) FROM pg_get_database_ddl('regression_database_ddl', pretty => true, tablespace => false);
 ddl_filter
 CREATE DATABASE regression_database_ddl
     WITH TEMPLATE = template0
diff --git a/src/test/regress/expected/role_ddl.out b/src/test/regress/expected/role_ddl.out
index 575111da55c..e87e168e1f5 100644
--- a/src/test/regress/expected/role_ddl.out
+++ b/src/test/regress/expected/role_ddl.out
@@ -65,7 +65,7 @@ SELECT * FROM pg_get_role_ddl('regress_role-with-dash');
 
 -- Pretty-printed output
 \pset format unaligned
-SELECT * FROM pg_get_role_ddl('regress_role_ddl_test3', 'pretty', 'true');
+SELECT * FROM pg_get_role_ddl('regress_role_ddl_test3', pretty => true);
 pg_get_role_ddl
 CREATE ROLE regress_role_ddl_test3
     SUPERUSER
@@ -99,7 +99,7 @@ SELECT * FROM pg_get_role_ddl('regress_role_ddl_member');
 (3 rows)
 
 -- Role with memberships suppressed
-SELECT * FROM pg_get_role_ddl('regress_role_ddl_member', 'memberships', 'false');
+SELECT * FROM pg_get_role_ddl('regress_role_ddl_member', memberships => false);
                                                   pg_get_role_ddl                                                   
 --------------------------------------------------------------------------------------------------------------------
  CREATE ROLE regress_role_ddl_member NOSUPERUSER INHERIT NOCREATEROLE NOCREATEDB NOLOGIN NOREPLICATION NOBYPASSRLS;
diff --git a/src/test/regress/expected/tablespace_ddl.out b/src/test/regress/expected/tablespace_ddl.out
index e52043273a9..4f0f4401d2f 100644
--- a/src/test/regress/expected/tablespace_ddl.out
+++ b/src/test/regress/expected/tablespace_ddl.out
@@ -43,7 +43,7 @@ SELECT * FROM pg_get_tablespace_ddl('regress_allopt_tblsp');
 
 -- pretty-printed output
 \pset format unaligned
-SELECT * FROM pg_get_tablespace_ddl('regress_allopt_tblsp', 'pretty', 'true');
+SELECT * FROM pg_get_tablespace_ddl('regress_allopt_tblsp', pretty => true);
 pg_get_tablespace_ddl
 CREATE TABLESPACE regress_allopt_tblsp
     OWNER regress_tblspc_ddl_user
@@ -52,7 +52,7 @@ ALTER TABLESPACE regress_allopt_tblsp SET (seq_page_cost='1.5', random_page_cost
 (2 rows)
 \pset format aligned
 -- tablespace with owner suppressed
-SELECT * FROM pg_get_tablespace_ddl('regress_allopt_tblsp', 'owner', 'false');
+SELECT * FROM pg_get_tablespace_ddl('regress_allopt_tblsp', owner => false);
                                                                        pg_get_tablespace_ddl                                                                       
 -------------------------------------------------------------------------------------------------------------------------------------------------------------------
  CREATE TABLESPACE regress_allopt_tblsp LOCATION '';
diff --git a/src/test/regress/sql/database_ddl.sql b/src/test/regress/sql/database_ddl.sql
index 89753ac6411..547e4d0f800 100644
--- a/src/test/regress/sql/database_ddl.sql
+++ b/src/test/regress/sql/database_ddl.sql
@@ -35,21 +35,16 @@ SELECT * FROM pg_get_database_ddl('regression_database');
 -- NULL value
 SELECT * FROM pg_get_database_ddl(NULL);
 
--- Invalid option value (should error)
-SELECT * FROM pg_get_database_ddl('regression_database_ddl', 'owner', 'invalid');
-
--- Duplicate option (should error)
-SELECT * FROM pg_get_database_ddl('regression_database_ddl', 'owner', 'false', 'owner', 'true');
 
 -- Without options
 SELECT ddl_filter(pg_get_database_ddl) FROM pg_get_database_ddl('regression_database_ddl');
 
 -- With owner
-SELECT ddl_filter(pg_get_database_ddl) FROM pg_get_database_ddl('regression_database_ddl', 'owner', 'true');
+SELECT ddl_filter(pg_get_database_ddl) FROM pg_get_database_ddl('regression_database_ddl', owner => true);
 
 -- Pretty-printed output
 \pset format unaligned
-SELECT ddl_filter(pg_get_database_ddl) FROM pg_get_database_ddl('regression_database_ddl', 'pretty', 'true', 'tablespace', 'false');
+SELECT ddl_filter(pg_get_database_ddl) FROM pg_get_database_ddl('regression_database_ddl', pretty => true, tablespace => false);
 \pset format aligned
 
 -- Permission check: revoke CONNECT on database
diff --git a/src/test/regress/sql/role_ddl.sql b/src/test/regress/sql/role_ddl.sql
index 3d0142242ec..1667a1f6e10 100644
--- a/src/test/regress/sql/role_ddl.sql
+++ b/src/test/regress/sql/role_ddl.sql
@@ -40,7 +40,7 @@ SELECT * FROM pg_get_role_ddl('regress_role-with-dash');
 
 -- Pretty-printed output
 \pset format unaligned
-SELECT * FROM pg_get_role_ddl('regress_role_ddl_test3', 'pretty', 'true');
+SELECT * FROM pg_get_role_ddl('regress_role_ddl_test3', pretty => true);
 \pset format aligned
 
 -- Role with memberships
@@ -57,7 +57,7 @@ RESET ROLE;
 SELECT * FROM pg_get_role_ddl('regress_role_ddl_member');
 
 -- Role with memberships suppressed
-SELECT * FROM pg_get_role_ddl('regress_role_ddl_member', 'memberships', 'false');
+SELECT * FROM pg_get_role_ddl('regress_role_ddl_member', memberships => false);
 
 -- Non-existent role (should error)
 SELECT * FROM pg_get_role_ddl(9999999::oid);
diff --git a/src/test/regress/sql/tablespace_ddl.sql b/src/test/regress/sql/tablespace_ddl.sql
index ee3cc6e2e1e..fece93df251 100644
--- a/src/test/regress/sql/tablespace_ddl.sql
+++ b/src/test/regress/sql/tablespace_ddl.sql
@@ -30,11 +30,11 @@ SELECT * FROM pg_get_tablespace_ddl('regress_allopt_tblsp');
 
 -- pretty-printed output
 \pset format unaligned
-SELECT * FROM pg_get_tablespace_ddl('regress_allopt_tblsp', 'pretty', 'true');
+SELECT * FROM pg_get_tablespace_ddl('regress_allopt_tblsp', pretty => true);
 \pset format aligned
 
 -- tablespace with owner suppressed
-SELECT * FROM pg_get_tablespace_ddl('regress_allopt_tblsp', 'owner', 'false');
+SELECT * FROM pg_get_tablespace_ddl('regress_allopt_tblsp', owner => false);
 
 DROP TABLESPACE regress_allopt_tblsp;
 
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index e9430e07b36..fbd1f499aec 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -637,8 +637,6 @@ DataChecksumsWorkerResult
 DataDirSyncMethod
 DataDumperPtr
 DataPageDeleteStack
-DdlOptType
-DdlOption
 DataTypesUsageChecks
 DataTypesUsageVersionCheck
 DatabaseInfo

base-commit: 93dc1ace2007fe7c1103ccda3d7bc13b4eb4352f
-- 
2.53.0

