diff options
Diffstat (limited to 'src/backend/catalog/Catalog.pm')
-rw-r--r-- | src/backend/catalog/Catalog.pm | 306 |
1 files changed, 157 insertions, 149 deletions
diff --git a/src/backend/catalog/Catalog.pm b/src/backend/catalog/Catalog.pm index cdb0bee1305..a66fce9e0dc 100644 --- a/src/backend/catalog/Catalog.pm +++ b/src/backend/catalog/Catalog.pm @@ -25,150 +25,158 @@ our @EXPORT_OK = qw(Catalogs RenameTempFile); # Returns a nested data structure describing the data in the headers. sub Catalogs { - my (%catalogs, $catname, $declaring_attributes, $most_recent); - $catalogs{names} = []; - - # There are a few types which are given one name in the C source, but a - # different name at the SQL level. These are enumerated here. - my %RENAME_ATTTYPE = ( - 'Oid' => 'oid', - 'NameData' => 'name', - 'TransactionId' => 'xid' - ); - - foreach my $input_file (@_) - { - my %catalog; - $catalog{columns} = []; - $catalog{data} = []; - - open(INPUT_FILE, '<', $input_file) || die "$input_file: $!"; - - # Scan the input file. - while (<INPUT_FILE>) - { - # Strip C-style comments. - s;/\*(.|\n)*\*/;;g; - if (m;/\*;) - { - # handle multi-line comments properly. - my $next_line = <INPUT_FILE>; - die "$input_file: ends within C-style comment\n" - if !defined $next_line; - $_ .= $next_line; - redo; - } - - # Strip useless whitespace and trailing semicolons. - chomp; - s/^\s+//; - s/;\s*$//; - s/\s+/ /g; - - # Push the data into the appropriate data structure. - if (/^DATA\(insert(\s+OID\s+=\s+(\d+))?\s+\(\s*(.*)\s*\)\s*\)$/) - { - push @{ $catalog{data} }, {oid => $2, bki_values => $3}; - } - elsif (/^DESCR\(\"(.*)\"\)$/) - { - $most_recent = $catalog{data}->[-1]; - # this tests if most recent line is not a DATA() statement - if (ref $most_recent ne 'HASH') - { - die "DESCR() does not apply to any catalog ($input_file)"; - } - if (!defined $most_recent->{oid}) - { - die "DESCR() does not apply to any oid ($input_file)"; - } - elsif ($1 ne '') - { - $most_recent->{descr} = $1; - } - } - elsif (/^SHDESCR\(\"(.*)\"\)$/) - { - $most_recent = $catalog{data}->[-1]; - # this tests if most recent line is not a DATA() statement - if (ref $most_recent ne 'HASH') - { - die "SHDESCR() does not apply to any catalog ($input_file)"; - } - if (!defined $most_recent->{oid}) - { - die "SHDESCR() does not apply to any oid ($input_file)"; - } - elsif ($1 ne '') - { - $most_recent->{shdescr} = $1; - } - } - elsif (/^DECLARE_TOAST\(\s*(\w+),\s*(\d+),\s*(\d+)\)/) - { - $catname = 'toasting'; - my ($toast_name, $toast_oid, $index_oid) = ($1, $2, $3); - push @{ $catalog{data} }, "declare toast $toast_oid $index_oid on $toast_name\n"; - } - elsif (/^DECLARE_(UNIQUE_)?INDEX\(\s*(\w+),\s*(\d+),\s*(.+)\)/) - { - $catname = 'indexing'; - my ($is_unique, $index_name, $index_oid, $using) = ($1, $2, $3, $4); - push @{ $catalog{data} }, - sprintf( - "declare %sindex %s %s %s\n", - $is_unique ? 'unique ' : '', - $index_name, $index_oid, $using - ); - } - elsif (/^BUILD_INDICES/) - { - push @{ $catalog{data} }, "build indices\n"; - } - elsif (/^CATALOG\(([^,]*),(\d+)\)/) - { - $catname = $1; - $catalog{relation_oid} = $2; - - # Store pg_* catalog names in the same order we receive them - push @{ $catalogs{names} }, $catname; - - $catalog{bootstrap} = /BKI_BOOTSTRAP/ ? ' bootstrap' : ''; - $catalog{shared_relation} = /BKI_SHARED_RELATION/ ? ' shared_relation' : ''; - $catalog{without_oids} = /BKI_WITHOUT_OIDS/ ? ' without_oids' : ''; - $catalog{rowtype_oid} = /BKI_ROWTYPE_OID\((\d+)\)/ ? " rowtype_oid $1" : ''; - $catalog{schema_macro} = /BKI_SCHEMA_MACRO/ ? 'True' : ''; - $declaring_attributes = 1; - } - elsif ($declaring_attributes) - { - next if (/^{|^$/); - next if (/^#/); - if (/^}/) - { - undef $declaring_attributes; - } - else - { - my ($atttype, $attname) = split /\s+/, $_; - die "parse error ($input_file)" unless $attname; - if (exists $RENAME_ATTTYPE{$atttype}) - { - $atttype = $RENAME_ATTTYPE{$atttype}; - } - if ($attname =~ /(.*)\[.*\]/) # array attribute - { - $attname = $1; - $atttype .= '[]'; # variable-length only - } - push @{ $catalog{columns} }, {$attname => $atttype}; - } - } - } - $catalogs{$catname} = \%catalog; - close INPUT_FILE; - } - return \%catalogs; + my (%catalogs, $catname, $declaring_attributes, $most_recent); + $catalogs{names} = []; + + # There are a few types which are given one name in the C source, but a + # different name at the SQL level. These are enumerated here. + my %RENAME_ATTTYPE = ( + 'Oid' => 'oid', + 'NameData' => 'name', + 'TransactionId' => 'xid'); + + foreach my $input_file (@_) + { + my %catalog; + $catalog{columns} = []; + $catalog{data} = []; + + open(INPUT_FILE, '<', $input_file) || die "$input_file: $!"; + + # Scan the input file. + while (<INPUT_FILE>) + { + + # Strip C-style comments. + s;/\*(.|\n)*\*/;;g; + if (m;/\*;) + { + + # handle multi-line comments properly. + my $next_line = <INPUT_FILE>; + die "$input_file: ends within C-style comment\n" + if !defined $next_line; + $_ .= $next_line; + redo; + } + + # Strip useless whitespace and trailing semicolons. + chomp; + s/^\s+//; + s/;\s*$//; + s/\s+/ /g; + + # Push the data into the appropriate data structure. + if (/^DATA\(insert(\s+OID\s+=\s+(\d+))?\s+\(\s*(.*)\s*\)\s*\)$/) + { + push @{ $catalog{data} }, { oid => $2, bki_values => $3 }; + } + elsif (/^DESCR\(\"(.*)\"\)$/) + { + $most_recent = $catalog{data}->[-1]; + + # this tests if most recent line is not a DATA() statement + if (ref $most_recent ne 'HASH') + { + die "DESCR() does not apply to any catalog ($input_file)"; + } + if (!defined $most_recent->{oid}) + { + die "DESCR() does not apply to any oid ($input_file)"; + } + elsif ($1 ne '') + { + $most_recent->{descr} = $1; + } + } + elsif (/^SHDESCR\(\"(.*)\"\)$/) + { + $most_recent = $catalog{data}->[-1]; + + # this tests if most recent line is not a DATA() statement + if (ref $most_recent ne 'HASH') + { + die + "SHDESCR() does not apply to any catalog ($input_file)"; + } + if (!defined $most_recent->{oid}) + { + die "SHDESCR() does not apply to any oid ($input_file)"; + } + elsif ($1 ne '') + { + $most_recent->{shdescr} = $1; + } + } + elsif (/^DECLARE_TOAST\(\s*(\w+),\s*(\d+),\s*(\d+)\)/) + { + $catname = 'toasting'; + my ($toast_name, $toast_oid, $index_oid) = ($1, $2, $3); + push @{ $catalog{data} }, + "declare toast $toast_oid $index_oid on $toast_name\n"; + } + elsif (/^DECLARE_(UNIQUE_)?INDEX\(\s*(\w+),\s*(\d+),\s*(.+)\)/) + { + $catname = 'indexing'; + my ($is_unique, $index_name, $index_oid, $using) = + ($1, $2, $3, $4); + push @{ $catalog{data} }, + sprintf( + "declare %sindex %s %s %s\n", + $is_unique ? 'unique ' : '', + $index_name, $index_oid, $using); + } + elsif (/^BUILD_INDICES/) + { + push @{ $catalog{data} }, "build indices\n"; + } + elsif (/^CATALOG\(([^,]*),(\d+)\)/) + { + $catname = $1; + $catalog{relation_oid} = $2; + + # Store pg_* catalog names in the same order we receive them + push @{ $catalogs{names} }, $catname; + + $catalog{bootstrap} = /BKI_BOOTSTRAP/ ? ' bootstrap' : ''; + $catalog{shared_relation} = + /BKI_SHARED_RELATION/ ? ' shared_relation' : ''; + $catalog{without_oids} = + /BKI_WITHOUT_OIDS/ ? ' without_oids' : ''; + $catalog{rowtype_oid} = + /BKI_ROWTYPE_OID\((\d+)\)/ ? " rowtype_oid $1" : ''; + $catalog{schema_macro} = /BKI_SCHEMA_MACRO/ ? 'True' : ''; + $declaring_attributes = 1; + } + elsif ($declaring_attributes) + { + next if (/^{|^$/); + next if (/^#/); + if (/^}/) + { + undef $declaring_attributes; + } + else + { + my ($atttype, $attname) = split /\s+/, $_; + die "parse error ($input_file)" unless $attname; + if (exists $RENAME_ATTTYPE{$atttype}) + { + $atttype = $RENAME_ATTTYPE{$atttype}; + } + if ($attname =~ /(.*)\[.*\]/) # array attribute + { + $attname = $1; + $atttype .= '[]'; # variable-length only + } + push @{ $catalog{columns} }, { $attname => $atttype }; + } + } + } + $catalogs{$catname} = \%catalog; + close INPUT_FILE; + } + return \%catalogs; } # Rename temporary files to final names. @@ -177,11 +185,11 @@ sub Catalogs # can't use the same temp files sub RenameTempFile { - my $final_name = shift; - my $extension = shift; - my $temp_name = $final_name . $extension; - print "Writing $final_name\n"; - rename($temp_name, $final_name) || die "rename: $temp_name: $!"; + my $final_name = shift; + my $extension = shift; + my $temp_name = $final_name . $extension; + print "Writing $final_name\n"; + rename($temp_name, $final_name) || die "rename: $temp_name: $!"; } 1; |