Index: src/backend/catalog/catalog.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/catalog/catalog.c,v
retrieving revision 1.89
diff -c -r1.89 catalog.c
*** src/backend/catalog/catalog.c	26 Feb 2010 02:00:36 -0000	1.89
--- src/backend/catalog/catalog.c	20 Apr 2010 21:28:40 -0000
***************
*** 327,335 ****
  		relationId == DbRoleSettingDatidRolidIndexId)
  		return true;
  	/* These are their toast tables and toast indexes (see toasting.h) */
! 	if (relationId == PgAuthidToastTable ||
! 		relationId == PgAuthidToastIndex ||
! 		relationId == PgDatabaseToastTable ||
  		relationId == PgDatabaseToastIndex ||
  		relationId == PgShdescriptionToastTable ||
  		relationId == PgShdescriptionToastIndex ||
--- 327,333 ----
  		relationId == DbRoleSettingDatidRolidIndexId)
  		return true;
  	/* These are their toast tables and toast indexes (see toasting.h) */
! 	if (relationId == PgDatabaseToastTable ||
  		relationId == PgDatabaseToastIndex ||
  		relationId == PgShdescriptionToastTable ||
  		relationId == PgShdescriptionToastIndex ||
Index: src/backend/catalog/genbki.pl
===================================================================
RCS file: /cvsroot/pgsql/src/backend/catalog/genbki.pl,v
retrieving revision 1.7
diff -c -r1.7 genbki.pl
*** src/backend/catalog/genbki.pl	22 Jan 2010 16:40:18 -0000	1.7
--- src/backend/catalog/genbki.pl	20 Apr 2010 21:28:40 -0000
***************
*** 183,195 ****
  
              # Generate entries for user attributes.
              my $attnum = 0;
              my @user_attrs = @{ $table->{columns} };
              foreach my $attr (@user_attrs)
              {
                  $attnum++;
!                 my $row = emit_pgattr_row($table_name, $attr);
                  $row->{attnum} = $attnum;
                  $row->{attstattarget} = '-1';
  
                  # If it's bootstrapped, put an entry in postgres.bki.
                  if ($is_bootstrap eq ' bootstrap')
--- 183,197 ----
  
              # Generate entries for user attributes.
              my $attnum = 0;
+             my $priornotnull = 1;
              my @user_attrs = @{ $table->{columns} };
              foreach my $attr (@user_attrs)
              {
                  $attnum++;
!                 my $row = emit_pgattr_row($table_name, $attr, $priornotnull);
                  $row->{attnum} = $attnum;
                  $row->{attstattarget} = '-1';
+                 $priornotnull &= ($row->{attnotnull} eq 't');
  
                  # If it's bootstrapped, put an entry in postgres.bki.
                  if ($is_bootstrap eq ' bootstrap')
***************
*** 221,227 ****
                  foreach my $attr (@SYS_ATTRS)
                  {
                      $attnum--;
!                     my $row = emit_pgattr_row($table_name, $attr);
                      $row->{attnum} = $attnum;
                      $row->{attstattarget} = '0';
  
--- 223,229 ----
                  foreach my $attr (@SYS_ATTRS)
                  {
                      $attnum--;
!                     my $row = emit_pgattr_row($table_name, $attr, 1);
                      $row->{attnum} = $attnum;
                      $row->{attstattarget} = '0';
  
***************
*** 308,317 ****
  
  # Given a system catalog name and a reference to a key-value pair corresponding
  # to the name and type of a column, generate a reference to a hash that
! # represents a pg_attribute entry
  sub emit_pgattr_row
  {
!     my ($table_name, $attr) = @_;
      my ($attname, $atttype) = %$attr;
      my %row;
  
--- 310,320 ----
  
  # Given a system catalog name and a reference to a key-value pair corresponding
  # to the name and type of a column, generate a reference to a hash that
! # represents a pg_attribute entry.  We must also be told whether preceding
! # columns were all not-null.
  sub emit_pgattr_row
  {
!     my ($table_name, $attr, $priornotnull) = @_;
      my ($attname, $atttype) = %$attr;
      my %row;
  
***************
*** 337,351 ****
              $row{attalign}    = $type->{typalign};
              # set attndims if it's an array type
              $row{attndims}    = $type->{typcategory} eq 'A' ? '1' : '0';
!             # This approach to attnotnull is not really good enough;
!             # we need to know about prior column types too.  Look at
!             # DefineAttr in bootstrap.c.  For the moment it's okay for
!             # the column orders appearing in bootstrapped catalogs.
!             $row{attnotnull}  =
!                 $type->{typname} eq 'oidvector' ? 't'
!               : $type->{typname} eq 'int2vector' ? 't'
!               : $type->{typlen} eq 'NAMEDATALEN' ? 't'
!               : $type->{typlen} > 0 ? 't' : 'f';
              last;
          }
      }
--- 340,360 ----
              $row{attalign}    = $type->{typalign};
              # set attndims if it's an array type
              $row{attndims}    = $type->{typcategory} eq 'A' ? '1' : '0';
!             # attnotnull must be set true if the type is fixed-width and
!             # prior columns are too --- compare DefineAttr in bootstrap.c.
!             # oidvector and int2vector are also treated as not-nullable.
!             if ($priornotnull)
!             {
!                 $row{attnotnull} =
!                     $type->{typname} eq 'oidvector' ? 't'
!                     : $type->{typname} eq 'int2vector' ? 't'
!                     : $type->{typlen} eq 'NAMEDATALEN' ? 't'
!                     : $type->{typlen} > 0 ? 't' : 'f';
!             }
!             else
!             {
!                 $row{attnotnull} = 'f';
!             }
              last;
          }
      }
Index: src/backend/utils/cache/catcache.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v
retrieving revision 1.151
diff -c -r1.151 catcache.c
*** src/backend/utils/cache/catcache.c	14 Feb 2010 18:42:17 -0000	1.151
--- src/backend/utils/cache/catcache.c	20 Apr 2010 21:28:40 -0000
***************
*** 981,1014 ****
   *		certain system indexes that support critical syscaches.
   *		We can't use an indexscan to fetch these, else we'll get into
   *		infinite recursion.  A plain heap scan will work, however.
-  *
   *		Once we have completed relcache initialization (signaled by
   *		criticalRelcachesBuilt), we don't have to worry anymore.
   */
  static bool
  IndexScanOK(CatCache *cache, ScanKey cur_skey)
  {
! 	if (cache->id == INDEXRELID)
  	{
! 		/*
! 		 * Rather than tracking exactly which indexes have to be loaded before
! 		 * we can use indexscans (which changes from time to time), just force
! 		 * all pg_index searches to be heap scans until we've built the
! 		 * critical relcaches.
! 		 */
! 		if (!criticalRelcachesBuilt)
  			return false;
! 	}
! 	else if (cache->id == AMOID ||
! 			 cache->id == AMNAME)
! 	{
! 		/*
! 		 * Always do heap scans in pg_am, because it's so small there's not
! 		 * much point in an indexscan anyway.  We *must* do this when
! 		 * initially building critical relcache entries, but we might as well
! 		 * just always do it.
! 		 */
! 		return false;
  	}
  
  	/* Normal case, allow index scan */
--- 981,1032 ----
   *		certain system indexes that support critical syscaches.
   *		We can't use an indexscan to fetch these, else we'll get into
   *		infinite recursion.  A plain heap scan will work, however.
   *		Once we have completed relcache initialization (signaled by
   *		criticalRelcachesBuilt), we don't have to worry anymore.
+  *
+  *		Similarly, during backend startup we have to be able to use the
+  *		pg_authid and pg_auth_members syscaches for authentication even if
+  *		we don't yet have relcache entries for those catalogs' indexes.
   */
  static bool
  IndexScanOK(CatCache *cache, ScanKey cur_skey)
  {
! 	switch (cache->id)
  	{
! 		case INDEXRELID:
! 			/*
! 			 * Rather than tracking exactly which indexes have to be loaded
! 			 * before we can use indexscans (which changes from time to time),
! 			 * just force all pg_index searches to be heap scans until we've
! 			 * built the critical relcaches.
! 			 */
! 			if (!criticalRelcachesBuilt)
! 				return false;
! 			break;
! 
! 		case AMOID:
! 		case AMNAME:
! 			/*
! 			 * Always do heap scans in pg_am, because it's so small there's
! 			 * not much point in an indexscan anyway.  We *must* do this when
! 			 * initially building critical relcache entries, but we might as
! 			 * well just always do it.
! 			 */
  			return false;
! 
! 		case AUTHNAME:
! 		case AUTHOID:
! 		case AUTHMEMMEMROLE:
! 			/*
! 			 * Protect authentication lookups occurring before relcache has
! 			 * collected entries for shared indexes.
! 			 */
! 			if (!criticalSharedRelcachesBuilt)
! 				return false;
! 			break;
! 
! 		default:
! 			break;
  	}
  
  	/* Normal case, allow index scan */
***************
*** 1397,1403 ****
  
  		scandesc = systable_beginscan(relation,
  									  cache->cc_indexoid,
! 									  true,
  									  SnapshotNow,
  									  nkeys,
  									  cur_skey);
--- 1415,1421 ----
  
  		scandesc = systable_beginscan(relation,
  									  cache->cc_indexoid,
! 									  IndexScanOK(cache, cur_skey),
  									  SnapshotNow,
  									  nkeys,
  									  cur_skey);
Index: src/backend/utils/cache/relcache.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v
retrieving revision 1.309
diff -c -r1.309 relcache.c
*** src/backend/utils/cache/relcache.c	14 Apr 2010 21:31:11 -0000	1.309
--- src/backend/utils/cache/relcache.c	20 Apr 2010 21:28:40 -0000
***************
*** 43,48 ****
--- 43,49 ----
  #include "catalog/pg_amproc.h"
  #include "catalog/pg_attrdef.h"
  #include "catalog/pg_authid.h"
+ #include "catalog/pg_auth_members.h"
  #include "catalog/pg_constraint.h"
  #include "catalog/pg_database.h"
  #include "catalog/pg_namespace.h"
***************
*** 87,99 ****
  #define RELCACHE_INIT_FILEMAGIC		0x573265	/* version ID value */
  
  /*
!  *		hardcoded tuple descriptors.  see include/catalog/pg_attribute.h
   */
  static const FormData_pg_attribute Desc_pg_class[Natts_pg_class] = {Schema_pg_class};
  static const FormData_pg_attribute Desc_pg_attribute[Natts_pg_attribute] = {Schema_pg_attribute};
  static const FormData_pg_attribute Desc_pg_proc[Natts_pg_proc] = {Schema_pg_proc};
  static const FormData_pg_attribute Desc_pg_type[Natts_pg_type] = {Schema_pg_type};
  static const FormData_pg_attribute Desc_pg_database[Natts_pg_database] = {Schema_pg_database};
  static const FormData_pg_attribute Desc_pg_index[Natts_pg_index] = {Schema_pg_index};
  
  /*
--- 88,102 ----
  #define RELCACHE_INIT_FILEMAGIC		0x573265	/* version ID value */
  
  /*
!  *		hardcoded tuple descriptors, generated by genbki.pl
   */
  static const FormData_pg_attribute Desc_pg_class[Natts_pg_class] = {Schema_pg_class};
  static const FormData_pg_attribute Desc_pg_attribute[Natts_pg_attribute] = {Schema_pg_attribute};
  static const FormData_pg_attribute Desc_pg_proc[Natts_pg_proc] = {Schema_pg_proc};
  static const FormData_pg_attribute Desc_pg_type[Natts_pg_type] = {Schema_pg_type};
  static const FormData_pg_attribute Desc_pg_database[Natts_pg_database] = {Schema_pg_database};
+ static const FormData_pg_attribute Desc_pg_authid[Natts_pg_authid] = {Schema_pg_authid};
+ static const FormData_pg_attribute Desc_pg_auth_members[Natts_pg_auth_members] = {Schema_pg_auth_members};
  static const FormData_pg_attribute Desc_pg_index[Natts_pg_index] = {Schema_pg_index};
  
  /*
***************
*** 118,124 ****
  
  /*
   * This flag is false until we have prepared the critical relcache entries
!  * for shared catalogs (specifically, pg_database and its indexes).
   */
  bool		criticalSharedRelcachesBuilt = false;
  
--- 121,127 ----
  
  /*
   * This flag is false until we have prepared the critical relcache entries
!  * for shared catalogs (which are the tables needed for login).
   */
  bool		criticalSharedRelcachesBuilt = false;
  
***************
*** 1379,1386 ****
   *		quite a lot since we only need to work for a few basic system
   *		catalogs.
   *
!  * formrdesc is currently used for: pg_database, pg_class, pg_attribute,
!  * pg_proc, and pg_type (see RelationCacheInitializePhase2/3).
   *
   * Note that these catalogs can't have constraints (except attnotnull),
   * default values, rules, or triggers, since we don't cope with any of that.
--- 1382,1390 ----
   *		quite a lot since we only need to work for a few basic system
   *		catalogs.
   *
!  * formrdesc is currently used for: pg_database, pg_authid, pg_auth_members,
!  * pg_class, pg_attribute, pg_proc, and pg_type
!  * (see RelationCacheInitializePhase2/3).
   *
   * Note that these catalogs can't have constraints (except attnotnull),
   * default values, rules, or triggers, since we don't cope with any of that.
***************
*** 1461,1468 ****
  	 * initialize attribute tuple form
  	 *
  	 * Unlike the case with the relation tuple, this data had better be right
! 	 * because it will never be replaced.  The input values must be correctly
! 	 * defined by macros in src/include/catalog/ headers.
  	 */
  	relation->rd_att = CreateTemplateTupleDesc(natts, hasoids);
  	relation->rd_att->tdrefcount = 1;	/* mark as refcounted */
--- 1465,1472 ----
  	 * initialize attribute tuple form
  	 *
  	 * Unlike the case with the relation tuple, this data had better be right
! 	 * because it will never be replaced.  The data comes from
! 	 * src/include/catalog/ headers via genbki.pl.
  	 */
  	relation->rd_att = CreateTemplateTupleDesc(natts, hasoids);
  	relation->rd_att->tdrefcount = 1;	/* mark as refcounted */
***************
*** 2455,2460 ****
--- 2459,2466 ----
  	switch (relid)
  	{
  		case DatabaseRelationId:
+ 		case AuthIdRelationId:
+ 		case AuthMemRelationId:
  		case RelationRelationId:
  		case AttributeRelationId:
  		case ProcedureRelationId:
***************
*** 2750,2761 ****
  /*
   *		RelationCacheInitializePhase2
   *
!  *		This is called to prepare for access to pg_database during startup.
!  *		We must at least set up a nailed reldesc for pg_database.  Ideally
!  *		we'd like to have reldescs for its indexes, too.  We attempt to
!  *		load this information from the shared relcache init file.  If that's
!  *		missing or broken, just make a phony entry for pg_database.
!  *		RelationCacheInitializePhase3 will clean up as needed.
   */
  void
  RelationCacheInitializePhase2(void)
--- 2756,2768 ----
  /*
   *		RelationCacheInitializePhase2
   *
!  *		This is called to prepare for access to shared catalogs during startup.
!  *		We must at least set up nailed reldescs for pg_database, pg_authid,
!  *		and pg_auth_members.  Ideally we'd like to have reldescs for their
!  *		indexes, too.  We attempt to load this information from the shared
!  *		relcache init file.  If that's missing or broken, just make phony
!  *		entries for the catalogs themselves.  RelationCacheInitializePhase3
!  *		will clean up as needed.
   */
  void
  RelationCacheInitializePhase2(void)
***************
*** 2768,2774 ****
  	RelationMapInitializePhase2();
  
  	/*
! 	 * In bootstrap mode, pg_database isn't there yet anyway, so do nothing.
  	 */
  	if (IsBootstrapProcessingMode())
  		return;
--- 2775,2782 ----
  	RelationMapInitializePhase2();
  
  	/*
! 	 * In bootstrap mode, the shared catalogs aren't there yet anyway,
! 	 * so do nothing.
  	 */
  	if (IsBootstrapProcessingMode())
  		return;
***************
*** 2780,2793 ****
  
  	/*
  	 * Try to load the shared relcache cache file.	If unsuccessful, bootstrap
! 	 * the cache with a pre-made descriptor for pg_database.
  	 */
  	if (!load_relcache_init_file(true))
  	{
  		formrdesc("pg_database", DatabaseRelation_Rowtype_Id, true,
  				  true, Natts_pg_database, Desc_pg_database);
  
! #define NUM_CRITICAL_SHARED_RELS	1	/* fix if you change list above */
  	}
  
  	MemoryContextSwitchTo(oldcxt);
--- 2788,2805 ----
  
  	/*
  	 * Try to load the shared relcache cache file.	If unsuccessful, bootstrap
! 	 * the cache with pre-made descriptors for the critical shared catalogs.
  	 */
  	if (!load_relcache_init_file(true))
  	{
  		formrdesc("pg_database", DatabaseRelation_Rowtype_Id, true,
  				  true, Natts_pg_database, Desc_pg_database);
+ 		formrdesc("pg_authid", AuthIdRelation_Rowtype_Id, true,
+ 				  true, Natts_pg_authid, Desc_pg_authid);
+ 		formrdesc("pg_auth_members", AuthMemRelation_Rowtype_Id, true,
+ 				  false, Natts_pg_auth_members, Desc_pg_auth_members);
  
! #define NUM_CRITICAL_SHARED_RELS	3	/* fix if you change list above */
  	}
  
  	MemoryContextSwitchTo(oldcxt);
***************
*** 2910,2916 ****
  	 * DatabaseNameIndexId isn't critical for relcache loading, but rather for
  	 * initial lookup of MyDatabaseId, without which we'll never find any
  	 * non-shared catalogs at all.	Autovacuum calls InitPostgres with a
! 	 * database OID, so it instead depends on DatabaseOidIndexId.
  	 */
  	if (!criticalSharedRelcachesBuilt)
  	{
--- 2922,2930 ----
  	 * DatabaseNameIndexId isn't critical for relcache loading, but rather for
  	 * initial lookup of MyDatabaseId, without which we'll never find any
  	 * non-shared catalogs at all.	Autovacuum calls InitPostgres with a
! 	 * database OID, so it instead depends on DatabaseOidIndexId.  We also
! 	 * need to nail up some indexes on pg_authid and pg_auth_members for use
! 	 * during client authentication.
  	 */
  	if (!criticalSharedRelcachesBuilt)
  	{
***************
*** 2918,2925 ****
  							DatabaseRelationId);
  		load_critical_index(DatabaseOidIndexId,
  							DatabaseRelationId);
  
! #define NUM_CRITICAL_SHARED_INDEXES 2	/* fix if you change list above */
  
  		criticalSharedRelcachesBuilt = true;
  	}
--- 2932,2945 ----
  							DatabaseRelationId);
  		load_critical_index(DatabaseOidIndexId,
  							DatabaseRelationId);
+ 		load_critical_index(AuthIdRolnameIndexId,
+ 							AuthIdRelationId);
+ 		load_critical_index(AuthIdOidIndexId,
+ 							AuthIdRelationId);
+ 		load_critical_index(AuthMemMemRoleIndexId,
+ 							AuthMemRelationId);
  
! #define NUM_CRITICAL_SHARED_INDEXES 5	/* fix if you change list above */
  
  		criticalSharedRelcachesBuilt = true;
  	}
Index: src/backend/utils/init/miscinit.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v
retrieving revision 1.183
diff -c -r1.183 miscinit.c
*** src/backend/utils/init/miscinit.c	26 Feb 2010 02:01:13 -0000	1.183
--- src/backend/utils/init/miscinit.c	20 Apr 2010 21:28:40 -0000
***************
*** 429,438 ****
  	 * These next checks are not enforced when in standalone mode, so that
  	 * there is a way to recover from sillinesses like "UPDATE pg_authid SET
  	 * rolcanlogin = false;".
- 	 *
- 	 * We do not enforce them for the autovacuum process either.
  	 */
! 	if (IsUnderPostmaster && !IsAutoVacuumWorkerProcess())
  	{
  		/*
  		 * Is role allowed to login at all?
--- 429,436 ----
  	 * These next checks are not enforced when in standalone mode, so that
  	 * there is a way to recover from sillinesses like "UPDATE pg_authid SET
  	 * rolcanlogin = false;".
  	 */
! 	if (IsUnderPostmaster)
  	{
  		/*
  		 * Is role allowed to login at all?
***************
*** 479,485 ****
  void
  InitializeSessionUserIdStandalone(void)
  {
! 	/* This function should only be called in a single-user backend. */
  	AssertState(!IsUnderPostmaster || IsAutoVacuumWorkerProcess());
  
  	/* call only once */
--- 477,486 ----
  void
  InitializeSessionUserIdStandalone(void)
  {
! 	/*
! 	 * This function should only be called in single-user mode and in
! 	 * autovacuum workers.
! 	 */
  	AssertState(!IsUnderPostmaster || IsAutoVacuumWorkerProcess());
  
  	/* call only once */
Index: src/backend/utils/init/postinit.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v
retrieving revision 1.209
diff -c -r1.209 postinit.c
*** src/backend/utils/init/postinit.c	20 Apr 2010 01:38:52 -0000	1.209
--- src/backend/utils/init/postinit.c	20 Apr 2010 21:28:40 -0000
***************
*** 552,558 ****
  
  	/*
  	 * Load relcache entries for the shared system catalogs.  This must create
! 	 * at least an entry for pg_database.
  	 */
  	RelationCacheInitializePhase2();
  
--- 552,558 ----
  
  	/*
  	 * Load relcache entries for the shared system catalogs.  This must create
! 	 * at least entries for pg_database and catalogs used for authentication.
  	 */
  	RelationCacheInitializePhase2();
  
***************
*** 586,598 ****
  	}
  
  	/*
  	 * Set up the global variables holding database id and default tablespace.
  	 * But note we won't actually try to touch the database just yet.
  	 *
! 	 * We take a shortcut in the bootstrap and walsender case, otherwise we
! 	 * have to look up the db's entry in pg_database.
  	 */
! 	if (bootstrap || am_walsender)
  	{
  		MyDatabaseId = TemplateDbOid;
  		MyDatabaseTableSpace = DEFAULTTABLESPACE_OID;
--- 586,644 ----
  	}
  
  	/*
+ 	 * Perform client authentication if necessary, then figure out our
+ 	 * postgres user ID, and see if we are a superuser.
+ 	 *
+ 	 * In standalone mode and in autovacuum worker processes, we use a fixed
+ 	 * ID, otherwise we figure it out from the authenticated user name.
+ 	 */
+ 	if (bootstrap || IsAutoVacuumWorkerProcess())
+ 	{
+ 		InitializeSessionUserIdStandalone();
+ 		am_superuser = true;
+ 	}
+ 	else if (!IsUnderPostmaster)
+ 	{
+ 		InitializeSessionUserIdStandalone();
+ 		am_superuser = true;
+ 		if (!ThereIsAtLeastOneRole())
+ 			ereport(WARNING,
+ 					(errcode(ERRCODE_UNDEFINED_OBJECT),
+ 					 errmsg("no roles are defined in this database system"),
+ 					 errhint("You should immediately run CREATE USER \"%s\" SUPERUSER;.",
+ 							 username)));
+ 	}
+ 	else
+ 	{
+ 		/* normal multiuser case */
+ 		Assert(MyProcPort != NULL);
+ 		PerformAuthentication(MyProcPort);
+ 		InitializeSessionUserId(username);
+ 		am_superuser = superuser();
+ 	}
+ 
+ 	/*
+ 	 * If walsender, we're done here --- we don't want to connect to any
+ 	 * particular database.
+ 	 */
+ 	if (am_walsender)
+ 	{
+ 		Assert(!bootstrap);
+ 		/* report this backend in the PgBackendStatus array */
+ 		pgstat_bestart();
+ 		/* close the transaction we started above */
+ 		CommitTransactionCommand();
+ 		return;
+ 	}
+ 
+ 	/*
  	 * Set up the global variables holding database id and default tablespace.
  	 * But note we won't actually try to touch the database just yet.
  	 *
! 	 * We take a shortcut in the bootstrap case, otherwise we have to look up
! 	 * the db's entry in pg_database.
  	 */
! 	if (bootstrap)
  	{
  		MyDatabaseId = TemplateDbOid;
  		MyDatabaseTableSpace = DEFAULTTABLESPACE_OID;
***************
*** 655,661 ****
  	 * AccessShareLock for such sessions and thereby not conflict against
  	 * CREATE DATABASE.
  	 */
! 	if (!bootstrap && !am_walsender)
  		LockSharedObject(DatabaseRelationId, MyDatabaseId, 0,
  						 RowExclusiveLock);
  
--- 701,707 ----
  	 * AccessShareLock for such sessions and thereby not conflict against
  	 * CREATE DATABASE.
  	 */
! 	if (!bootstrap)
  		LockSharedObject(DatabaseRelationId, MyDatabaseId, 0,
  						 RowExclusiveLock);
  
***************
*** 664,670 ****
  	 * If there was a concurrent DROP DATABASE, this ensures we will die
  	 * cleanly without creating a mess.
  	 */
! 	if (!bootstrap && !am_walsender)
  	{
  		HeapTuple	tuple;
  
--- 710,716 ----
  	 * If there was a concurrent DROP DATABASE, this ensures we will die
  	 * cleanly without creating a mess.
  	 */
! 	if (!bootstrap)
  	{
  		HeapTuple	tuple;
  
***************
*** 684,690 ****
  	 */
  	fullpath = GetDatabasePath(MyDatabaseId, MyDatabaseTableSpace);
  
! 	if (!bootstrap && !am_walsender)
  	{
  		if (access(fullpath, F_OK) == -1)
  		{
--- 730,736 ----
  	 */
  	fullpath = GetDatabasePath(MyDatabaseId, MyDatabaseTableSpace);
  
! 	if (!bootstrap)
  	{
  		if (access(fullpath, F_OK) == -1)
  		{
***************
*** 715,765 ****
  	 */
  	RelationCacheInitializePhase3();
  
- 	/*
- 	 * Perform client authentication if necessary, then figure out our
- 	 * postgres user ID, and see if we are a superuser.
- 	 *
- 	 * In standalone mode and in autovacuum worker processes, we use a fixed
- 	 * ID, otherwise we figure it out from the authenticated user name.
- 	 */
- 	if (bootstrap || IsAutoVacuumWorkerProcess())
- 	{
- 		InitializeSessionUserIdStandalone();
- 		am_superuser = true;
- 	}
- 	else if (!IsUnderPostmaster)
- 	{
- 		InitializeSessionUserIdStandalone();
- 		am_superuser = true;
- 		if (!ThereIsAtLeastOneRole())
- 			ereport(WARNING,
- 					(errcode(ERRCODE_UNDEFINED_OBJECT),
- 					 errmsg("no roles are defined in this database system"),
- 					 errhint("You should immediately run CREATE USER \"%s\" SUPERUSER;.",
- 							 username)));
- 	}
- 	else
- 	{
- 		/* normal multiuser case */
- 		Assert(MyProcPort != NULL);
- 		PerformAuthentication(MyProcPort);
- 		InitializeSessionUserId(username);
- 		am_superuser = superuser();
- 	}
- 
  	/* set up ACL framework (so CheckMyDatabase can check permissions) */
  	initialize_acl();
  
- 	/* Process pg_db_role_setting options */
- 	process_settings(MyDatabaseId, GetSessionUserId());
- 
  	/*
  	 * Re-read the pg_database row for our database, check permissions and set
  	 * up database-specific GUC settings.  We can't do this until all the
  	 * database-access infrastructure is up.  (Also, it wants to know if the
  	 * user is a superuser, so the above stuff has to happen first.)
  	 */
! 	if (!bootstrap && !am_walsender)
  		CheckMyDatabase(dbname, am_superuser);
  
  	/*
--- 761,776 ----
  	 */
  	RelationCacheInitializePhase3();
  
  	/* set up ACL framework (so CheckMyDatabase can check permissions) */
  	initialize_acl();
  
  	/*
  	 * Re-read the pg_database row for our database, check permissions and set
  	 * up database-specific GUC settings.  We can't do this until all the
  	 * database-access infrastructure is up.  (Also, it wants to know if the
  	 * user is a superuser, so the above stuff has to happen first.)
  	 */
! 	if (!bootstrap)
  		CheckMyDatabase(dbname, am_superuser);
  
  	/*
***************
*** 841,846 ****
--- 852,860 ----
  		}
  	}
  
+ 	/* Process pg_db_role_setting options */
+ 	process_settings(MyDatabaseId, GetSessionUserId());
+ 
  	/* Apply PostAuthDelay as soon as we've read all options */
  	if (PostAuthDelay > 0)
  		pg_usleep(PostAuthDelay * 1000000L);
***************
*** 856,865 ****
  	/* initialize client encoding */
  	InitializeClientEncoding();
  
- 	/* reset the database for walsender */
- 	if (am_walsender)
- 		MyProc->databaseId = MyDatabaseId = InvalidOid;
- 
  	/* report this backend in the PgBackendStatus array */
  	if (!bootstrap)
  		pgstat_bestart();
--- 870,875 ----
Index: src/include/catalog/catversion.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/catalog/catversion.h,v
retrieving revision 1.585
diff -c -r1.585 catversion.h
*** src/include/catalog/catversion.h	16 Feb 2010 22:34:54 -0000	1.585
--- src/include/catalog/catversion.h	20 Apr 2010 21:28:40 -0000
***************
*** 53,58 ****
   */
  
  /*							yyyymmddN */
! #define CATALOG_VERSION_NO	201002161
  
  #endif
--- 53,58 ----
   */
  
  /*							yyyymmddN */
! #define CATALOG_VERSION_NO	201004201
  
  #endif
Index: src/include/catalog/pg_auth_members.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/catalog/pg_auth_members.h,v
retrieving revision 1.8
diff -c -r1.8 pg_auth_members.h
*** src/include/catalog/pg_auth_members.h	5 Jan 2010 01:06:56 -0000	1.8
--- src/include/catalog/pg_auth_members.h	20 Apr 2010 21:28:40 -0000
***************
*** 27,34 ****
   * ----------------
   */
  #define AuthMemRelationId	1261
  
! CATALOG(pg_auth_members,1261) BKI_SHARED_RELATION BKI_WITHOUT_OIDS
  {
  	Oid			roleid;			/* ID of a role */
  	Oid			member;			/* ID of a member of that role */
--- 27,35 ----
   * ----------------
   */
  #define AuthMemRelationId	1261
+ #define AuthMemRelation_Rowtype_Id	2843
  
! CATALOG(pg_auth_members,1261) BKI_SHARED_RELATION BKI_WITHOUT_OIDS BKI_ROWTYPE_OID(2843) BKI_SCHEMA_MACRO
  {
  	Oid			roleid;			/* ID of a role */
  	Oid			member;			/* ID of a member of that role */
Index: src/include/catalog/pg_authid.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/catalog/pg_authid.h,v
retrieving revision 1.12
diff -c -r1.12 pg_authid.h
*** src/include/catalog/pg_authid.h	5 Jan 2010 01:06:56 -0000	1.12
--- src/include/catalog/pg_authid.h	20 Apr 2010 21:28:40 -0000
***************
*** 40,47 ****
   * ----------------
   */
  #define AuthIdRelationId	1260
  
! CATALOG(pg_authid,1260) BKI_SHARED_RELATION
  {
  	NameData	rolname;		/* name of role */
  	bool		rolsuper;		/* read this field via superuser() only! */
--- 40,48 ----
   * ----------------
   */
  #define AuthIdRelationId	1260
+ #define AuthIdRelation_Rowtype_Id	2842
  
! CATALOG(pg_authid,1260) BKI_SHARED_RELATION BKI_ROWTYPE_OID(2842) BKI_SCHEMA_MACRO
  {
  	NameData	rolname;		/* name of role */
  	bool		rolsuper;		/* read this field via superuser() only! */
***************
*** 71,77 ****
   *		compiler constants for pg_authid
   * ----------------
   */
! #define Natts_pg_authid					11
  #define Anum_pg_authid_rolname			1
  #define Anum_pg_authid_rolsuper			2
  #define Anum_pg_authid_rolinherit		3
--- 72,78 ----
   *		compiler constants for pg_authid
   * ----------------
   */
! #define Natts_pg_authid					10
  #define Anum_pg_authid_rolname			1
  #define Anum_pg_authid_rolsuper			2
  #define Anum_pg_authid_rolinherit		3
Index: src/include/catalog/toasting.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/catalog/toasting.h,v
retrieving revision 1.13
diff -c -r1.13 toasting.h
*** src/include/catalog/toasting.h	6 Jan 2010 03:04:03 -0000	1.13
--- src/include/catalog/toasting.h	20 Apr 2010 21:28:40 -0000
***************
*** 49,57 ****
  DECLARE_TOAST(pg_trigger, 2336, 2337);
  
  /* shared catalogs */
- DECLARE_TOAST(pg_authid, 2842, 2843);
- #define PgAuthidToastTable 2842
- #define PgAuthidToastIndex 2843
  DECLARE_TOAST(pg_database, 2844, 2845);
  #define PgDatabaseToastTable 2844
  #define PgDatabaseToastIndex 2845
--- 49,54 ----
