Hi,
On 2026-02-16 14:13:45 -0500, Tom Lane wrote:
> Andres Freund <[email protected]> writes:
> > I wish we could just generate the parse-analyzed representation for default
> > values during bootstrap, but that's probably not realistic.
>
> > Although, I guess we don't really need the full machinery. Afaict we just
> > need
> > a list of simple CONST nodes.
>
> Const is enough to be problematic. In particular, the bytes of the
> stored Datum are shown in physical order so that the results are
> endian-dependent. We can't have machine dependencies in postgres.bki.
I was more thinking we would teach bootstrap.c/bootparse.y to generate the
List(Const+) from a simpler representation that would be included in
postgres.bki, rather than include the node tree soup in postgres.bki.
> I think what we'd really want here is some smarts in backend bootstrap
> mode to be able to invoke the correct datatype input function to
> convert the type's standard string representation into a Datum.
> I wonder how complicated that'd be.
Seems we were thinking something roughly similar...
Looks like the slightly difficult bit is that we haven't assembled the pg_proc
row by the time we'd do the OidInputFunctionCall() in InsertOneValue(), so
we'd not trivially know the type of the corresponding column.
But if we made the input something like {'some'::type1, 'value'::type2}, we
wouldn't need to know the corresponding column's type, and genbki could build
it.
I'm starting to wonder if we shouldn't do something more bespoke for all
functions during bootstrap in general, rather than just for the argument
defaults.
Particularly for SRFs, I find it rather painful to keep proargtypes,
proallargtypes, proargmodes, proargnames in sync. Not helped by proargtypes
and proallargtypes/proargmodes/... having a different input syntax. I've
spent too much time trying to keep the arguments of stats functions in sync.
{ oid => '3786', descr => 'set up a logical replication slot',
proname => 'pg_create_logical_replication_slot', provolatile => 'v',
proparallel => 'u', prorettype => 'record',
proargtypes => 'name name bool bool bool',
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}',
prosrc => 'pg_create_logical_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';
could be
{ oid => '3786', descr => 'set up a logical replication slot',
proname => 'pg_create_logical_replication_slot', provolatile => 'v',
proparallel => 'u',
proargs => [
{type => 'name', name => 'slot_name'},
{type => 'name', name => 'plugin'},
{type => 'bool', name => 'temporary', default => 'false'},
{type => 'bool', name => 'twophase', default => 'false'},
{type => 'bool', name => 'failover', default => 'false'},
],
prorettype => [
{type => 'name', name => 'slot_name'},
{type => 'pg_lsn', name => 'lsn'},
]
}
and then either turn that into something like the current representation, or
perhaps better, into a new top-level 'proc' bootstrap command, which then
would know how to interpret the default literals into the node soup.
Greetings,
Andres Freund