Re: generating function default settings from pg_proc.dat - Mailing list pgsql-hackers

From Tom Lane
Subject Re: generating function default settings from pg_proc.dat
Date
Msg-id 1881128.1771353709@sss.pgh.pa.us
Whole thread Raw
In response to Re: generating function default settings from pg_proc.dat  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: generating function default settings from pg_proc.dat
List pgsql-hackers
Here's the promised v2, which addresses all your review comments.

With respect to the list of supported types in bki.sgml: I wonder if
we should just drop that, because it evidently hasn't been maintained
well.  It wasn't at all in sync with the actual contents of TypInfo[].
I made it be so, but ...

Poking further at that, I found that there were a lot of TypInfo[]
entries that were not actually used and seem to have just been
cargo-culted in.  So this patch removes all the ones that aren't
demonstrably necessary to get through initdb.  Maybe that's too
aggressive, but in view of the potential for maintenance errors
(cf 7cdb633c8) I don't think we should be carrying unused entries
there.

            regards, tom lane

From fa818e3fa7c74019c2b6ffc3a0050db719581852 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Tue, 17 Feb 2026 13:31:56 -0500
Subject: [PATCH v2] Simplify creation of built-in functions with default
 arguments.

Up to now, to create such a function, one had to make a pg_proc.dat
entry and then overwrite it with a CREATE OR REPLACE command in
system_functions.sql.  That's error-prone (cf. bug #19409) and
results in leaving dead rows in the initial contents of pg_proc.

Manual maintenance of pg_node_tree strings seems entirely impractical,
and parsing expressions during bootstrap would be extremely difficult
as well.  But Andres Freund observed that all the current use-cases
are simple constants, and building a Const node is well within the
capabilities of bootstrap mode.  So this patch invents a special case:
if bootstrap mode is asked to ingest a non-null value for
pg_proc.proargdefaults (which would otherwise fail in
pg_node_tree_in), it parses the value as an array literal and then
feeds the element strings to the input functions for the corresponding
parameter types.  Then we can build a suitable pg_node_tree string
with just a few more lines of code.

This allows removing all the system_functions.sql entries that are
just there to set up default arguments, replacing them with
proargdefaults fields in pg_proc.dat entries.  The old technique
remains available in case someone needs a non-constant default.

The initial contents of pg_proc are demonstrably the same after
this patch, except that (1) json_strip_nulls and jsonb_strip_nulls
now have the correct provolatile setting, as per bug #19409;
(2) pg_terminate_backend, make_interval, and drandom_normal
now have defaults that don't include a type coercion, which is
how they should have been all along.

Author: Tom Lane <tgl@sss.pgh.pa.us>
Author: Andrew Dunstan <andrew@dunslane.net>
Reviewed-by: Andres Freund <andres@anarazel.de>
Discussion: https://postgr.es/m/183292bb-4891-4c96-a3ca-e78b5e0e1358@dunslane.net
---
 doc/src/sgml/bki.sgml                    |  34 ++-
 src/backend/bootstrap/bootstrap.c        | 177 ++++++++++++--
 src/backend/catalog/system_functions.sql | 285 +----------------------
 src/backend/utils/cache/lsyscache.c      |   4 +-
 src/include/bootstrap/bootstrap.h        |   3 +-
 src/include/catalog/pg_proc.dat          |  86 ++++++-
 6 files changed, 262 insertions(+), 327 deletions(-)

diff --git a/doc/src/sgml/bki.sgml b/doc/src/sgml/bki.sgml
index 53a982bf60d..087a6827b00 100644
--- a/doc/src/sgml/bki.sgml
+++ b/doc/src/sgml/bki.sgml
@@ -271,6 +271,21 @@
      </para>
     </listitem>

+    <listitem>
+     <para>
+      There is a special case for values of the
+      <structname>pg_proc</structname>.<structfield>proargdefaults</structfield>
+      field, which is of type <type>pg_node_tree</type>.  The real
+      contents of that type are too complex for hand-written entries,
+      but what we need for <structfield>proargdefaults</structfield> is
+      typically just a list of Const nodes.  Therefore, the bootstrap
+      backend will interpret a value given for that field according to
+      text array syntax, and then feed the array element values to the
+      datatype input routines for the corresponding input parameters' data
+      types, and finally build Const nodes from the datums.
+     </para>
+    </listitem>
+
     <listitem>
      <para>
       Since hashes are unordered data structures, field order and line
@@ -817,11 +832,11 @@ $ perl  rewrite_dat_with_prokind.pl  pg_proc.dat
       The following column types are supported directly by
       <filename>bootstrap.c</filename>: <type>bool</type>,
       <type>bytea</type>, <type>char</type> (1 byte),
-      <type>name</type>, <type>int2</type>,
-      <type>int4</type>, <type>regproc</type>, <type>regclass</type>,
-      <type>regtype</type>, <type>text</type>,
-      <type>oid</type>, <type>tid</type>, <type>xid</type>,
-      <type>cid</type>, <type>int2vector</type>, <type>oidvector</type>,
+      <type>int2</type>, <type>int4</type>, <type>int8</type>,
+      <type>float4</type>, <type>float8</type>,
+      <type>name</type>, <type>regproc</type>, <type>text</type>,
+      <type>jsonb</type>, <type>oid</type>, <type>pg_node_tree</type>,
+      <type>int2vector</type>, <type>oidvector</type>,
       <type>_int4</type> (array), <type>_text</type> (array),
       <type>_oid</type> (array), <type>_char</type> (array),
       <type>_aclitem</type> (array).  Although it is possible to create
@@ -884,7 +899,7 @@ $ perl  rewrite_dat_with_prokind.pl  pg_proc.dat

    <varlistentry>
     <term>
-     <literal>insert</literal> <literal>(</literal> <optional><replaceable
class="parameter">oid_value</replaceable></optional><replaceable class="parameter">value1</replaceable> <replaceable
class="parameter">value2</replaceable>... <literal>)</literal> 
+     <literal>insert</literal> <literal>(</literal> <replaceable class="parameter">value1</replaceable> <replaceable
class="parameter">value2</replaceable>... <literal>)</literal> 
     </term>

     <listitem>
@@ -902,6 +917,13 @@ $ perl  rewrite_dat_with_prokind.pl  pg_proc.dat
       (To include a single quote in a value, write it twice.
       Escape-string-style backslash escapes are allowed in the string, too.)
      </para>
+
+     <para>
+      In most cases a <replaceable class="parameter">value</replaceable>
+      string is simply fed to the datatype input routine for the column's
+      data type, after de-quoting if needed.  However there are exceptions
+      for certain fields, as detailed previously.
+     </para>
     </listitem>
    </varlistentry>

diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index 7d32cd0e159..8d601c363b4 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -26,6 +26,7 @@
 #include "bootstrap/bootstrap.h"
 #include "catalog/index.h"
 #include "catalog/pg_collation.h"
+#include "catalog/pg_proc.h"
 #include "catalog/pg_type.h"
 #include "common/link-canary.h"
 #include "miscadmin.h"
@@ -46,6 +47,7 @@
 static void CheckerModeMain(void);
 static void bootstrap_signals(void);
 static Form_pg_attribute AllocateAttribute(void);
+static void InsertOneProargdefaultsValue(char *value);
 static void populate_typ_list(void);
 static Oid    gettype(char *type);
 static void cleanup(void);
@@ -91,38 +93,28 @@ static const struct typinfo TypInfo[] = {
     F_BYTEAIN, F_BYTEAOUT},
     {"char", CHAROID, 0, 1, true, TYPALIGN_CHAR, TYPSTORAGE_PLAIN, InvalidOid,
     F_CHARIN, F_CHAROUT},
+    {"cstring", CSTRINGOID, 0, -2, false, TYPALIGN_CHAR, TYPSTORAGE_PLAIN, InvalidOid,
+    F_CSTRING_IN, F_CSTRING_OUT},
     {"int2", INT2OID, 0, 2, true, TYPALIGN_SHORT, TYPSTORAGE_PLAIN, InvalidOid,
     F_INT2IN, F_INT2OUT},
     {"int4", INT4OID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
     F_INT4IN, F_INT4OUT},
+    {"int8", INT8OID, 0, 8, true, TYPALIGN_DOUBLE, TYPSTORAGE_PLAIN, InvalidOid,
+    F_INT8IN, F_INT8OUT},
     {"float4", FLOAT4OID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
     F_FLOAT4IN, F_FLOAT4OUT},
+    {"float8", FLOAT8OID, 0, 8, true, TYPALIGN_DOUBLE, TYPSTORAGE_PLAIN, InvalidOid,
+    F_FLOAT8IN, F_FLOAT8OUT},
     {"name", NAMEOID, CHAROID, NAMEDATALEN, false, TYPALIGN_CHAR, TYPSTORAGE_PLAIN, C_COLLATION_OID,
     F_NAMEIN, F_NAMEOUT},
-    {"regclass", REGCLASSOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
-    F_REGCLASSIN, F_REGCLASSOUT},
     {"regproc", REGPROCOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
     F_REGPROCIN, F_REGPROCOUT},
-    {"regtype", REGTYPEOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
-    F_REGTYPEIN, F_REGTYPEOUT},
-    {"regrole", REGROLEOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
-    F_REGROLEIN, F_REGROLEOUT},
-    {"regnamespace", REGNAMESPACEOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
-    F_REGNAMESPACEIN, F_REGNAMESPACEOUT},
-    {"regdatabase", REGDATABASEOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
-    F_REGDATABASEIN, F_REGDATABASEOUT},
     {"text", TEXTOID, 0, -1, false, TYPALIGN_INT, TYPSTORAGE_EXTENDED, DEFAULT_COLLATION_OID,
     F_TEXTIN, F_TEXTOUT},
+    {"jsonb", JSONBOID, 0, -1, false, TYPALIGN_INT, TYPSTORAGE_EXTENDED, InvalidOid,
+    F_JSONB_IN, F_JSONB_OUT},
     {"oid", OIDOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
     F_OIDIN, F_OIDOUT},
-    {"oid8", OID8OID, 0, 8, true, TYPALIGN_DOUBLE, TYPSTORAGE_PLAIN, InvalidOid,
-    F_OID8IN, F_OID8OUT},
-    {"tid", TIDOID, 0, 6, false, TYPALIGN_SHORT, TYPSTORAGE_PLAIN, InvalidOid,
-    F_TIDIN, F_TIDOUT},
-    {"xid", XIDOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
-    F_XIDIN, F_XIDOUT},
-    {"cid", CIDOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
-    F_CIDIN, F_CIDOUT},
     {"pg_node_tree", PG_NODE_TREEOID, 0, -1, false, TYPALIGN_INT, TYPSTORAGE_EXTENDED, DEFAULT_COLLATION_OID,
     F_PG_NODE_TREE_IN, F_PG_NODE_TREE_OUT},
     {"int2vector", INT2VECTOROID, INT2OID, -1, false, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
@@ -660,6 +652,7 @@ InsertOneTuple(void)
 void
 InsertOneValue(char *value, int i)
 {
+    Form_pg_attribute attr;
     Oid            typoid;
     int16        typlen;
     bool        typbyval;
@@ -668,19 +661,42 @@ InsertOneValue(char *value, int i)
     Oid            typioparam;
     Oid            typinput;
     Oid            typoutput;
+    Oid            typcollation;

     Assert(i >= 0 && i < MAXATTR);

     elog(DEBUG4, "inserting column %d value \"%s\"", i, value);

-    typoid = TupleDescAttr(boot_reldesc->rd_att, i)->atttypid;
+    attr = TupleDescAttr(RelationGetDescr(boot_reldesc), i);
+    typoid = attr->atttypid;

     boot_get_type_io_data(typoid,
                           &typlen, &typbyval, &typalign,
                           &typdelim, &typioparam,
-                          &typinput, &typoutput);
+                          &typinput, &typoutput,
+                          &typcollation);

-    values[i] = OidInputFunctionCall(typinput, value, typioparam, -1);
+    /*
+     * pg_node_tree values can't be inserted normally (pg_node_tree_in would
+     * just error out), so provide special cases for such columns that we
+     * would like to fill during bootstrap.
+     */
+    if (typoid == PG_NODE_TREEOID)
+    {
+        /* pg_proc.proargdefaults */
+        if (RelationGetRelid(boot_reldesc) == ProcedureRelationId &&
+            i == Anum_pg_proc_proargdefaults - 1)
+            InsertOneProargdefaultsValue(value);
+        else                    /* maybe other cases later */
+            elog(ERROR, "can't handle pg_node_tree input for %s.%s",
+                 RelationGetRelationName(boot_reldesc),
+                 NameStr(attr->attname));
+    }
+    else
+    {
+        /* Normal case */
+        values[i] = OidInputFunctionCall(typinput, value, typioparam, -1);
+    }

     /*
      * We use ereport not elog here so that parameters aren't evaluated unless
@@ -691,6 +707,111 @@ InsertOneValue(char *value, int i)
                              OidOutputFunctionCall(typoutput, values[i]))));
 }

+/* ----------------
+ *        InsertOneProargdefaultsValue
+ *
+ * In general, proargdefaults can be a list of any expressions, but
+ * for bootstrap we only support a list of Const nodes.  The input
+ * has the form of a text array, and we feed non-null elements to the
+ * typinput functions for the appropriate parameters.
+ * ----------------
+ */
+static void
+InsertOneProargdefaultsValue(char *value)
+{
+    int            pronargs;
+    oidvector  *proargtypes;
+    Datum        arrayval;
+    Datum       *array_datums;
+    bool       *array_nulls;
+    int            array_count;
+    List       *proargdefaults;
+    char       *nodestring;
+
+    /* The pg_proc columns we need to use must have been filled already */
+    StaticAssertDecl(Anum_pg_proc_pronargs < Anum_pg_proc_proargdefaults,
+                     "pronargs must come before proargdefaults");
+    StaticAssertDecl(Anum_pg_proc_pronargdefaults < Anum_pg_proc_proargdefaults,
+                     "pronargdefaults must come before proargdefaults");
+    StaticAssertDecl(Anum_pg_proc_proargtypes < Anum_pg_proc_proargdefaults,
+                     "proargtypes must come before proargdefaults");
+    if (Nulls[Anum_pg_proc_pronargs - 1])
+        elog(ERROR, "pronargs must not be null");
+    if (Nulls[Anum_pg_proc_proargtypes - 1])
+        elog(ERROR, "proargtypes must not be null");
+    pronargs = DatumGetInt16(values[Anum_pg_proc_pronargs - 1]);
+    proargtypes = DatumGetPointer(values[Anum_pg_proc_proargtypes - 1]);
+    Assert(pronargs == proargtypes->dim1);
+
+    /* Parse the input string as an array value, then deconstruct to Datums */
+    arrayval = OidFunctionCall3(F_ARRAY_IN,
+                                CStringGetDatum(value),
+                                ObjectIdGetDatum(CSTRINGOID),
+                                Int32GetDatum(-1));
+    deconstruct_array_builtin(DatumGetArrayTypeP(arrayval), CSTRINGOID,
+                              &array_datums, &array_nulls, &array_count);
+
+    /* The values should correspond to the last N argtypes */
+    if (array_count > pronargs)
+        elog(ERROR, "too many proargdefaults entries");
+
+    /* Build the List of Const nodes */
+    proargdefaults = NIL;
+    for (int i = 0; i < array_count; i++)
+    {
+        Oid            argtype = proargtypes->values[pronargs - array_count + i];
+        int16        typlen;
+        bool        typbyval;
+        char        typalign;
+        char        typdelim;
+        Oid            typioparam;
+        Oid            typinput;
+        Oid            typoutput;
+        Oid            typcollation;
+        Datum        defval;
+        bool        defnull;
+        Const       *defConst;
+
+        boot_get_type_io_data(argtype,
+                              &typlen, &typbyval, &typalign,
+                              &typdelim, &typioparam,
+                              &typinput, &typoutput,
+                              &typcollation);
+
+        defnull = array_nulls[i];
+        if (defnull)
+            defval = (Datum) 0;
+        else
+            defval = OidInputFunctionCall(typinput,
+                                          DatumGetCString(array_datums[i]),
+                                          typioparam, -1);
+
+        defConst = makeConst(argtype,
+                             -1,    /* never any typmod */
+                             typcollation,
+                             typlen,
+                             defval,
+                             defnull,
+                             typbyval);
+        proargdefaults = lappend(proargdefaults, defConst);
+    }
+
+    /*
+     * Flatten the List to a node-tree string, then convert to a text datum,
+     * which is the storage representation of pg_node_tree.
+     */
+    nodestring = nodeToString(proargdefaults);
+    values[Anum_pg_proc_proargdefaults - 1] = CStringGetTextDatum(nodestring);
+    Nulls[Anum_pg_proc_proargdefaults - 1] = false;
+
+    /*
+     * Hack: fill in pronargdefaults with the right value.  This is surely
+     * ugly, but it beats making the programmer do it.
+     */
+    values[Anum_pg_proc_pronargdefaults - 1] = Int16GetDatum(array_count);
+    Nulls[Anum_pg_proc_pronargdefaults - 1] = false;
+}
+
 /* ----------------
  *        InsertOneNull
  * ----------------
@@ -831,10 +952,11 @@ gettype(char *type)
  *        boot_get_type_io_data
  *
  * Obtain type I/O information at bootstrap time.  This intentionally has
- * almost the same API as lsyscache.c's get_type_io_data, except that
+ * an API very close to that of lsyscache.c's get_type_io_data, except that
  * we only support obtaining the typinput and typoutput routines, not
- * the binary I/O routines.  It is exported so that array_in and array_out
- * can be made to work during early bootstrap.
+ * the binary I/O routines, and we also return the type's collation.
+ * This is exported so that array_in and array_out can be made to work
+ * during early bootstrap.
  * ----------------
  */
 void
@@ -845,7 +967,8 @@ boot_get_type_io_data(Oid typid,
                       char *typdelim,
                       Oid *typioparam,
                       Oid *typinput,
-                      Oid *typoutput)
+                      Oid *typoutput,
+                      Oid *typcollation)
 {
     if (Typ != NIL)
     {
@@ -876,6 +999,8 @@ boot_get_type_io_data(Oid typid,

         *typinput = ap->am_typ.typinput;
         *typoutput = ap->am_typ.typoutput;
+
+        *typcollation = ap->am_typ.typcollation;
     }
     else
     {
@@ -904,6 +1029,8 @@ boot_get_type_io_data(Oid typid,

         *typinput = TypInfo[typeindex].inproc;
         *typoutput = TypInfo[typeindex].outproc;
+
+        *typcollation = TypInfo[typeindex].collation;
     }
 }

diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql
index eb9e31ae1bf..4e24d6b55fa 100644
--- a/src/backend/catalog/system_functions.sql
+++ b/src/backend/catalog/system_functions.sql
@@ -7,7 +7,8 @@
  *
  * This file redefines certain built-in functions that are impractical
  * to fully define in pg_proc.dat.  In most cases that's because they use
- * SQL-standard function bodies and/or default expressions.  The node
+ * SQL-standard function bodies and/or default expressions.  (But defaults
+ * that are just constants can be entered in pg_proc.dat.)  The node
  * tree representations of those are too unreadable, platform-dependent,
  * and changeable to want to deal with them manually.  Hence, we put stub
  * definitions of such functions into pg_proc.dat and then replace them
@@ -66,13 +67,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 +376,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/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index b924a2d900b..1913b009d40 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2492,6 +2492,7 @@ get_type_io_data(Oid typid,
     {
         Oid            typinput;
         Oid            typoutput;
+        Oid            typcollation;

         boot_get_type_io_data(typid,
                               typlen,
@@ -2500,7 +2501,8 @@ get_type_io_data(Oid typid,
                               typdelim,
                               typioparam,
                               &typinput,
-                              &typoutput);
+                              &typoutput,
+                              &typcollation);
         switch (which_func)
         {
             case IOFunc_input:
diff --git a/src/include/bootstrap/bootstrap.h b/src/include/bootstrap/bootstrap.h
index 51680522afc..21447a3d661 100644
--- a/src/include/bootstrap/bootstrap.h
+++ b/src/include/bootstrap/bootstrap.h
@@ -53,7 +53,8 @@ extern void boot_get_type_io_data(Oid typid,
                                   char *typdelim,
                                   Oid *typioparam,
                                   Oid *typinput,
-                                  Oid *typoutput);
+                                  Oid *typoutput,
+                                  Oid *typcollation);

 union YYSTYPE;
 typedef void *yyscan_t;
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 83f6501df38..dac40992cbc 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}', proargdefaults => '{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}', proargdefaults => '{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
acrossall 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}',
+  proargdefaults => '{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}',
+  proargdefaults => '{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}', proargdefaults => '{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}',
+  proargdefaults => '{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}',
+  proargdefaults => '{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}', proargdefaults => '{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}', proargdefaults => '{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}',
+  proargdefaults => '{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}',
+  proargdefaults => '{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}', proargdefaults => '{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}',
+  proargdefaults => '{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}',
+  proargdefaults => '{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}',
+  proargdefaults => '{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}',
+  proargdefaults => '{"{}",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}',
+  proargdefaults => '{"{}",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}',
+  proargdefaults => '{"{}",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}',
+  proargdefaults => '{"{}",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}',
+  proargdefaults => '{"{}",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}',
+  proargdefaults => '{"{}",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}',
+  proargdefaults => '{"{}",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}',
+  proargdefaults => '{"{}",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}',
+  proargdefaults => '{"{}",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}',
+  proargdefaults => '{"{}",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}',
+  proargdefaults => '{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}',
+  proargdefaults => '{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}',
+  proargdefaults => '{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}',
+  proargdefaults => '{"{}"}',
   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}',
+  proargdefaults => '{"{}"}',
   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}',
+  proargdefaults => '{"{}"}',
   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}',
+  proargdefaults => '{"{}"}',
   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}',
+  proargdefaults => '{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}',
+  proargdefaults => '{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}', proargdefaults => '{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',
+  proargdefaults => '{NFC}',
   prosrc => 'unicode_normalize_func' },

 { oid => '4351', descr => 'check Unicode normalization',
   proname => 'is_normalized', prorettype => 'bool', proargtypes => 'text text',
+  proargdefaults => '{NFC}',
   prosrc => 'unicode_is_normalized' },

 { oid => '6198', descr => 'unescape Unicode characters',
--
2.43.7


pgsql-hackers by date:

Previous
From: Peter Geoghegan
Date:
Subject: Re: index prefetching
Next
From: Noah Misch
Date:
Subject: EUC_* encodings: pass check-world