Oh, one more thing: looking again at the contents of pg_proc.dat,
I find myself annoyed at the need to specify pronargs.  That's
entirely derivable from proargtypes, and if we did so, we'd get
down to this for the first few pg_proc entries:

{ oid => '1242', descr => 'I/O',
  proname => 'boolin', prorettype => 'bool', proargtypes => 'cstring',
  prosrc => 'boolin' },
{ oid => '1243', descr => 'I/O',
  proname => 'boolout', prorettype => 'cstring', proargtypes => 'bool',
  prosrc => 'boolout' },
{ oid => '1244', descr => 'I/O',
  proname => 'byteain', prorettype => 'bytea', proargtypes => 'cstring',
  prosrc => 'byteain' },

which seems pretty close to the minimum amount of stuff you could expect
to need to write.

I recall that this and some other data compression methods were on the
table awhile back, and I expressed doubt about putting very much magic
knowledge in genbki.pl, but this case seems like a no-brainer.  genbki
can always get the right answer, and expecting people to do it just
creates another way to make a mistake.

So attached is an incremental patch to do that.  I had to adjust
AddDefaultValues's argument list to tell it the catalog name,
and once I did that, I saw that the API arrangement whereby the
caller throws error was just useless complexity, so I got rid of it.

                        regards, tom lane

diff --git a/src/backend/catalog/Catalog.pm b/src/backend/catalog/Catalog.pm
index 70aea89..3b3bb6b 100644
*** a/src/backend/catalog/Catalog.pm
--- b/src/backend/catalog/Catalog.pm
*************** sub ParseData
*** 254,265 ****
  				}
  
  				# Expand tuples to their full representation.
! 				my $error = AddDefaultValues($hash_ref, $schema);
! 				if ($error)
! 				{
! 					print "Failed to form full tuple for $catname\n";
! 					die $error;
! 				}
  			}
  			else
  			{
--- 254,260 ----
  				}
  
  				# Expand tuples to their full representation.
! 				AddDefaultValues($hash_ref, $schema, $catname);
  			}
  			else
  			{
*************** sub ParseData
*** 289,302 ****
  	return $data;
  }
  
! # Fill in default values of a record using the given schema. It's the
! # caller's responsibility to specify other values beforehand.
! # If we fail to fill all fields, return a nonempty error message.
  sub AddDefaultValues
  {
! 	my ($row, $schema) = @_;
  	my @missing_fields;
- 	my $msg;
  
  	foreach my $column (@$schema)
  	{
--- 284,295 ----
  	return $data;
  }
  
! # Fill in default values of a record using the given schema.
! # It's the caller's responsibility to specify other values beforehand.
  sub AddDefaultValues
  {
! 	my ($row, $schema, $catname) = @_;
  	my @missing_fields;
  
  	foreach my $column (@$schema)
  	{
*************** sub AddDefaultValues
*** 311,316 ****
--- 304,316 ----
  		{
  			$row->{$attname} = $column->{default};
  		}
+ 		elsif ($catname eq 'pg_proc' && $attname eq 'pronargs' &&
+ 			   defined($row->{proargtypes}))
+ 		{
+ 			# pg_proc.pronargs can be derived from proargtypes.
+ 			my @proargtypes = split /\s+/, $row->{proargtypes};
+ 			$row->{$attname} = scalar(@proargtypes);
+ 		}
  		else
  		{
  			# Failed to find a value.
*************** sub AddDefaultValues
*** 320,333 ****
  
  	if (@missing_fields)
  	{
! 		$msg = "Missing values for: " . join(', ', @missing_fields);
! 		$msg .= "\nShowing other values for context:\n";
  		while (my($key, $value) = each %$row)
  		{
  			$msg .= "$key => $value, ";
  		}
  	}
- 	return $msg;
  }
  
  # Rename temporary files to final names.
--- 320,334 ----
  
  	if (@missing_fields)
  	{
! 		my $msg = "Failed to form full tuple for $catname\n";
! 		$msg .= "Missing values for: " . join(', ', @missing_fields);
! 		$msg .= "\nOther values for row:\n";
  		while (my($key, $value) = each %$row)
  		{
  			$msg .= "$key => $value, ";
  		}
+ 		die $msg;
  	}
  }
  
  # Rename temporary files to final names.
diff --git a/src/backend/catalog/genbki.pl b/src/backend/catalog/genbki.pl
index d4c2ddf..3512952 100644
*** a/src/backend/catalog/genbki.pl
--- b/src/backend/catalog/genbki.pl
*************** sub morph_row_for_pgattr
*** 641,651 ****
  		$row->{attnotnull} = 'f';
  	}
  
! 	my $error = Catalog::AddDefaultValues($row, $pgattr_schema);
! 	if ($error)
! 	{
! 		die "Failed to form full tuple for pg_attribute: ", $error;
! 	}
  }
  
  # Write an entry to postgres.bki. Adding quotes here allows us to keep
--- 641,647 ----
  		$row->{attnotnull} = 'f';
  	}
  
! 	Catalog::AddDefaultValues($row, $pgattr_schema, 'pg_attribute');
  }
  
  # Write an entry to postgres.bki. Adding quotes here allows us to keep
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 2c42b5c..b25546e 100644
*** a/src/include/catalog/pg_proc.h
--- b/src/include/catalog/pg_proc.h
*************** CATALOG(pg_proc,1255,ProcedureRelationId
*** 73,78 ****
--- 73,79 ----
  	char		proparallel BKI_DEFAULT(s);
  
  	/* number of arguments */
+ 	/* Note: need not be given in pg_proc.dat; genbki.pl will compute it */
  	int16		pronargs;
  
  	/* number of arguments with defaults */
diff --git a/src/include/catalog/reformat_dat_file.pl b/src/include/catalog/reformat_dat_file.pl
index b20d236..bbceb16 100644
*** a/src/include/catalog/reformat_dat_file.pl
--- b/src/include/catalog/reformat_dat_file.pl
*************** sub strip_default_values
*** 201,206 ****
--- 201,213 ----
  		{
  			delete $row->{$attname};
  		}
+ 
+ 		# Also delete pg_proc.pronargs, since that can be recomputed.
+ 		if ($catname eq 'pg_proc' && $attname eq 'pronargs' &&
+ 			defined($row->{proargtypes}))
+ 		{
+ 			delete $row->{$attname};
+ 		}
  	}
  }
  

Reply via email to