diff --git a/src/backend/bootstrap/bootparse.y b/src/backend/bootstrap/bootparse.y
index 0b2733148e898518d4c07e56ac27b7de859de2f1..b7624547aac76a6c2cb7a5a0f8f683d31f36fa2e 100644
--- a/src/backend/bootstrap/bootparse.y
+++ b/src/backend/bootstrap/bootparse.y
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/bootstrap/bootparse.y,v 1.98 2009/09/26 22:42:01 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/bootstrap/bootparse.y,v 1.99 2009/09/27 01:32:11 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -87,7 +87,7 @@ do_end(void)
 }
 
 
-int num_columns_read = 0;
+static int num_columns_read = 0;
 
 %}
 
@@ -105,16 +105,16 @@ int num_columns_read = 0;
 
 %type <list>  boot_index_params
 %type <ielem> boot_index_param
-%type <ival>  boot_const boot_ident
+%type <str>   boot_const boot_ident
 %type <ival>  optbootstrap optsharedrelation optwithoutoids
-%type <ival>  boot_tuple boot_tuplelist
 %type <oidval> oidspec optoideq optrowtypeoid
 
-%token <ival> CONST_P ID
+%token <str> CONST_P ID
 %token OPEN XCLOSE XCREATE INSERT_TUPLE
 %token XDECLARE INDEX ON USING XBUILD INDICES UNIQUE XTOAST
 %token COMMA EQUALS LPAREN RPAREN
 %token OBJ_ID XBOOTSTRAP XSHARED_RELATION XWITHOUT_OIDS XROWTYPE_OID NULLVAL
+
 %start TopLevel
 
 %nonassoc low
@@ -147,7 +147,7 @@ Boot_OpenStmt:
 		  OPEN boot_ident
 				{
 					do_start();
-					boot_openrel(LexIDStr($2));
+					boot_openrel($2);
 					do_end();
 				}
 		;
@@ -156,7 +156,7 @@ Boot_CloseStmt:
 		  XCLOSE boot_ident %prec low
 				{
 					do_start();
-					closerel(LexIDStr($2));
+					closerel($2);
 					do_end();
 				}
 		| XCLOSE %prec high
@@ -175,10 +175,10 @@ Boot_CreateStmt:
 					elog(DEBUG4, "creating%s%s relation %s %u",
 						 $4 ? " bootstrap" : "",
 						 $5 ? " shared" : "",
-						 LexIDStr($2),
+						 $2,
 						 $3);
 				}
-		  boot_typelist
+		  boot_column_list
 				{
 					do_end();
 				}
@@ -198,7 +198,7 @@ Boot_CreateStmt:
 							closerel(NULL);
 						}
 
-						boot_reldesc = heap_create(LexIDStr($2),
+						boot_reldesc = heap_create($2,
 												   PG_CATALOG_NAMESPACE,
 												   $5 ? GLOBALTABLESPACE_OID : 0,
 												   $3,
@@ -212,7 +212,7 @@ Boot_CreateStmt:
 					{
 						Oid id;
 
-						id = heap_create_with_catalog(LexIDStr($2),
+						id = heap_create_with_catalog($2,
 													  PG_CATALOG_NAMESPACE,
 													  $5 ? GLOBALTABLESPACE_OID : 0,
 													  $3,
@@ -243,7 +243,7 @@ Boot_InsertStmt:
 						elog(DEBUG4, "inserting row");
 					num_columns_read = 0;
 				}
-		  LPAREN  boot_tuplelist RPAREN
+		  LPAREN boot_column_val_list RPAREN
 				{
 					if (num_columns_read != numattr)
 						elog(ERROR, "incorrect number of columns in row (expected %d, got %d)",
@@ -260,10 +260,10 @@ Boot_DeclareIndexStmt:
 				{
 					do_start();
 
-					DefineIndex(makeRangeVar(NULL, LexIDStr($6), -1),
-								LexIDStr($3),
+					DefineIndex(makeRangeVar(NULL, $6, -1),
+								$3,
 								$4,
-								LexIDStr($8),
+								$8,
 								NULL,
 								$10,
 								NULL, NIL,
@@ -278,10 +278,10 @@ Boot_DeclareUniqueIndexStmt:
 				{
 					do_start();
 
-					DefineIndex(makeRangeVar(NULL, LexIDStr($7), -1),
-								LexIDStr($4),
+					DefineIndex(makeRangeVar(NULL, $7, -1),
+								$4,
 								$5,
-								LexIDStr($9),
+								$9,
 								NULL,
 								$11,
 								NULL, NIL,
@@ -296,7 +296,7 @@ Boot_DeclareToastStmt:
 				{
 					do_start();
 
-					BootstrapToastTable(LexIDStr($6), $3, $4);
+					BootstrapToastTable($6, $3, $4);
 					do_end();
 				}
 		;
@@ -320,9 +320,9 @@ boot_index_param:
 		boot_ident boot_ident
 				{
 					IndexElem *n = makeNode(IndexElem);
-					n->name = LexIDStr($1);
+					n->name = $1;
 					n->expr = NULL;
-					n->opclass = list_make1(makeString(LexIDStr($2)));
+					n->opclass = list_make1(makeString($2));
 					n->ordering = SORTBY_DEFAULT;
 					n->nulls_ordering = SORTBY_NULLS_DEFAULT;
 					$$ = n;
@@ -349,22 +349,22 @@ optrowtypeoid:
 		|							{ $$ = InvalidOid; }
 		;
 
-boot_typelist:
-		  boot_type_thing
-		| boot_typelist COMMA boot_type_thing
+boot_column_list:
+		  boot_column_def
+		| boot_column_list COMMA boot_column_def
 		;
 
-boot_type_thing:
+boot_column_def:
 		  boot_ident EQUALS boot_ident
 				{
 				   if (++numattr > MAXATTR)
 						elog(FATAL, "too many columns");
-				   DefineAttr(LexIDStr($1),LexIDStr($3),numattr-1);
+				   DefineAttr($1, $3, numattr-1);
 				}
 		;
 
 oidspec:
-			boot_ident							{ $$ = atooid(LexIDStr($1)); }
+			boot_ident							{ $$ = atooid($1); }
 		;
 
 optoideq:
@@ -372,27 +372,27 @@ optoideq:
 		|										{ $$ = InvalidOid; }
 		;
 
-boot_tuplelist:
-		   boot_tuple
-		|  boot_tuplelist boot_tuple
-		|  boot_tuplelist COMMA boot_tuple
+boot_column_val_list:
+		   boot_column_val
+		|  boot_column_val_list boot_column_val
+		|  boot_column_val_list COMMA boot_column_val
 		;
 
-boot_tuple:
+boot_column_val:
 		  boot_ident
-			{ InsertOneValue(LexIDStr($1), num_columns_read++); }
+			{ InsertOneValue($1, num_columns_read++); }
 		| boot_const
-			{ InsertOneValue(LexIDStr($1), num_columns_read++); }
+			{ InsertOneValue($1, num_columns_read++); }
 		| NULLVAL
 			{ InsertOneNull(num_columns_read++); }
 		;
 
 boot_const :
-		  CONST_P { $$=yylval.ival; }
+		  CONST_P { $$ = yylval.str; }
 		;
 
 boot_ident :
-		  ID	{ $$=yylval.ival; }
+		  ID	{ $$ = yylval.str; }
 		;
 %%
 
diff --git a/src/backend/bootstrap/bootscanner.l b/src/backend/bootstrap/bootscanner.l
index d4bcffee53416c7572cdaf6426d048d9a93f0bd9..92defef159155b063c8d3977973ae415ff0a1e85 100644
--- a/src/backend/bootstrap/bootscanner.l
+++ b/src/backend/bootstrap/bootscanner.l
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/bootstrap/bootscanner.l,v 1.49 2009/09/26 22:42:01 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/bootstrap/bootscanner.l,v 1.50 2009/09/27 01:32:11 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -104,21 +104,16 @@ insert			{ return(INSERT_TUPLE); }
 "toast"			{ return(XTOAST); }
 
 {arrayid}		{
-					yylval.ival = EnterString(MapArrayTypeName((char*)yytext));
+					yylval.str = pstrdup(MapArrayTypeName(yytext));
 					return(ID);
 				}
 {id}			{
-					char   *newid = scanstr((char*)yytext);
-					yylval.ival = EnterString(newid);
-					pfree(newid);
+					yylval.str = scanstr(yytext);
 					return(ID);
 				}
 {sid}			{
-					char   *newid;
 					yytext[strlen(yytext)-1] = '\0'; /* strip off quotes */
-					newid = scanstr((char*)yytext+1);
-					yylval.ival = EnterString(newid);
-					pfree(newid);
+					yylval.str = scanstr(yytext+1);
 					yytext[strlen(yytext)] = '"'; /* restore quotes */
 					return(ID);
 				}
@@ -126,7 +121,7 @@ insert			{ return(INSERT_TUPLE); }
 (-)?{D}+"."{D}*({Exp})? |
 (-)?{D}*"."{D}+({Exp})? |
 (-)?{D}+{Exp}			{
-							yylval.ival = EnterString((char*)yytext);
+							yylval.str = pstrdup(yytext);
 							return(CONST_P);
 						}
 
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index ac560ee298ddd46b217d481a6d48e1bb90a9bf65..89991ea2fb79b9136bc4e911ac5223b4eabddfcb 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.252 2009/08/02 22:14:51 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.253 2009/09/27 01:32:11 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,10 +53,7 @@ static void CheckerModeMain(void);
 static void BootstrapModeMain(void);
 static void bootstrap_signals(void);
 static void ShutdownAuxiliaryProcess(int code, Datum arg);
-static hashnode *AddStr(char *str, int strlength, int mderef);
 static Form_pg_attribute AllocateAttribute(void);
-static int	CompHash(char *str, int len);
-static hashnode *FindStr(char *str, int length, hashnode *mderef);
 static Oid	gettype(char *type);
 static void cleanup(void);
 
@@ -67,30 +64,11 @@ static void cleanup(void);
 
 Relation	boot_reldesc;		/* current relation descriptor */
 
-/*
- * In the lexical analyzer, we need to get the reference number quickly from
- * the string, and the string from the reference number.  Thus we have
- * as our data structure a hash table, where the hashing key taken from
- * the particular string.  The hash table is chained.  One of the fields
- * of the hash table node is an index into the array of character pointers.
- * The unique index number that every string is assigned is simply the
- * position of its string pointer in the array of string pointers.
- */
-
-#define STRTABLESIZE	10000
-#define HASHTABLESIZE	503
-
-/* Hash function numbers */
-#define NUM		23
-#define NUMSQR	529
-#define NUMCUBE 12167
-
-char	   *strtable[STRTABLESIZE];
-hashnode   *hashtable[HASHTABLESIZE];
+Form_pg_attribute attrtypes[MAXATTR];	/* points to attribute info */
+int			numattr;			/* number of attributes for cur. rel */
 
-static int	strtable_end = -1;	/* Tells us last occupied string space */
 
-/*-
+/*
  * Basic information associated with each type.  This is used before
  * pg_type is created.
  *
@@ -169,12 +147,9 @@ struct typmap
 static struct typmap **Typ = NULL;
 static struct typmap *Ap = NULL;
 
+static Datum values[MAXATTR];	/* current row's attribute values */
 static bool Nulls[MAXATTR];
 
-Form_pg_attribute attrtypes[MAXATTR];	/* points to attribute info */
-static Datum values[MAXATTR];	/* corresponding attribute values */
-int			numattr;			/* number of attributes for cur. rel */
-
 static MemoryContext nogc = NULL;		/* special no-gc mem context */
 
 /*
@@ -501,10 +476,6 @@ BootstrapModeMain(void)
 		attrtypes[i] = NULL;
 		Nulls[i] = false;
 	}
-	for (i = 0; i < STRTABLESIZE; ++i)
-		strtable[i] = NULL;
-	for (i = 0; i < HASHTABLESIZE; ++i)
-		hashtable[i] = NULL;
 
 	/*
 	 * Process bootstrap input.
@@ -1080,155 +1051,6 @@ MapArrayTypeName(char *s)
 	return newStr;
 }
 
-/* ----------------
- *		EnterString
- *		returns the string table position of the identifier
- *		passed to it.  We add it to the table if we can't find it.
- * ----------------
- */
-int
-EnterString(char *str)
-{
-	hashnode   *node;
-	int			len;
-
-	len = strlen(str);
-
-	node = FindStr(str, len, NULL);
-	if (node)
-		return node->strnum;
-	else
-	{
-		node = AddStr(str, len, 0);
-		return node->strnum;
-	}
-}
-
-/* ----------------
- *		LexIDStr
- *		when given an idnum into the 'string-table' return the string
- *		associated with the idnum
- * ----------------
- */
-char *
-LexIDStr(int ident_num)
-{
-	return strtable[ident_num];
-}
-
-
-/* ----------------
- *		CompHash
- *
- *		Compute a hash function for a given string.  We look at the first,
- *		the last, and the middle character of a string to try to get spread
- *		the strings out.  The function is rather arbitrary, except that we
- *		are mod'ing by a prime number.
- * ----------------
- */
-static int
-CompHash(char *str, int len)
-{
-	int			result;
-
-	result = (NUM * str[0] + NUMSQR * str[len - 1] + NUMCUBE * str[(len - 1) / 2]);
-
-	return result % HASHTABLESIZE;
-
-}
-
-/* ----------------
- *		FindStr
- *
- *		This routine looks for the specified string in the hash
- *		table.	It returns a pointer to the hash node found,
- *		or NULL if the string is not in the table.
- * ----------------
- */
-static hashnode *
-FindStr(char *str, int length, hashnode *mderef)
-{
-	hashnode   *node;
-
-	node = hashtable[CompHash(str, length)];
-	while (node != NULL)
-	{
-		/*
-		 * We must differentiate between string constants that might have the
-		 * same value as a identifier and the identifier itself.
-		 */
-		if (!strcmp(str, strtable[node->strnum]))
-		{
-			return node;		/* no need to check */
-		}
-		else
-			node = node->next;
-	}
-	/* Couldn't find it in the list */
-	return NULL;
-}
-
-/* ----------------
- *		AddStr
- *
- *		This function adds the specified string, along with its associated
- *		data, to the hash table and the string table.  We return the node
- *		so that the calling routine can find out the unique id that AddStr
- *		has assigned to this string.
- * ----------------
- */
-static hashnode *
-AddStr(char *str, int strlength, int mderef)
-{
-	hashnode   *temp,
-			   *trail,
-			   *newnode;
-	int			hashresult;
-	int			len;
-
-	if (++strtable_end >= STRTABLESIZE)
-		elog(FATAL, "bootstrap string table overflow");
-
-	/*
-	 * Some of the utilites (eg, define type, create relation) assume that the
-	 * string they're passed is a NAMEDATALEN.  We get array bound read
-	 * violations from purify if we don't allocate at least NAMEDATALEN bytes
-	 * for strings of this sort.  Because we're lazy, we allocate at least
-	 * NAMEDATALEN bytes all the time.
-	 */
-
-	if ((len = strlength + 1) < NAMEDATALEN)
-		len = NAMEDATALEN;
-
-	strtable[strtable_end] = malloc((unsigned) len);
-	strcpy(strtable[strtable_end], str);
-
-	/* Now put a node in the hash table */
-
-	newnode = (hashnode *) malloc(sizeof(hashnode) * 1);
-	newnode->strnum = strtable_end;
-	newnode->next = NULL;
-
-	/* Find out where it goes */
-
-	hashresult = CompHash(str, strlength);
-	if (hashtable[hashresult] == NULL)
-		hashtable[hashresult] = newnode;
-	else
-	{							/* There is something in the list */
-		trail = hashtable[hashresult];
-		temp = trail->next;
-		while (temp != NULL)
-		{
-			trail = temp;
-			temp = temp->next;
-		}
-		trail->next = newnode;
-	}
-	return newnode;
-}
-
-
 
 /*
  *	index_register() -- record an index that has been set up for building
diff --git a/src/include/bootstrap/bootstrap.h b/src/include/bootstrap/bootstrap.h
index acc6468f9da50ff6e492b2dfc929a57b051bb21a..3ae14b0faf398aa6314ab13f3d15293f779c1c89 100644
--- a/src/include/bootstrap/bootstrap.h
+++ b/src/include/bootstrap/bootstrap.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/bootstrap/bootstrap.h,v 1.52 2009/07/31 20:26:23 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/bootstrap/bootstrap.h,v 1.53 2009/09/27 01:32:11 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -16,38 +16,43 @@
 
 #include "nodes/execnodes.h"
 
+typedef enum
+{
+	CheckerProcess,
+	BootstrapProcess,
+	StartupProcess,
+	BgWriterProcess,
+	WalWriterProcess,
+
+	NUM_AUXPROCTYPES			/* Must be last! */
+} AuxProcType;
+
 /*
  * MAXATTR is the maximum number of attributes in a relation supported
  * at bootstrap time (i.e., the max possible in a system table).
  */
 #define MAXATTR 40
 
-typedef struct hashnode
-{
-	int			strnum;			/* Index into string table */
-	struct hashnode *next;
-} hashnode;
-
-
 extern Relation boot_reldesc;
 extern Form_pg_attribute attrtypes[MAXATTR];
 extern int	numattr;
-extern void AuxiliaryProcessMain(int argc, char *argv[]);
 
-extern void index_register(Oid heap, Oid ind, IndexInfo *indexInfo);
+
+extern void AuxiliaryProcessMain(int argc, char *argv[]);
 
 extern void err_out(void);
-extern void InsertOneTuple(Oid objectid);
+
 extern void closerel(char *name);
 extern void boot_openrel(char *name);
-extern char *LexIDStr(int ident_num);
 
 extern void DefineAttr(char *name, char *type, int attnum);
+extern void InsertOneTuple(Oid objectid);
 extern void InsertOneValue(char *value, int i);
 extern void InsertOneNull(int i);
+
 extern char *MapArrayTypeName(char *s);
-extern char *CleanUpStr(char *s);
-extern int	EnterString(char *str);
+
+extern void index_register(Oid heap, Oid ind, IndexInfo *indexInfo);
 extern void build_indices(void);
 
 extern void boot_get_type_io_data(Oid typid,
@@ -64,15 +69,4 @@ extern int	boot_yyparse(void);
 extern int	boot_yylex(void);
 extern void boot_yyerror(const char *str);
 
-typedef enum
-{
-	CheckerProcess,
-	BootstrapProcess,
-	StartupProcess,
-	BgWriterProcess,
-	WalWriterProcess,
-
-	NUM_AUXPROCTYPES			/* Must be last! */
-} AuxProcType;
-
 #endif   /* BOOTSTRAP_H */