diff --git a/contrib/pgstattuple/README.pgstattuple b/contrib/pgstattuple/README.pgstattuple
index 6a191e9cced316a92f532536d74b67f21cd34a81..7237b9a4dc847c9bd6608b1f44b0bb3cdb1edbcd 100644
--- a/contrib/pgstattuple/README.pgstattuple
+++ b/contrib/pgstattuple/README.pgstattuple
@@ -33,7 +33,7 @@ NOTICE:  physical length: 0.08MB live tuples: 20 (0.00MB, 1.17%) dead tuples: 32
 
    pgstattuple can be called as a function:
 
-   pgstattuple(NAME) RETURNS FLOAT8
+   pgstattuple(TEXT) RETURNS FLOAT8
 
    The argument is the table name.  pgstattuple returns the percentage
    of the "dead" tuples of a table.
diff --git a/contrib/pgstattuple/pgstattuple.c b/contrib/pgstattuple/pgstattuple.c
index beda282172d8713c9280744066d8621eb283f4c6..39bd5d1f95e0b556159905e13688a1ea6ebb93b5 100644
--- a/contrib/pgstattuple/pgstattuple.c
+++ b/contrib/pgstattuple/pgstattuple.c
@@ -1,5 +1,5 @@
 /*
- * $Header: /cvsroot/pgsql/contrib/pgstattuple/pgstattuple.c,v 1.4 2002/03/06 06:09:10 momjian Exp $
+ * $Header: /cvsroot/pgsql/contrib/pgstattuple/pgstattuple.c,v 1.5 2002/03/30 01:02:41 tgl Exp $
  *
  * Copyright (c) 2001  Tatsuo Ishii
  *
@@ -27,6 +27,9 @@
 #include "fmgr.h"
 #include "access/heapam.h"
 #include "access/transam.h"
+#include "catalog/namespace.h"
+#include "utils/builtins.h"
+
 
 PG_FUNCTION_INFO_V1(pgstattuple);
 
@@ -43,8 +46,8 @@ extern Datum pgstattuple(PG_FUNCTION_ARGS);
 Datum
 pgstattuple(PG_FUNCTION_ARGS)
 {
-	Name		p = PG_GETARG_NAME(0);
-
+	text	   *relname = PG_GETARG_TEXT_P(0);
+	RangeVar   *relrv;
 	Relation	rel;
 	HeapScanDesc scan;
 	HeapTuple	tuple;
@@ -59,11 +62,13 @@ pgstattuple(PG_FUNCTION_ARGS)
 	uint64		dead_tuple_count = 0;
 	double		tuple_percent;
 	double		dead_tuple_percent;
-
 	uint64		free_space = 0; /* free/reusable space in bytes */
 	double		free_percent;	/* free/reusable space in % */
 
-	rel = heap_openr(NameStr(*p), AccessShareLock);
+	relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname,
+														"pgstattuple"));
+	rel = heap_openrv(relrv, AccessShareLock);
+
 	nblocks = RelationGetNumberOfBlocks(rel);
 	scan = heap_beginscan(rel, false, SnapshotAny, 0, NULL);
 
diff --git a/contrib/pgstattuple/pgstattuple.sql.in b/contrib/pgstattuple/pgstattuple.sql.in
index 7a7706fa190cea5fccb437f3eabc495a7e23e15f..b49a13483f7b2e89e9d054a8fd1cd81c11a2be87 100644
--- a/contrib/pgstattuple/pgstattuple.sql.in
+++ b/contrib/pgstattuple/pgstattuple.sql.in
@@ -1,4 +1,4 @@
-DROP FUNCTION pgstattuple(NAME);
-CREATE FUNCTION pgstattuple(NAME) RETURNS FLOAT8
+DROP FUNCTION pgstattuple(text);
+CREATE FUNCTION pgstattuple(text) RETURNS float8
 AS 'MODULE_PATHNAME', 'pgstattuple'
 LANGUAGE 'c' WITH (isstrict);
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index a1ea6ed24fe23181998191fc2bb130ef67fba453..e245ae5a3e43fa38df5dec0d340c12c32c75081b 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -13,7 +13,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.2 2002/03/29 19:06:01 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.3 2002/03/30 01:02:41 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -81,6 +81,10 @@ RangeVarGetRelid(const RangeVar *relation, bool failOK)
  * RangeVarGetCreationNamespace
  *		Given a RangeVar describing a to-be-created relation,
  *		choose which namespace to create it in.
+ *
+ * Note: calling this may result in a CommandCounterIncrement operation.
+ * That will happen on the first request for a temp table in any particular
+ * backend run; we will need to either create or clean out the temp schema.
  */
 Oid
 RangeVarGetCreationNamespace(const RangeVar *newRelation)
@@ -126,6 +130,21 @@ RelnameGetRelid(const char *relname)
 	return get_relname_relid(relname, PG_CATALOG_NAMESPACE);
 }
 
+/*
+ * TypenameGetTypid
+ *		Try to resolve an unqualified datatype name.
+ *		Returns OID if type found in search path, else InvalidOid.
+ */
+Oid
+TypenameGetTypid(const char *typname)
+{
+	/* XXX wrong, should use namespace search */
+	return GetSysCacheOid(TYPENAMENSP,
+						  PointerGetDatum(typname),
+						  ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
+						  0, 0);
+}
+
 /*
  * QualifiedNameGetCreationNamespace
  *		Given a possibly-qualified name for an object (in List-of-Values
diff --git a/src/backend/commands/command.c b/src/backend/commands/command.c
index 9180c539ff20138295622097985fb8e598f02340..2c029fa2ae9f28e1faf2a9cda2acdf65a224b625 100644
--- a/src/backend/commands/command.c
+++ b/src/backend/commands/command.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.167 2002/03/29 19:06:03 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.168 2002/03/30 01:02:41 tgl Exp $
  *
  * NOTES
  *	  The PerformAddAttribute() code, like most of the relation
@@ -1755,13 +1755,13 @@ AlterTableCreateToastTable(Oid relOid, bool silent)
 	tupdesc->attrs[2]->attstorage = 'p';
 
 	/*
-	 * Note: the toast relation is considered a "normal" relation even if
-	 * its master relation is a temp table.  There cannot be any naming
-	 * collision, and the toast rel will be destroyed when its master is,
-	 * so there's no need to handle the toast rel as temp.
+	 * Note: the toast relation is placed in the regular pg_toast namespace
+	 * even if its master relation is a temp table.  There cannot be any
+	 * naming collision, and the toast rel will be destroyed when its master
+	 * is, so there's no need to handle the toast rel as temp.
 	 */
 	toast_relid = heap_create_with_catalog(toast_relname,
-										   RelationGetNamespace(rel),
+										   PG_TOAST_NAMESPACE,
 										   tupdesc,
 										   RELKIND_TOASTVALUE, false,
 										   false, true);
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index 54ca1d19a10082cedd9afe4f9eb7d12c7045a752..a7678c5ce38484567e7ff38c25a27bf3f463947c 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -8,15 +8,14 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.75 2002/03/29 19:06:07 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.76 2002/03/30 01:02:41 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "postgres.h"
 
-#include <ctype.h>
-
 #include "access/heapam.h"
+#include "catalog/namespace.h"
 #include "catalog/pg_type.h"
 #include "commands/creatinh.h"
 #include "commands/sequence.h"
@@ -24,9 +23,6 @@
 #include "utils/acl.h"
 #include "utils/builtins.h"
 #include "utils/int8.h"
-#ifdef MULTIBYTE
-#include "mb/pg_wchar.h"
-#endif
 
 
 #define SEQ_MAGIC	  0x1717
@@ -57,7 +53,6 @@ typedef struct sequence_magic
 
 typedef struct SeqTableData
 {
-	char	   *name;
 	Oid			relid;
 	Relation	rel;			/* NULL if rel is not open in cur xact */
 	int64		cached;
@@ -70,12 +65,11 @@ typedef SeqTableData *SeqTable;
 
 static SeqTable seqtab = NULL;
 
-static char *get_seq_name(text *seqin);
-static SeqTable init_sequence(char *caller, char *name);
+static SeqTable init_sequence(char *caller, RangeVar *relation);
 static Form_pg_sequence read_info(char *caller, SeqTable elm, Buffer *buf);
 static void init_params(CreateSeqStmt *seq, Form_pg_sequence new);
 static int64 get_param(DefElem *def);
-static void do_setval(char *seqname, int64 next, bool iscalled);
+static void do_setval(RangeVar *sequence, int64 next, bool iscalled);
 
 /*
  * DefineSequence
@@ -285,7 +279,7 @@ Datum
 nextval(PG_FUNCTION_ARGS)
 {
 	text	   *seqin = PG_GETARG_TEXT_P(0);
-	char	   *seqname = get_seq_name(seqin);
+	RangeVar   *sequence;
 	SeqTable	elm;
 	Buffer		buf;
 	Page		page;
@@ -302,14 +296,15 @@ nextval(PG_FUNCTION_ARGS)
 				rescnt = 0;
 	bool		logit = false;
 
+	sequence = makeRangeVarFromNameList(textToQualifiedNameList(seqin,
+																"nextval"));
+
 	/* open and AccessShareLock sequence */
-	elm = init_sequence("nextval", seqname);
+	elm = init_sequence("nextval", sequence);
 
 	if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_UPDATE) != ACLCHECK_OK)
 		elog(ERROR, "%s.nextval: you don't have permissions to set sequence %s",
-			 seqname, seqname);
-
-	pfree(seqname);
+			 sequence->relname, sequence->relname);
 
 	if (elm->last != elm->cached)		/* some numbers were cached */
 	{
@@ -379,7 +374,7 @@ nextval(PG_FUNCTION_ARGS)
 					break;		/* stop fetching */
 				if (!seq->is_cycled)
 					elog(ERROR, "%s.nextval: reached MAXVALUE (" INT64_FORMAT ")",
-						 elm->name, maxv);
+						 sequence->relname, maxv);
 				next = minv;
 			}
 			else
@@ -395,7 +390,7 @@ nextval(PG_FUNCTION_ARGS)
 					break;		/* stop fetching */
 				if (!seq->is_cycled)
 					elog(ERROR, "%s.nextval: reached MINVALUE (" INT64_FORMAT ")",
-						 elm->name, minv);
+						 sequence->relname, minv);
 				next = maxv;
 			}
 			else
@@ -456,7 +451,7 @@ nextval(PG_FUNCTION_ARGS)
 	LockBuffer(buf, BUFFER_LOCK_UNLOCK);
 
 	if (WriteBuffer(buf) == STATUS_ERROR)
-		elog(ERROR, "%s.nextval: WriteBuffer failed", elm->name);
+		elog(ERROR, "%s.nextval: WriteBuffer failed", sequence->relname);
 
 	PG_RETURN_INT64(result);
 }
@@ -465,25 +460,26 @@ Datum
 currval(PG_FUNCTION_ARGS)
 {
 	text	   *seqin = PG_GETARG_TEXT_P(0);
-	char	   *seqname = get_seq_name(seqin);
+	RangeVar   *sequence;
 	SeqTable	elm;
 	int64		result;
 
+	sequence = makeRangeVarFromNameList(textToQualifiedNameList(seqin,
+																"currval"));
+
 	/* open and AccessShareLock sequence */
-	elm = init_sequence("currval", seqname);
+	elm = init_sequence("currval", sequence);
 
 	if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_SELECT) != ACLCHECK_OK)
 		elog(ERROR, "%s.currval: you don't have permissions to read sequence %s",
-			 seqname, seqname);
+			 sequence->relname, sequence->relname);
 
 	if (elm->increment == 0)	/* nextval/read_info were not called */
 		elog(ERROR, "%s.currval is not yet defined in this session",
-			 seqname);
+			 sequence->relname);
 
 	result = elm->last;
 
-	pfree(seqname);
-
 	PG_RETURN_INT64(result);
 }
 
@@ -501,25 +497,25 @@ currval(PG_FUNCTION_ARGS)
  * sequence.
  */
 static void
-do_setval(char *seqname, int64 next, bool iscalled)
+do_setval(RangeVar *sequence, int64 next, bool iscalled)
 {
 	SeqTable	elm;
 	Buffer		buf;
 	Form_pg_sequence seq;
 
 	/* open and AccessShareLock sequence */
-	elm = init_sequence("setval", seqname);
+	elm = init_sequence("setval", sequence);
 
 	if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_UPDATE) != ACLCHECK_OK)
 		elog(ERROR, "%s.setval: you don't have permissions to set sequence %s",
-			 seqname, seqname);
+			 sequence->relname, sequence->relname);
 
 	/* lock page' buffer and read tuple */
 	seq = read_info("setval", elm, &buf);
 
 	if ((next < seq->min_value) || (next > seq->max_value))
 		elog(ERROR, "%s.setval: value " INT64_FORMAT " is out of bounds (" INT64_FORMAT "," INT64_FORMAT ")",
-			 seqname, next, seq->min_value, seq->max_value);
+			 sequence->relname, next, seq->min_value, seq->max_value);
 
 	/* save info in local cache */
 	elm->last = next;			/* last returned number */
@@ -562,9 +558,7 @@ do_setval(char *seqname, int64 next, bool iscalled)
 	LockBuffer(buf, BUFFER_LOCK_UNLOCK);
 
 	if (WriteBuffer(buf) == STATUS_ERROR)
-		elog(ERROR, "%s.setval: WriteBuffer failed", seqname);
-
-	pfree(seqname);
+		elog(ERROR, "%s.setval: WriteBuffer failed", sequence->relname);
 }
 
 /*
@@ -576,9 +570,12 @@ setval(PG_FUNCTION_ARGS)
 {
 	text	   *seqin = PG_GETARG_TEXT_P(0);
 	int64		next = PG_GETARG_INT64(1);
-	char	   *seqname = get_seq_name(seqin);
+	RangeVar   *sequence;
+
+	sequence = makeRangeVarFromNameList(textToQualifiedNameList(seqin,
+																"setval"));
 
-	do_setval(seqname, next, true);
+	do_setval(sequence, next, true);
 
 	PG_RETURN_INT64(next);
 }
@@ -593,65 +590,14 @@ setval_and_iscalled(PG_FUNCTION_ARGS)
 	text	   *seqin = PG_GETARG_TEXT_P(0);
 	int64		next = PG_GETARG_INT64(1);
 	bool		iscalled = PG_GETARG_BOOL(2);
-	char	   *seqname = get_seq_name(seqin);
+	RangeVar   *sequence;
 
-	do_setval(seqname, next, iscalled);
+	sequence = makeRangeVarFromNameList(textToQualifiedNameList(seqin,
+																"setval"));
 
-	PG_RETURN_INT64(next);
-}
+	do_setval(sequence, next, iscalled);
 
-/*
- * Given a 'text' parameter to a sequence function, extract the actual
- * sequence name.  We downcase the name if it's not double-quoted,
- * and truncate it if it's too long.
- *
- * This is a kluge, really --- should be able to write nextval(seqrel).
- */
-static char *
-get_seq_name(text *seqin)
-{
-	char	   *rawname = DatumGetCString(DirectFunctionCall1(textout,
-												PointerGetDatum(seqin)));
-	int			rawlen = strlen(rawname);
-	char	   *seqname;
-
-	if (rawlen >= 2 &&
-		rawname[0] == '\"' && rawname[rawlen - 1] == '\"')
-	{
-		/* strip off quotes, keep case */
-		rawname[rawlen - 1] = '\0';
-		seqname = pstrdup(rawname + 1);
-		pfree(rawname);
-	}
-	else
-	{
-		seqname = rawname;
-
-		/*
-		 * It's important that this match the identifier downcasing code
-		 * used by backend/parser/scan.l.
-		 */
-		for (; *rawname; rawname++)
-		{
-			if (isupper((unsigned char) *rawname))
-				*rawname = tolower((unsigned char) *rawname);
-		}
-	}
-
-	/* Truncate name if it's overlength; again, should match scan.l */
-	if (strlen(seqname) >= NAMEDATALEN)
-	{
-#ifdef MULTIBYTE
-		int			len;
-
-		len = pg_mbcliplen(seqname, rawlen, NAMEDATALEN - 1);
-		seqname[len] = '\0';
-#else
-		seqname[NAMEDATALEN - 1] = '\0';
-#endif
-	}
-
-	return seqname;
+	PG_RETURN_INT64(next);
 }
 
 static Form_pg_sequence
@@ -665,11 +611,12 @@ read_info(char *caller, SeqTable elm, Buffer *buf)
 
 	if (elm->rel->rd_nblocks > 1)
 		elog(ERROR, "%s.%s: invalid number of blocks in sequence",
-			 elm->name, caller);
+			 RelationGetRelationName(elm->rel), caller);
 
 	*buf = ReadBuffer(elm->rel, 0);
 	if (!BufferIsValid(*buf))
-		elog(ERROR, "%s.%s: ReadBuffer failed", elm->name, caller);
+		elog(ERROR, "%s.%s: ReadBuffer failed",
+			 RelationGetRelationName(elm->rel), caller);
 
 	LockBuffer(*buf, BUFFER_LOCK_EXCLUSIVE);
 
@@ -677,7 +624,8 @@ read_info(char *caller, SeqTable elm, Buffer *buf)
 	sm = (sequence_magic *) PageGetSpecialPointer(page);
 
 	if (sm->magic != SEQ_MAGIC)
-		elog(ERROR, "%s.%s: bad magic (%08X)", elm->name, caller, sm->magic);
+		elog(ERROR, "%s.%s: bad magic (%08X)",
+			 RelationGetRelationName(elm->rel), caller, sm->magic);
 
 	lp = PageGetItemId(page, FirstOffsetNumber);
 	Assert(ItemIdIsUsed(lp));
@@ -692,16 +640,17 @@ read_info(char *caller, SeqTable elm, Buffer *buf)
 
 
 static SeqTable
-init_sequence(char *caller, char *name)
+init_sequence(char *caller, RangeVar *relation)
 {
+	Oid			relid = RangeVarGetRelid(relation, false);
 	SeqTable	elm,
 				prev = (SeqTable) NULL;
 	Relation	seqrel;
-
-	/* Look to see if we already have a seqtable entry for name */
+	
+	/* Look to see if we already have a seqtable entry for relation */
 	for (elm = seqtab; elm != (SeqTable) NULL; elm = elm->next)
 	{
-		if (strcmp(elm->name, name) == 0)
+		if (elm->relid == relid)
 			break;
 		prev = elm;
 	}
@@ -711,24 +660,22 @@ init_sequence(char *caller, char *name)
 		return elm;
 
 	/* Else open and check it */
-	seqrel = heap_openr(name, AccessShareLock);
+	seqrel = heap_open(relid, AccessShareLock);
 	if (seqrel->rd_rel->relkind != RELKIND_SEQUENCE)
-		elog(ERROR, "%s.%s: %s is not a sequence", name, caller, name);
+		elog(ERROR, "%s.%s: %s is not a sequence",
+			 relation->relname, caller, relation->relname);
 
+	/*
+	 * If elm exists but elm->rel is NULL, the seqtable entry is left over
+	 * from a previous xact -- update the entry and reuse it.
+	 *
+	 * NOTE: seqtable entries remain in the list for the life of a backend.
+	 * If the sequence itself is deleted then the entry becomes wasted memory,
+	 * but it's small enough that this should not matter.
+	 */ 
 	if (elm != (SeqTable) NULL)
 	{
-		/*
-		 * We are using a seqtable entry left over from a previous xact;
-		 * must check for relid change.
-		 */
 		elm->rel = seqrel;
-		if (RelationGetRelid(seqrel) != elm->relid)
-		{
-			elog(WARNING, "%s.%s: sequence was re-created",
-				 name, caller);
-			elm->relid = RelationGetRelid(seqrel);
-			elm->cached = elm->last = elm->increment = 0;
-		}
 	}
 	else
 	{
@@ -739,11 +686,8 @@ init_sequence(char *caller, char *name)
 		elm = (SeqTable) malloc(sizeof(SeqTableData));
 		if (elm == NULL)
 			elog(ERROR, "Memory exhausted in init_sequence");
-		elm->name = strdup(name);
-		if (elm->name == NULL)
-			elog(ERROR, "Memory exhausted in init_sequence");
 		elm->rel = seqrel;
-		elm->relid = RelationGetRelid(seqrel);
+		elm->relid = relid;
 		elm->cached = elm->last = elm->increment = 0;
 		elm->next = (SeqTable) NULL;
 
diff --git a/src/backend/parser/parse_type.c b/src/backend/parser/parse_type.c
index 22db859ed2beeab03e88e3dde383e83bd9f8d6bf..a6ba9661951a8a33a90d8db1e7919ac9e69abd5c 100644
--- a/src/backend/parser/parse_type.c
+++ b/src/backend/parser/parse_type.c
@@ -8,14 +8,13 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_type.c,v 1.38 2002/03/29 19:06:12 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_type.c,v 1.39 2002/03/30 01:02:41 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "postgres.h"
 
 #include "catalog/namespace.h"
-#include "catalog/pg_namespace.h"
 #include "catalog/pg_type.h"
 #include "lib/stringinfo.h"
 #include "miscadmin.h"
@@ -132,6 +131,7 @@ LookupTypeName(const TypeName *typename)
 
 		if (schemaname)
 		{
+			/* Look in specific schema only */
 			Oid		namespaceId;
 
 			namespaceId = GetSysCacheOid(NAMESPACENAME,
@@ -147,11 +147,8 @@ LookupTypeName(const TypeName *typename)
 		}
 		else
 		{
-			/* XXX wrong, should use namespace search */
-			restype = GetSysCacheOid(TYPENAMENSP,
-									 PointerGetDatum(typname),
-									 ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
-									 0, 0);
+			/* Unqualified type name, so search the search path */
+			restype = TypenameGetTypid(typname);
 		}
 	}
 
diff --git a/src/backend/utils/adt/not_in.c b/src/backend/utils/adt/not_in.c
index 8c3ca1b73bc22f74004fa62c48948cd143980ed1..970b1fc9c29c95ba4bf266d4880dd5a4345bfb98 100644
--- a/src/backend/utils/adt/not_in.c
+++ b/src/backend/utils/adt/not_in.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/not_in.c,v 1.27 2001/10/25 05:49:45 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/not_in.c,v 1.28 2002/03/30 01:02:41 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -25,7 +25,9 @@
  */
 
 #include "postgres.h"
+
 #include "access/heapam.h"
+#include "catalog/namespace.h"
 #include "utils/builtins.h"
 
 static int	my_varattno(Relation rd, char *a);
@@ -39,43 +41,39 @@ int4notin(PG_FUNCTION_ARGS)
 {
 	int32		not_in_arg = PG_GETARG_INT32(0);
 	text	   *relation_and_attr = PG_GETARG_TEXT_P(1);
+	List	   *names;
+	int			nnames;
+	RangeVar   *relrv;
+	char	   *attribute;
 	Relation	relation_to_scan;
 	int32		integer_value;
 	HeapTuple	current_tuple;
 	HeapScanDesc scan_descriptor;
 	bool		isNull,
 				retval;
-	int			attrid,
-				strlength;
-	char	   *relation,
-			   *attribute;
-	char		my_copy[NAMEDATALEN * 2 + 2];
+	int			attrid;
 	Datum		value;
 
-	/* make a null-terminated copy of text */
-	strlength = VARSIZE(relation_and_attr) - VARHDRSZ;
-	if (strlength >= sizeof(my_copy))
-		strlength = sizeof(my_copy) - 1;
-	memcpy(my_copy, VARDATA(relation_and_attr), strlength);
-	my_copy[strlength] = '\0';
+	/* Parse the argument */
 
-	relation = (char *) strtok(my_copy, ".");
-	attribute = (char *) strtok(NULL, ".");
-	if (attribute == NULL)
+	names = textToQualifiedNameList(relation_and_attr, "int4notin");
+	nnames = length(names);
+	if (nnames < 2)
 		elog(ERROR, "int4notin: must provide relationname.attributename");
+	attribute = strVal(nth(nnames-1, names));
+	names = ltruncate(nnames-1, names);
+	relrv = makeRangeVarFromNameList(names);
 
 	/* Open the relation and get a relation descriptor */
 
-	relation_to_scan = heap_openr(relation, AccessShareLock);
+	relation_to_scan = heap_openrv(relrv, AccessShareLock);
 
 	/* Find the column to search */
 
 	attrid = my_varattno(relation_to_scan, attribute);
 	if (attrid < 0)
-	{
 		elog(ERROR, "int4notin: unknown attribute %s for relation %s",
-			 attribute, relation);
-	}
+			 attribute, RelationGetRelationName(relation_to_scan));
 
 	scan_descriptor = heap_beginscan(relation_to_scan, false, SnapshotNow,
 									 0, (ScanKey) NULL);
diff --git a/src/backend/utils/adt/tid.c b/src/backend/utils/adt/tid.c
index 623d3178e007c7a8f4fce739b7c184673f78baf9..9f3dcf8fa1606cc2ba86b18e6ea48b94d05b2f77 100644
--- a/src/backend/utils/adt/tid.c
+++ b/src/backend/utils/adt/tid.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/tid.c,v 1.28 2001/10/25 05:49:45 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/tid.c,v 1.29 2002/03/30 01:02:41 tgl Exp $
  *
  * NOTES
  *	  input routine largely stolen from boxin().
@@ -19,6 +19,7 @@
 #include "postgres.h"
 
 #include "access/heapam.h"
+#include "catalog/namespace.h"
 #include "utils/builtins.h"
 
 #define DatumGetItemPointer(X)	 ((ItemPointer) DatumGetPointer(X))
@@ -146,14 +147,13 @@ currtid_byreloid(PG_FUNCTION_ARGS)
 		*result = Current_last_tid;
 		PG_RETURN_ITEMPOINTER(result);
 	}
+
+	rel = heap_open(reloid, AccessShareLock);
+
 	ItemPointerCopy(tid, result);
-	if ((rel = heap_open(reloid, AccessShareLock)) != NULL)
-	{
-		heap_get_latest_tid(rel, SnapshotNow, result);
-		heap_close(rel, AccessShareLock);
-	}
-	else
-		elog(ERROR, "Relation %u not found", reloid);
+	heap_get_latest_tid(rel, SnapshotNow, result);
+
+	heap_close(rel, AccessShareLock);
 
 	PG_RETURN_ITEMPOINTER(result);
 }
@@ -164,23 +164,19 @@ currtid_byrelname(PG_FUNCTION_ARGS)
 	text	   *relname = PG_GETARG_TEXT_P(0);
 	ItemPointer tid = PG_GETARG_ITEMPOINTER(1);
 	ItemPointer result;
-	char	   *str;
+	RangeVar   *relrv;
 	Relation	rel;
 
-	str = DatumGetCString(DirectFunctionCall1(textout,
-											  PointerGetDatum(relname)));
+	relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname,
+														"currtid_byrelname"));
+	rel = heap_openrv(relrv, AccessShareLock);
 
 	result = (ItemPointer) palloc(sizeof(ItemPointerData));
 	ItemPointerCopy(tid, result);
-	if ((rel = heap_openr(str, AccessShareLock)) != NULL)
-	{
-		heap_get_latest_tid(rel, SnapshotNow, result);
-		heap_close(rel, AccessShareLock);
-	}
-	else
-		elog(ERROR, "Relation %s not found", str);
 
-	pfree(str);
+	heap_get_latest_tid(rel, SnapshotNow, result);
+
+	heap_close(rel, AccessShareLock);
 
 	PG_RETURN_ITEMPOINTER(result);
 }
diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c
index b10ec7d68553db3a228b965042771fbac7aabc5f..ce3e8dc254dbab978ff36123768027f0c51ce937 100644
--- a/src/backend/utils/adt/varlena.c
+++ b/src/backend/utils/adt/varlena.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.79 2002/03/05 05:33:19 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.80 2002/03/30 01:02:42 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1039,6 +1039,122 @@ name_text(PG_FUNCTION_ARGS)
 }
 
 
+/*
+ * textToQualifiedNameList - convert a text object to list of names
+ *
+ * This implements the input parsing needed by nextval() and other
+ * functions that take a text parameter representing a qualified name.
+ * We split the name at dots, downcase if not double-quoted, and
+ * truncate names if they're too long.
+ *
+ * This is a kluge, really, and exists only for historical reasons.
+ * A better notation for such functions would be nextval(relname).
+ */
+List *
+textToQualifiedNameList(text *textval, const char *caller)
+{
+	char	   *rawname;
+	char	   *nextp;
+	List	   *result = NIL;
+
+	/* Convert to C string (handles possible detoasting). */
+	/* Note we rely on being able to modify rawname below. */
+	rawname = DatumGetCString(DirectFunctionCall1(textout,
+												  PointerGetDatum(textval)));
+	nextp = rawname;
+
+	do
+	{
+		char	   *curname;
+		char	   *endp;
+		char	   *cp;
+		int			curlen;
+
+		if (*nextp == '\"')
+		{
+			/* Quoted name --- collapse quote-quote pairs, no downcasing */
+			curname = nextp + 1;
+			for (;;)
+			{
+				endp = strchr(nextp + 1, '\"');
+				if (endp == NULL)
+					elog(ERROR, "%s: invalid quoted name: mismatched quotes",
+						 caller);
+				if (endp[1] != '\"')
+					break;		/* found end of quoted name */
+				/* Collapse adjacent quotes into one quote, and look again */
+				memmove(endp, endp+1, strlen(endp));
+				nextp = endp;
+			}
+			*endp = '\0';
+			nextp = endp + 1;
+			if (*nextp)
+			{
+				if (*nextp != '.')
+					elog(ERROR, "%s: invalid name syntax",
+						 caller);
+				nextp++;
+				if (*nextp == '\0')
+					elog(ERROR, "%s: invalid name syntax",
+						 caller);
+			}
+		}
+		else
+		{
+			/* Unquoted name --- extends to next dot */
+			if (*nextp == '\0')				/* empty name not okay here */
+				elog(ERROR, "%s: invalid name syntax",
+					 caller);
+			curname = nextp;
+			endp = strchr(nextp, '.');
+			if (endp)
+			{
+				*endp = '\0';
+				nextp = endp + 1;
+				if (*nextp == '\0')
+					elog(ERROR, "%s: invalid name syntax",
+						 caller);
+			}
+			else
+				nextp = nextp + strlen(nextp);
+			/*
+			 * It's important that this match the identifier downcasing code
+			 * used by backend/parser/scan.l.
+			 */
+			for (cp = curname; *cp; cp++)
+			{
+				if (isupper((unsigned char) *cp))
+					*cp = tolower((unsigned char) *cp);
+			}
+		}
+
+		/* Truncate name if it's overlength; again, should match scan.l */
+		curlen = strlen(curname);
+		if (curlen >= NAMEDATALEN)
+		{
+#ifdef MULTIBYTE
+			curlen = pg_mbcliplen(curname, curlen, NAMEDATALEN - 1);
+			curname[curlen] = '\0';
+#else
+			curname[NAMEDATALEN - 1] = '\0';
+#endif
+		}
+
+		/*
+		 * Finished isolating current name --- add it to list
+		 */
+		result = lappend(result, makeString(pstrdup(curname)));
+		/*
+		 * Loop back if we found a dot
+		 */
+	} while (*nextp);
+
+	pfree(rawname);
+
+	return result;
+}
+
+
 /*****************************************************************************
  *	Comparison Functions used for bytea
  *
diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h
index f6f359813cd43cfffe77fb1f69aa143ab17caa91..242050de490a8305ffc8aad037628effd2fa3f06 100644
--- a/src/include/catalog/namespace.h
+++ b/src/include/catalog/namespace.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: namespace.h,v 1.2 2002/03/29 19:06:18 tgl Exp $
+ * $Id: namespace.h,v 1.3 2002/03/30 01:02:42 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -23,6 +23,8 @@ extern Oid	RangeVarGetCreationNamespace(const RangeVar *newRelation);
 
 extern Oid	RelnameGetRelid(const char *relname);
 
+extern Oid	TypenameGetTypid(const char *typname);
+
 extern Oid	QualifiedNameGetCreationNamespace(List *names, char **objname_p);
 
 extern RangeVar *makeRangeVarFromNameList(List *names);
diff --git a/src/include/catalog/pg_namespace.h b/src/include/catalog/pg_namespace.h
index 8a57cf7977bb1426bda60b2ee07e7f7cc3ddb5f6..607b74132e4b790d9fbf6fad5f815bdcb86405de 100644
--- a/src/include/catalog/pg_namespace.h
+++ b/src/include/catalog/pg_namespace.h
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_namespace.h,v 1.1 2002/03/22 21:34:44 tgl Exp $
+ * $Id: pg_namespace.h,v 1.2 2002/03/30 01:02:42 tgl Exp $
  *
  * NOTES
  *	  the genbki.sh script reads this file and generates .bki
@@ -69,6 +69,12 @@ typedef FormData_pg_namespace *Form_pg_namespace;
 DATA(insert OID = 11 ( "pg_catalog" PGUID "{=r}" ));
 DESCR("System catalog namespace");
 #define PG_CATALOG_NAMESPACE 11
+DATA(insert OID = 99 ( "pg_toast" PGUID "{=r}" ));
+DESCR("Reserved namespace for TOAST tables");
+#define PG_TOAST_NAMESPACE 99
+DATA(insert OID = 2071 ( "pg_public" PGUID "{=rw}" ));
+DESCR("Standard public namespace");
+#define PG_PUBLIC_NAMESPACE 2071
 
 
 /*
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index e1343bf4fcd7b3fe7a9a4594eb5a780edc0ac8b6..7bd111cd544ec7006aac37e8e1e74aad6735f8c4 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: builtins.h,v 1.173 2002/03/22 02:56:37 tgl Exp $
+ * $Id: builtins.h,v 1.174 2002/03/30 01:02:42 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -410,6 +410,7 @@ extern Datum text_substr(PG_FUNCTION_ARGS);
 extern Datum name_text(PG_FUNCTION_ARGS);
 extern Datum text_name(PG_FUNCTION_ARGS);
 extern int	varstr_cmp(char *arg1, int len1, char *arg2, int len2);
+extern List *textToQualifiedNameList(text *textval, const char *caller);
 
 extern Datum byteain(PG_FUNCTION_ARGS);
 extern Datum byteaout(PG_FUNCTION_ARGS);
diff --git a/src/test/regress/output/constraints.source b/src/test/regress/output/constraints.source
index 0e12a368164541dd0ddc5829b8349ab041cb4907..8986118fd48684b1bfc9fbe61e996d8bbf4edad8 100644
--- a/src/test/regress/output/constraints.source
+++ b/src/test/regress/output/constraints.source
@@ -216,7 +216,6 @@ INSERT INTO tmp VALUES (null, 'Y', null);
 INSERT INTO tmp VALUES (5, '!check failed', null);
 INSERT INTO tmp VALUES (null, 'try again', null);
 INSERT INTO INSERT_TBL(y) select yd from tmp;
-WARNING:  insert_seq.nextval: sequence was re-created
 SELECT '' AS three, * FROM INSERT_TBL;
  three | x |       y       | z  
 -------+---+---------------+----