Skip to content

Commit 3dc820c

Browse files
committed
Teach genbki.pl to auto-generate pg_type entries for array types.
This eliminates some more tedium in adding new catalog entries, specifically the need to set up an array type when adding a new built-in data type. Now it's sufficient to assign an OID for the array type and write it in an "array_type_oid" metadata field. You don't have to fill the base type's typarray link explicitly, either. No catversion bump since the contents of pg_type aren't changed. (Well, their order might be different, but that doesn't matter.) John Naylor, reviewed and whacked around a bit by Dagfinn Ilmari Mannsåker, and some more by me. Discussion: https://postgr.es/m/CAJVSVGVTb6m9pJF49b3SuA8J+T-THO9c0hxOmoyv-yGKh-FbNg@mail.gmail.com
1 parent 09e99ce commit 3dc820c

File tree

7 files changed

+415
-642
lines changed

7 files changed

+415
-642
lines changed

doc/src/sgml/bki.sgml

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -217,12 +217,14 @@
217217
<replaceable>value</replaceable> pairs. The
218218
allowed <replaceable>key</replaceable>s are the names of the catalog's
219219
columns, plus the metadata keys <literal>oid</literal>,
220-
<literal>oid_symbol</literal>, and <literal>descr</literal>.
220+
<literal>oid_symbol</literal>,
221+
<literal>array_type_oid</literal>, and <literal>descr</literal>.
221222
(The use of <literal>oid</literal> and <literal>oid_symbol</literal>
222-
is described in <xref linkend="system-catalog-oid-assignment"/>
223-
below. <literal>descr</literal> supplies a description string for
224-
the object, which will be inserted
225-
into <structname>pg_description</structname>
223+
is described in <xref linkend="system-catalog-oid-assignment"/> below,
224+
while <literal>array_type_oid</literal> is described in
225+
<xref linkend="system-catalog-auto-array-types"/>.
226+
<literal>descr</literal> supplies a description string for the object,
227+
which will be inserted into <structname>pg_description</structname>
226228
or <structname>pg_shdescription</structname> as appropriate.)
227229
While the metadata keys are optional, the catalog's defined columns
228230
must all be provided, except when the catalog's <literal>.h</literal>
@@ -282,8 +284,9 @@
282284
<para>
283285
Within each pair of curly braces, the metadata
284286
fields <literal>oid</literal>, <literal>oid_symbol</literal>,
285-
and <literal>descr</literal> (if present) come first, in that
286-
order, then the catalog's own fields appear in their defined order.
287+
<literal>array_type_oid</literal>, and <literal>descr</literal>
288+
(if present) come first, in that order, then the catalog's own
289+
fields appear in their defined order.
287290
</para>
288291
</listitem>
289292

@@ -498,6 +501,41 @@
498501
</para>
499502
</sect2>
500503

504+
<sect2 id="system-catalog-auto-array-types">
505+
<title>Automatic Creation of Array Types</title>
506+
507+
<para>
508+
Most scalar data types should have a corresponding array type (that is,
509+
a standard varlena array type whose element type is the scalar type, and
510+
which is referenced by the <structfield>typarray</structfield> field of
511+
the scalar type's <structname>pg_type</structname>
512+
entry). <filename>genbki.pl</filename> is able to generate
513+
the <structname>pg_type</structname> entry for the array type
514+
automatically in most cases.
515+
</para>
516+
517+
<para>
518+
To use this facility, just write an <literal>array_type_oid
519+
=&gt; <replaceable>nnnn</replaceable></literal> metadata field in the
520+
scalar type's <structname>pg_type</structname> entry, specifying the OID
521+
to use for the array type. You may then omit
522+
the <structfield>typarray</structfield> field, since it will be filled
523+
automatically with that OID.
524+
</para>
525+
526+
<para>
527+
The generated array type's name is the scalar type's name with an
528+
underscore prepended. The array entry's other fields are filled from
529+
<literal>BKI_ARRAY_DEFAULT(<replaceable>value</replaceable>)</literal>
530+
annotations in <filename>pg_type.h</filename>, or if there isn't one,
531+
copied from the scalar type. (There's also a special case
532+
for <structfield>typalign</structfield>.) Then
533+
the <structfield>typelem</structfield>
534+
and <structfield>typarray</structfield> fields of the two entries are
535+
set to cross-reference each other.
536+
</para>
537+
</sect2>
538+
501539
<sect2 id="system-catalog-recipes">
502540
<title>Recipes for Editing Data Files</title>
503541

src/backend/catalog/Catalog.pm

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,11 @@ sub ParseHeader
191191
{
192192
$column{default} = $1;
193193
}
194+
elsif (
195+
$attopt =~ /BKI_ARRAY_DEFAULT\(['"]?([^'"]+)['"]?\)/)
196+
{
197+
$column{array_default} = $1;
198+
}
194199
elsif ($attopt =~ /BKI_LOOKUP\((\w+)\)/)
195200
{
196201
$column{lookup} = $1;
@@ -277,19 +282,27 @@ sub ParseData
277282
}
278283
}
279284

280-
# If we found a hash reference, keep it.
281-
# Only keep non-data strings if we
282-
# are told to preserve formatting.
285+
# If we found a hash reference, keep it, unless it is marked as
286+
# autogenerated; in that case it'd duplicate an entry we'll
287+
# autogenerate below. (This makes it safe for reformat_dat_file.pl
288+
# with --full-tuples to print autogenerated entries, which seems like
289+
# useful behavior for debugging.)
290+
#
291+
# Only keep non-data strings if we are told to preserve formatting.
283292
if (defined $hash_ref)
284293
{
285-
push @$data, $hash_ref;
294+
push @$data, $hash_ref if !$hash_ref->{autogenerated};
286295
}
287296
elsif ($preserve_formatting)
288297
{
289298
push @$data, $_;
290299
}
291300
}
292301
close $ifd;
302+
303+
# If this is pg_type, auto-generate array types too.
304+
GenerateArrayTypes($schema, $data) if $catname eq 'pg_type';
305+
293306
return $data;
294307
}
295308

@@ -343,6 +356,63 @@ sub AddDefaultValues
343356
}
344357
}
345358

359+
# If a pg_type entry has an array_type_oid metadata field,
360+
# auto-generate an entry for its array type.
361+
sub GenerateArrayTypes
362+
{
363+
my $pgtype_schema = shift;
364+
my $types = shift;
365+
my @array_types;
366+
367+
foreach my $elem_type (@$types)
368+
{
369+
next if !(ref $elem_type eq 'HASH');
370+
next if !defined($elem_type->{array_type_oid});
371+
372+
my %array_type;
373+
374+
# Set up metadata fields for array type.
375+
$array_type{oid} = $elem_type->{array_type_oid};
376+
$array_type{autogenerated} = 1;
377+
$array_type{line_number} = $elem_type->{line_number};
378+
379+
# Set up column values derived from the element type.
380+
$array_type{typname} = '_' . $elem_type->{typname};
381+
$array_type{typelem} = $elem_type->{typname};
382+
383+
# Arrays require INT alignment, unless the element type requires
384+
# DOUBLE alignment.
385+
$array_type{typalign} = $elem_type->{typalign} eq 'd' ? 'd' : 'i';
386+
387+
# Fill in the rest of the array entry's fields.
388+
foreach my $column (@$pgtype_schema)
389+
{
390+
my $attname = $column->{name};
391+
392+
# Skip if we already set it above.
393+
next if defined $array_type{$attname};
394+
395+
# Apply the BKI_ARRAY_DEFAULT setting if there is one,
396+
# otherwise copy the field from the element type.
397+
if (defined $column->{array_default})
398+
{
399+
$array_type{$attname} = $column->{array_default};
400+
}
401+
else
402+
{
403+
$array_type{$attname} = $elem_type->{$attname};
404+
}
405+
}
406+
407+
# Lastly, cross-link the array to the element type.
408+
$elem_type->{typarray} = $array_type{typname};
409+
410+
push @array_types, \%array_type;
411+
}
412+
413+
push @$types, @array_types;
414+
}
415+
346416
# Rename temporary files to final names.
347417
# Call this function with the final file name and the .tmp extension.
348418
#

src/backend/catalog/genbki.pl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,9 @@
394394
next
395395
if $key eq "oid"
396396
|| $key eq "oid_symbol"
397+
|| $key eq "array_type_oid"
397398
|| $key eq "descr"
399+
|| $key eq "autogenerated"
398400
|| $key eq "line_number";
399401
die sprintf "unrecognized field name \"%s\" in %s.dat line %s\n",
400402
$key, $catname, $bki_values{line_number}

src/include/catalog/genbki.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
#define BKI_FORCE_NOT_NULL
3535
/* Specifies a default value for a catalog field */
3636
#define BKI_DEFAULT(value)
37+
/* Specifies a default value for auto-generated array types */
38+
#define BKI_ARRAY_DEFAULT(value)
3739
/* Indicates how to perform name lookups for an OID or OID-array field */
3840
#define BKI_LOOKUP(catalog)
3941

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy