aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/catalog/Catalog.pm78
-rw-r--r--src/backend/catalog/genbki.pl2
2 files changed, 76 insertions, 4 deletions
diff --git a/src/backend/catalog/Catalog.pm b/src/backend/catalog/Catalog.pm
index ae5b499b6ad..d2f48d1d0d5 100644
--- a/src/backend/catalog/Catalog.pm
+++ b/src/backend/catalog/Catalog.pm
@@ -191,6 +191,11 @@ sub ParseHeader
{
$column{default} = $1;
}
+ elsif (
+ $attopt =~ /BKI_ARRAY_DEFAULT\(['"]?([^'"]+)['"]?\)/)
+ {
+ $column{array_default} = $1;
+ }
elsif ($attopt =~ /BKI_LOOKUP\((\w+)\)/)
{
$column{lookup} = $1;
@@ -277,12 +282,16 @@ sub ParseData
}
}
- # If we found a hash reference, keep it.
- # Only keep non-data strings if we
- # are told to preserve formatting.
+ # If we found a hash reference, keep it, unless it is marked as
+ # autogenerated; in that case it'd duplicate an entry we'll
+ # autogenerate below. (This makes it safe for reformat_dat_file.pl
+ # with --full-tuples to print autogenerated entries, which seems like
+ # useful behavior for debugging.)
+ #
+ # Only keep non-data strings if we are told to preserve formatting.
if (defined $hash_ref)
{
- push @$data, $hash_ref;
+ push @$data, $hash_ref if !$hash_ref->{autogenerated};
}
elsif ($preserve_formatting)
{
@@ -290,6 +299,10 @@ sub ParseData
}
}
close $ifd;
+
+ # If this is pg_type, auto-generate array types too.
+ GenerateArrayTypes($schema, $data) if $catname eq 'pg_type';
+
return $data;
}
@@ -343,6 +356,63 @@ sub AddDefaultValues
}
}
+# If a pg_type entry has an array_type_oid metadata field,
+# auto-generate an entry for its array type.
+sub GenerateArrayTypes
+{
+ my $pgtype_schema = shift;
+ my $types = shift;
+ my @array_types;
+
+ foreach my $elem_type (@$types)
+ {
+ next if !(ref $elem_type eq 'HASH');
+ next if !defined($elem_type->{array_type_oid});
+
+ my %array_type;
+
+ # Set up metadata fields for array type.
+ $array_type{oid} = $elem_type->{array_type_oid};
+ $array_type{autogenerated} = 1;
+ $array_type{line_number} = $elem_type->{line_number};
+
+ # Set up column values derived from the element type.
+ $array_type{typname} = '_' . $elem_type->{typname};
+ $array_type{typelem} = $elem_type->{typname};
+
+ # Arrays require INT alignment, unless the element type requires
+ # DOUBLE alignment.
+ $array_type{typalign} = $elem_type->{typalign} eq 'd' ? 'd' : 'i';
+
+ # Fill in the rest of the array entry's fields.
+ foreach my $column (@$pgtype_schema)
+ {
+ my $attname = $column->{name};
+
+ # Skip if we already set it above.
+ next if defined $array_type{$attname};
+
+ # Apply the BKI_ARRAY_DEFAULT setting if there is one,
+ # otherwise copy the field from the element type.
+ if (defined $column->{array_default})
+ {
+ $array_type{$attname} = $column->{array_default};
+ }
+ else
+ {
+ $array_type{$attname} = $elem_type->{$attname};
+ }
+ }
+
+ # Lastly, cross-link the array to the element type.
+ $elem_type->{typarray} = $array_type{typname};
+
+ push @array_types, \%array_type;
+ }
+
+ push @$types, @array_types;
+}
+
# Rename temporary files to final names.
# Call this function with the final file name and the .tmp extension.
#
diff --git a/src/backend/catalog/genbki.pl b/src/backend/catalog/genbki.pl
index 9be51d28b03..649200260a4 100644
--- a/src/backend/catalog/genbki.pl
+++ b/src/backend/catalog/genbki.pl
@@ -394,7 +394,9 @@ EOM
next
if $key eq "oid"
|| $key eq "oid_symbol"
+ || $key eq "array_type_oid"
|| $key eq "descr"
+ || $key eq "autogenerated"
|| $key eq "line_number";
die sprintf "unrecognized field name \"%s\" in %s.dat line %s\n",
$key, $catname, $bki_values{line_number}