Motivated by Bug 19409 [1] I decided to do something about a wart that
has bugged me for a while, namely the requirement to write stuff in
system_views.sql if you need to specify default values for function
arguments. Here's my attempt. The first patch here sets up the required
infrastructure. genbki.pl creates a file called function_defaults.sql
which is run by initdb at the appropriate time. There are two new fields
in pg_proc.dat entries: proargdflts,and provariadicdflt. These are
parsed and the appropriate CREATE OR REPLACE statement is generated and
placed in function_defaults.sql. The second patch applies this treatment
to 37 function definitions and removes the corresponding statements from
system_views.sql. This gets us closer to having pg_proc.dat as a single
source of truth.
cheers
andrew
[1]
https://www.postgresql.org/message-id/19409-e16cd2605e59a4af%40postgresql.org
--
Andrew Dunstan
EDB: https://www.enterprisedb.com
From 7e80ad51623b87dff4ad810124dd485684b6ef3f Mon Sep 17 00:00:00 2001
From: Andrew Dunstan <[email protected]>
Date: Mon, 16 Feb 2026 11:57:27 -0500
Subject: [PATCH 1/2] Add infrastructure for proargdflts in pg_proc.dat
Add support for specifying function argument defaults directly in
pg_proc.dat using a new proargdflts field for IN arguments and
provariadicdflt for VARIADIC arguments. The genbki.pl script
generates function_defaults.sql which is processed by initdb after
postgres.bki.
---
src/backend/catalog/genbki.pl | 218 +++++++++++++++++++++++++++++++-
src/bin/initdb/initdb.c | 5 +
src/include/catalog/Makefile | 4 +-
src/include/catalog/meson.build | 2 +
4 files changed, 225 insertions(+), 4 deletions(-)
diff --git a/src/backend/catalog/genbki.pl b/src/backend/catalog/genbki.pl
index b2c1b1c5733..113cb0e4996 100644
--- a/src/backend/catalog/genbki.pl
+++ b/src/backend/catalog/genbki.pl
@@ -2,9 +2,12 @@
#----------------------------------------------------------------------
#
# genbki.pl
-# Perl script that generates postgres.bki and symbol definition
-# headers from specially formatted header files and data files.
-# postgres.bki is used to initialize the postgres template database.
+# Perl script that generates postgres.bki, symbol definition headers,
+# and function_defaults.sql from specially formatted header files and
+# data files. postgres.bki is used to initialize the postgres template
+# database. function_defaults.sql provides default argument values for
+# built-in functions specified via proargdflts (for IN arguments)
+# and provariadicdflt (for VARIADIC arguments) in pg_proc.dat.
#
# Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
# Portions Copyright (c) 1994, Regents of the University of California
@@ -452,6 +455,9 @@ open my $syscache_ids_fh, '>', $syscache_ids_file . $tmpext
my $syscache_info_file = $output_path . 'syscache_info.h';
open my $syscache_info_fh, '>', $syscache_info_file . $tmpext
or die "can't open $syscache_info_file$tmpext: $!";
+my $fmgr_defaults_file = $output_path . 'function_defaults.sql';
+open my $fmgr_defaults, '>', $fmgr_defaults_file . $tmpext
+ or die "can't open $fmgr_defaults_file$tmpext: $!";
# Generate postgres.bki and pg_*_d.h headers.
@@ -597,6 +603,8 @@ EOM
if $key eq "oid_symbol"
|| $key eq "array_type_oid"
|| $key eq "descr"
+ || $key eq "proargdflts"
+ || $key eq "provariadicdflt"
|| $key eq "autogenerated"
|| $key eq "line_number";
die sprintf "unrecognized field name \"%s\" in %s.dat line %s\n",
@@ -726,6 +734,171 @@ foreach my $c (@system_constraints)
print $constraints $c, "\n\n";
}
+# Now generate function_defaults.sql
+# This file contains CREATE OR REPLACE FUNCTION statements to set default argument values
+# for functions that have proargdflts specified in pg_proc.dat.
+
+print $fmgr_defaults <<EOM;
+--
+-- PostgreSQL System Function Defaults
+--
+-- Auto-generated from pg_proc.dat proargdflts entries.
+-- Do not edit manually.
+--
+-- This file sets default argument values for built-in functions.
+-- It is processed after postgres.bki during initdb.
+--
+
+EOM
+
+# Maps for converting catalog codes to SQL keywords
+my %volatility_map = ('i' => 'IMMUTABLE', 's' => 'STABLE', 'v' => 'VOLATILE');
+my %parallel_map = ('s' => 'PARALLEL SAFE', 'r' => 'PARALLEL RESTRICTED', 'u' => 'PARALLEL UNSAFE');
+
+foreach my $row (@{ $catalog_data{pg_proc} })
+{
+ next unless defined $row->{proargdflts} || defined $row->{provariadicdflt};
+
+ my $proname = $row->{proname};
+
+ # Get all argument types (use proallargtypes if present and not NULL, else proargtypes)
+ my @allargtypes;
+ if (defined $row->{proallargtypes} && $row->{proallargtypes} ne '' && $row->{proallargtypes} ne '_null_')
+ {
+ my $alltypes = $row->{proallargtypes};
+ $alltypes =~ s/^\{|\}$//g;
+ @allargtypes = split /,/, $alltypes;
+ }
+ else
+ {
+ @allargtypes = split /\s+/, $row->{proargtypes};
+ }
+
+ # Get argument modes (i=IN, o=OUT, b=INOUT, v=VARIADIC, t=TABLE)
+ my @argmodes;
+ if (defined $row->{proargmodes} && $row->{proargmodes} ne '' && $row->{proargmodes} ne '_null_')
+ {
+ my $modes = $row->{proargmodes};
+ $modes =~ s/^\{|\}$//g;
+ @argmodes = split /,/, $modes;
+ }
+ else
+ {
+ # All arguments are IN if no modes specified
+ @argmodes = ('i') x scalar(@allargtypes);
+ }
+
+ # Parse proargnames: '{name1,name2}' -> ['name1', 'name2']
+ my @argnames;
+ if (defined $row->{proargnames})
+ {
+ my $names = $row->{proargnames};
+ $names =~ s/^\{|\}$//g;
+ @argnames = split /,/, $names;
+ }
+
+ # Count IN arguments (these are the ones that can have defaults)
+ my $n_in_args = 0;
+ for my $mode (@argmodes)
+ {
+ $n_in_args++ if $mode eq 'i';
+ }
+
+ # Parse defaults: '{val1,val2}' or 'val1,val2' -> ['val1', 'val2']
+ my @defaults;
+ my $ndefaults = 0;
+ if (defined $row->{proargdflts})
+ {
+ my $defaults_str = $row->{proargdflts};
+ $defaults_str =~ s/^\{|\}$//g;
+ # Split on comma, but respect parentheses for function calls like foo(1,2)
+ @defaults = parse_defaults_list($defaults_str);
+ $ndefaults = scalar @defaults;
+ }
+
+ if ($ndefaults > $n_in_args)
+ {
+ die sprintf "too many defaults (%d) for function %s with %d IN args at line %s\n",
+ $ndefaults, $proname, $n_in_args, $row->{line_number};
+ }
+
+ # Build the argument list with names, types, modes, and defaults
+ my $first_default_in_arg = $n_in_args - $ndefaults;
+ my @arg_defs;
+ my $in_arg_idx = 0;
+ for (my $i = 0; $i < scalar(@allargtypes); $i++)
+ {
+ my $argname = $argnames[$i] // '';
+ my $argtype = $allargtypes[$i];
+ my $argmode = $argmodes[$i];
+ my $arg_def;
+
+ if ($argmode eq 'o')
+ {
+ $arg_def = "OUT $argname $argtype";
+ }
+ elsif ($argmode eq 'b')
+ {
+ $arg_def = "INOUT $argname $argtype";
+ }
+ elsif ($argmode eq 'v')
+ {
+ $arg_def = "VARIADIC $argname $argtype";
+ if (defined $row->{provariadicdflt})
+ {
+ my $vardefault = $row->{provariadicdflt};
+ $vardefault =~ s/^\s+|\s+$//g; # trim whitespace
+ $arg_def .= " DEFAULT $vardefault";
+ }
+ }
+ else
+ {
+ # IN argument (mode 'i' or default)
+ $arg_def = "$argname $argtype";
+
+ # Add default if this IN arg has one
+ if ($in_arg_idx >= $first_default_in_arg)
+ {
+ my $default_idx = $in_arg_idx - $first_default_in_arg;
+ my $default_val = $defaults[$default_idx];
+ $default_val =~ s/^\s+|\s+$//g; # trim whitespace
+ $arg_def .= " DEFAULT $default_val";
+ }
+ $in_arg_idx++;
+ }
+ push @arg_defs, $arg_def;
+ }
+
+ my $volatility = $volatility_map{$row->{provolatile} // 'v'} // 'VOLATILE';
+ my $parallel = $parallel_map{$row->{proparallel} // 'u'} // 'PARALLEL UNSAFE';
+
+ # Check if function is strict
+ my $strict = ($row->{proisstrict} // 't') eq 't' ? 'STRICT' : '';
+
+ # Get cost (default is 1 for internal functions)
+ my $cost = "COST " . ($row->{procost} // 1);
+
+ # Get return type and prosrc
+ my $rettype = $row->{prorettype};
+ # Add SETOF if proretset is true
+ if (($row->{proretset} // 'f') eq 't')
+ {
+ $rettype = "SETOF $rettype";
+ }
+ my $prosrc = $row->{prosrc};
+
+ # Build the CREATE OR REPLACE FUNCTION statement
+ my $args_str = join(",\n ", @arg_defs);
+ my @options = grep { $_ ne '' } ($volatility, $parallel, $strict, $cost);
+ my $options_str = join(' ', @options);
+
+ print $fmgr_defaults "CREATE OR REPLACE FUNCTION \"$proname\"(\n $args_str)\n" .
+ " RETURNS $rettype\n" .
+ " LANGUAGE internal\n" .
+ " $options_str\n" .
+ "AS '$prosrc';\n\n";
+}
+
# Now generate schemapg.h
print_boilerplate($schemapg, "schemapg.h",
@@ -837,6 +1010,7 @@ close $fk_info;
close $constraints;
close $syscache_ids_fh;
close $syscache_info_fh;
+close $fmgr_defaults;
# Finally, rename the completed files into place.
Catalog::RenameTempFile($bkifile, $tmpext);
@@ -845,6 +1019,7 @@ Catalog::RenameTempFile($fk_info_file, $tmpext);
Catalog::RenameTempFile($constraints_file, $tmpext);
Catalog::RenameTempFile($syscache_ids_file, $tmpext);
Catalog::RenameTempFile($syscache_info_file, $tmpext);
+Catalog::RenameTempFile($fmgr_defaults_file, $tmpext);
exit($num_errors != 0 ? 1 : 0);
@@ -1176,6 +1351,43 @@ sub print_boilerplate
EOM
}
+# Parse a comma-separated list of default values, respecting parentheses.
+# This handles expressions like "foo(1,2), bar" correctly.
+sub parse_defaults_list
+{
+ my $str = shift;
+ my @result;
+ my $current = '';
+ my $depth = 0;
+
+ for my $char (split //, $str)
+ {
+ if ($char eq '(' || $char eq '[')
+ {
+ $depth++;
+ $current .= $char;
+ }
+ elsif ($char eq ')' || $char eq ']')
+ {
+ $depth--;
+ $current .= $char;
+ }
+ elsif ($char eq ',' && $depth == 0)
+ {
+ push @result, $current;
+ $current = '';
+ }
+ else
+ {
+ $current .= $char;
+ }
+ }
+ # Don't forget the last element
+ push @result, $current if $current ne '' || @result > 0;
+
+ return @result;
+}
+
sub usage
{
die <<EOM;
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index a3980e5535f..811988bb590 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -183,6 +183,7 @@ static char *info_schema_file;
static char *features_file;
static char *system_constraints_file;
static char *system_functions_file;
+static char *function_defaults_file;
static char *system_views_file;
static bool success = false;
static bool made_new_pgdata = false;
@@ -2799,6 +2800,7 @@ setup_data_file_paths(void)
set_input(&features_file, "sql_features.txt");
set_input(&system_constraints_file, "system_constraints.sql");
set_input(&system_functions_file, "system_functions.sql");
+ set_input(&function_defaults_file, "function_defaults.sql");
set_input(&system_views_file, "system_views.sql");
if (show_setting || debug)
@@ -2827,6 +2829,7 @@ setup_data_file_paths(void)
check_input(features_file);
check_input(system_constraints_file);
check_input(system_functions_file);
+ check_input(function_defaults_file);
check_input(system_views_file);
}
@@ -3119,6 +3122,8 @@ initialize_data_directory(void)
setup_run_file(cmdfd, system_functions_file);
+ setup_run_file(cmdfd, function_defaults_file);
+
setup_depend(cmdfd);
/*
diff --git a/src/include/catalog/Makefile b/src/include/catalog/Makefile
index c90022f7c57..dbf67eb44dc 100644
--- a/src/include/catalog/Makefile
+++ b/src/include/catalog/Makefile
@@ -118,6 +118,7 @@ GENBKI_OUTPUT_FILES = \
$(GENERATED_HEADERS) \
postgres.bki \
system_constraints.sql \
+ function_defaults.sql \
schemapg.h \
syscache_ids.h \
syscache_info.h \
@@ -145,6 +146,7 @@ bki-stamp: $(top_srcdir)/src/backend/catalog/genbki.pl $(top_srcdir)/src/backend
install: all installdirs
$(INSTALL_DATA) postgres.bki '$(DESTDIR)$(datadir)/postgres.bki'
$(INSTALL_DATA) system_constraints.sql '$(DESTDIR)$(datadir)/system_constraints.sql'
+ $(INSTALL_DATA) function_defaults.sql '$(DESTDIR)$(datadir)/function_defaults.sql'
# In non-vpath builds, src/include/Makefile already installs all headers.
ifeq ($(vpath_build),yes)
$(INSTALL_DATA) schemapg.h '$(DESTDIR)$(includedir_server)'/catalog/schemapg.h
@@ -159,7 +161,7 @@ installdirs:
$(MKDIR_P) '$(DESTDIR)$(datadir)' '$(DESTDIR)$(includedir_server)'
uninstall:
- rm -f $(addprefix '$(DESTDIR)$(datadir)'/, postgres.bki system_constraints.sql)
+ rm -f $(addprefix '$(DESTDIR)$(datadir)'/, postgres.bki system_constraints.sql function_defaults.sql)
rm -f $(addprefix '$(DESTDIR)$(includedir_server)'/catalog/, schemapg.h syscache_ids.h system_fk_info.h $(GENERATED_HEADERS))
clean:
diff --git a/src/include/catalog/meson.build b/src/include/catalog/meson.build
index b63cd584068..e9968438a0d 100644
--- a/src/include/catalog/meson.build
+++ b/src/include/catalog/meson.build
@@ -105,12 +105,14 @@ input = []
output_files = [
'postgres.bki',
'system_constraints.sql',
+ 'function_defaults.sql',
'schemapg.h',
'syscache_ids.h',
'syscache_info.h',
'system_fk_info.h',
]
output_install = [
+ dir_data,
dir_data,
dir_data,
dir_include_server / 'catalog',
--
2.43.0
From 78a83084e7c18414bb7d4e5b1f44e960a2519ea9 Mon Sep 17 00:00:00 2001
From: Andrew Dunstan <[email protected]>
Date: Mon, 16 Feb 2026 11:58:22 -0500
Subject: [PATCH 2/2] Move function defaults from system_functions.sql to
pg_proc.dat
Functions using proargdflts (33 entries, 32 unique):
is_normalized, json_populate_record, json_populate_recordset,
json_strip_nulls, jsonb_insert, jsonb_path_exists, jsonb_path_exists_tz,
jsonb_path_match, jsonb_path_match_tz, jsonb_path_query,
jsonb_path_query_array, jsonb_path_query_array_tz, jsonb_path_query_first,
jsonb_path_query_first_tz, jsonb_path_query_tz, jsonb_set, jsonb_set_lax,
jsonb_strip_nulls, make_interval, normalize, parse_ident, pg_backup_start,
pg_backup_stop, pg_create_logical_replication_slot,
pg_create_physical_replication_slot, pg_logical_emit_message, pg_promote,
pg_replication_origin_session_setup, pg_stat_reset_shared,
pg_stat_reset_slru, pg_terminate_backend, random_normal
Functions using provariadicdflt (4 entries):
pg_logical_slot_get_binary_changes, pg_logical_slot_get_changes,
pg_logical_slot_peek_binary_changes, pg_logical_slot_peek_changes
---
src/backend/catalog/system_functions.sql | 282 -----------------------
src/include/catalog/pg_proc.dat | 86 ++++++-
2 files changed, 75 insertions(+), 293 deletions(-)
diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql
index eb9e31ae1bf..8fa025be17b 100644
--- a/src/backend/catalog/system_functions.sql
+++ b/src/backend/catalog/system_functions.sql
@@ -66,13 +66,6 @@ CREATE OR REPLACE FUNCTION bit_length(text)
IMMUTABLE PARALLEL SAFE STRICT COST 1
RETURN octet_length($1) * 8;
-CREATE OR REPLACE FUNCTION
- random_normal(mean float8 DEFAULT 0, stddev float8 DEFAULT 1)
- RETURNS float8
- LANGUAGE internal
- VOLATILE PARALLEL RESTRICTED STRICT COST 1
-AS 'drandom_normal';
-
CREATE OR REPLACE FUNCTION log(numeric)
RETURNS numeric
LANGUAGE sql
@@ -382,281 +375,6 @@ CREATE OR REPLACE FUNCTION ts_debug(document text,
BEGIN ATOMIC
SELECT * FROM ts_debug(get_current_ts_config(), $1);
END;
-
-CREATE OR REPLACE FUNCTION
- pg_backup_start(label text, fast boolean DEFAULT false)
- RETURNS pg_lsn STRICT VOLATILE LANGUAGE internal AS 'pg_backup_start'
- PARALLEL RESTRICTED;
-
-CREATE OR REPLACE FUNCTION pg_backup_stop (
- wait_for_archive boolean DEFAULT true, OUT lsn pg_lsn,
- OUT labelfile text, OUT spcmapfile text)
- RETURNS record STRICT VOLATILE LANGUAGE internal as 'pg_backup_stop'
- PARALLEL RESTRICTED;
-
-CREATE OR REPLACE FUNCTION
- pg_promote(wait boolean DEFAULT true, wait_seconds integer DEFAULT 60)
- RETURNS boolean STRICT VOLATILE LANGUAGE INTERNAL AS 'pg_promote'
- PARALLEL SAFE;
-
-CREATE OR REPLACE FUNCTION
- pg_terminate_backend(pid integer, timeout int8 DEFAULT 0)
- RETURNS boolean STRICT VOLATILE LANGUAGE INTERNAL AS 'pg_terminate_backend'
- PARALLEL SAFE;
-
--- legacy definition for compatibility with 9.3
-CREATE OR REPLACE FUNCTION
- json_populate_record(base anyelement, from_json json, use_json_as_text boolean DEFAULT false)
- RETURNS anyelement LANGUAGE internal STABLE AS 'json_populate_record' PARALLEL SAFE;
-
--- legacy definition for compatibility with 9.3
-CREATE OR REPLACE FUNCTION
- json_populate_recordset(base anyelement, from_json json, use_json_as_text boolean DEFAULT false)
- RETURNS SETOF anyelement LANGUAGE internal STABLE ROWS 100 AS 'json_populate_recordset' PARALLEL SAFE;
-
-CREATE OR REPLACE FUNCTION pg_logical_slot_get_changes(
- IN slot_name name, IN upto_lsn pg_lsn, IN upto_nchanges int, VARIADIC options text[] DEFAULT '{}',
- OUT lsn pg_lsn, OUT xid xid, OUT data text)
-RETURNS SETOF RECORD
-LANGUAGE INTERNAL
-VOLATILE ROWS 1000 COST 1000
-AS 'pg_logical_slot_get_changes';
-
-CREATE OR REPLACE FUNCTION pg_logical_slot_peek_changes(
- IN slot_name name, IN upto_lsn pg_lsn, IN upto_nchanges int, VARIADIC options text[] DEFAULT '{}',
- OUT lsn pg_lsn, OUT xid xid, OUT data text)
-RETURNS SETOF RECORD
-LANGUAGE INTERNAL
-VOLATILE ROWS 1000 COST 1000
-AS 'pg_logical_slot_peek_changes';
-
-CREATE OR REPLACE FUNCTION pg_logical_slot_get_binary_changes(
- IN slot_name name, IN upto_lsn pg_lsn, IN upto_nchanges int, VARIADIC options text[] DEFAULT '{}',
- OUT lsn pg_lsn, OUT xid xid, OUT data bytea)
-RETURNS SETOF RECORD
-LANGUAGE INTERNAL
-VOLATILE ROWS 1000 COST 1000
-AS 'pg_logical_slot_get_binary_changes';
-
-CREATE OR REPLACE FUNCTION pg_logical_slot_peek_binary_changes(
- IN slot_name name, IN upto_lsn pg_lsn, IN upto_nchanges int, VARIADIC options text[] DEFAULT '{}',
- OUT lsn pg_lsn, OUT xid xid, OUT data bytea)
-RETURNS SETOF RECORD
-LANGUAGE INTERNAL
-VOLATILE ROWS 1000 COST 1000
-AS 'pg_logical_slot_peek_binary_changes';
-
-CREATE OR REPLACE FUNCTION pg_logical_emit_message(
- transactional boolean,
- prefix text,
- message text,
- flush boolean DEFAULT false)
-RETURNS pg_lsn
-LANGUAGE INTERNAL
-STRICT VOLATILE
-AS 'pg_logical_emit_message_text';
-
-CREATE OR REPLACE FUNCTION pg_logical_emit_message(
- transactional boolean,
- prefix text,
- message bytea,
- flush boolean DEFAULT false)
-RETURNS pg_lsn
-LANGUAGE INTERNAL
-STRICT VOLATILE
-AS 'pg_logical_emit_message_bytea';
-
-CREATE OR REPLACE FUNCTION pg_create_physical_replication_slot(
- IN slot_name name, IN immediately_reserve boolean DEFAULT false,
- IN temporary boolean DEFAULT false,
- OUT slot_name name, OUT lsn pg_lsn)
-RETURNS RECORD
-LANGUAGE INTERNAL
-STRICT VOLATILE
-AS 'pg_create_physical_replication_slot';
-
-CREATE OR REPLACE FUNCTION pg_create_logical_replication_slot(
- IN slot_name name, IN plugin name,
- IN temporary boolean DEFAULT false,
- IN twophase boolean DEFAULT false,
- IN failover boolean DEFAULT false,
- OUT slot_name name, OUT lsn pg_lsn)
-RETURNS RECORD
-LANGUAGE INTERNAL
-STRICT VOLATILE
-AS 'pg_create_logical_replication_slot';
-
-CREATE OR REPLACE FUNCTION
- make_interval(years int4 DEFAULT 0, months int4 DEFAULT 0, weeks int4 DEFAULT 0,
- days int4 DEFAULT 0, hours int4 DEFAULT 0, mins int4 DEFAULT 0,
- secs double precision DEFAULT 0.0)
-RETURNS interval
-LANGUAGE INTERNAL
-STRICT IMMUTABLE PARALLEL SAFE
-AS 'make_interval';
-
-CREATE OR REPLACE FUNCTION
- jsonb_set(jsonb_in jsonb, path text[] , replacement jsonb,
- create_if_missing boolean DEFAULT true)
-RETURNS jsonb
-LANGUAGE INTERNAL
-STRICT IMMUTABLE PARALLEL SAFE
-AS 'jsonb_set';
-
-CREATE OR REPLACE FUNCTION
- jsonb_set_lax(jsonb_in jsonb, path text[] , replacement jsonb,
- create_if_missing boolean DEFAULT true,
- null_value_treatment text DEFAULT 'use_json_null')
-RETURNS jsonb
-LANGUAGE INTERNAL
-CALLED ON NULL INPUT IMMUTABLE PARALLEL SAFE
-AS 'jsonb_set_lax';
-
-CREATE OR REPLACE FUNCTION
- parse_ident(str text, strict boolean DEFAULT true)
-RETURNS text[]
-LANGUAGE INTERNAL
-STRICT IMMUTABLE PARALLEL SAFE
-AS 'parse_ident';
-
-CREATE OR REPLACE FUNCTION
- jsonb_insert(jsonb_in jsonb, path text[] , replacement jsonb,
- insert_after boolean DEFAULT false)
-RETURNS jsonb
-LANGUAGE INTERNAL
-STRICT IMMUTABLE PARALLEL SAFE
-AS 'jsonb_insert';
-
-CREATE OR REPLACE FUNCTION
- jsonb_path_exists(target jsonb, path jsonpath, vars jsonb DEFAULT '{}',
- silent boolean DEFAULT false)
-RETURNS boolean
-LANGUAGE INTERNAL
-STRICT IMMUTABLE PARALLEL SAFE
-AS 'jsonb_path_exists';
-
-CREATE OR REPLACE FUNCTION
- jsonb_path_match(target jsonb, path jsonpath, vars jsonb DEFAULT '{}',
- silent boolean DEFAULT false)
-RETURNS boolean
-LANGUAGE INTERNAL
-STRICT IMMUTABLE PARALLEL SAFE
-AS 'jsonb_path_match';
-
-CREATE OR REPLACE FUNCTION
- jsonb_path_query(target jsonb, path jsonpath, vars jsonb DEFAULT '{}',
- silent boolean DEFAULT false)
-RETURNS SETOF jsonb
-LANGUAGE INTERNAL
-STRICT IMMUTABLE PARALLEL SAFE
-AS 'jsonb_path_query';
-
-CREATE OR REPLACE FUNCTION
- jsonb_path_query_array(target jsonb, path jsonpath, vars jsonb DEFAULT '{}',
- silent boolean DEFAULT false)
-RETURNS jsonb
-LANGUAGE INTERNAL
-STRICT IMMUTABLE PARALLEL SAFE
-AS 'jsonb_path_query_array';
-
-CREATE OR REPLACE FUNCTION
- jsonb_path_query_first(target jsonb, path jsonpath, vars jsonb DEFAULT '{}',
- silent boolean DEFAULT false)
-RETURNS jsonb
-LANGUAGE INTERNAL
-STRICT IMMUTABLE PARALLEL SAFE
-AS 'jsonb_path_query_first';
-
-CREATE OR REPLACE FUNCTION
- jsonb_path_exists_tz(target jsonb, path jsonpath, vars jsonb DEFAULT '{}',
- silent boolean DEFAULT false)
-RETURNS boolean
-LANGUAGE INTERNAL
-STRICT STABLE PARALLEL SAFE
-AS 'jsonb_path_exists_tz';
-
-CREATE OR REPLACE FUNCTION
- jsonb_path_match_tz(target jsonb, path jsonpath, vars jsonb DEFAULT '{}',
- silent boolean DEFAULT false)
-RETURNS boolean
-LANGUAGE INTERNAL
-STRICT STABLE PARALLEL SAFE
-AS 'jsonb_path_match_tz';
-
-CREATE OR REPLACE FUNCTION
- jsonb_path_query_tz(target jsonb, path jsonpath, vars jsonb DEFAULT '{}',
- silent boolean DEFAULT false)
-RETURNS SETOF jsonb
-LANGUAGE INTERNAL
-STRICT STABLE PARALLEL SAFE
-AS 'jsonb_path_query_tz';
-
-CREATE OR REPLACE FUNCTION
- jsonb_path_query_array_tz(target jsonb, path jsonpath, vars jsonb DEFAULT '{}',
- silent boolean DEFAULT false)
-RETURNS jsonb
-LANGUAGE INTERNAL
-STRICT STABLE PARALLEL SAFE
-AS 'jsonb_path_query_array_tz';
-
-CREATE OR REPLACE FUNCTION
- jsonb_path_query_first_tz(target jsonb, path jsonpath, vars jsonb DEFAULT '{}',
- silent boolean DEFAULT false)
-RETURNS jsonb
-LANGUAGE INTERNAL
-STRICT STABLE PARALLEL SAFE
-AS 'jsonb_path_query_first_tz';
-
-CREATE OR REPLACE FUNCTION
- jsonb_strip_nulls(target jsonb, strip_in_arrays boolean DEFAULT false)
-RETURNS jsonb
-LANGUAGE INTERNAL
-STRICT STABLE PARALLEL SAFE
-AS 'jsonb_strip_nulls';
-
-CREATE OR REPLACE FUNCTION
- json_strip_nulls(target json, strip_in_arrays boolean DEFAULT false)
-RETURNS json
-LANGUAGE INTERNAL
-STRICT STABLE PARALLEL SAFE
-AS 'json_strip_nulls';
-
--- default normalization form is NFC, per SQL standard
-CREATE OR REPLACE FUNCTION
- "normalize"(text, text DEFAULT 'NFC')
-RETURNS text
-LANGUAGE internal
-STRICT IMMUTABLE PARALLEL SAFE
-AS 'unicode_normalize_func';
-
-CREATE OR REPLACE FUNCTION
- is_normalized(text, text DEFAULT 'NFC')
-RETURNS boolean
-LANGUAGE internal
-STRICT IMMUTABLE PARALLEL SAFE
-AS 'unicode_is_normalized';
-
-CREATE OR REPLACE FUNCTION
- pg_stat_reset_shared(target text DEFAULT NULL)
-RETURNS void
-LANGUAGE INTERNAL
-CALLED ON NULL INPUT VOLATILE PARALLEL SAFE
-AS 'pg_stat_reset_shared';
-
-CREATE OR REPLACE FUNCTION
- pg_stat_reset_slru(target text DEFAULT NULL)
-RETURNS void
-LANGUAGE INTERNAL
-CALLED ON NULL INPUT VOLATILE PARALLEL SAFE
-AS 'pg_stat_reset_slru';
-
-CREATE OR REPLACE FUNCTION
- pg_replication_origin_session_setup(node_name text, pid integer DEFAULT 0)
-RETURNS void
-LANGUAGE INTERNAL
-STRICT VOLATILE PARALLEL UNSAFE
-AS 'pg_replication_origin_session_setup';
-
--
-- The default permissions for functions mean that anyone can execute them.
-- A number of functions shouldn't be executable by just anyone, but rather
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 83f6501df38..d59d61f4511 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -3499,6 +3499,7 @@
{ oid => '6212', descr => 'random value from normal distribution',
proname => 'random_normal', provolatile => 'v', proparallel => 'r',
prorettype => 'float8', proargtypes => 'float8 float8',
+ proargnames => '{mean,stddev}', proargdflts => '{0,1}',
prosrc => 'drandom_normal' },
{ oid => '6339', descr => 'random integer in range',
proname => 'random', provolatile => 'v', proparallel => 'r',
@@ -6174,6 +6175,7 @@
descr => 'statistics: reset collected statistics shared across the cluster',
proname => 'pg_stat_reset_shared', proisstrict => 'f', provolatile => 'v',
prorettype => 'void', proargtypes => 'text',
+ proargnames => '{target}', proargdflts => '{NULL}',
prosrc => 'pg_stat_reset_shared' },
{ oid => '3776',
descr => 'statistics: reset collected statistics for a single table or index in the current database or shared across all databases in the cluster',
@@ -6193,6 +6195,7 @@
descr => 'statistics: reset collected statistics for a single SLRU',
proname => 'pg_stat_reset_slru', proisstrict => 'f', provolatile => 'v',
prorettype => 'void', proargtypes => 'text', proargnames => '{target}',
+ proargdflts => '{NULL}',
prosrc => 'pg_stat_reset_slru' },
{ oid => '6170',
descr => 'statistics: reset collected statistics for a single replication slot',
@@ -6728,20 +6731,24 @@
{ oid => '2096', descr => 'terminate a server process',
proname => 'pg_terminate_backend', provolatile => 'v', prorettype => 'bool',
proargtypes => 'int4 int8', proargnames => '{pid,timeout}',
+ proargdflts => '{0}',
prosrc => 'pg_terminate_backend' },
{ oid => '2172', descr => 'prepare for taking an online backup',
proname => 'pg_backup_start', provolatile => 'v', proparallel => 'r',
prorettype => 'pg_lsn', proargtypes => 'text bool',
+ proargnames => '{label,fast}', proargdflts => '{false}',
prosrc => 'pg_backup_start' },
{ oid => '2739', descr => 'finish taking an online backup',
proname => 'pg_backup_stop', provolatile => 'v', proparallel => 'r',
prorettype => 'record', proargtypes => 'bool',
proallargtypes => '{bool,pg_lsn,text,text}', proargmodes => '{i,o,o,o}',
proargnames => '{wait_for_archive,lsn,labelfile,spcmapfile}',
+ proargdflts => '{true}',
prosrc => 'pg_backup_stop' },
{ oid => '3436', descr => 'promote standby server',
proname => 'pg_promote', provolatile => 'v', prorettype => 'bool',
proargtypes => 'bool int4', proargnames => '{wait,wait_seconds}',
+ proargdflts => '{true,60}',
prosrc => 'pg_promote' },
{ oid => '2848', descr => 'switch to new wal file',
proname => 'pg_switch_wal', provolatile => 'v', prorettype => 'pg_lsn',
@@ -7517,7 +7524,8 @@
{ oid => '1268',
descr => 'parse qualified identifier to array of identifiers',
proname => 'parse_ident', prorettype => '_text', proargtypes => 'text bool',
- proargnames => '{str,strict}', prosrc => 'parse_ident' },
+ proargnames => '{str,strict}', proargdflts => '{true}',
+ prosrc => 'parse_ident' },
{ oid => '2246', descr => '(internal)',
proname => 'fmgr_internal_validator', provolatile => 's',
@@ -9423,7 +9431,9 @@
proargtypes => 'anyelement', prosrc => 'to_json' },
{ oid => '3261', descr => 'remove object fields with null values from json',
proname => 'json_strip_nulls', prorettype => 'json',
- proargtypes => 'json bool', prosrc => 'json_strip_nulls' },
+ proargtypes => 'json bool',
+ proargnames => '{target,strip_in_arrays}', proargdflts => '{false}',
+ prosrc => 'json_strip_nulls' },
{ oid => '3947',
proname => 'json_object_field', prorettype => 'json',
@@ -9480,12 +9490,17 @@
{ oid => '3960', descr => 'get record fields from a json object',
proname => 'json_populate_record', proisstrict => 'f', provolatile => 's',
prorettype => 'anyelement', proargtypes => 'anyelement json bool',
+ proargnames => '{base,from_json,use_json_as_text}',
+ proargdflts => '{false}',
prosrc => 'json_populate_record' },
{ oid => '3961',
descr => 'get set of records with fields from a json array of objects',
proname => 'json_populate_recordset', prorows => '100', proisstrict => 'f',
proretset => 't', provolatile => 's', prorettype => 'anyelement',
- proargtypes => 'anyelement json bool', prosrc => 'json_populate_recordset' },
+ proargtypes => 'anyelement json bool',
+ proargnames => '{base,from_json,use_json_as_text}',
+ proargdflts => '{false}',
+ prosrc => 'json_populate_recordset' },
{ oid => '3204', descr => 'get record fields from a json object',
proname => 'json_to_record', provolatile => 's', prorettype => 'record',
proargtypes => 'json', prosrc => 'json_to_record' },
@@ -10364,7 +10379,9 @@
prosrc => 'jsonb_build_object_noargs' },
{ oid => '3262', descr => 'remove object fields with null values from jsonb',
proname => 'jsonb_strip_nulls', prorettype => 'jsonb',
- proargtypes => 'jsonb bool', prosrc => 'jsonb_strip_nulls' },
+ proargtypes => 'jsonb bool',
+ proargnames => '{target,strip_in_arrays}', proargdflts => '{false}',
+ prosrc => 'jsonb_strip_nulls' },
{ oid => '3478',
proname => 'jsonb_object_field', prorettype => 'jsonb',
@@ -10538,16 +10555,25 @@
proargtypes => 'jsonb _text', prosrc => 'jsonb_delete_path' },
{ oid => '5054', descr => 'Set part of a jsonb, handle NULL value',
proname => 'jsonb_set_lax', proisstrict => 'f', prorettype => 'jsonb',
- proargtypes => 'jsonb _text jsonb bool text', prosrc => 'jsonb_set_lax' },
+ proargtypes => 'jsonb _text jsonb bool text',
+ proargnames => '{jsonb_in,path,replacement,create_if_missing,null_value_treatment}',
+ proargdflts => "{true,'use_json_null'}",
+ prosrc => 'jsonb_set_lax' },
{ oid => '3305', descr => 'Set part of a jsonb',
proname => 'jsonb_set', prorettype => 'jsonb',
- proargtypes => 'jsonb _text jsonb bool', prosrc => 'jsonb_set' },
+ proargtypes => 'jsonb _text jsonb bool',
+ proargnames => '{jsonb_in,path,replacement,create_if_missing}',
+ proargdflts => '{true}',
+ prosrc => 'jsonb_set' },
{ oid => '3306', descr => 'Indented text from jsonb',
proname => 'jsonb_pretty', prorettype => 'text', proargtypes => 'jsonb',
prosrc => 'jsonb_pretty' },
{ oid => '3579', descr => 'Insert value into a jsonb',
proname => 'jsonb_insert', prorettype => 'jsonb',
- proargtypes => 'jsonb _text jsonb bool', prosrc => 'jsonb_insert' },
+ proargtypes => 'jsonb _text jsonb bool',
+ proargnames => '{jsonb_in,path,replacement,insert_after}',
+ proargdflts => '{false}',
+ prosrc => 'jsonb_insert' },
# jsonpath
{ oid => '4001', descr => 'I/O',
@@ -10565,42 +10591,66 @@
{ oid => '4005', descr => 'jsonpath exists test',
proname => 'jsonb_path_exists', prorettype => 'bool',
- proargtypes => 'jsonb jsonpath jsonb bool', prosrc => 'jsonb_path_exists' },
+ proargtypes => 'jsonb jsonpath jsonb bool',
+ proargnames => '{target,path,vars,silent}',
+ proargdflts => "{'{}',false}",
+ prosrc => 'jsonb_path_exists' },
{ oid => '4006', descr => 'jsonpath query',
proname => 'jsonb_path_query', prorows => '1000', proretset => 't',
prorettype => 'jsonb', proargtypes => 'jsonb jsonpath jsonb bool',
+ proargnames => '{target,path,vars,silent}',
+ proargdflts => "{'{}',false}",
prosrc => 'jsonb_path_query' },
{ oid => '4007', descr => 'jsonpath query wrapped into array',
proname => 'jsonb_path_query_array', prorettype => 'jsonb',
proargtypes => 'jsonb jsonpath jsonb bool',
+ proargnames => '{target,path,vars,silent}',
+ proargdflts => "{'{}',false}",
prosrc => 'jsonb_path_query_array' },
{ oid => '4008', descr => 'jsonpath query first item',
proname => 'jsonb_path_query_first', prorettype => 'jsonb',
proargtypes => 'jsonb jsonpath jsonb bool',
+ proargnames => '{target,path,vars,silent}',
+ proargdflts => "{'{}',false}",
prosrc => 'jsonb_path_query_first' },
{ oid => '4009', descr => 'jsonpath match',
proname => 'jsonb_path_match', prorettype => 'bool',
- proargtypes => 'jsonb jsonpath jsonb bool', prosrc => 'jsonb_path_match' },
+ proargtypes => 'jsonb jsonpath jsonb bool',
+ proargnames => '{target,path,vars,silent}',
+ proargdflts => "{'{}',false}",
+ prosrc => 'jsonb_path_match' },
{ oid => '1177', descr => 'jsonpath exists test with timezone',
proname => 'jsonb_path_exists_tz', provolatile => 's', prorettype => 'bool',
proargtypes => 'jsonb jsonpath jsonb bool',
+ proargnames => '{target,path,vars,silent}',
+ proargdflts => "{'{}',false}",
prosrc => 'jsonb_path_exists_tz' },
{ oid => '1179', descr => 'jsonpath query with timezone',
proname => 'jsonb_path_query_tz', prorows => '1000', proretset => 't',
provolatile => 's', prorettype => 'jsonb',
- proargtypes => 'jsonb jsonpath jsonb bool', prosrc => 'jsonb_path_query_tz' },
+ proargtypes => 'jsonb jsonpath jsonb bool',
+ proargnames => '{target,path,vars,silent}',
+ proargdflts => "{'{}',false}",
+ prosrc => 'jsonb_path_query_tz' },
{ oid => '1180', descr => 'jsonpath query wrapped into array with timezone',
proname => 'jsonb_path_query_array_tz', provolatile => 's',
prorettype => 'jsonb', proargtypes => 'jsonb jsonpath jsonb bool',
+ proargnames => '{target,path,vars,silent}',
+ proargdflts => "{'{}',false}",
prosrc => 'jsonb_path_query_array_tz' },
{ oid => '2023', descr => 'jsonpath query first item with timezone',
proname => 'jsonb_path_query_first_tz', provolatile => 's',
prorettype => 'jsonb', proargtypes => 'jsonb jsonpath jsonb bool',
+ proargnames => '{target,path,vars,silent}',
+ proargdflts => "{'{}',false}",
prosrc => 'jsonb_path_query_first_tz' },
{ oid => '2030', descr => 'jsonpath match with timezone',
proname => 'jsonb_path_match_tz', provolatile => 's', prorettype => 'bool',
- proargtypes => 'jsonb jsonpath jsonb bool', prosrc => 'jsonb_path_match_tz' },
+ proargtypes => 'jsonb jsonpath jsonb bool',
+ proargnames => '{target,path,vars,silent}',
+ proargdflts => "{'{}',false}",
+ prosrc => 'jsonb_path_match_tz' },
{ oid => '4010', descr => 'implementation of @? operator',
proname => 'jsonb_path_exists_opr', prorettype => 'bool',
@@ -11411,6 +11461,7 @@
proname => 'make_interval', prorettype => 'interval',
proargtypes => 'int4 int4 int4 int4 int4 int4 float8',
proargnames => '{years,months,weeks,days,hours,mins,secs}',
+ proargdflts => '{0,0,0,0,0,0,0.0}',
prosrc => 'make_interval' },
# spgist opclasses
@@ -11511,6 +11562,7 @@
proallargtypes => '{name,bool,bool,name,pg_lsn}',
proargmodes => '{i,i,i,o,o}',
proargnames => '{slot_name,immediately_reserve,temporary,slot_name,lsn}',
+ proargdflts => '{false,false}',
prosrc => 'pg_create_physical_replication_slot' },
{ oid => '4220',
descr => 'copy a physical replication slot, changing temporality',
@@ -11546,6 +11598,7 @@
proallargtypes => '{name,name,bool,bool,bool,name,pg_lsn}',
proargmodes => '{i,i,i,i,i,o,o}',
proargnames => '{slot_name,plugin,temporary,twophase,failover,slot_name,lsn}',
+ proargdflts => '{false,false,false}',
prosrc => 'pg_create_logical_replication_slot' },
{ oid => '4222',
descr => 'copy a logical replication slot, changing temporality and plugin',
@@ -11578,6 +11631,7 @@
proallargtypes => '{name,pg_lsn,int4,_text,pg_lsn,xid,text}',
proargmodes => '{i,i,i,v,o,o,o}',
proargnames => '{slot_name,upto_lsn,upto_nchanges,options,lsn,xid,data}',
+ provariadicdflt => "'{}'",
prosrc => 'pg_logical_slot_get_changes' },
{ oid => '3783', descr => 'get binary changes from replication slot',
proname => 'pg_logical_slot_get_binary_changes', procost => '1000',
@@ -11587,6 +11641,7 @@
proallargtypes => '{name,pg_lsn,int4,_text,pg_lsn,xid,bytea}',
proargmodes => '{i,i,i,v,o,o,o}',
proargnames => '{slot_name,upto_lsn,upto_nchanges,options,lsn,xid,data}',
+ provariadicdflt => "'{}'",
prosrc => 'pg_logical_slot_get_binary_changes' },
{ oid => '3784', descr => 'peek at changes from replication slot',
proname => 'pg_logical_slot_peek_changes', procost => '1000',
@@ -11596,6 +11651,7 @@
proallargtypes => '{name,pg_lsn,int4,_text,pg_lsn,xid,text}',
proargmodes => '{i,i,i,v,o,o,o}',
proargnames => '{slot_name,upto_lsn,upto_nchanges,options,lsn,xid,data}',
+ provariadicdflt => "'{}'",
prosrc => 'pg_logical_slot_peek_changes' },
{ oid => '3785', descr => 'peek at binary changes from replication slot',
proname => 'pg_logical_slot_peek_binary_changes', procost => '1000',
@@ -11605,6 +11661,7 @@
proallargtypes => '{name,pg_lsn,int4,_text,pg_lsn,xid,bytea}',
proargmodes => '{i,i,i,v,o,o,o}',
proargnames => '{slot_name,upto_lsn,upto_nchanges,options,lsn,xid,data}',
+ provariadicdflt => "'{}'",
prosrc => 'pg_logical_slot_peek_binary_changes' },
{ oid => '3878', descr => 'advance logical replication slot',
proname => 'pg_replication_slot_advance', provolatile => 'v',
@@ -11615,10 +11672,14 @@
{ oid => '3577', descr => 'emit a textual logical decoding message',
proname => 'pg_logical_emit_message', provolatile => 'v', proparallel => 'u',
prorettype => 'pg_lsn', proargtypes => 'bool text text bool',
+ proargnames => '{transactional,prefix,message,flush}',
+ proargdflts => '{false}',
prosrc => 'pg_logical_emit_message_text' },
{ oid => '3578', descr => 'emit a binary logical decoding message',
proname => 'pg_logical_emit_message', provolatile => 'v', proparallel => 'u',
prorettype => 'pg_lsn', proargtypes => 'bool text bytea bool',
+ proargnames => '{transactional,prefix,message,flush}',
+ proargdflts => '{false}',
prosrc => 'pg_logical_emit_message_bytea' },
{ oid => '6344',
descr => 'sync replication slots from the primary to the standby',
@@ -12268,6 +12329,7 @@
descr => 'configure session to maintain replication progress tracking for the passed in origin',
proname => 'pg_replication_origin_session_setup', provolatile => 'v',
proparallel => 'u', prorettype => 'void', proargtypes => 'text int4',
+ proargnames => '{node_name,pid}', proargdflts => '{0}',
prosrc => 'pg_replication_origin_session_setup' },
{ oid => '6007', descr => 'teardown configured replication progress tracking',
@@ -12518,10 +12580,12 @@
{ oid => '4350', descr => 'Unicode normalization',
proname => 'normalize', prorettype => 'text', proargtypes => 'text text',
+ proargnames => '{str,form}', proargdflts => "{'NFC'}",
prosrc => 'unicode_normalize_func' },
{ oid => '4351', descr => 'check Unicode normalization',
proname => 'is_normalized', prorettype => 'bool', proargtypes => 'text text',
+ proargnames => '{str,form}', proargdflts => "{'NFC'}",
prosrc => 'unicode_is_normalized' },
{ oid => '6198', descr => 'unescape Unicode characters',
--
2.43.0