| From: | Andres Freund <andres(at)anarazel(dot)de> |
|---|---|
| To: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
| Cc: | Andrew Dunstan <andrew(at)dunslane(dot)net>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org> |
| Subject: | Re: generating function default settings from pg_proc.dat |
| Date: | 2026-02-17 15:13:43 |
| Message-ID: | vyg3dbti5plpcebb5omrwfmw3uvbh2csa4tobmgvz5g5dipxhl@ynpfdfbx7ylc |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi,
On 2026-02-16 20:36:25 -0500, Tom Lane wrote:
> Here is a draft patch along those lines. I've verified that
> the initial contents of pg_proc are exactly as before,
> except that json[b]_strip_nulls gain the correct provolatile
> value, and a few proargdefaults entries no longer involve
> cast functions.
Nice.
> @@ -817,8 +832,10 @@ $ 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>int2</type>, <type>int4</type>, <type>int8</type>,
> + <type>float4</type>, <type>float8</type>,
> + <type>name</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>,
Don't you also add jsonb support below?
> + /*
> + * 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)
> + values[i] = ConvertOneProargdefaultsValue(value);
> + else /* maybe other cases later */
> + elog(ERROR, "can't handle pg_node_tree input");
Perhaps add the relid to the ERROR?
> +/* ----------------
> + * ConvertOneProargdefaultsValue
> + *
> + * 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 Datum
> +ConvertOneProargdefaultsValue(char *value)
> +{
> + int pronargs;
> + oidvector *proargtypes;
> + Datum arrayval;
> + Datum *array_datums;
> + bool *array_nulls;
> + int array_count;
> + List *proargdefaults;
> +
> + /* 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 a text[] value, then deconstruct to Datums */
> + arrayval = OidFunctionCall3(F_ARRAY_IN,
> + CStringGetDatum(value),
> + ObjectIdGetDatum(TEXTOID),
> + Int32GetDatum(-1));
>
> + deconstruct_array_builtin(DatumGetArrayTypeP(arrayval), TEXTOID,
> + &array_datums, &array_nulls, &array_count);
If we convert to cstring below anyway, why not make it a cstring array?
> + /* 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 = boot_get_typcollation(argtype);
> + defnull = array_nulls[i];
> + if (defnull)
> + defval = (Datum) 0;
> + else
> + {
> + char *defstr = text_to_cstring(DatumGetTextPP(array_datums[i]));
> +
> + defval = OidInputFunctionCall(typinput, defstr, typioparam, -1);
> + }
> +
> + defConst = makeConst(argtype,
> + -1, /* never any typmod */
> + typcollation,
> + typlen,
> + defval,
> + defnull,
> + typbyval);
> + proargdefaults = lappend(proargdefaults, defConst);
> + }
> +
> + /*
> + * 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;
I don't mind the hack, but I wonder about it location. It's odd that the
caller puts the return value of ConvertOneProargdefaultsValue() into the
values array, but then ConvertOneProargdefaultsValue() also sets
pronargdefaults?
> +/* ----------------
> + * boot_get_typcollation
> + *
> + * Obtain type's collation at bootstrap time. This intentionally has
> + * the same API as lsyscache.c's get_typcollation.
> + *
> + * XXX would it be better to add another output to boot_get_type_io_data?
Yes, it seems like it would? There aren't many callers for it...
Greetings,
Andres Freund
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Zsolt Parragi | 2026-02-17 15:14:59 | Headerscheck support for meson |
| Previous Message | Tom Lane | 2026-02-17 15:00:31 | Re: generating function default settings from pg_proc.dat |