diff --git a/configure b/configure
index 3490b9a6956e5853daa3c909ec05aac6d2b79cfe..9403fa4537390212a8bfcf3a0ba261fe078cbe1a 100755
--- a/configure
+++ b/configure
@@ -11744,8 +11744,7 @@ fi
 
 
 
-
-for ac_func in crypt fseeko getopt getrusage inet_aton random rint srandom strcasecmp strdup strerror strtol strtoul unsetenv
+for ac_func in crypt fseeko getopt getrusage inet_aton random rint srandom strdup strerror strtol strtoul unsetenv
 do
 as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
 echo "$as_me:$LINENO: checking for $ac_func" >&5
diff --git a/configure.in b/configure.in
index 8ddb6b73726db2c48fad217d4c78f3ebdcb3045c..1cad0dbe281914a70b36ad359c720123baa7b669 100644
--- a/configure.in
+++ b/configure.in
@@ -1,5 +1,5 @@
 dnl Process this file with autoconf to produce a configure script.
-dnl $PostgreSQL: pgsql/configure.in,v 1.344 2004/05/05 21:18:29 tgl Exp $
+dnl $PostgreSQL: pgsql/configure.in,v 1.345 2004/05/07 00:24:57 tgl Exp $
 dnl
 dnl Developers, please strive to achieve this order:
 dnl
@@ -858,7 +858,7 @@ else
   AC_CHECK_FUNCS([fpclass fp_class fp_class_d class], [break])
 fi
 
-AC_REPLACE_FUNCS([crypt fseeko getopt getrusage inet_aton random rint srandom strcasecmp strdup strerror strtol strtoul unsetenv])
+AC_REPLACE_FUNCS([crypt fseeko getopt getrusage inet_aton random rint srandom strdup strerror strtol strtoul unsetenv])
 
 # system's version of getaddrinfo(), if any, may be used only if we found
 # a definition for struct addrinfo; see notes in src/include/getaddrinfo.h
diff --git a/contrib/ltree/lquery_op.c b/contrib/ltree/lquery_op.c
index 2328fcd238670a1804948f6ac1ef19030c3d5cae..81a1b788aa27bc5a5da0c78e8a7fb24ac03efe74 100644
--- a/contrib/ltree/lquery_op.c
+++ b/contrib/ltree/lquery_op.c
@@ -91,7 +91,7 @@ checkLevel(lquery_level * curq, ltree_level * curt)
 
 	for (i = 0; i < curq->numvar; i++)
 	{
-		cmpptr = (curvar->flag & LVAR_INCASE) ? strncasecmp : strncmp;
+		cmpptr = (curvar->flag & LVAR_INCASE) ? pg_strncasecmp : strncmp;
 
 		if (curvar->flag & LVAR_SUBLEXEM)
 		{
diff --git a/contrib/ltree/ltxtquery_op.c b/contrib/ltree/ltxtquery_op.c
index 263f39b5e4d73061df218b458e2a98cebea6ebbc..1bba66954b5bb20da5863cbd9f5d347b57cde73b 100644
--- a/contrib/ltree/ltxtquery_op.c
+++ b/contrib/ltree/ltxtquery_op.c
@@ -54,7 +54,7 @@ checkcondition_str(void *checkval, ITEM * val)
 	char	   *op = ((CHKVAL *) checkval)->operand + val->distance;
 	int			(*cmpptr) (const char *, const char *, size_t);
 
-	cmpptr = (val->flag & LVAR_INCASE) ? strncasecmp : strncmp;
+	cmpptr = (val->flag & LVAR_INCASE) ? pg_strncasecmp : strncmp;
 	while (tlen > 0)
 	{
 		if (val->flag & LVAR_SUBLEXEM)
diff --git a/contrib/pgcrypto/internal.c b/contrib/pgcrypto/internal.c
index 4dca6dba541800288953ee9c66e7c4056f6f5263..db7b46da0673b093eba97f6c6afcad513d0ee41b 100644
--- a/contrib/pgcrypto/internal.c
+++ b/contrib/pgcrypto/internal.c
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $PostgreSQL: pgsql/contrib/pgcrypto/internal.c,v 1.12 2003/11/29 22:39:28 pgsql Exp $
+ * $PostgreSQL: pgsql/contrib/pgcrypto/internal.c,v 1.13 2004/05/07 00:24:57 tgl Exp $
  */
 
 
@@ -561,7 +561,7 @@ px_find_digest(const char *name, PX_MD ** res)
 	PX_MD	   *h;
 
 	for (p = int_digest_list; p->name; p++)
-		if (!strcasecmp(p->name, name))
+		if (pg_strcasecmp(p->name, name) == 0)
 		{
 			h = px_alloc(sizeof(*h));
 			p->init(h);
diff --git a/contrib/pgcrypto/md5.c b/contrib/pgcrypto/md5.c
index 35bbe78711818a4199f313db26814334baab535e..4a236178760628fdeb48b90255f32756f58f50f1 100644
--- a/contrib/pgcrypto/md5.c
+++ b/contrib/pgcrypto/md5.c
@@ -1,4 +1,4 @@
-/*	$PostgreSQL: pgsql/contrib/pgcrypto/md5.c,v 1.10 2003/11/29 22:39:28 pgsql Exp $	*/
+/*	$PostgreSQL: pgsql/contrib/pgcrypto/md5.c,v 1.11 2004/05/07 00:24:57 tgl Exp $	*/
 /*	   $KAME: md5.c,v 1.3 2000/02/22 14:01:17 itojun Exp $	   */
 
 /*
@@ -141,7 +141,7 @@ md5_init(md5_ctxt * ctxt)
 	ctxt->md5_stb = MD5_B0;
 	ctxt->md5_stc = MD5_C0;
 	ctxt->md5_std = MD5_D0;
-	bzero(ctxt->md5_buf, sizeof(ctxt->md5_buf));
+	memset(ctxt->md5_buf, 0, sizeof(ctxt->md5_buf));
 }
 
 void
diff --git a/contrib/pgcrypto/mhash.c b/contrib/pgcrypto/mhash.c
index 1ecfca6bed12f7e483832d292a95834308b94d7c..934a83271df598f43d300dcb7bff7b025e043cd5 100644
--- a/contrib/pgcrypto/mhash.c
+++ b/contrib/pgcrypto/mhash.c
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $PostgreSQL: pgsql/contrib/pgcrypto/mhash.c,v 1.9 2003/11/29 22:39:28 pgsql Exp $
+ * $PostgreSQL: pgsql/contrib/pgcrypto/mhash.c,v 1.10 2004/05/07 00:24:57 tgl Exp $
  */
 
 #include <postgres.h>
@@ -217,9 +217,9 @@ find_hashid(const char *name)
 		mname = mhash_get_hash_name(i);
 		if (mname == NULL)
 			continue;
-		b = strcasecmp(name, mname);
+		b = pg_strcasecmp(name, mname);
 		free(mname);
-		if (!b)
+		if (b == 0)
 		{
 			res = i;
 			break;
@@ -312,7 +312,7 @@ px_find_cipher(const char *name, PX_Cipher ** res)
 
 	PX_Cipher  *c;
 
-	strcpy(nbuf, name);
+	StrNCpy(nbuf, name, sizeof(nbuf));
 
 	if ((p = strrchr(nbuf, '-')) != NULL)
 	{
diff --git a/contrib/pgcrypto/pgcrypto.c b/contrib/pgcrypto/pgcrypto.c
index 6efc044b007d61541c50a1fd6956d4ffb483b5ec..f28f960ad05fc3de8743b4dba11620f37d1fd2c5 100644
--- a/contrib/pgcrypto/pgcrypto.c
+++ b/contrib/pgcrypto/pgcrypto.c
@@ -26,13 +26,16 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $PostgreSQL: pgsql/contrib/pgcrypto/pgcrypto.c,v 1.15 2003/11/29 22:39:28 pgsql Exp $
+ * $PostgreSQL: pgsql/contrib/pgcrypto/pgcrypto.c,v 1.16 2004/05/07 00:24:57 tgl Exp $
  */
 
-#include <postgres.h>
-#include <fmgr.h>
+#include "postgres.h"
+
 #include <ctype.h>
 
+#include "fmgr.h"
+#include "parser/scansup.h"
+
 #include "px.h"
 #include "px-crypt.h"
 #include "pgcrypto.h"
@@ -554,26 +557,12 @@ find_provider(text *name,
 			  char *desc, int silent)
 {
 	void	   *res;
-	char		buf[PX_MAX_NAMELEN + 1],
-			   *p;
-	unsigned	len;
-	unsigned	i;
+	char	   *buf;
 	int			err;
 
-	len = VARSIZE(name) - VARHDRSZ;
-	if (len > PX_MAX_NAMELEN)
-	{
-		if (silent)
-			return NULL;
-		ereport(ERROR,
-				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-				 errmsg("%s type does not exist (name too long)", desc)));
-	}
-
-	p = VARDATA(name);
-	for (i = 0; i < len; i++)
-		buf[i] = tolower((unsigned char) p[i]);
-	buf[len] = 0;
+	buf = downcase_truncate_identifier(VARDATA(name),
+									   VARSIZE(name) - VARHDRSZ,
+									   false);
 
 	err = provider_lookup(buf, &res);
 
@@ -582,5 +571,7 @@ find_provider(text *name,
 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 				 errmsg("%s type does not exist: \"%s\"", desc, buf)));
 
+	pfree(buf);
+
 	return err ? NULL : res;
 }
diff --git a/contrib/pgcrypto/px-crypt.c b/contrib/pgcrypto/px-crypt.c
index 84a3e78f9d378cd0adf4f9db46506ddf3b2f1610..463d1ddf731ce49e6fb4a5286bbd08eb88691e2d 100644
--- a/contrib/pgcrypto/px-crypt.c
+++ b/contrib/pgcrypto/px-crypt.c
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $PostgreSQL: pgsql/contrib/pgcrypto/px-crypt.c,v 1.7 2003/11/29 22:39:28 pgsql Exp $
+ * $PostgreSQL: pgsql/contrib/pgcrypto/px-crypt.c,v 1.8 2004/05/07 00:24:57 tgl Exp $
  */
 
 #include <postgres.h>
@@ -170,7 +170,7 @@ px_gen_salt(const char *salt_type, char *buf, int rounds)
 	for (i = 0; gen_list[i].name; i++)
 	{
 		g = &gen_list[i];
-		if (strcasecmp(g->name, salt_type) != 0)
+		if (pg_strcasecmp(g->name, salt_type) != 0)
 			continue;
 
 		if (g->def_rounds)
diff --git a/contrib/pgcrypto/px.c b/contrib/pgcrypto/px.c
index 1f5aa434b4d02b27bb65b9c1575ac97edc8ad61d..49c4bdc7317d518759c9f9c7f9ce9dff5697af59 100644
--- a/contrib/pgcrypto/px.c
+++ b/contrib/pgcrypto/px.c
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $PostgreSQL: pgsql/contrib/pgcrypto/px.c,v 1.8 2003/11/29 22:39:28 pgsql Exp $
+ * $PostgreSQL: pgsql/contrib/pgcrypto/px.c,v 1.9 2004/05/07 00:24:57 tgl Exp $
  */
 
 #include <postgres.h>
@@ -39,7 +39,7 @@ px_resolve_alias(const PX_Alias * list, const char *name)
 {
 	while (list->name)
 	{
-		if (!strcasecmp(list->alias, name))
+		if (pg_strcasecmp(list->alias, name) == 0)
 			return list->name;
 		list++;
 	}
diff --git a/contrib/pgcrypto/sha1.c b/contrib/pgcrypto/sha1.c
index 21df9d6ff8befc4eaa31942529a27a58ffc5bfa0..0fc78bba437787ff80afd42cb8c4ef6c1e734476 100644
--- a/contrib/pgcrypto/sha1.c
+++ b/contrib/pgcrypto/sha1.c
@@ -1,4 +1,4 @@
-/*	$PostgreSQL: pgsql/contrib/pgcrypto/sha1.c,v 1.12 2003/11/29 22:39:28 pgsql Exp $ */
+/*	$PostgreSQL: pgsql/contrib/pgcrypto/sha1.c,v 1.13 2004/05/07 00:24:57 tgl Exp $ */
 /*	   $KAME: sha1.c,v 1.3 2000/02/22 14:01:18 itojun Exp $    */
 
 /*
@@ -227,7 +227,7 @@ sha1_step(struct sha1_ctxt * ctxt)
 	H(3) = H(3) + d;
 	H(4) = H(4) + e;
 
-	bzero(&ctxt->m.b8[0], 64);
+	memset(&ctxt->m.b8[0], 0, 64);
 }
 
 /*------------------------------------------------------------*/
@@ -235,7 +235,7 @@ sha1_step(struct sha1_ctxt * ctxt)
 void
 sha1_init(struct sha1_ctxt * ctxt)
 {
-	bzero(ctxt, sizeof(struct sha1_ctxt));
+	memset(ctxt, 0, sizeof(struct sha1_ctxt));
 	H(0) = 0x67452301;
 	H(1) = 0xefcdab89;
 	H(2) = 0x98badcfe;
@@ -255,14 +255,14 @@ sha1_pad(struct sha1_ctxt * ctxt)
 	padlen = 64 - padstart;
 	if (padlen < 8)
 	{
-		bzero(&ctxt->m.b8[padstart], padlen);
+		memset(&ctxt->m.b8[padstart], 0, padlen);
 		COUNT += padlen;
 		COUNT %= 64;
 		sha1_step(ctxt);
 		padstart = COUNT % 64;	/* should be 0 */
 		padlen = 64 - padstart; /* should be 64 */
 	}
-	bzero(&ctxt->m.b8[padstart], padlen - 8);
+	memset(&ctxt->m.b8[padstart], 0, padlen - 8);
 	COUNT += (padlen - 8);
 	COUNT %= 64;
 #if BYTE_ORDER == BIG_ENDIAN
diff --git a/contrib/spi/timetravel.c b/contrib/spi/timetravel.c
index 29de8c6fda4cfd1bd3766d65e8ddc54fd46987cb..02570a403d74f5b598f661ce8296e2e44dcffbe7 100644
--- a/contrib/spi/timetravel.c
+++ b/contrib/spi/timetravel.c
@@ -498,7 +498,7 @@ findTTStatus(char *name)
 	TTOffList  *pp;
 
 	for (pp = TTOff.next; pp; pp = pp->next)
-		if (strcasecmp(name, pp->name) == 0)
+		if (pg_strcasecmp(name, pp->name) == 0)
 			return 0;
 	return 1;
 }
diff --git a/contrib/tsearch2/dict_ispell.c b/contrib/tsearch2/dict_ispell.c
index a0e67a69e1de96746fb6e36d2131189f69ea7c8b..5725c8fb3629020d8efaa3d3c475879e80c301e2 100644
--- a/contrib/tsearch2/dict_ispell.c
+++ b/contrib/tsearch2/dict_ispell.c
@@ -62,7 +62,7 @@ spell_init(PG_FUNCTION_ARGS)
 	pcfg = cfg;
 	while (pcfg->key)
 	{
-		if (strcasecmp("DictFile", pcfg->key) == 0)
+		if (pg_strcasecmp("DictFile", pcfg->key) == 0)
 		{
 			if (dictloaded)
 			{
@@ -81,7 +81,7 @@ spell_init(PG_FUNCTION_ARGS)
 			}
 			dictloaded = true;
 		}
-		else if (strcasecmp("AffFile", pcfg->key) == 0)
+		else if (pg_strcasecmp("AffFile", pcfg->key) == 0)
 		{
 			if (affloaded)
 			{
@@ -100,7 +100,7 @@ spell_init(PG_FUNCTION_ARGS)
 			}
 			affloaded = true;
 		}
-		else if (strcasecmp("StopFile", pcfg->key) == 0)
+		else if (pg_strcasecmp("StopFile", pcfg->key) == 0)
 		{
 			text	   *tmp = char2text(pcfg->value);
 
diff --git a/contrib/tsearch2/ispell/spell.c b/contrib/tsearch2/ispell/spell.c
index 838d9957028c883fc2d177af0bb5717d604b4f74..10b0ca9e40ac5fdb18f2e100e63179d20b612891 100644
--- a/contrib/tsearch2/ispell/spell.c
+++ b/contrib/tsearch2/ispell/spell.c
@@ -10,7 +10,7 @@
 #define MAX_NORM 1024
 #define MAXNORMLEN 256
 
-#define STRNCASECMP(x,y)		(strncasecmp(x,y,strlen(y)))
+#define STRNCASECMP(x,y)		pg_strncasecmp(x, y, strlen(y))
 #define GETWCHAR(W,L,N,T) ( ((uint8*)(W))[ ((T)=='p') ? (N) : ( (L) - 1 - (N) ) ] )
 #define GETCHAR(A,N,T)	  GETWCHAR( (A)->repl, (A)->replen, N, T )
 
@@ -304,19 +304,19 @@ NIImportAffixes(IspellDict * Conf, const char *filename)
 				continue; 
 			}
 		}
-		if (!STRNCASECMP(str, "suffixes"))
+		if (STRNCASECMP(str, "suffixes")==0)
 		{
 			suffixes = 1;
 			prefixes = 0;
 			continue;
 		}
-		if (!STRNCASECMP(str, "prefixes"))
+		if (STRNCASECMP(str, "prefixes")==0)
 		{
 			suffixes = 0;
 			prefixes = 1;
 			continue;
 		}
-		if (!STRNCASECMP(str, "flag "))
+		if (STRNCASECMP(str, "flag ")==0)
 		{
 			s = str + 5;
 			flagflags=0;
diff --git a/contrib/tsearch2/wparser_def.c b/contrib/tsearch2/wparser_def.c
index 99b47196e9bfb9c436fb87761728a8bb8f7f1fa7..a3d61126282c0f07998693d7c490879e2b70d275 100644
--- a/contrib/tsearch2/wparser_def.c
+++ b/contrib/tsearch2/wparser_def.c
@@ -210,15 +210,15 @@ prsd_headline(PG_FUNCTION_ARGS)
 
 		while (mptr && mptr->key)
 		{
-			if (strcasecmp(mptr->key, "MaxWords") == 0)
+			if (pg_strcasecmp(mptr->key, "MaxWords") == 0)
 				max_words = pg_atoi(mptr->value, 4, 1);
-			else if (strcasecmp(mptr->key, "MinWords") == 0)
+			else if (pg_strcasecmp(mptr->key, "MinWords") == 0)
 				min_words = pg_atoi(mptr->value, 4, 1);
-			else if (strcasecmp(mptr->key, "ShortWord") == 0)
+			else if (pg_strcasecmp(mptr->key, "ShortWord") == 0)
 				shortword = pg_atoi(mptr->value, 4, 1);
-			else if (strcasecmp(mptr->key, "StartSel") == 0)
+			else if (pg_strcasecmp(mptr->key, "StartSel") == 0)
 				prs->startsel = pstrdup(mptr->value);
-			else if (strcasecmp(mptr->key, "StopSel") == 0)
+			else if (pg_strcasecmp(mptr->key, "StopSel") == 0)
 				prs->stopsel = pstrdup(mptr->value);
 
 			pfree(mptr->key);
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index 35cdc7974c2d72deefbde119af9b47ddb83ac1d5..9dda9bf8b0026542a04b09bea923fd61600f64ae 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -1,5 +1,5 @@
 # -*-makefile-*-
-# $PostgreSQL: pgsql/src/Makefile.global.in,v 1.180 2004/04/30 15:01:25 momjian Exp $
+# $PostgreSQL: pgsql/src/Makefile.global.in,v 1.181 2004/05/07 00:24:57 tgl Exp $
 
 #------------------------------------------------------------------------------
 # All PostgreSQL makefiles include this file and use the variables it sets,
@@ -339,7 +339,7 @@ endif
 #
 # substitute implementations of the C library
 
-LIBOBJS = @LIBOBJS@ noblock.o path.o pgsleep.o sprompt.o thread.o
+LIBOBJS = @LIBOBJS@ noblock.o path.o pgsleep.o pgstrcasecmp.o sprompt.o thread.o
 
 ifneq (,$(LIBOBJS))
 LIBS += -lpgport
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 6a1ccef8ec50d3ed6dbfa92f4437e935c73f6eb7..b6199706f67e24fa188e2406c31cf5f44323c6e8 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.139 2004/04/19 17:42:57 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.140 2004/05/07 00:24:57 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -3778,27 +3778,27 @@ assign_xlog_sync_method(const char *method, bool doit, GucSource source)
 	int			new_sync_method;
 	int			new_sync_bit;
 
-	if (strcasecmp(method, "fsync") == 0)
+	if (pg_strcasecmp(method, "fsync") == 0)
 	{
 		new_sync_method = SYNC_METHOD_FSYNC;
 		new_sync_bit = 0;
 	}
 #ifdef HAVE_FDATASYNC
-	else if (strcasecmp(method, "fdatasync") == 0)
+	else if (pg_strcasecmp(method, "fdatasync") == 0)
 	{
 		new_sync_method = SYNC_METHOD_FDATASYNC;
 		new_sync_bit = 0;
 	}
 #endif
 #ifdef OPEN_SYNC_FLAG
-	else if (strcasecmp(method, "open_sync") == 0)
+	else if (pg_strcasecmp(method, "open_sync") == 0)
 	{
 		new_sync_method = SYNC_METHOD_OPEN;
 		new_sync_bit = OPEN_SYNC_FLAG;
 	}
 #endif
 #ifdef OPEN_DATASYNC_FLAG
-	else if (strcasecmp(method, "open_datasync") == 0)
+	else if (pg_strcasecmp(method, "open_datasync") == 0)
 	{
 		new_sync_method = SYNC_METHOD_OPEN;
 		new_sync_bit = OPEN_DATASYNC_FLAG;
diff --git a/src/backend/commands/aggregatecmds.c b/src/backend/commands/aggregatecmds.c
index 3dfacf7d186ee0d5b2c1a3e9ca591b28256e66f9..d587245ef97c257e24dc6ea4d38e2526f8b8e596 100644
--- a/src/backend/commands/aggregatecmds.c
+++ b/src/backend/commands/aggregatecmds.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/aggregatecmds.c,v 1.16 2003/11/29 19:51:47 pgsql Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/aggregatecmds.c,v 1.17 2004/05/07 00:24:57 tgl Exp $
  *
  * DESCRIPTION
  *	  The "DefineFoo" routines take the parse tree and pick out the
@@ -75,21 +75,21 @@ DefineAggregate(List *names, List *parameters)
 		 * sfunc1, stype1, and initcond1 are accepted as obsolete
 		 * spellings for sfunc, stype, initcond.
 		 */
-		if (strcasecmp(defel->defname, "sfunc") == 0)
+		if (pg_strcasecmp(defel->defname, "sfunc") == 0)
 			transfuncName = defGetQualifiedName(defel);
-		else if (strcasecmp(defel->defname, "sfunc1") == 0)
+		else if (pg_strcasecmp(defel->defname, "sfunc1") == 0)
 			transfuncName = defGetQualifiedName(defel);
-		else if (strcasecmp(defel->defname, "finalfunc") == 0)
+		else if (pg_strcasecmp(defel->defname, "finalfunc") == 0)
 			finalfuncName = defGetQualifiedName(defel);
-		else if (strcasecmp(defel->defname, "basetype") == 0)
+		else if (pg_strcasecmp(defel->defname, "basetype") == 0)
 			baseType = defGetTypeName(defel);
-		else if (strcasecmp(defel->defname, "stype") == 0)
+		else if (pg_strcasecmp(defel->defname, "stype") == 0)
 			transType = defGetTypeName(defel);
-		else if (strcasecmp(defel->defname, "stype1") == 0)
+		else if (pg_strcasecmp(defel->defname, "stype1") == 0)
 			transType = defGetTypeName(defel);
-		else if (strcasecmp(defel->defname, "initcond") == 0)
+		else if (pg_strcasecmp(defel->defname, "initcond") == 0)
 			initval = defGetString(defel);
-		else if (strcasecmp(defel->defname, "initcond1") == 0)
+		else if (pg_strcasecmp(defel->defname, "initcond1") == 0)
 			initval = defGetString(defel);
 		else
 			ereport(WARNING,
@@ -124,7 +124,7 @@ DefineAggregate(List *names, List *parameters)
 	 * be able to store values of the transtype.  However, we can allow
 	 * polymorphic transtype in some cases (AggregateCreate will check).
 	 */
-	if (strcasecmp(TypeNameToString(baseType), "ANY") == 0)
+	if (pg_strcasecmp(TypeNameToString(baseType), "ANY") == 0)
 		baseTypeId = ANYOID;
 	else
 		baseTypeId = typenameTypeId(baseType);
diff --git a/src/backend/commands/define.c b/src/backend/commands/define.c
index fc24c2c30fb2cbde081275a229868de3516ebc69..19f14879a0e83440f97120e4c3d2b9fd977c02bb 100644
--- a/src/backend/commands/define.c
+++ b/src/backend/commands/define.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/define.c,v 1.86 2004/02/21 00:34:52 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/define.c,v 1.87 2004/05/07 00:24:57 tgl Exp $
  *
  * DESCRIPTION
  *	  The "DefineFoo" routines take the parse tree and pick out the
@@ -240,12 +240,12 @@ defGetTypeLength(DefElem *def)
 							def->defname)));
 			break;
 		case T_String:
-			if (strcasecmp(strVal(def->arg), "variable") == 0)
+			if (pg_strcasecmp(strVal(def->arg), "variable") == 0)
 				return -1;		/* variable length */
 			break;
 		case T_TypeName:
 			/* cope if grammar chooses to believe "variable" is a typename */
-			if (strcasecmp(TypeNameToString((TypeName *) def->arg),
+			if (pg_strcasecmp(TypeNameToString((TypeName *) def->arg),
 						   "variable") == 0)
 				return -1;		/* variable length */
 			break;
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index c91b31ed6fd58f9238ee0b1f917a069d042820f7..a0a9c5824095850628c64189f6ebca7658b79a2a 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.44 2004/02/21 00:34:52 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.45 2004/05/07 00:24:57 tgl Exp $
  *
  * DESCRIPTION
  *	  These routines take the parse tree and pick out the
@@ -328,9 +328,9 @@ compute_attributes_with_style(List *parameters, bool *isStrict_p, char *volatili
 	{
 		DefElem    *param = (DefElem *) lfirst(pl);
 
-		if (strcasecmp(param->defname, "isstrict") == 0)
+		if (pg_strcasecmp(param->defname, "isstrict") == 0)
 			*isStrict_p = true;
-		else if (strcasecmp(param->defname, "iscachable") == 0)
+		else if (pg_strcasecmp(param->defname, "iscachable") == 0)
 		{
 			/* obsolete spelling of isImmutable */
 			*volatility_p = PROVOLATILE_IMMUTABLE;
diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c
index 657e289fbb020e8c0850f800c0049ddb1fece6b6..2736a31f3c094a9613f5e72d347c163812282e8c 100644
--- a/src/backend/commands/operatorcmds.c
+++ b/src/backend/commands/operatorcmds.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.13 2003/11/29 19:51:47 pgsql Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.14 2004/05/07 00:24:57 tgl Exp $
  *
  * DESCRIPTION
  *	  The "DefineFoo" routines take the parse tree and pick out the
@@ -97,7 +97,7 @@ DefineOperator(List *names, List *parameters)
 	{
 		DefElem    *defel = (DefElem *) lfirst(pl);
 
-		if (strcasecmp(defel->defname, "leftarg") == 0)
+		if (pg_strcasecmp(defel->defname, "leftarg") == 0)
 		{
 			typeName1 = defGetTypeName(defel);
 			if (typeName1->setof)
@@ -105,7 +105,7 @@ DefineOperator(List *names, List *parameters)
 						(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
 				errmsg("setof type not allowed for operator argument")));
 		}
-		else if (strcasecmp(defel->defname, "rightarg") == 0)
+		else if (pg_strcasecmp(defel->defname, "rightarg") == 0)
 		{
 			typeName2 = defGetTypeName(defel);
 			if (typeName2->setof)
@@ -113,27 +113,27 @@ DefineOperator(List *names, List *parameters)
 						(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
 				errmsg("setof type not allowed for operator argument")));
 		}
-		else if (strcasecmp(defel->defname, "procedure") == 0)
+		else if (pg_strcasecmp(defel->defname, "procedure") == 0)
 			functionName = defGetQualifiedName(defel);
-		else if (strcasecmp(defel->defname, "commutator") == 0)
+		else if (pg_strcasecmp(defel->defname, "commutator") == 0)
 			commutatorName = defGetQualifiedName(defel);
-		else if (strcasecmp(defel->defname, "negator") == 0)
+		else if (pg_strcasecmp(defel->defname, "negator") == 0)
 			negatorName = defGetQualifiedName(defel);
-		else if (strcasecmp(defel->defname, "restrict") == 0)
+		else if (pg_strcasecmp(defel->defname, "restrict") == 0)
 			restrictionName = defGetQualifiedName(defel);
-		else if (strcasecmp(defel->defname, "join") == 0)
+		else if (pg_strcasecmp(defel->defname, "join") == 0)
 			joinName = defGetQualifiedName(defel);
-		else if (strcasecmp(defel->defname, "hashes") == 0)
+		else if (pg_strcasecmp(defel->defname, "hashes") == 0)
 			canHash = TRUE;
-		else if (strcasecmp(defel->defname, "merges") == 0)
+		else if (pg_strcasecmp(defel->defname, "merges") == 0)
 			canMerge = TRUE;
-		else if (strcasecmp(defel->defname, "sort1") == 0)
+		else if (pg_strcasecmp(defel->defname, "sort1") == 0)
 			leftSortName = defGetQualifiedName(defel);
-		else if (strcasecmp(defel->defname, "sort2") == 0)
+		else if (pg_strcasecmp(defel->defname, "sort2") == 0)
 			rightSortName = defGetQualifiedName(defel);
-		else if (strcasecmp(defel->defname, "ltcmp") == 0)
+		else if (pg_strcasecmp(defel->defname, "ltcmp") == 0)
 			ltCompareName = defGetQualifiedName(defel);
-		else if (strcasecmp(defel->defname, "gtcmp") == 0)
+		else if (pg_strcasecmp(defel->defname, "gtcmp") == 0)
 			gtCompareName = defGetQualifiedName(defel);
 		else
 			ereport(WARNING,
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index f19645a82604e664573efa8b8f3729fffe595a26..d74e1e7ab310e3a3b1d0ae34372061dd206b6d61 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.104 2004/05/06 16:10:57 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.105 2004/05/07 00:24:57 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -3126,13 +3126,13 @@ ATExecSetStorage(Relation rel, const char *colName, Node *newValue)
 	Assert(IsA(newValue, String));
 	storagemode = strVal(newValue);
 
-	if (strcasecmp(storagemode, "plain") == 0)
+	if (pg_strcasecmp(storagemode, "plain") == 0)
 		newstorage = 'p';
-	else if (strcasecmp(storagemode, "external") == 0)
+	else if (pg_strcasecmp(storagemode, "external") == 0)
 		newstorage = 'e';
-	else if (strcasecmp(storagemode, "extended") == 0)
+	else if (pg_strcasecmp(storagemode, "extended") == 0)
 		newstorage = 'x';
-	else if (strcasecmp(storagemode, "main") == 0)
+	else if (pg_strcasecmp(storagemode, "main") == 0)
 		newstorage = 'm';
 	else
 	{
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index d76e048a3e748b4d348e40bbd665a0121546e047..411ad725bc8fd83110fa526c9b89a7c22e20109a 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.54 2004/05/05 17:06:56 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.55 2004/05/07 00:24:57 tgl Exp $
  *
  * DESCRIPTION
  *	  The "DefineFoo" routines take the parse tree and pick out the
@@ -142,28 +142,28 @@ DefineType(List *names, List *parameters)
 	{
 		DefElem    *defel = (DefElem *) lfirst(pl);
 
-		if (strcasecmp(defel->defname, "internallength") == 0)
+		if (pg_strcasecmp(defel->defname, "internallength") == 0)
 			internalLength = defGetTypeLength(defel);
-		else if (strcasecmp(defel->defname, "externallength") == 0)
+		else if (pg_strcasecmp(defel->defname, "externallength") == 0)
 			;					/* ignored -- remove after 7.3 */
-		else if (strcasecmp(defel->defname, "input") == 0)
+		else if (pg_strcasecmp(defel->defname, "input") == 0)
 			inputName = defGetQualifiedName(defel);
-		else if (strcasecmp(defel->defname, "output") == 0)
+		else if (pg_strcasecmp(defel->defname, "output") == 0)
 			outputName = defGetQualifiedName(defel);
-		else if (strcasecmp(defel->defname, "receive") == 0)
+		else if (pg_strcasecmp(defel->defname, "receive") == 0)
 			receiveName = defGetQualifiedName(defel);
-		else if (strcasecmp(defel->defname, "send") == 0)
+		else if (pg_strcasecmp(defel->defname, "send") == 0)
 			sendName = defGetQualifiedName(defel);
-		else if (strcasecmp(defel->defname, "analyze") == 0 ||
-				 strcasecmp(defel->defname, "analyse") == 0)
+		else if (pg_strcasecmp(defel->defname, "analyze") == 0 ||
+				 pg_strcasecmp(defel->defname, "analyse") == 0)
 			analyzeName = defGetQualifiedName(defel);
-		else if (strcasecmp(defel->defname, "delimiter") == 0)
+		else if (pg_strcasecmp(defel->defname, "delimiter") == 0)
 		{
 			char	   *p = defGetString(defel);
 
 			delimiter = p[0];
 		}
-		else if (strcasecmp(defel->defname, "element") == 0)
+		else if (pg_strcasecmp(defel->defname, "element") == 0)
 		{
 			elemType = typenameTypeId(defGetTypeName(defel));
 			/* disallow arrays of pseudotypes */
@@ -173,11 +173,11 @@ DefineType(List *names, List *parameters)
 						 errmsg("array element type cannot be %s",
 								format_type_be(elemType))));
 		}
-		else if (strcasecmp(defel->defname, "default") == 0)
+		else if (pg_strcasecmp(defel->defname, "default") == 0)
 			defaultValue = defGetString(defel);
-		else if (strcasecmp(defel->defname, "passedbyvalue") == 0)
+		else if (pg_strcasecmp(defel->defname, "passedbyvalue") == 0)
 			byValue = true;
-		else if (strcasecmp(defel->defname, "alignment") == 0)
+		else if (pg_strcasecmp(defel->defname, "alignment") == 0)
 		{
 			char	   *a = defGetString(defel);
 
@@ -187,35 +187,35 @@ DefineType(List *names, List *parameters)
 			 * recognize translated type names as well as the nominal
 			 * form.
 			 */
-			if (strcasecmp(a, "double") == 0 ||
-				strcasecmp(a, "float8") == 0 ||
-				strcasecmp(a, "pg_catalog.float8") == 0)
+			if (pg_strcasecmp(a, "double") == 0 ||
+				pg_strcasecmp(a, "float8") == 0 ||
+				pg_strcasecmp(a, "pg_catalog.float8") == 0)
 				alignment = 'd';
-			else if (strcasecmp(a, "int4") == 0 ||
-					 strcasecmp(a, "pg_catalog.int4") == 0)
+			else if (pg_strcasecmp(a, "int4") == 0 ||
+					 pg_strcasecmp(a, "pg_catalog.int4") == 0)
 				alignment = 'i';
-			else if (strcasecmp(a, "int2") == 0 ||
-					 strcasecmp(a, "pg_catalog.int2") == 0)
+			else if (pg_strcasecmp(a, "int2") == 0 ||
+					 pg_strcasecmp(a, "pg_catalog.int2") == 0)
 				alignment = 's';
-			else if (strcasecmp(a, "char") == 0 ||
-					 strcasecmp(a, "pg_catalog.bpchar") == 0)
+			else if (pg_strcasecmp(a, "char") == 0 ||
+					 pg_strcasecmp(a, "pg_catalog.bpchar") == 0)
 				alignment = 'c';
 			else
 				ereport(ERROR,
 						(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 						 errmsg("alignment \"%s\" not recognized", a)));
 		}
-		else if (strcasecmp(defel->defname, "storage") == 0)
+		else if (pg_strcasecmp(defel->defname, "storage") == 0)
 		{
 			char	   *a = defGetString(defel);
 
-			if (strcasecmp(a, "plain") == 0)
+			if (pg_strcasecmp(a, "plain") == 0)
 				storage = 'p';
-			else if (strcasecmp(a, "external") == 0)
+			else if (pg_strcasecmp(a, "external") == 0)
 				storage = 'e';
-			else if (strcasecmp(a, "extended") == 0)
+			else if (pg_strcasecmp(a, "extended") == 0)
 				storage = 'x';
-			else if (strcasecmp(a, "main") == 0)
+			else if (pg_strcasecmp(a, "main") == 0)
 				storage = 'm';
 			else
 				ereport(ERROR,
diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c
index 14c408e0010f7d396dc6eaa2f339fd36b3718949..f83ce51baca796e319da2916e55dcb0d44548ae1 100644
--- a/src/backend/commands/variable.c
+++ b/src/backend/commands/variable.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/variable.c,v 1.93 2004/01/19 19:04:40 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/variable.c,v 1.94 2004/05/07 00:24:57 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -23,6 +23,7 @@
 #include "catalog/pg_shadow.h"
 #include "commands/variable.h"
 #include "miscadmin.h"
+#include "parser/scansup.h"
 #include "utils/builtins.h"
 #include "utils/guc.h"
 #include "utils/syscache.h"
@@ -82,22 +83,22 @@ assign_datestyle(const char *value, bool doit, GucSource source)
 
 		/* Ugh. Somebody ought to write a table driven version -- mjl */
 
-		if (strcasecmp(tok, "ISO") == 0)
+		if (pg_strcasecmp(tok, "ISO") == 0)
 		{
 			newDateStyle = USE_ISO_DATES;
 			scnt++;
 		}
-		else if (strcasecmp(tok, "SQL") == 0)
+		else if (pg_strcasecmp(tok, "SQL") == 0)
 		{
 			newDateStyle = USE_SQL_DATES;
 			scnt++;
 		}
-		else if (strncasecmp(tok, "POSTGRES", 8) == 0)
+		else if (pg_strncasecmp(tok, "POSTGRES", 8) == 0)
 		{
 			newDateStyle = USE_POSTGRES_DATES;
 			scnt++;
 		}
-		else if (strcasecmp(tok, "GERMAN") == 0)
+		else if (pg_strcasecmp(tok, "GERMAN") == 0)
 		{
 			newDateStyle = USE_GERMAN_DATES;
 			scnt++;
@@ -105,25 +106,25 @@ assign_datestyle(const char *value, bool doit, GucSource source)
 			if (ocnt == 0)
 				newDateOrder = DATEORDER_DMY;
 		}
-		else if (strcasecmp(tok, "YMD") == 0)
+		else if (pg_strcasecmp(tok, "YMD") == 0)
 		{
 			newDateOrder = DATEORDER_YMD;
 			ocnt++;
 		}
-		else if (strcasecmp(tok, "DMY") == 0 ||
-				 strncasecmp(tok, "EURO", 4) == 0)
+		else if (pg_strcasecmp(tok, "DMY") == 0 ||
+				 pg_strncasecmp(tok, "EURO", 4) == 0)
 		{
 			newDateOrder = DATEORDER_DMY;
 			ocnt++;
 		}
-		else if (strcasecmp(tok, "MDY") == 0 ||
-				 strcasecmp(tok, "US") == 0 ||
-				 strncasecmp(tok, "NONEURO", 7) == 0)
+		else if (pg_strcasecmp(tok, "MDY") == 0 ||
+				 pg_strcasecmp(tok, "US") == 0 ||
+				 pg_strncasecmp(tok, "NONEURO", 7) == 0)
 		{
 			newDateOrder = DATEORDER_MDY;
 			ocnt++;
 		}
-		else if (strcasecmp(tok, "DEFAULT") == 0)
+		else if (pg_strcasecmp(tok, "DEFAULT") == 0)
 		{
 			/*
 			 * Easiest way to get the current DEFAULT state is to fetch
@@ -321,8 +322,7 @@ clear_tz(void)
 static bool
 tzset_succeeded(const char *tz)
 {
-	char		tztmp[TZBUF_LEN];
-	char	   *cp;
+	char	   *tztmp;
 	int			tzval;
 
 	/*
@@ -339,9 +339,7 @@ tzset_succeeded(const char *tz)
 	 * Check for known spellings of "UTC".	Note we must downcase the
 	 * input before passing it to DecodePosixTimezone().
 	 */
-	StrNCpy(tztmp, tz, sizeof(tztmp));
-	for (cp = tztmp; *cp; cp++)
-		*cp = tolower((unsigned char) *cp);
+	tztmp = downcase_truncate_identifier(tz, strlen(tz), false);
 	if (DecodePosixTimezone(tztmp, &tzval) == 0)
 		if (tzval == 0)
 			return true;
@@ -410,7 +408,7 @@ assign_timezone(const char *value, bool doit, GucSource source)
 	/*
 	 * Check for INTERVAL 'foo'
 	 */
-	if (strncasecmp(value, "interval", 8) == 0)
+	if (pg_strncasecmp(value, "interval", 8) == 0)
 	{
 		const char *valueptr = value;
 		char	   *val;
@@ -474,7 +472,7 @@ assign_timezone(const char *value, bool doit, GucSource source)
 				HasCTZSet = true;
 			}
 		}
-		else if (strcasecmp(value, "UNKNOWN") == 0)
+		else if (pg_strcasecmp(value, "UNKNOWN") == 0)
 		{
 			/*
 			 * UNKNOWN is the value shown as the "default" for TimeZone in
diff --git a/src/backend/regex/regc_locale.c b/src/backend/regex/regc_locale.c
index d3a7f3d12597e0079deb1a3d0f1c31b3c96abfe1..06c5f46a128f316d14727562046147b2a5de4f15 100644
--- a/src/backend/regex/regc_locale.c
+++ b/src/backend/regex/regc_locale.c
@@ -47,7 +47,7 @@
  * permission to use and distribute the software in accordance with the
  * terms specified in this license.
  *
- * $PostgreSQL: pgsql/src/backend/regex/regc_locale.c,v 1.5 2003/11/29 19:51:55 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/regex/regc_locale.c,v 1.6 2004/05/07 00:24:57 tgl Exp $
  */
 
 /* ASCII character-name table */
@@ -353,61 +353,61 @@ static struct cname
  * some ctype functions with non-ascii-char guard
  */
 static int
-pg_isdigit(pg_wchar c)
+pg_wc_isdigit(pg_wchar c)
 {
 	return (c >= 0 && c <= UCHAR_MAX && isdigit((unsigned char) c));
 }
 
 static int
-pg_isalpha(pg_wchar c)
+pg_wc_isalpha(pg_wchar c)
 {
 	return (c >= 0 && c <= UCHAR_MAX && isalpha((unsigned char) c));
 }
 
 static int
-pg_isalnum(pg_wchar c)
+pg_wc_isalnum(pg_wchar c)
 {
 	return (c >= 0 && c <= UCHAR_MAX && isalnum((unsigned char) c));
 }
 
 static int
-pg_isupper(pg_wchar c)
+pg_wc_isupper(pg_wchar c)
 {
 	return (c >= 0 && c <= UCHAR_MAX && isupper((unsigned char) c));
 }
 
 static int
-pg_islower(pg_wchar c)
+pg_wc_islower(pg_wchar c)
 {
 	return (c >= 0 && c <= UCHAR_MAX && islower((unsigned char) c));
 }
 
 static int
-pg_isgraph(pg_wchar c)
+pg_wc_isgraph(pg_wchar c)
 {
 	return (c >= 0 && c <= UCHAR_MAX && isgraph((unsigned char) c));
 }
 
 static int
-pg_isprint(pg_wchar c)
+pg_wc_isprint(pg_wchar c)
 {
 	return (c >= 0 && c <= UCHAR_MAX && isprint((unsigned char) c));
 }
 
 static int
-pg_ispunct(pg_wchar c)
+pg_wc_ispunct(pg_wchar c)
 {
 	return (c >= 0 && c <= UCHAR_MAX && ispunct((unsigned char) c));
 }
 
 static int
-pg_isspace(pg_wchar c)
+pg_wc_isspace(pg_wchar c)
 {
 	return (c >= 0 && c <= UCHAR_MAX && isspace((unsigned char) c));
 }
 
 static pg_wchar
-pg_toupper(pg_wchar c)
+pg_wc_toupper(pg_wchar c)
 {
 	if (c >= 0 && c <= UCHAR_MAX)
 		return toupper((unsigned char) c);
@@ -415,7 +415,7 @@ pg_toupper(pg_wchar c)
 }
 
 static pg_wchar
-pg_tolower(pg_wchar c)
+pg_wc_tolower(pg_wchar c)
 {
 	if (c >= 0 && c <= UCHAR_MAX)
 		return tolower((unsigned char) c);
@@ -534,10 +534,10 @@ range(struct vars * v,			/* context */
 	for (c = a; c <= b; c++)
 	{
 		addchr(cv, c);
-		lc = pg_tolower((chr) c);
+		lc = pg_wc_tolower((chr) c);
 		if (c != lc)
 			addchr(cv, lc);
-		uc = pg_toupper((chr) c);
+		uc = pg_wc_toupper((chr) c);
 		if (c != uc)
 			addchr(cv, uc);
 	}
@@ -668,7 +668,7 @@ cclass(struct vars * v,			/* context */
 			{
 				for (i = 0; i <= UCHAR_MAX; i++)
 				{
-					if (pg_isprint((chr) i))
+					if (pg_wc_isprint((chr) i))
 						addchr(cv, (chr) i);
 				}
 			}
@@ -679,7 +679,7 @@ cclass(struct vars * v,			/* context */
 			{
 				for (i = 0; i <= UCHAR_MAX; i++)
 				{
-					if (pg_isalnum((chr) i))
+					if (pg_wc_isalnum((chr) i))
 						addchr(cv, (chr) i);
 				}
 			}
@@ -690,7 +690,7 @@ cclass(struct vars * v,			/* context */
 			{
 				for (i = 0; i <= UCHAR_MAX; i++)
 				{
-					if (pg_isalpha((chr) i))
+					if (pg_wc_isalpha((chr) i))
 						addchr(cv, (chr) i);
 				}
 			}
@@ -721,7 +721,7 @@ cclass(struct vars * v,			/* context */
 			{
 				for (i = 0; i <= UCHAR_MAX; i++)
 				{
-					if (pg_ispunct((chr) i))
+					if (pg_wc_ispunct((chr) i))
 						addchr(cv, (chr) i);
 				}
 			}
@@ -741,7 +741,7 @@ cclass(struct vars * v,			/* context */
 			{
 				for (i = 0; i <= UCHAR_MAX; i++)
 				{
-					if (pg_isspace((chr) i))
+					if (pg_wc_isspace((chr) i))
 						addchr(cv, (chr) i);
 				}
 			}
@@ -752,7 +752,7 @@ cclass(struct vars * v,			/* context */
 			{
 				for (i = 0; i <= UCHAR_MAX; i++)
 				{
-					if (pg_islower((chr) i))
+					if (pg_wc_islower((chr) i))
 						addchr(cv, (chr) i);
 				}
 			}
@@ -763,7 +763,7 @@ cclass(struct vars * v,			/* context */
 			{
 				for (i = 0; i <= UCHAR_MAX; i++)
 				{
-					if (pg_isupper((chr) i))
+					if (pg_wc_isupper((chr) i))
 						addchr(cv, (chr) i);
 				}
 			}
@@ -774,7 +774,7 @@ cclass(struct vars * v,			/* context */
 			{
 				for (i = 0; i <= UCHAR_MAX; i++)
 				{
-					if (pg_isgraph((chr) i))
+					if (pg_wc_isgraph((chr) i))
 						addchr(cv, (chr) i);
 				}
 			}
@@ -800,8 +800,8 @@ allcases(struct vars * v,		/* context */
 	chr			lc,
 				uc;
 
-	lc = pg_tolower((chr) c);
-	uc = pg_toupper((chr) c);
+	lc = pg_wc_tolower((chr) c);
+	uc = pg_wc_toupper((chr) c);
 
 	cv = getcvec(v, 2, 0, 0);
 	addchr(cv, lc);
@@ -839,7 +839,7 @@ casecmp(const chr *x, const chr *y,		/* strings to compare */
 {
 	for (; len > 0; len--, x++, y++)
 	{
-		if ((*x != *y) && (pg_tolower(*x) != pg_tolower(*y)))
+		if ((*x != *y) && (pg_wc_tolower(*x) != pg_wc_tolower(*y)))
 			return 1;
 	}
 	return 0;
diff --git a/src/backend/regex/regcomp.c b/src/backend/regex/regcomp.c
index 4ace0f086e3ea3673ef2484b513fda3e7b02576b..9d350683fcc5b8209bfb6f3e025250641ed77985 100644
--- a/src/backend/regex/regcomp.c
+++ b/src/backend/regex/regcomp.c
@@ -28,7 +28,7 @@
  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $PostgreSQL: pgsql/src/backend/regex/regcomp.c,v 1.40 2003/11/29 19:51:55 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/regex/regcomp.c,v 1.41 2004/05/07 00:24:57 tgl Exp $
  *
  */
 
@@ -178,17 +178,17 @@ static struct cvec *getcvec(struct vars *, int, int, int);
 static void freecvec(struct cvec *);
 
 /* === regc_locale.c === */
-static int	pg_isdigit(pg_wchar c);
-static int	pg_isalpha(pg_wchar c);
-static int	pg_isalnum(pg_wchar c);
-static int	pg_isupper(pg_wchar c);
-static int	pg_islower(pg_wchar c);
-static int	pg_isgraph(pg_wchar c);
-static int	pg_isprint(pg_wchar c);
-static int	pg_ispunct(pg_wchar c);
-static int	pg_isspace(pg_wchar c);
-static pg_wchar pg_toupper(pg_wchar c);
-static pg_wchar pg_tolower(pg_wchar c);
+static int	pg_wc_isdigit(pg_wchar c);
+static int	pg_wc_isalpha(pg_wchar c);
+static int	pg_wc_isalnum(pg_wchar c);
+static int	pg_wc_isupper(pg_wchar c);
+static int	pg_wc_islower(pg_wchar c);
+static int	pg_wc_isgraph(pg_wchar c);
+static int	pg_wc_isprint(pg_wchar c);
+static int	pg_wc_ispunct(pg_wchar c);
+static int	pg_wc_isspace(pg_wchar c);
+static pg_wchar pg_wc_toupper(pg_wchar c);
+static pg_wchar pg_wc_tolower(pg_wchar c);
 static int	nmcces(struct vars *);
 static int	nleaders(struct vars *);
 static struct cvec *allmcces(struct vars *, struct cvec *);
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
index 5883c18878440b4bf2c761920b15621ef4acc812..214bda2245a8e0d3b92c11ce8bb297fb2292cb94 100644
--- a/src/backend/utils/adt/acl.c
+++ b/src/backend/utils/adt/acl.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.103 2004/05/02 13:38:27 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.104 2004/05/07 00:24:57 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -882,29 +882,29 @@ convert_priv_string(text *priv_type_text)
 	priv_type = DatumGetCString(DirectFunctionCall1(textout,
 									   PointerGetDatum(priv_type_text)));
 
-	if (strcasecmp(priv_type, "SELECT") == 0)
+	if (pg_strcasecmp(priv_type, "SELECT") == 0)
 		return ACL_SELECT;
-	if (strcasecmp(priv_type, "INSERT") == 0)
+	if (pg_strcasecmp(priv_type, "INSERT") == 0)
 		return ACL_INSERT;
-	if (strcasecmp(priv_type, "UPDATE") == 0)
+	if (pg_strcasecmp(priv_type, "UPDATE") == 0)
 		return ACL_UPDATE;
-	if (strcasecmp(priv_type, "DELETE") == 0)
+	if (pg_strcasecmp(priv_type, "DELETE") == 0)
 		return ACL_DELETE;
-	if (strcasecmp(priv_type, "RULE") == 0)
+	if (pg_strcasecmp(priv_type, "RULE") == 0)
 		return ACL_RULE;
-	if (strcasecmp(priv_type, "REFERENCES") == 0)
+	if (pg_strcasecmp(priv_type, "REFERENCES") == 0)
 		return ACL_REFERENCES;
-	if (strcasecmp(priv_type, "TRIGGER") == 0)
+	if (pg_strcasecmp(priv_type, "TRIGGER") == 0)
 		return ACL_TRIGGER;
-	if (strcasecmp(priv_type, "EXECUTE") == 0)
+	if (pg_strcasecmp(priv_type, "EXECUTE") == 0)
 		return ACL_EXECUTE;
-	if (strcasecmp(priv_type, "USAGE") == 0)
+	if (pg_strcasecmp(priv_type, "USAGE") == 0)
 		return ACL_USAGE;
-	if (strcasecmp(priv_type, "CREATE") == 0)
+	if (pg_strcasecmp(priv_type, "CREATE") == 0)
 		return ACL_CREATE;
-	if (strcasecmp(priv_type, "TEMP") == 0)
+	if (pg_strcasecmp(priv_type, "TEMP") == 0)
 		return ACL_CREATE_TEMP;
-	if (strcasecmp(priv_type, "TEMPORARY") == 0)
+	if (pg_strcasecmp(priv_type, "TEMPORARY") == 0)
 		return ACL_CREATE_TEMP;
 
 	ereport(ERROR,
@@ -1097,39 +1097,39 @@ convert_table_priv_string(text *priv_type_text)
 	/*
 	 * Return mode from priv_type string
 	 */
-	if (strcasecmp(priv_type, "SELECT") == 0)
+	if (pg_strcasecmp(priv_type, "SELECT") == 0)
 		return ACL_SELECT;
-	if (strcasecmp(priv_type, "SELECT WITH GRANT OPTION") == 0)
+	if (pg_strcasecmp(priv_type, "SELECT WITH GRANT OPTION") == 0)
 		return ACL_GRANT_OPTION_FOR(ACL_SELECT);
 
-	if (strcasecmp(priv_type, "INSERT") == 0)
+	if (pg_strcasecmp(priv_type, "INSERT") == 0)
 		return ACL_INSERT;
-	if (strcasecmp(priv_type, "INSERT WITH GRANT OPTION") == 0)
+	if (pg_strcasecmp(priv_type, "INSERT WITH GRANT OPTION") == 0)
 		return ACL_GRANT_OPTION_FOR(ACL_INSERT);
 
-	if (strcasecmp(priv_type, "UPDATE") == 0)
+	if (pg_strcasecmp(priv_type, "UPDATE") == 0)
 		return ACL_UPDATE;
-	if (strcasecmp(priv_type, "UPDATE WITH GRANT OPTION") == 0)
+	if (pg_strcasecmp(priv_type, "UPDATE WITH GRANT OPTION") == 0)
 		return ACL_GRANT_OPTION_FOR(ACL_UPDATE);
 
-	if (strcasecmp(priv_type, "DELETE") == 0)
+	if (pg_strcasecmp(priv_type, "DELETE") == 0)
 		return ACL_DELETE;
-	if (strcasecmp(priv_type, "DELETE WITH GRANT OPTION") == 0)
+	if (pg_strcasecmp(priv_type, "DELETE WITH GRANT OPTION") == 0)
 		return ACL_GRANT_OPTION_FOR(ACL_DELETE);
 
-	if (strcasecmp(priv_type, "RULE") == 0)
+	if (pg_strcasecmp(priv_type, "RULE") == 0)
 		return ACL_RULE;
-	if (strcasecmp(priv_type, "RULE WITH GRANT OPTION") == 0)
+	if (pg_strcasecmp(priv_type, "RULE WITH GRANT OPTION") == 0)
 		return ACL_GRANT_OPTION_FOR(ACL_RULE);
 
-	if (strcasecmp(priv_type, "REFERENCES") == 0)
+	if (pg_strcasecmp(priv_type, "REFERENCES") == 0)
 		return ACL_REFERENCES;
-	if (strcasecmp(priv_type, "REFERENCES WITH GRANT OPTION") == 0)
+	if (pg_strcasecmp(priv_type, "REFERENCES WITH GRANT OPTION") == 0)
 		return ACL_GRANT_OPTION_FOR(ACL_REFERENCES);
 
-	if (strcasecmp(priv_type, "TRIGGER") == 0)
+	if (pg_strcasecmp(priv_type, "TRIGGER") == 0)
 		return ACL_TRIGGER;
-	if (strcasecmp(priv_type, "TRIGGER WITH GRANT OPTION") == 0)
+	if (pg_strcasecmp(priv_type, "TRIGGER WITH GRANT OPTION") == 0)
 		return ACL_GRANT_OPTION_FOR(ACL_TRIGGER);
 
 	ereport(ERROR,
@@ -1329,19 +1329,19 @@ convert_database_priv_string(text *priv_type_text)
 	/*
 	 * Return mode from priv_type string
 	 */
-	if (strcasecmp(priv_type, "CREATE") == 0)
+	if (pg_strcasecmp(priv_type, "CREATE") == 0)
 		return ACL_CREATE;
-	if (strcasecmp(priv_type, "CREATE WITH GRANT OPTION") == 0)
+	if (pg_strcasecmp(priv_type, "CREATE WITH GRANT OPTION") == 0)
 		return ACL_GRANT_OPTION_FOR(ACL_CREATE);
 
-	if (strcasecmp(priv_type, "TEMPORARY") == 0)
+	if (pg_strcasecmp(priv_type, "TEMPORARY") == 0)
 		return ACL_CREATE_TEMP;
-	if (strcasecmp(priv_type, "TEMPORARY WITH GRANT OPTION") == 0)
+	if (pg_strcasecmp(priv_type, "TEMPORARY WITH GRANT OPTION") == 0)
 		return ACL_GRANT_OPTION_FOR(ACL_CREATE_TEMP);
 
-	if (strcasecmp(priv_type, "TEMP") == 0)
+	if (pg_strcasecmp(priv_type, "TEMP") == 0)
 		return ACL_CREATE_TEMP;
-	if (strcasecmp(priv_type, "TEMP WITH GRANT OPTION") == 0)
+	if (pg_strcasecmp(priv_type, "TEMP WITH GRANT OPTION") == 0)
 		return ACL_GRANT_OPTION_FOR(ACL_CREATE_TEMP);
 
 	ereport(ERROR,
@@ -1543,9 +1543,9 @@ convert_function_priv_string(text *priv_type_text)
 	/*
 	 * Return mode from priv_type string
 	 */
-	if (strcasecmp(priv_type, "EXECUTE") == 0)
+	if (pg_strcasecmp(priv_type, "EXECUTE") == 0)
 		return ACL_EXECUTE;
-	if (strcasecmp(priv_type, "EXECUTE WITH GRANT OPTION") == 0)
+	if (pg_strcasecmp(priv_type, "EXECUTE WITH GRANT OPTION") == 0)
 		return ACL_GRANT_OPTION_FOR(ACL_EXECUTE);
 
 	ereport(ERROR,
@@ -1747,9 +1747,9 @@ convert_language_priv_string(text *priv_type_text)
 	/*
 	 * Return mode from priv_type string
 	 */
-	if (strcasecmp(priv_type, "USAGE") == 0)
+	if (pg_strcasecmp(priv_type, "USAGE") == 0)
 		return ACL_USAGE;
-	if (strcasecmp(priv_type, "USAGE WITH GRANT OPTION") == 0)
+	if (pg_strcasecmp(priv_type, "USAGE WITH GRANT OPTION") == 0)
 		return ACL_GRANT_OPTION_FOR(ACL_USAGE);
 
 	ereport(ERROR,
@@ -1951,14 +1951,14 @@ convert_schema_priv_string(text *priv_type_text)
 	/*
 	 * Return mode from priv_type string
 	 */
-	if (strcasecmp(priv_type, "CREATE") == 0)
+	if (pg_strcasecmp(priv_type, "CREATE") == 0)
 		return ACL_CREATE;
-	if (strcasecmp(priv_type, "CREATE WITH GRANT OPTION") == 0)
+	if (pg_strcasecmp(priv_type, "CREATE WITH GRANT OPTION") == 0)
 		return ACL_GRANT_OPTION_FOR(ACL_CREATE);
 
-	if (strcasecmp(priv_type, "USAGE") == 0)
+	if (pg_strcasecmp(priv_type, "USAGE") == 0)
 		return ACL_USAGE;
-	if (strcasecmp(priv_type, "USAGE WITH GRANT OPTION") == 0)
+	if (pg_strcasecmp(priv_type, "USAGE WITH GRANT OPTION") == 0)
 		return ACL_GRANT_OPTION_FOR(ACL_USAGE);
 
 	ereport(ERROR,
diff --git a/src/backend/utils/adt/bool.c b/src/backend/utils/adt/bool.c
index 05f03c2634479e270ca5d469812e211883a01492..ddb8c923591f65219036dd06f071f035b3fa0244 100644
--- a/src/backend/utils/adt/bool.c
+++ b/src/backend/utils/adt/bool.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/bool.c,v 1.31 2003/11/29 19:51:58 pgsql Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/bool.c,v 1.32 2004/05/07 00:24:58 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -39,35 +39,35 @@ boolin(PG_FUNCTION_ARGS)
 	{
 		case 't':
 		case 'T':
-			if (strncasecmp(b, "true", strlen(b)) == 0)
+			if (pg_strncasecmp(b, "true", strlen(b)) == 0)
 				PG_RETURN_BOOL(true);
 			break;
 
 		case 'f':
 		case 'F':
-			if (strncasecmp(b, "false", strlen(b)) == 0)
+			if (pg_strncasecmp(b, "false", strlen(b)) == 0)
 				PG_RETURN_BOOL(false);
 			break;
 
 		case 'y':
 		case 'Y':
-			if (strncasecmp(b, "yes", strlen(b)) == 0)
+			if (pg_strncasecmp(b, "yes", strlen(b)) == 0)
 				PG_RETURN_BOOL(true);
 			break;
 
 		case '1':
-			if (strncasecmp(b, "1", strlen(b)) == 0)
+			if (pg_strncasecmp(b, "1", strlen(b)) == 0)
 				PG_RETURN_BOOL(true);
 			break;
 
 		case 'n':
 		case 'N':
-			if (strncasecmp(b, "no", strlen(b)) == 0)
+			if (pg_strncasecmp(b, "no", strlen(b)) == 0)
 				PG_RETURN_BOOL(false);
 			break;
 
 		case '0':
-			if (strncasecmp(b, "0", strlen(b)) == 0)
+			if (pg_strncasecmp(b, "0", strlen(b)) == 0)
 				PG_RETURN_BOOL(false);
 			break;
 
diff --git a/src/backend/utils/adt/cash.c b/src/backend/utils/adt/cash.c
index dfe8331b0100a36b0d7b240f2b1c098cc8f3de25..166decb74e473085ed4e3e2e176da7618b031d25 100644
--- a/src/backend/utils/adt/cash.c
+++ b/src/backend/utils/adt/cash.c
@@ -9,7 +9,7 @@
  * workings can be found in the book "Software Solutions in C" by
  * Dale Schumacher, Academic Press, ISBN: 0-12-632360-7.
  *
- * $PostgreSQL: pgsql/src/backend/utils/adt/cash.c,v 1.62 2003/11/29 19:51:58 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/cash.c,v 1.63 2004/05/07 00:24:58 tgl Exp $
  */
 
 #include "postgres.h"
@@ -745,7 +745,7 @@ cash_words(PG_FUNCTION_ARGS)
 	strcat(buf, m0 == 1 ? " cent" : " cents");
 
 	/* capitalize output */
-	buf[0] = toupper((unsigned char) buf[0]);
+	buf[0] = pg_toupper((unsigned char) buf[0]);
 
 	/* make a text type for output */
 	result = (text *) palloc(strlen(buf) + VARHDRSZ);
diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c
index 9346f2ab68c997bf6b5914df1aecba7b74f74e57..555ba5455adcc0dd52d80fd95a3412c033583340 100644
--- a/src/backend/utils/adt/date.c
+++ b/src/backend/utils/adt/date.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.95 2004/02/14 20:16:17 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.96 2004/05/07 00:24:58 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -23,6 +23,7 @@
 #include "access/hash.h"
 #include "libpq/pqformat.h"
 #include "miscadmin.h"
+#include "parser/scansup.h"
 #include "utils/builtins.h"
 #include "utils/date.h"
 #include "utils/nabstime.h"
@@ -1627,23 +1628,11 @@ time_part(PG_FUNCTION_ARGS)
 	float8		result;
 	int			type,
 				val;
-	int			i;
-	char	   *up,
-			   *lp,
-				lowunits[MAXDATELEN + 1];
-
-	if (VARSIZE(units) - VARHDRSZ > MAXDATELEN)
-		ereport(ERROR,
-				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-				 errmsg("\"time\" units \"%s\" not recognized",
-						DatumGetCString(DirectFunctionCall1(textout,
-											 PointerGetDatum(units))))));
+	char	   *lowunits;
 
-	up = VARDATA(units);
-	lp = lowunits;
-	for (i = 0; i < (VARSIZE(units) - VARHDRSZ); i++)
-		*lp++ = tolower((unsigned char) *up++);
-	*lp = '\0';
+	lowunits = downcase_truncate_identifier(VARDATA(units),
+											VARSIZE(units) - VARHDRSZ,
+											false);
 
 	type = DecodeUnits(0, lowunits, &val);
 	if (type == UNKNOWN_FIELD)
@@ -2390,23 +2379,11 @@ timetz_part(PG_FUNCTION_ARGS)
 	float8		result;
 	int			type,
 				val;
-	int			i;
-	char	   *up,
-			   *lp,
-				lowunits[MAXDATELEN + 1];
-
-	if (VARSIZE(units) - VARHDRSZ > MAXDATELEN)
-		ereport(ERROR,
-				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-				 errmsg("\"time with time zone\" units \"%s\" not recognized",
-						DatumGetCString(DirectFunctionCall1(textout,
-											 PointerGetDatum(units))))));
+	char	   *lowunits;
 
-	up = VARDATA(units);
-	lp = lowunits;
-	for (i = 0; i < (VARSIZE(units) - VARHDRSZ); i++)
-		*lp++ = tolower((unsigned char) *up++);
-	*lp = '\0';
+	lowunits = downcase_truncate_identifier(VARDATA(units),
+											VARSIZE(units) - VARHDRSZ,
+											false);
 
 	type = DecodeUnits(0, lowunits, &val);
 	if (type == UNKNOWN_FIELD)
@@ -2523,23 +2500,11 @@ timetz_zone(PG_FUNCTION_ARGS)
 	int			tz;
 	int			type,
 				val;
-	int			i;
-	char	   *up,
-			   *lp,
-				lowzone[MAXDATELEN + 1];
-
-	if (VARSIZE(zone) - VARHDRSZ > MAXDATELEN)
-		ereport(ERROR,
-				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-				 errmsg("time zone \"%s\" not recognized",
-						DatumGetCString(DirectFunctionCall1(textout,
-											  PointerGetDatum(zone))))));
+	char	   *lowzone;
 
-	up = VARDATA(zone);
-	lp = lowzone;
-	for (i = 0; i < (VARSIZE(zone) - VARHDRSZ); i++)
-		*lp++ = tolower((unsigned char) *up++);
-	*lp = '\0';
+	lowzone = downcase_truncate_identifier(VARDATA(zone),
+										   VARSIZE(zone) - VARHDRSZ,
+										   false);
 
 	type = DecodeSpecial(0, lowzone, &val);
 
diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c
index be764ce45e287368734ca90e5119415eb86ea37c..040e1691daf4a0bc3b6b3a93d49036e281645a5d 100644
--- a/src/backend/utils/adt/datetime.c
+++ b/src/backend/utils/adt/datetime.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.126 2004/03/30 15:53:18 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.127 2004/05/07 00:24:58 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -794,7 +794,7 @@ ParseDateTime(const char *timestr, char *lowstr,
 				{
 					ftype[nf] = DTK_DATE;
 					while (isalnum((unsigned char) *cp) || (*cp == delim))
-						*lp++ = tolower((unsigned char) *cp++);
+						*lp++ = pg_tolower((unsigned char) *cp++);
 				}
 			}
 
@@ -822,9 +822,9 @@ ParseDateTime(const char *timestr, char *lowstr,
 		else if (isalpha((unsigned char) *cp))
 		{
 			ftype[nf] = DTK_STRING;
-			*lp++ = tolower((unsigned char) *cp++);
+			*lp++ = pg_tolower((unsigned char) *cp++);
 			while (isalpha((unsigned char) *cp))
-				*lp++ = tolower((unsigned char) *cp++);
+				*lp++ = pg_tolower((unsigned char) *cp++);
 
 			/*
 			 * Full date string with leading text month? Could also be a
@@ -860,9 +860,9 @@ ParseDateTime(const char *timestr, char *lowstr,
 			else if (isalpha((unsigned char) *cp))
 			{
 				ftype[nf] = DTK_SPECIAL;
-				*lp++ = tolower((unsigned char) *cp++);
+				*lp++ = pg_tolower((unsigned char) *cp++);
 				while (isalpha((unsigned char) *cp))
-					*lp++ = tolower((unsigned char) *cp++);
+					*lp++ = pg_tolower((unsigned char) *cp++);
 			}
 			/* otherwise something wrong... */
 			else
diff --git a/src/backend/utils/adt/encode.c b/src/backend/utils/adt/encode.c
index e7edc83f6fd4887ecacb3bc5d2a4603d70d5fb00..488afa09666d1a33924717db6306d93ea5a11c27 100644
--- a/src/backend/utils/adt/encode.c
+++ b/src/backend/utils/adt/encode.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/encode.c,v 1.10 2003/11/29 19:51:58 pgsql Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/encode.c,v 1.11 2004/05/07 00:24:58 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -549,7 +549,7 @@ pg_find_encoding(const char *name)
 	int			i;
 
 	for (i = 0; enclist[i].name; i++)
-		if (strcasecmp(enclist[i].name, name) == 0)
+		if (pg_strcasecmp(enclist[i].name, name) == 0)
 			return &enclist[i].enc;
 
 	return NULL;
diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c
index a903249215569bcf69ff11a290893273c2ba97cb..c48af109e3ea25f914b9819972721e1fa97414e2 100644
--- a/src/backend/utils/adt/float.c
+++ b/src/backend/utils/adt/float.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.103 2004/04/01 23:52:18 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.104 2004/05/07 00:24:58 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -291,17 +291,17 @@ float4in(PG_FUNCTION_ARGS)
 		 * set ERANGE anyway...)  Therefore, we check for these inputs
 		 * ourselves.
 		 */
-		if (strncasecmp(num, "NaN", 3) == 0)
+		if (pg_strncasecmp(num, "NaN", 3) == 0)
 		{
 			val = get_float4_nan();
 			endptr = num + 3;
 		}
-		else if (strncasecmp(num, "Infinity", 8) == 0)
+		else if (pg_strncasecmp(num, "Infinity", 8) == 0)
 		{
 			val = get_float4_infinity();
 			endptr = num + 8;
 		}
-		else if (strncasecmp(num, "-Infinity", 9) == 0)
+		else if (pg_strncasecmp(num, "-Infinity", 9) == 0)
 		{
 			val = - get_float4_infinity();
 			endptr = num + 9;
@@ -456,17 +456,17 @@ float8in(PG_FUNCTION_ARGS)
 		 * set ERANGE anyway...)  Therefore, we check for these inputs
 		 * ourselves.
 		 */
-		if (strncasecmp(num, "NaN", 3) == 0)
+		if (pg_strncasecmp(num, "NaN", 3) == 0)
 		{
 			val = get_float8_nan();
 			endptr = num + 3;
 		}
-		else if (strncasecmp(num, "Infinity", 8) == 0)
+		else if (pg_strncasecmp(num, "Infinity", 8) == 0)
 		{
 			val = get_float8_infinity();
 			endptr = num + 8;
 		}
-		else if (strncasecmp(num, "-Infinity", 9) == 0)
+		else if (pg_strncasecmp(num, "-Infinity", 9) == 0)
 		{
 			val = - get_float8_infinity();
 			endptr = num + 9;
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 3393a0ac4ce9682b945e15e2dfdde14b16c0f641..6a9f26e0001706e0bcb20d3a4565d0dbcfa3b77e 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -1,7 +1,7 @@
 /* -----------------------------------------------------------------------
  * formatting.c
  *
- * $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.73 2004/03/30 15:53:18 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.74 2004/05/07 00:24:58 tgl Exp $
  *
  *
  *	 Portions Copyright (c) 1999-2003, PostgreSQL Global Development Group
@@ -1477,7 +1477,7 @@ str_toupper(char *buff)
 
 	while (*p_buff)
 	{
-		*p_buff = toupper((unsigned char) *p_buff);
+		*p_buff = pg_toupper((unsigned char) *p_buff);
 		++p_buff;
 	}
 	return buff;
@@ -1497,7 +1497,7 @@ str_tolower(char *buff)
 
 	while (*p_buff)
 	{
-		*p_buff = tolower((unsigned char) *p_buff);
+		*p_buff = pg_tolower((unsigned char) *p_buff);
 		++p_buff;
 	}
 	return buff;
@@ -1523,9 +1523,9 @@ seq_search(char *name, char **array, int type, int max, int *len)
 
 	/* set first char */
 	if (type == ONE_UPPER || type == ALL_UPPER)
-		*name = toupper((unsigned char) *name);
+		*name = pg_toupper((unsigned char) *name);
 	else if (type == ALL_LOWER)
-		*name = tolower((unsigned char) *name);
+		*name = pg_tolower((unsigned char) *name);
 
 	for (last = 0, a = array; *a != NULL; a++)
 	{
@@ -1559,9 +1559,9 @@ seq_search(char *name, char **array, int type, int max, int *len)
 			if (i > last)
 			{
 				if (type == ONE_UPPER || type == ALL_LOWER)
-					*n = tolower((unsigned char) *n);
+					*n = pg_tolower((unsigned char) *n);
 				else if (type == ALL_UPPER)
-					*n = toupper((unsigned char) *n);
+					*n = pg_toupper((unsigned char) *n);
 				last = i;
 			}
 
@@ -2192,7 +2192,7 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
 
 		case DCH_month:
 			sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, months_full[tm->tm_mon - 1]);
-			*inout = tolower((unsigned char) *inout);
+			*inout = pg_tolower((unsigned char) *inout);
 			if (S_FM(suf))
 				return strlen(p_inout) - 1;
 			else
@@ -2209,7 +2209,7 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
 
 		case DCH_mon:
 			strcpy(inout, months[tm->tm_mon - 1]);
-			*inout = tolower((unsigned char) *inout);
+			*inout = pg_tolower((unsigned char) *inout);
 			return 2;
 
 		case DCH_MM:
@@ -2255,7 +2255,7 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
 
 		case DCH_day:
 			sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, days[tm->tm_wday]);
-			*inout = tolower((unsigned char) *inout);
+			*inout = pg_tolower((unsigned char) *inout);
 			if (S_FM(suf))
 				return strlen(p_inout) - 1;
 			else
@@ -2272,7 +2272,7 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
 
 		case DCH_dy:
 			strcpy(inout, days[tm->tm_wday]);
-			*inout = tolower((unsigned char) *inout);
+			*inout = pg_tolower((unsigned char) *inout);
 			return 2;
 
 		case DCH_DDD:
diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c
index 341bd9cc4c503f8c0a4331b5acc44d7d19688810..28390ee5c35ab6c518e90d18ff3732ff09fcb653 100644
--- a/src/backend/utils/adt/numeric.c
+++ b/src/backend/utils/adt/numeric.c
@@ -14,7 +14,7 @@
  * Copyright (c) 1998-2003, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.72 2004/03/15 03:29:22 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.73 2004/05/07 00:24:58 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -315,7 +315,7 @@ numeric_in(PG_FUNCTION_ARGS)
 	/*
 	 * Check for NaN
 	 */
-	if (strcasecmp(str, "NaN") == 0)
+	if (pg_strcasecmp(str, "NaN") == 0)
 		PG_RETURN_NUMERIC(make_result(&const_nan));
 
 	/*
diff --git a/src/backend/utils/adt/regexp.c b/src/backend/utils/adt/regexp.c
index cc26ab09d8ca076a81f72387713d17ed81a25580..6491bbca705195378ef0fafab6f411af4054dc06 100644
--- a/src/backend/utils/adt/regexp.c
+++ b/src/backend/utils/adt/regexp.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/regexp.c,v 1.52 2004/02/03 17:52:55 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/regexp.c,v 1.53 2004/05/07 00:24:58 tgl Exp $
  *
  *		Alistair Crooks added the code for the regex caching
  *		agc - cached the regular expressions used - there's a good chance
@@ -233,17 +233,17 @@ const char *
 assign_regex_flavor(const char *value,
 					bool doit, GucSource source)
 {
-	if (strcasecmp(value, "advanced") == 0)
+	if (pg_strcasecmp(value, "advanced") == 0)
 	{
 		if (doit)
 			regex_flavor = REG_ADVANCED;
 	}
-	else if (strcasecmp(value, "extended") == 0)
+	else if (pg_strcasecmp(value, "extended") == 0)
 	{
 		if (doit)
 			regex_flavor = REG_EXTENDED;
 	}
-	else if (strcasecmp(value, "basic") == 0)
+	else if (pg_strcasecmp(value, "basic") == 0)
 	{
 		if (doit)
 			regex_flavor = REG_BASIC;
diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index 40203161e7dd4fa3671f64c4af7d2bfea7d5c85a..fe2e7aa6cf86095f9d113c3c692a07ed216466de 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -13,7 +13,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/regproc.c,v 1.86 2004/01/31 05:09:40 neilc Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/regproc.c,v 1.87 2004/05/07 00:24:58 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1259,7 +1259,7 @@ parseNameAndArgTypes(const char *string, const char *caller,
 			*ptr2 = '\0';
 		}
 
-		if (allowNone && strcasecmp(typename, "none") == 0)
+		if (allowNone && pg_strcasecmp(typename, "none") == 0)
 		{
 			/* Special case for NONE */
 			typeid = InvalidOid;
diff --git a/src/backend/utils/adt/tid.c b/src/backend/utils/adt/tid.c
index 0914abaaad9d69404b886daaec4683cf8d4fcd1c..8433bc98c4df79dc97ee47a8c89f4347a72419bd 100644
--- a/src/backend/utils/adt/tid.c
+++ b/src/backend/utils/adt/tid.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/tid.c,v 1.42 2003/11/29 19:51:59 pgsql Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/tid.c,v 1.43 2004/05/07 00:24:58 tgl Exp $
  *
  * NOTES
  *	  input routine largely stolen from boxin().
@@ -218,7 +218,7 @@ currtid_for_view(Relation viewrel, ItemPointer tid)
 
 	for (i = 0; i < natts; i++)
 	{
-		if (strcasecmp(NameStr(att->attrs[i]->attname), "ctid") == 0)
+		if (strcmp(NameStr(att->attrs[i]->attname), "ctid") == 0)
 		{
 			if (att->attrs[i]->atttypid != TIDOID)
 				elog(ERROR, "ctid isn't of type TID");
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c
index b2628a3a6f6aa4ea8fea63951607cf6175c5191a..cd59b7f34ad079756f514fdac5643ec29b280f7e 100644
--- a/src/backend/utils/adt/timestamp.c
+++ b/src/backend/utils/adt/timestamp.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.104 2004/04/10 18:02:59 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.105 2004/05/07 00:24:58 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -26,6 +26,7 @@
 #include "catalog/pg_type.h"
 #include "libpq/pqformat.h"
 #include "miscadmin.h"
+#include "parser/scansup.h"
 #include "utils/array.h"
 #include "utils/builtins.h"
 
@@ -2699,32 +2700,20 @@ timestamp_trunc(PG_FUNCTION_ARGS)
 	Timestamp	result;
 	int			type,
 				val;
-	int			i;
-	char	   *up,
-			   *lp,
-				lowunits[MAXDATELEN + 1];
+	char	   *lowunits;
 	fsec_t		fsec;
 	struct tm	tt,
 			   *tm = &tt;
 
-	if (VARSIZE(units) - VARHDRSZ > MAXDATELEN)
-		ereport(ERROR,
-				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-				 errmsg("timestamp units \"%s\" not recognized",
-						DatumGetCString(DirectFunctionCall1(textout,
-											 PointerGetDatum(units))))));
+	if (TIMESTAMP_NOT_FINITE(timestamp))
+		PG_RETURN_TIMESTAMP(timestamp);
 
-	up = VARDATA(units);
-	lp = lowunits;
-	for (i = 0; i < (VARSIZE(units) - VARHDRSZ); i++)
-		*lp++ = tolower((unsigned char) *up++);
-	*lp = '\0';
+	lowunits = downcase_truncate_identifier(VARDATA(units),
+											VARSIZE(units) - VARHDRSZ,
+											false);
 
 	type = DecodeUnits(0, lowunits, &val);
 
-	if (TIMESTAMP_NOT_FINITE(timestamp))
-		PG_RETURN_TIMESTAMP(timestamp);
-
 	if (type == UNITS)
 	{
 		if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) != 0)
@@ -2814,32 +2803,21 @@ timestamptz_trunc(PG_FUNCTION_ARGS)
 	int			tz;
 	int			type,
 				val;
-	int			i;
-	char	   *up,
-			   *lp,
-				lowunits[MAXDATELEN + 1];
+	char	   *lowunits;
 	fsec_t		fsec;
 	char	   *tzn;
 	struct tm	tt,
 			   *tm = &tt;
 
-	if (VARSIZE(units) - VARHDRSZ > MAXDATELEN)
-		ereport(ERROR,
-				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-		   errmsg("timestamp with time zone units \"%s\" not recognized",
-				  DatumGetCString(DirectFunctionCall1(textout,
-											 PointerGetDatum(units))))));
-	up = VARDATA(units);
-	lp = lowunits;
-	for (i = 0; i < (VARSIZE(units) - VARHDRSZ); i++)
-		*lp++ = tolower((unsigned char) *up++);
-	*lp = '\0';
-
-	type = DecodeUnits(0, lowunits, &val);
-
 	if (TIMESTAMP_NOT_FINITE(timestamp))
 		PG_RETURN_TIMESTAMPTZ(timestamp);
 
+	lowunits = downcase_truncate_identifier(VARDATA(units),
+											VARSIZE(units) - VARHDRSZ,
+											false);
+
+	type = DecodeUnits(0, lowunits, &val);
+
 	if (type == UNITS)
 	{
 		if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn) != 0)
@@ -2929,27 +2907,16 @@ interval_trunc(PG_FUNCTION_ARGS)
 	Interval   *result;
 	int			type,
 				val;
-	int			i;
-	char	   *up,
-			   *lp,
-				lowunits[MAXDATELEN + 1];
+	char	   *lowunits;
 	fsec_t		fsec;
 	struct tm	tt,
 			   *tm = &tt;
 
 	result = (Interval *) palloc(sizeof(Interval));
 
-	if (VARSIZE(units) - VARHDRSZ > MAXDATELEN)
-		ereport(ERROR,
-				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-				 errmsg("interval units \"%s\" not recognized",
-						DatumGetCString(DirectFunctionCall1(textout,
-											 PointerGetDatum(units))))));
-	up = VARDATA(units);
-	lp = lowunits;
-	for (i = 0; i < (VARSIZE(units) - VARHDRSZ); i++)
-		*lp++ = tolower((unsigned char) *up++);
-	*lp = '\0';
+	lowunits = downcase_truncate_identifier(VARDATA(units),
+											VARSIZE(units) - VARHDRSZ,
+											false);
 
 	type = DecodeUnits(0, lowunits, &val);
 
@@ -3173,36 +3140,25 @@ timestamp_part(PG_FUNCTION_ARGS)
 	float8		result;
 	int			type,
 				val;
-	int			i;
-	char	   *up,
-			   *lp,
-				lowunits[MAXDATELEN + 1];
+	char	   *lowunits;
 	fsec_t		fsec;
 	struct tm	tt,
 			   *tm = &tt;
 
-	if (VARSIZE(units) - VARHDRSZ > MAXDATELEN)
-		ereport(ERROR,
-				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-				 errmsg("timestamp units \"%s\" not recognized",
-						DatumGetCString(DirectFunctionCall1(textout,
-											 PointerGetDatum(units))))));
-	up = VARDATA(units);
-	lp = lowunits;
-	for (i = 0; i < (VARSIZE(units) - VARHDRSZ); i++)
-		*lp++ = tolower((unsigned char) *up++);
-	*lp = '\0';
-
-	type = DecodeUnits(0, lowunits, &val);
-	if (type == UNKNOWN_FIELD)
-		type = DecodeSpecial(0, lowunits, &val);
-
 	if (TIMESTAMP_NOT_FINITE(timestamp))
 	{
 		result = 0;
 		PG_RETURN_FLOAT8(result);
 	}
 
+	lowunits = downcase_truncate_identifier(VARDATA(units),
+											VARSIZE(units) - VARHDRSZ,
+											false);
+
+	type = DecodeUnits(0, lowunits, &val);
+	if (type == UNKNOWN_FIELD)
+		type = DecodeSpecial(0, lowunits, &val);
+
 	if (type == UNITS)
 	{
 		if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) != 0)
@@ -3395,38 +3351,27 @@ timestamptz_part(PG_FUNCTION_ARGS)
 	int			tz;
 	int			type,
 				val;
-	int			i;
-	char	   *up,
-			   *lp,
-				lowunits[MAXDATELEN + 1];
+	char	   *lowunits;
 	double		dummy;
 	fsec_t		fsec;
 	char	   *tzn;
 	struct tm	tt,
 			   *tm = &tt;
 
-	if (VARSIZE(units) - VARHDRSZ > MAXDATELEN)
-		ereport(ERROR,
-				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-		   errmsg("timestamp with time zone units \"%s\" not recognized",
-				  DatumGetCString(DirectFunctionCall1(textout,
-											 PointerGetDatum(units))))));
-	up = VARDATA(units);
-	lp = lowunits;
-	for (i = 0; i < (VARSIZE(units) - VARHDRSZ); i++)
-		*lp++ = tolower((unsigned char) *up++);
-	*lp = '\0';
-
-	type = DecodeUnits(0, lowunits, &val);
-	if (type == UNKNOWN_FIELD)
-		type = DecodeSpecial(0, lowunits, &val);
-
 	if (TIMESTAMP_NOT_FINITE(timestamp))
 	{
 		result = 0;
 		PG_RETURN_FLOAT8(result);
 	}
 
+	lowunits = downcase_truncate_identifier(VARDATA(units),
+											VARSIZE(units) - VARHDRSZ,
+											false);
+
+	type = DecodeUnits(0, lowunits, &val);
+	if (type == UNKNOWN_FIELD)
+		type = DecodeSpecial(0, lowunits, &val);
+
 	if (type == UNITS)
 	{
 		if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn) != 0)
@@ -3597,25 +3542,14 @@ interval_part(PG_FUNCTION_ARGS)
 	float8		result;
 	int			type,
 				val;
-	int			i;
-	char	   *up,
-			   *lp,
-				lowunits[MAXDATELEN + 1];
+	char	   *lowunits;
 	fsec_t		fsec;
 	struct tm	tt,
 			   *tm = &tt;
 
-	if (VARSIZE(units) - VARHDRSZ > MAXDATELEN)
-		ereport(ERROR,
-				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-				 errmsg("interval units \"%s\" not recognized",
-						DatumGetCString(DirectFunctionCall1(textout,
-											 PointerGetDatum(units))))));
-	up = VARDATA(units);
-	lp = lowunits;
-	for (i = 0; i < (VARSIZE(units) - VARHDRSZ); i++)
-		*lp++ = tolower((unsigned char) *up++);
-	*lp = '\0';
+	lowunits = downcase_truncate_identifier(VARDATA(units),
+											VARSIZE(units) - VARHDRSZ,
+											false);
 
 	type = DecodeUnits(0, lowunits, &val);
 	if (type == UNKNOWN_FIELD)
@@ -3744,26 +3678,14 @@ timestamp_zone(PG_FUNCTION_ARGS)
 	int			tz;
 	int			type,
 				val;
-	int			i;
-	char	   *up,
-			   *lp,
-				lowzone[MAXDATELEN + 1];
-
-	if (VARSIZE(zone) - VARHDRSZ > MAXDATELEN)
-		ereport(ERROR,
-				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-				 errmsg("time zone \"%s\" not recognized",
-						DatumGetCString(DirectFunctionCall1(textout,
-											  PointerGetDatum(zone))))));
+	char	   *lowzone;
 
 	if (TIMESTAMP_NOT_FINITE(timestamp))
 		PG_RETURN_TIMESTAMPTZ(timestamp);
 
-	up = VARDATA(zone);
-	lp = lowzone;
-	for (i = 0; i < (VARSIZE(zone) - VARHDRSZ); i++)
-		*lp++ = tolower((unsigned char) *up++);
-	*lp = '\0';
+	lowzone = downcase_truncate_identifier(VARDATA(zone),
+										   VARSIZE(zone) - VARHDRSZ,
+										   false);
 
 	type = DecodeSpecial(0, lowzone, &val);
 
@@ -3903,28 +3825,17 @@ timestamptz_zone(PG_FUNCTION_ARGS)
 	int			tz;
 	int			type,
 				val;
-	int			i;
-	char	   *up,
-			   *lp,
-				lowzone[MAXDATELEN + 1];
-
-	if (VARSIZE(zone) - VARHDRSZ > MAXDATELEN)
-		ereport(ERROR,
-				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-				 errmsg("time zone \"%s\" not recognized",
-						DatumGetCString(DirectFunctionCall1(textout,
-											  PointerGetDatum(zone))))));
-	up = VARDATA(zone);
-	lp = lowzone;
-	for (i = 0; i < (VARSIZE(zone) - VARHDRSZ); i++)
-		*lp++ = tolower((unsigned char) *up++);
-	*lp = '\0';
-
-	type = DecodeSpecial(0, lowzone, &val);
+	char	   *lowzone;
 
 	if (TIMESTAMP_NOT_FINITE(timestamp))
 		PG_RETURN_NULL();
 
+	lowzone = downcase_truncate_identifier(VARDATA(zone),
+										   VARSIZE(zone) - VARHDRSZ,
+										   false);
+
+	type = DecodeSpecial(0, lowzone, &val);
+
 	if ((type == TZ) || (type == DTZ))
 	{
 		tz = val * 60;
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index 234bc4af39f39f1d34e4f8837a2e1035407198a8..012842b61d9d12dfdd9b020d2d4a4052b841c75c 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -37,7 +37,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.135 2004/04/22 03:51:09 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.136 2004/05/07 00:24:58 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1010,21 +1010,21 @@ write_syslog(int level, const char *line)
 
 	if (!openlog_done)
 	{
-		if (strcasecmp(Syslog_facility, "LOCAL0") == 0)
+		if (pg_strcasecmp(Syslog_facility, "LOCAL0") == 0)
 			syslog_fac = LOG_LOCAL0;
-		if (strcasecmp(Syslog_facility, "LOCAL1") == 0)
+		if (pg_strcasecmp(Syslog_facility, "LOCAL1") == 0)
 			syslog_fac = LOG_LOCAL1;
-		if (strcasecmp(Syslog_facility, "LOCAL2") == 0)
+		if (pg_strcasecmp(Syslog_facility, "LOCAL2") == 0)
 			syslog_fac = LOG_LOCAL2;
-		if (strcasecmp(Syslog_facility, "LOCAL3") == 0)
+		if (pg_strcasecmp(Syslog_facility, "LOCAL3") == 0)
 			syslog_fac = LOG_LOCAL3;
-		if (strcasecmp(Syslog_facility, "LOCAL4") == 0)
+		if (pg_strcasecmp(Syslog_facility, "LOCAL4") == 0)
 			syslog_fac = LOG_LOCAL4;
-		if (strcasecmp(Syslog_facility, "LOCAL5") == 0)
+		if (pg_strcasecmp(Syslog_facility, "LOCAL5") == 0)
 			syslog_fac = LOG_LOCAL5;
-		if (strcasecmp(Syslog_facility, "LOCAL6") == 0)
+		if (pg_strcasecmp(Syslog_facility, "LOCAL6") == 0)
 			syslog_fac = LOG_LOCAL6;
-		if (strcasecmp(Syslog_facility, "LOCAL7") == 0)
+		if (pg_strcasecmp(Syslog_facility, "LOCAL7") == 0)
 			syslog_fac = LOG_LOCAL7;
 		openlog(Syslog_ident, LOG_PID | LOG_NDELAY, syslog_fac);
 		openlog_done = true;
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 8c7106110cd636d26fab3b7e63bfef39fbe21407..d7961eff4219776e9c54d69c85e11045c7e2a397 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -10,7 +10,7 @@
  * Written by Peter Eisentraut <peter_e@gmx.net>.
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.201 2004/04/19 21:22:14 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.202 2004/05/07 00:24:58 tgl Exp $
  *
  *--------------------------------------------------------------------
  */
@@ -2443,45 +2443,45 @@ parse_bool(const char *value, bool *result)
 {
 	size_t		len = strlen(value);
 
-	if (strncasecmp(value, "true", len) == 0)
+	if (pg_strncasecmp(value, "true", len) == 0)
 	{
 		if (result)
 			*result = true;
 	}
-	else if (strncasecmp(value, "false", len) == 0)
+	else if (pg_strncasecmp(value, "false", len) == 0)
 	{
 		if (result)
 			*result = false;
 	}
 
-	else if (strncasecmp(value, "yes", len) == 0)
+	else if (pg_strncasecmp(value, "yes", len) == 0)
 	{
 		if (result)
 			*result = true;
 	}
-	else if (strncasecmp(value, "no", len) == 0)
+	else if (pg_strncasecmp(value, "no", len) == 0)
 	{
 		if (result)
 			*result = false;
 	}
 
-	else if (strcasecmp(value, "on") == 0)
+	else if (pg_strcasecmp(value, "on") == 0)
 	{
 		if (result)
 			*result = true;
 	}
-	else if (strcasecmp(value, "off") == 0)
+	else if (pg_strcasecmp(value, "off") == 0)
 	{
 		if (result)
 			*result = false;
 	}
 
-	else if (strcasecmp(value, "1") == 0)
+	else if (pg_strcasecmp(value, "1") == 0)
 	{
 		if (result)
 			*result = true;
 	}
-	else if (strcasecmp(value, "0") == 0)
+	else if (pg_strcasecmp(value, "0") == 0)
 	{
 		if (result)
 			*result = false;
@@ -3463,7 +3463,7 @@ set_config_by_name(PG_FUNCTION_ARGS)
 void
 GetPGVariable(const char *name, DestReceiver *dest)
 {
-	if (strcasecmp(name, "all") == 0)
+	if (pg_strcasecmp(name, "all") == 0)
 		ShowAllGUCConfig(dest);
 	else
 		ShowGUCConfigOption(name, dest);
@@ -3474,7 +3474,7 @@ GetPGVariableResultDesc(const char *name)
 {
 	TupleDesc	tupdesc;
 
-	if (strcasecmp(name, "all") == 0)
+	if (pg_strcasecmp(name, "all") == 0)
 	{
 		/* need a tuple descriptor representing two TEXT columns */
 		tupdesc = CreateTemplateTupleDesc(2, false);
@@ -3504,7 +3504,7 @@ GetPGVariableResultDesc(const char *name)
 void
 ResetPGVariable(const char *name)
 {
-	if (strcasecmp(name, "all") == 0)
+	if (pg_strcasecmp(name, "all") == 0)
 		ResetAllOptions();
 	else
 		set_config_option(name,
@@ -4455,14 +4455,14 @@ assign_log_destination(const char *value, bool doit, GucSource source)
 	{
 		char *tok = (char *) lfirst(l);
 	
-		if (strcasecmp(tok,"stderr") == 0)
+		if (pg_strcasecmp(tok,"stderr") == 0)
 			newlogdest |= LOG_DESTINATION_STDERR;
 #ifdef HAVE_SYSLOG
-		else if (strcasecmp(tok,"syslog") == 0)
+		else if (pg_strcasecmp(tok,"syslog") == 0)
 			newlogdest |= LOG_DESTINATION_SYSLOG;
 #endif
 #ifdef WIN32
-		else if (strcasecmp(tok,"eventlog") == 0)
+		else if (pg_strcasecmp(tok,"eventlog") == 0)
 			newlogdest |= LOG_DESTINATION_EVENTLOG;
 #endif
 		else {
@@ -4494,21 +4494,21 @@ assign_log_destination(const char *value, bool doit, GucSource source)
 static const char *
 assign_facility(const char *facility, bool doit, GucSource source)
 {
-	if (strcasecmp(facility, "LOCAL0") == 0)
+	if (pg_strcasecmp(facility, "LOCAL0") == 0)
 		return facility;
-	if (strcasecmp(facility, "LOCAL1") == 0)
+	if (pg_strcasecmp(facility, "LOCAL1") == 0)
 		return facility;
-	if (strcasecmp(facility, "LOCAL2") == 0)
+	if (pg_strcasecmp(facility, "LOCAL2") == 0)
 		return facility;
-	if (strcasecmp(facility, "LOCAL3") == 0)
+	if (pg_strcasecmp(facility, "LOCAL3") == 0)
 		return facility;
-	if (strcasecmp(facility, "LOCAL4") == 0)
+	if (pg_strcasecmp(facility, "LOCAL4") == 0)
 		return facility;
-	if (strcasecmp(facility, "LOCAL5") == 0)
+	if (pg_strcasecmp(facility, "LOCAL5") == 0)
 		return facility;
-	if (strcasecmp(facility, "LOCAL6") == 0)
+	if (pg_strcasecmp(facility, "LOCAL6") == 0)
 		return facility;
-	if (strcasecmp(facility, "LOCAL7") == 0)
+	if (pg_strcasecmp(facility, "LOCAL7") == 0)
 		return facility;
 	return NULL;
 }
@@ -4518,22 +4518,22 @@ assign_facility(const char *facility, bool doit, GucSource source)
 static const char *
 assign_defaultxactisolevel(const char *newval, bool doit, GucSource source)
 {
-	if (strcasecmp(newval, "serializable") == 0)
+	if (pg_strcasecmp(newval, "serializable") == 0)
 	{
 		if (doit)
 			DefaultXactIsoLevel = XACT_SERIALIZABLE;
 	}
-	else if (strcasecmp(newval, "repeatable read") == 0)
+	else if (pg_strcasecmp(newval, "repeatable read") == 0)
 	{
 		if (doit)
 			DefaultXactIsoLevel = XACT_REPEATABLE_READ;
 	}
-	else if (strcasecmp(newval, "read committed") == 0)
+	else if (pg_strcasecmp(newval, "read committed") == 0)
 	{
 		if (doit)
 			DefaultXactIsoLevel = XACT_READ_COMMITTED;
 	}
-	else if (strcasecmp(newval, "read uncommitted") == 0)
+	else if (pg_strcasecmp(newval, "read uncommitted") == 0)
 	{
 		if (doit)
 			DefaultXactIsoLevel = XACT_READ_UNCOMMITTED;
@@ -4566,68 +4566,68 @@ assign_min_error_statement(const char *newval, bool doit, GucSource source)
 static const char *
 assign_msglvl(int *var, const char *newval, bool doit, GucSource source)
 {
-	if (strcasecmp(newval, "debug") == 0)
+	if (pg_strcasecmp(newval, "debug") == 0)
 	{
 		if (doit)
 			(*var) = DEBUG2;
 	}
-	else if (strcasecmp(newval, "debug5") == 0)
+	else if (pg_strcasecmp(newval, "debug5") == 0)
 	{
 		if (doit)
 			(*var) = DEBUG5;
 	}
-	else if (strcasecmp(newval, "debug4") == 0)
+	else if (pg_strcasecmp(newval, "debug4") == 0)
 	{
 		if (doit)
 			(*var) = DEBUG4;
 	}
-	else if (strcasecmp(newval, "debug3") == 0)
+	else if (pg_strcasecmp(newval, "debug3") == 0)
 	{
 		if (doit)
 			(*var) = DEBUG3;
 	}
-	else if (strcasecmp(newval, "debug2") == 0)
+	else if (pg_strcasecmp(newval, "debug2") == 0)
 	{
 		if (doit)
 			(*var) = DEBUG2;
 	}
-	else if (strcasecmp(newval, "debug1") == 0)
+	else if (pg_strcasecmp(newval, "debug1") == 0)
 	{
 		if (doit)
 			(*var) = DEBUG1;
 	}
-	else if (strcasecmp(newval, "log") == 0)
+	else if (pg_strcasecmp(newval, "log") == 0)
 	{
 		if (doit)
 			(*var) = LOG;
 	}
-	else if (strcasecmp(newval, "info") == 0)
+	else if (pg_strcasecmp(newval, "info") == 0)
 	{
 		if (doit)
 			(*var) = INFO;
 	}
-	else if (strcasecmp(newval, "notice") == 0)
+	else if (pg_strcasecmp(newval, "notice") == 0)
 	{
 		if (doit)
 			(*var) = NOTICE;
 	}
-	else if (strcasecmp(newval, "warning") == 0)
+	else if (pg_strcasecmp(newval, "warning") == 0)
 	{
 		if (doit)
 			(*var) = WARNING;
 	}
-	else if (strcasecmp(newval, "error") == 0)
+	else if (pg_strcasecmp(newval, "error") == 0)
 	{
 		if (doit)
 			(*var) = ERROR;
 	}
 	/* We allow FATAL/PANIC for client-side messages too. */
-	else if (strcasecmp(newval, "fatal") == 0)
+	else if (pg_strcasecmp(newval, "fatal") == 0)
 	{
 		if (doit)
 			(*var) = FATAL;
 	}
-	else if (strcasecmp(newval, "panic") == 0)
+	else if (pg_strcasecmp(newval, "panic") == 0)
 	{
 		if (doit)
 			(*var) = PANIC;
@@ -4640,17 +4640,17 @@ assign_msglvl(int *var, const char *newval, bool doit, GucSource source)
 static const char *
 assign_log_error_verbosity(const char *newval, bool doit, GucSource source)
 {
-	if (strcasecmp(newval, "terse") == 0)
+	if (pg_strcasecmp(newval, "terse") == 0)
 	{
 		if (doit)
 			Log_error_verbosity = PGERROR_TERSE;
 	}
-	else if (strcasecmp(newval, "default") == 0)
+	else if (pg_strcasecmp(newval, "default") == 0)
 	{
 		if (doit)
 			Log_error_verbosity = PGERROR_DEFAULT;
 	}
-	else if (strcasecmp(newval, "verbose") == 0)
+	else if (pg_strcasecmp(newval, "verbose") == 0)
 	{
 		if (doit)
 			Log_error_verbosity = PGERROR_VERBOSE;
@@ -4669,22 +4669,22 @@ assign_log_statement(const char *newval, bool doit, GucSource source)
 static const char *
 assign_log_stmtlvl(int *var, const char *newval, bool doit, GucSource source)
 {
-	if (strcasecmp(newval, "none") == 0)
+	if (pg_strcasecmp(newval, "none") == 0)
 	{
 		if (doit)
 			(*var) = LOGSTMT_NONE;
 	}
-	else if (strcasecmp(newval, "mod") == 0)
+	else if (pg_strcasecmp(newval, "mod") == 0)
 	{
 		if (doit)
 			(*var) = LOGSTMT_MOD;
 	}
-	else if (strcasecmp(newval, "ddl") == 0)
+	else if (pg_strcasecmp(newval, "ddl") == 0)
 	{
 		if (doit)
 			(*var) = LOGSTMT_DDL;
 	}
-	else if (strcasecmp(newval, "all") == 0)
+	else if (pg_strcasecmp(newval, "all") == 0)
 	{
 		if (doit)
 			(*var) = LOGSTMT_ALL;
diff --git a/src/bin/pg_dump/pg_backup_tar.c b/src/bin/pg_dump/pg_backup_tar.c
index 047e25b621c69123714403885ad8fd297c8446cc..f472c9de02d7a5cc302603ce6e1eb445af0ef208 100644
--- a/src/bin/pg_dump/pg_backup_tar.c
+++ b/src/bin/pg_dump/pg_backup_tar.c
@@ -16,7 +16,7 @@
  *
  *
  * IDENTIFICATION
- *		$PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_tar.c,v 1.42 2004/03/03 21:28:54 tgl Exp $
+ *		$PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_tar.c,v 1.43 2004/05/07 00:24:58 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -627,7 +627,7 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt)
 		/* Get a copy of the COPY statement and clean it up */
 		tmpCopy = strdup(te->copyStmt);
 		for (i = 0; i < strlen(tmpCopy); i++)
-			tmpCopy[i] = tolower((unsigned char) tmpCopy[i]);
+			tmpCopy[i] = pg_tolower((unsigned char) tmpCopy[i]);
 
 		/*
 		 * This is very nasty; we don't know if the archive used WITH
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index d6727121b53020ff652cf27b728618936fe14c47..d880afbd2769199f56d6a4d5a471a0c3b0881600 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2000-2003, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.115 2004/03/27 18:01:40 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.116 2004/05/07 00:24:58 tgl Exp $
  */
 #include "postgres_fe.h"
 #include "command.h"
@@ -263,7 +263,7 @@ exec_command(const char *cmd,
 	}
 
 	/* \copy */
-	else if (strcasecmp(cmd, "copy") == 0)
+	else if (pg_strcasecmp(cmd, "copy") == 0)
 	{
 		char	   *opt = psql_scan_slash_option(scan_state,
 												 OT_WHOLE_LINE, NULL, false);
@@ -1321,13 +1321,13 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
 	{
 		if (!value)
 			;
-		else if (strncasecmp("unaligned", value, vallen) == 0)
+		else if (pg_strncasecmp("unaligned", value, vallen) == 0)
 			popt->topt.format = PRINT_UNALIGNED;
-		else if (strncasecmp("aligned", value, vallen) == 0)
+		else if (pg_strncasecmp("aligned", value, vallen) == 0)
 			popt->topt.format = PRINT_ALIGNED;
-		else if (strncasecmp("html", value, vallen) == 0)
+		else if (pg_strncasecmp("html", value, vallen) == 0)
 			popt->topt.format = PRINT_HTML;
-		else if (strncasecmp("latex", value, vallen) == 0)
+		else if (pg_strncasecmp("latex", value, vallen) == 0)
 			popt->topt.format = PRINT_LATEX;
 		else
 		{
@@ -1452,7 +1452,7 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
 	/* toggle use of pager */
 	else if (strcmp(param, "pager") == 0)
 	{
-		if (value && strcasecmp(value, "always") == 0)
+		if (value && pg_strcasecmp(value, "always") == 0)
 			popt->topt.pager = 2;
 		else if (popt->topt.pager == 1)
 			popt->topt.pager = 0;
diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c
index 3b1a1228c1e804752c72b99a00f419dd61586838..445064b0c40eac0aa4ae9625b51a69a7035a7bc9 100644
--- a/src/bin/psql/common.c
+++ b/src/bin/psql/common.c
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2000-2003, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/bin/psql/common.c,v 1.85 2004/03/21 22:29:11 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/common.c,v 1.86 2004/05/07 00:24:58 tgl Exp $
  */
 #include "postgres_fe.h"
 #include "common.h"
@@ -985,17 +985,17 @@ is_transact_command(const char *query)
 	while (isalpha((unsigned char) query[wordlen]))
 		wordlen++;
 
-	if (wordlen == 5 && strncasecmp(query, "begin", 5) == 0)
+	if (wordlen == 5 && pg_strncasecmp(query, "begin", 5) == 0)
 		return true;
-	if (wordlen == 6 && strncasecmp(query, "commit", 6) == 0)
+	if (wordlen == 6 && pg_strncasecmp(query, "commit", 6) == 0)
 		return true;
-	if (wordlen == 8 && strncasecmp(query, "rollback", 8) == 0)
+	if (wordlen == 8 && pg_strncasecmp(query, "rollback", 8) == 0)
 		return true;
-	if (wordlen == 5 && strncasecmp(query, "abort", 5) == 0)
+	if (wordlen == 5 && pg_strncasecmp(query, "abort", 5) == 0)
 		return true;
-	if (wordlen == 3 && strncasecmp(query, "end", 3) == 0)
+	if (wordlen == 3 && pg_strncasecmp(query, "end", 3) == 0)
 		return true;
-	if (wordlen == 5 && strncasecmp(query, "start", 5) == 0)
+	if (wordlen == 5 && pg_strncasecmp(query, "start", 5) == 0)
 		return true;
 
 	return false;
diff --git a/src/bin/psql/copy.c b/src/bin/psql/copy.c
index da91fe8c714a7960d7923e2c76c73a554e3c83ae..a8998fd23d1d449ead149604db7e2d9cf7cf28b5 100644
--- a/src/bin/psql/copy.c
+++ b/src/bin/psql/copy.c
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2000-2003, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/bin/psql/copy.c,v 1.46 2004/04/21 00:34:18 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/copy.c,v 1.47 2004/05/07 00:24:58 tgl Exp $
  */
 #include "postgres_fe.h"
 #include "copy.h"
@@ -27,7 +27,6 @@
 #include "stringutils.h"
 
 #if defined(WIN32) && (!defined(__MINGW32__))
-#define strcasecmp(x,y) stricmp(x,y)
 #define __S_ISTYPE(mode, mask)	(((mode) & S_IFMT) == (mask))
 #define S_ISDIR(mode)	 __S_ISTYPE((mode), S_IFDIR)
 #endif
@@ -133,7 +132,7 @@ parse_slash_copy(const char *args)
 
 #ifdef NOT_USED
 	/* this is not implemented yet */
-	if (strcasecmp(token, "binary") == 0)
+	if (pg_strcasecmp(token, "binary") == 0)
 	{
 		result->binary = true;
 		token = strtokx(NULL, whitespace, ".,()", "\"",
@@ -200,11 +199,11 @@ parse_slash_copy(const char *args)
 	/*
 	 * Allows old COPY syntax for backward compatibility 2002-06-19
 	 */
-	if (strcasecmp(token, "with") == 0)
+	if (pg_strcasecmp(token, "with") == 0)
 	{
 		token = strtokx(NULL, whitespace, NULL, NULL,
 						0, false, pset.encoding);
-		if (!token || strcasecmp(token, "oids") != 0)
+		if (!token || pg_strcasecmp(token, "oids") != 0)
 			goto error;
 		result->oids = true;
 
@@ -214,9 +213,9 @@ parse_slash_copy(const char *args)
 			goto error;
 	}
 
-	if (strcasecmp(token, "from") == 0)
+	if (pg_strcasecmp(token, "from") == 0)
 		result->from = true;
-	else if (strcasecmp(token, "to") == 0)
+	else if (pg_strcasecmp(token, "to") == 0)
 		result->from = false;
 	else
 		goto error;
@@ -226,14 +225,14 @@ parse_slash_copy(const char *args)
 	if (!token)
 		goto error;
 
-	if (strcasecmp(token, "stdin") == 0 ||
-		strcasecmp(token, "stdout") == 0)
+	if (pg_strcasecmp(token, "stdin") == 0 ||
+		pg_strcasecmp(token, "stdout") == 0)
 	{
 		result->psql_inout = false;
 		result->file = NULL;
 	}
-	else if (strcasecmp(token, "pstdin") == 0 ||
-		strcasecmp(token, "pstdout") == 0)
+	else if (pg_strcasecmp(token, "pstdin") == 0 ||
+		pg_strcasecmp(token, "pstdout") == 0)
 	{
 		result->psql_inout = true;
 		result->file = NULL;
@@ -251,14 +250,14 @@ parse_slash_copy(const char *args)
 	/*
 	 * Allows old COPY syntax for backward compatibility 2002-06-19
 	 */
-	if (token && strcasecmp(token, "using") == 0)
+	if (token && pg_strcasecmp(token, "using") == 0)
 	{
 		token = strtokx(NULL, whitespace, NULL, NULL,
 						0, false, pset.encoding);
-		if (!(token && strcasecmp(token, "delimiters") == 0))
+		if (!(token && pg_strcasecmp(token, "delimiters") == 0))
 			goto error;
 	}
-	if (token && strcasecmp(token, "delimiters") == 0)
+	if (token && pg_strcasecmp(token, "delimiters") == 0)
 	{
 		token = strtokx(NULL, whitespace, NULL, "'",
 						'\\', false, pset.encoding);
@@ -275,7 +274,7 @@ parse_slash_copy(const char *args)
 		 * WITH is optional.  Also, the backend will allow WITH followed by
 		 * nothing, so we do too.
 		 */
-		if (strcasecmp(token, "with") == 0)
+		if (pg_strcasecmp(token, "with") == 0)
 			token = strtokx(NULL, whitespace, NULL, NULL,
 							0, false, pset.encoding);
 
@@ -286,19 +285,19 @@ parse_slash_copy(const char *args)
 			fetch_next = true;
 			
 			/* someday allow BINARY here */
-			if (strcasecmp(token, "oids") == 0)
+			if (pg_strcasecmp(token, "oids") == 0)
 			{
 				result->oids = true;
 			}
-			else if (strcasecmp(token, "csv") == 0)
+			else if (pg_strcasecmp(token, "csv") == 0)
 			{
 				result->csv_mode = true;
 			}
-			else if (strcasecmp(token, "delimiter") == 0)
+			else if (pg_strcasecmp(token, "delimiter") == 0)
 			{
 				token = strtokx(NULL, whitespace, NULL, "'",
 								'\\', false, pset.encoding);
-				if (token && strcasecmp(token, "as") == 0)
+				if (token && pg_strcasecmp(token, "as") == 0)
 					token = strtokx(NULL, whitespace, NULL, "'",
 									'\\', false, pset.encoding);
 				if (token)
@@ -306,11 +305,11 @@ parse_slash_copy(const char *args)
 				else
 					goto error;
 			}
-			else if (strcasecmp(token, "null") == 0)
+			else if (pg_strcasecmp(token, "null") == 0)
 			{
 				token = strtokx(NULL, whitespace, NULL, "'",
 								'\\', false, pset.encoding);
-				if (token && strcasecmp(token, "as") == 0)
+				if (token && pg_strcasecmp(token, "as") == 0)
 					token = strtokx(NULL, whitespace, NULL, "'",
 									'\\', false, pset.encoding);
 				if (token)
@@ -318,11 +317,11 @@ parse_slash_copy(const char *args)
 				else
 					goto error;
 			}
-			else if (strcasecmp(token, "quote") == 0)
+			else if (pg_strcasecmp(token, "quote") == 0)
 			{
 				token = strtokx(NULL, whitespace, NULL, "'",
 								'\\', false, pset.encoding);
-				if (token && strcasecmp(token, "as") == 0)
+				if (token && pg_strcasecmp(token, "as") == 0)
 					token = strtokx(NULL, whitespace, NULL, "'",
 									'\\', false, pset.encoding);
 				if (token)
@@ -330,11 +329,11 @@ parse_slash_copy(const char *args)
 				else
 					goto error;
 			}
-			else if (strcasecmp(token, "escape") == 0)
+			else if (pg_strcasecmp(token, "escape") == 0)
 			{
 				token = strtokx(NULL, whitespace, NULL, "'",
 								'\\', false, pset.encoding);
-				if (token && strcasecmp(token, "as") == 0)
+				if (token && pg_strcasecmp(token, "as") == 0)
 					token = strtokx(NULL, whitespace, NULL, "'",
 									'\\', false, pset.encoding);
 				if (token)
@@ -342,11 +341,11 @@ parse_slash_copy(const char *args)
 				else
 					goto error;
 			}
-			else if (strcasecmp(token, "force") == 0)
+			else if (pg_strcasecmp(token, "force") == 0)
 			{
 				token = strtokx(NULL, whitespace, ",", "\"",
 								0, false, pset.encoding);
-				if (strcasecmp(token, "quote") == 0)
+				if (pg_strcasecmp(token, "quote") == 0)
 				{
 					/* handle column list */
 					fetch_next = false;
@@ -367,11 +366,11 @@ parse_slash_copy(const char *args)
 						xstrcat(&result->force_quote_list, token);
 					}
 				}
-				else if (strcasecmp(token, "not") == 0)
+				else if (pg_strcasecmp(token, "not") == 0)
 				{
 					token = strtokx(NULL, whitespace, ",", "\"",
 									0, false, pset.encoding);
-					if (strcasecmp(token, "null") != 0)
+					if (pg_strcasecmp(token, "null") != 0)
 						goto error;
 					/* handle column list */
 					fetch_next = false;
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 1a0ed8c8819c174df76e736c6cea9cb2c04a2b07..e06c2001581b323dc25d121634c5ce224df6214f 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2000-2003, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.97 2004/04/22 17:38:16 neilc Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.98 2004/05/07 00:24:58 tgl Exp $
  */
 #include "postgres_fe.h"
 #include "describe.h"
@@ -1718,7 +1718,7 @@ processNamePattern(PQExpBuffer buf, const char *pattern,
 		else if (!inquotes && isupper((unsigned char) *cp))
 		{
 			appendPQExpBufferChar(&namebuf,
-								  tolower((unsigned char) *cp));
+								  pg_tolower((unsigned char) *cp));
 			cp++;
 		}
 		else if (!inquotes && *cp == '*')
diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c
index a60c0a6520f7e38aae3276e152af34adc9276386..f7e9022e425727535ec2d36d94caf1f1654684d6 100644
--- a/src/bin/psql/help.c
+++ b/src/bin/psql/help.c
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2000-2003, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/bin/psql/help.c,v 1.86 2004/03/22 03:38:24 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/help.c,v 1.87 2004/05/07 00:24:58 tgl Exp $
  */
 #include "postgres_fe.h"
 #include "common.h"
@@ -317,7 +317,7 @@ helpSQL(const char *topic, unsigned short int pager)
 		/* Count newlines for pager */
 		for (i = 0; QL_HELP[i].cmd; i++)
 		{
-			if (strncasecmp(topic, QL_HELP[i].cmd, len) == 0 ||
+			if (pg_strncasecmp(topic, QL_HELP[i].cmd, len) == 0 ||
 				strcmp(topic, "*") == 0)
 			{
 				nl_count += 5;
@@ -325,7 +325,7 @@ helpSQL(const char *topic, unsigned short int pager)
 					if (*ch == '\n')
 						nl_count++;
 				/* If we have an exact match, exit.  Fixes \h SELECT */
-				if (strcasecmp(topic, QL_HELP[i].cmd) == 0)
+				if (pg_strcasecmp(topic, QL_HELP[i].cmd) == 0)
 					break;
 			}
 		}
@@ -334,7 +334,7 @@ helpSQL(const char *topic, unsigned short int pager)
 
 		for (i = 0; QL_HELP[i].cmd; i++)
 		{
-			if (strncasecmp(topic, QL_HELP[i].cmd, len) == 0 ||
+			if (pg_strncasecmp(topic, QL_HELP[i].cmd, len) == 0 ||
 				strcmp(topic, "*") == 0)
 			{
 				help_found = true;
@@ -345,7 +345,7 @@ helpSQL(const char *topic, unsigned short int pager)
 						gettext(QL_HELP[i].help),
 						gettext(QL_HELP[i].syntax));
 				/* If we have an exact match, exit.  Fixes \h SELECT */
-				if (strcasecmp(topic, QL_HELP[i].cmd) == 0)
+				if (pg_strcasecmp(topic, QL_HELP[i].cmd) == 0)
 					break;
 			}
 		}
diff --git a/src/bin/psql/psqlscan.l b/src/bin/psql/psqlscan.l
index 5eb3f40fc8e81e24c30c000f06e230674bc69eab..0207be1d80df33d784c0550710a3b74c9dfaf799 100644
--- a/src/bin/psql/psqlscan.l
+++ b/src/bin/psql/psqlscan.l
@@ -31,7 +31,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/bin/psql/psqlscan.l,v 1.2 2004/02/24 21:45:18 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/bin/psql/psqlscan.l,v 1.3 2004/05/07 00:24:58 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1374,10 +1374,7 @@ psql_scan_slash_option(PsqlScanState state,
 					else
 					{
 						if (!inquotes && type == OT_SQLID)
-						{
-							if (isupper((unsigned char) *cp))
-								*cp = tolower((unsigned char) *cp);
-						}
+							*cp = pg_tolower((unsigned char) *cp);
 						cp += PQmblen(cp, pset.encoding);
 					}
 				}
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index ba3039d9930a70de1d4773d11764bb2fe1ce66c1..f2b2d0902b65ca50d0782bb98a9ab0395ad7303f 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2000-2003, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.104 2004/04/05 03:02:09 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.105 2004/05/07 00:24:58 tgl Exp $
  */
 
 /*----------------------------------------------------------------------
@@ -617,9 +617,9 @@ psql_completion(char *text, int start, int end)
 
 /* CREATE or DROP but not ALTER TABLE sth DROP */
 	/* complete with something you can create or drop */
-	else if (strcasecmp(prev_wd, "CREATE") == 0 ||
-			 (strcasecmp(prev_wd, "DROP") == 0 &&
-			  strcasecmp(prev3_wd, "TABLE") != 0))
+	else if (pg_strcasecmp(prev_wd, "CREATE") == 0 ||
+			 (pg_strcasecmp(prev_wd, "DROP") == 0 &&
+			  pg_strcasecmp(prev3_wd, "TABLE") != 0))
 		matches = completion_matches(text, create_command_generator);
 
 /* ALTER */
@@ -628,8 +628,8 @@ psql_completion(char *text, int start, int end)
 	 * complete with what you can alter (TABLE, GROUP, USER, ...) unless
 	 * we're in ALTER TABLE sth ALTER
 	 */
-	else if (strcasecmp(prev_wd, "ALTER") == 0 &&
-			 strcasecmp(prev3_wd, "TABLE") != 0)
+	else if (pg_strcasecmp(prev_wd, "ALTER") == 0 &&
+			 pg_strcasecmp(prev3_wd, "TABLE") != 0)
 	{
 		static const char *const list_ALTER[] =
 		{"DATABASE", "GROUP", "SCHEMA", "TABLE", "TRIGGER", "USER", NULL};
@@ -638,8 +638,8 @@ psql_completion(char *text, int start, int end)
 	}
 
 	/* ALTER DATABASE <name> */
-	else if (strcasecmp(prev3_wd, "ALTER") == 0 &&
-			 strcasecmp(prev2_wd, "DATABASE") == 0)
+	else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
+			 pg_strcasecmp(prev2_wd, "DATABASE") == 0)
 	{
 		static const char *const list_ALTERDATABASE[] =
 		{"RESET", "SET", "RENAME TO", NULL};
@@ -647,24 +647,24 @@ psql_completion(char *text, int start, int end)
 		COMPLETE_WITH_LIST(list_ALTERDATABASE);
 	}
 	/* ALTER TRIGGER <name>, add ON */
-	else if (strcasecmp(prev3_wd, "ALTER") == 0 &&
-			 strcasecmp(prev2_wd, "TRIGGER") == 0)
+	else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
+			 pg_strcasecmp(prev2_wd, "TRIGGER") == 0)
 		COMPLETE_WITH_CONST("ON");
 
 	/*
 	 * If we have ALTER TRIGGER <sth> ON, then add the correct tablename
 	 */
-	else if (strcasecmp(prev4_wd, "ALTER") == 0 &&
-			 strcasecmp(prev3_wd, "TRIGGER") == 0 &&
-			 strcasecmp(prev_wd, "ON") == 0)
+	else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 &&
+			 pg_strcasecmp(prev3_wd, "TRIGGER") == 0 &&
+			 pg_strcasecmp(prev_wd, "ON") == 0)
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
 
 	/*
 	 * If we detect ALTER TABLE <name>, suggest either ADD, DROP, ALTER,
 	 * RENAME, or OWNER
 	 */
-	else if (strcasecmp(prev3_wd, "ALTER") == 0 &&
-			 strcasecmp(prev2_wd, "TABLE") == 0)
+	else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
+			 pg_strcasecmp(prev2_wd, "TABLE") == 0)
 	{
 		static const char *const list_ALTER2[] =
 		{"ADD", "ALTER", "DROP", "RENAME", "OWNER TO", NULL};
@@ -672,14 +672,14 @@ psql_completion(char *text, int start, int end)
 		COMPLETE_WITH_LIST(list_ALTER2);
 	}
 	/* If we have TABLE <sth> ALTER|RENAME, provide list of columns */
-	else if (strcasecmp(prev3_wd, "TABLE") == 0 &&
-			 (strcasecmp(prev_wd, "ALTER") == 0 ||
-			  strcasecmp(prev_wd, "RENAME") == 0))
+	else if (pg_strcasecmp(prev3_wd, "TABLE") == 0 &&
+			 (pg_strcasecmp(prev_wd, "ALTER") == 0 ||
+			  pg_strcasecmp(prev_wd, "RENAME") == 0))
 		COMPLETE_WITH_ATTR(prev2_wd);
 
 	/* If we have TABLE <sth> DROP, provide COLUMN or CONSTRAINT */
-	else if (strcasecmp(prev3_wd, "TABLE") == 0 &&
-			 strcasecmp(prev_wd, "DROP") == 0)
+	else if (pg_strcasecmp(prev3_wd, "TABLE") == 0 &&
+			 pg_strcasecmp(prev_wd, "DROP") == 0)
 	{
 		static const char *const list_TABLEDROP[] =
 		{"COLUMN", "CONSTRAINT", NULL};
@@ -687,14 +687,14 @@ psql_completion(char *text, int start, int end)
 		COMPLETE_WITH_LIST(list_TABLEDROP);
 	}
 	/* If we have TABLE <sth> DROP COLUMN, provide list of columns */
-	else if (strcasecmp(prev4_wd, "TABLE") == 0 &&
-			 strcasecmp(prev2_wd, "DROP") == 0 &&
-			 strcasecmp(prev_wd, "COLUMN") == 0)
+	else if (pg_strcasecmp(prev4_wd, "TABLE") == 0 &&
+			 pg_strcasecmp(prev2_wd, "DROP") == 0 &&
+			 pg_strcasecmp(prev_wd, "COLUMN") == 0)
 		COMPLETE_WITH_ATTR(prev3_wd);
 
 	/* complete ALTER GROUP <foo> with ADD or DROP */
-	else if (strcasecmp(prev3_wd, "ALTER") == 0 &&
-			 strcasecmp(prev2_wd, "GROUP") == 0)
+	else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
+			 pg_strcasecmp(prev2_wd, "GROUP") == 0)
 	{
 		static const char *const list_ALTERGROUP[] =
 		{"ADD", "DROP", NULL};
@@ -702,32 +702,32 @@ psql_completion(char *text, int start, int end)
 		COMPLETE_WITH_LIST(list_ALTERGROUP);
 	}
 	/* complete ALTER GROUP <foo> ADD|DROP with USER */
-	else if (strcasecmp(prev4_wd, "ALTER") == 0 &&
-			 strcasecmp(prev3_wd, "GROUP") == 0 &&
-			 (strcasecmp(prev_wd, "ADD") == 0 ||
-			  strcasecmp(prev_wd, "DROP") == 0))
+	else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 &&
+			 pg_strcasecmp(prev3_wd, "GROUP") == 0 &&
+			 (pg_strcasecmp(prev_wd, "ADD") == 0 ||
+			  pg_strcasecmp(prev_wd, "DROP") == 0))
 		COMPLETE_WITH_CONST("USER");
 	/* complete {ALTER} GROUP <foo> ADD|DROP USER with a user name */
-	else if (strcasecmp(prev4_wd, "GROUP") == 0 &&
-			 (strcasecmp(prev2_wd, "ADD") == 0 ||
-			  strcasecmp(prev2_wd, "DROP") == 0) &&
-			 strcasecmp(prev_wd, "USER") == 0)
+	else if (pg_strcasecmp(prev4_wd, "GROUP") == 0 &&
+			 (pg_strcasecmp(prev2_wd, "ADD") == 0 ||
+			  pg_strcasecmp(prev2_wd, "DROP") == 0) &&
+			 pg_strcasecmp(prev_wd, "USER") == 0)
 		COMPLETE_WITH_QUERY(Query_for_list_of_users);
 
 /* ANALYZE */
 	/* If the previous word is ANALYZE, produce list of tables. */
-	else if (strcasecmp(prev_wd, "ANALYZE") == 0)
+	else if (pg_strcasecmp(prev_wd, "ANALYZE") == 0)
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
 	/* If we have ANALYZE <table>, complete with semicolon. */
-	else if (strcasecmp(prev2_wd, "ANALYZE") == 0)
+	else if (pg_strcasecmp(prev2_wd, "ANALYZE") == 0)
 		COMPLETE_WITH_CONST(";");
 
 /* BEGIN, COMMIT, ROLLBACK, ABORT, */
-	else if (strcasecmp(prev_wd, "BEGIN") == 0 ||
-	         strcasecmp(prev_wd, "END") == 0 ||
-	         strcasecmp(prev_wd, "COMMIT") == 0 ||
-	         strcasecmp(prev_wd, "ROLLBACK") == 0 ||
-	         strcasecmp(prev_wd, "ABORT") == 0)
+	else if (pg_strcasecmp(prev_wd, "BEGIN") == 0 ||
+	         pg_strcasecmp(prev_wd, "END") == 0 ||
+	         pg_strcasecmp(prev_wd, "COMMIT") == 0 ||
+	         pg_strcasecmp(prev_wd, "ROLLBACK") == 0 ||
+	         pg_strcasecmp(prev_wd, "ABORT") == 0)
 	{
 		static const char * const list_TRANS[] =
 		{"WORK", "TRANSACTION", NULL};
@@ -736,28 +736,28 @@ psql_completion(char *text, int start, int end)
 	}
 /* CLUSTER */
 	/* If the previous word is CLUSTER, produce list of indexes. */
-	else if (strcasecmp(prev_wd, "CLUSTER") == 0)
+	else if (pg_strcasecmp(prev_wd, "CLUSTER") == 0)
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);
 	/* If we have CLUSTER <sth>, then add "ON" */
-	else if (strcasecmp(prev2_wd, "CLUSTER") == 0)
+	else if (pg_strcasecmp(prev2_wd, "CLUSTER") == 0)
 		COMPLETE_WITH_CONST("ON");
 
 	/*
 	 * If we have CLUSTER <sth> ON, then add the correct tablename as
 	 * well.
 	 */
-	else if (strcasecmp(prev3_wd, "CLUSTER") == 0 &&
-			 strcasecmp(prev_wd, "ON") == 0)
+	else if (pg_strcasecmp(prev3_wd, "CLUSTER") == 0 &&
+			 pg_strcasecmp(prev_wd, "ON") == 0)
 	{
 		completion_info_charp = prev2_wd;
 		COMPLETE_WITH_QUERY(Query_for_table_owning_index);
 	}
 
 /* COMMENT */
-	else if (strcasecmp(prev_wd, "COMMENT") == 0)
+	else if (pg_strcasecmp(prev_wd, "COMMENT") == 0)
 		COMPLETE_WITH_CONST("ON");
-	else if (strcasecmp(prev2_wd, "COMMENT") == 0 &&
-			 strcasecmp(prev_wd, "ON") == 0)
+	else if (pg_strcasecmp(prev2_wd, "COMMENT") == 0 &&
+			 pg_strcasecmp(prev_wd, "ON") == 0)
 	{
 		static const char *const list_COMMENT[] =
 		{"DATABASE", "INDEX", "RULE", "SCHEMA", "SEQUENCE", "TABLE",
@@ -766,8 +766,8 @@ psql_completion(char *text, int start, int end)
 
 		COMPLETE_WITH_LIST(list_COMMENT);
 	}
-	else if (strcasecmp(prev4_wd, "COMMENT") == 0 &&
-			 strcasecmp(prev3_wd, "ON") == 0)
+	else if (pg_strcasecmp(prev4_wd, "COMMENT") == 0 &&
+			 pg_strcasecmp(prev3_wd, "ON") == 0)
 		COMPLETE_WITH_CONST("IS");
 
 /* COPY */
@@ -776,15 +776,15 @@ psql_completion(char *text, int start, int end)
 	 * If we have COPY [BINARY] (which you'd have to type yourself), offer
 	 * list of tables (Also cover the analogous backslash command)
 	 */
-	else if (strcasecmp(prev_wd, "COPY") == 0 ||
-			 strcasecmp(prev_wd, "\\copy") == 0 ||
-			 (strcasecmp(prev2_wd, "COPY") == 0 &&
-			  strcasecmp(prev_wd, "BINARY") == 0))
+	else if (pg_strcasecmp(prev_wd, "COPY") == 0 ||
+			 pg_strcasecmp(prev_wd, "\\copy") == 0 ||
+			 (pg_strcasecmp(prev2_wd, "COPY") == 0 &&
+			  pg_strcasecmp(prev_wd, "BINARY") == 0))
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
 	/* If we have COPY|BINARY <sth>, complete it with "TO" or "FROM" */
-	else if (strcasecmp(prev2_wd, "COPY") == 0 ||
-			 strcasecmp(prev2_wd, "\\copy") == 0 ||
-			 strcasecmp(prev2_wd, "BINARY") == 0)
+	else if (pg_strcasecmp(prev2_wd, "COPY") == 0 ||
+			 pg_strcasecmp(prev2_wd, "\\copy") == 0 ||
+			 pg_strcasecmp(prev2_wd, "BINARY") == 0)
 	{
 		static const char *const list_FROMTO[] =
 		{"FROM", "TO", NULL};
@@ -794,32 +794,32 @@ psql_completion(char *text, int start, int end)
 
 /* CREATE INDEX */
 	/* First off we complete CREATE UNIQUE with "INDEX" */
-	else if (strcasecmp(prev2_wd, "CREATE") == 0 &&
-			 strcasecmp(prev_wd, "UNIQUE") == 0)
+	else if (pg_strcasecmp(prev2_wd, "CREATE") == 0 &&
+			 pg_strcasecmp(prev_wd, "UNIQUE") == 0)
 		COMPLETE_WITH_CONST("INDEX");
 	/* If we have CREATE|UNIQUE INDEX <sth>, then add "ON" */
-	else if (strcasecmp(prev2_wd, "INDEX") == 0 &&
-			 (strcasecmp(prev3_wd, "CREATE") == 0 ||
-			  strcasecmp(prev3_wd, "UNIQUE") == 0))
+	else if (pg_strcasecmp(prev2_wd, "INDEX") == 0 &&
+			 (pg_strcasecmp(prev3_wd, "CREATE") == 0 ||
+			  pg_strcasecmp(prev3_wd, "UNIQUE") == 0))
 		COMPLETE_WITH_CONST("ON");
 	/* Complete ... INDEX <name> ON with a list of tables  */
-	else if (strcasecmp(prev3_wd, "INDEX") == 0 &&
-			 strcasecmp(prev_wd, "ON") == 0)
+	else if (pg_strcasecmp(prev3_wd, "INDEX") == 0 &&
+			 pg_strcasecmp(prev_wd, "ON") == 0)
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
 
 	/*
 	 * Complete INDEX <name> ON <table> with a list of table columns
 	 * (which should really be in parens)
 	 */
-	else if (strcasecmp(prev4_wd, "INDEX") == 0 &&
-			 strcasecmp(prev2_wd, "ON") == 0)
+	else if (pg_strcasecmp(prev4_wd, "INDEX") == 0 &&
+			 pg_strcasecmp(prev2_wd, "ON") == 0)
 		COMPLETE_WITH_ATTR(prev_wd);
 	/* same if you put in USING */
-	else if (strcasecmp(prev4_wd, "ON") == 0 &&
-			 strcasecmp(prev2_wd, "USING") == 0)
+	else if (pg_strcasecmp(prev4_wd, "ON") == 0 &&
+			 pg_strcasecmp(prev2_wd, "USING") == 0)
 		COMPLETE_WITH_ATTR(prev3_wd);
 	/* Complete USING with an index method */
-	else if (strcasecmp(prev_wd, "USING") == 0)
+	else if (pg_strcasecmp(prev_wd, "USING") == 0)
 	{
 		static const char *const index_mth[] =
 		{"BTREE", "RTREE", "HASH", "GIST", NULL};
@@ -829,18 +829,18 @@ psql_completion(char *text, int start, int end)
 
 /* CREATE RULE */
 	/* Complete "CREATE RULE <sth>" with "AS" */
-	else if (strcasecmp(prev3_wd, "CREATE") == 0 &&
-			 strcasecmp(prev2_wd, "RULE") == 0)
+	else if (pg_strcasecmp(prev3_wd, "CREATE") == 0 &&
+			 pg_strcasecmp(prev2_wd, "RULE") == 0)
 		COMPLETE_WITH_CONST("AS");
 	/* Complete "CREATE RULE <sth> AS with "ON" */
-	else if (strcasecmp(prev4_wd, "CREATE") == 0 &&
-			 strcasecmp(prev3_wd, "RULE") == 0 &&
-			 strcasecmp(prev_wd, "AS") == 0)
+	else if (pg_strcasecmp(prev4_wd, "CREATE") == 0 &&
+			 pg_strcasecmp(prev3_wd, "RULE") == 0 &&
+			 pg_strcasecmp(prev_wd, "AS") == 0)
 		COMPLETE_WITH_CONST("ON");
 	/* Complete "RULE * AS ON" with SELECT|UPDATE|DELETE|INSERT */
-	else if (strcasecmp(prev4_wd, "RULE") == 0 &&
-			 strcasecmp(prev2_wd, "AS") == 0 &&
-			 strcasecmp(prev_wd, "ON") == 0)
+	else if (pg_strcasecmp(prev4_wd, "RULE") == 0 &&
+			 pg_strcasecmp(prev2_wd, "AS") == 0 &&
+			 pg_strcasecmp(prev_wd, "ON") == 0)
 	{
 		static const char *const rule_events[] =
 		{"SELECT", "UPDATE", "INSERT", "DELETE", NULL};
@@ -848,21 +848,21 @@ psql_completion(char *text, int start, int end)
 		COMPLETE_WITH_LIST(rule_events);
 	}
 	/* Complete "AS ON <sth with a 'T' :)>" with a "TO" */
-	else if (strcasecmp(prev3_wd, "AS") == 0 &&
-			 strcasecmp(prev2_wd, "ON") == 0 &&
+	else if (pg_strcasecmp(prev3_wd, "AS") == 0 &&
+			 pg_strcasecmp(prev2_wd, "ON") == 0 &&
 			 (toupper((unsigned char) prev_wd[4]) == 'T' ||
 			  toupper((unsigned char) prev_wd[5]) == 'T'))
 		COMPLETE_WITH_CONST("TO");
 	/* Complete "AS ON <sth> TO" with a table name */
-	else if (strcasecmp(prev4_wd, "AS") == 0 &&
-			 strcasecmp(prev3_wd, "ON") == 0 &&
-			 strcasecmp(prev_wd, "TO") == 0)
+	else if (pg_strcasecmp(prev4_wd, "AS") == 0 &&
+			 pg_strcasecmp(prev3_wd, "ON") == 0 &&
+			 pg_strcasecmp(prev_wd, "TO") == 0)
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
 
 /* CREATE TABLE */
 	/* Complete CREATE TEMP with "TABLE" */
-	else if (strcasecmp(prev2_wd, "CREATE") == 0 &&
-			 strcasecmp(prev_wd, "TEMP") == 0)
+	else if (pg_strcasecmp(prev2_wd, "CREATE") == 0 &&
+			 pg_strcasecmp(prev_wd, "TEMP") == 0)
 		COMPLETE_WITH_CONST("TABLE");
 
 /* CREATE TRIGGER */
@@ -870,13 +870,13 @@ psql_completion(char *text, int start, int end)
 
 /* CREATE VIEW */
 	/* Complete "CREATE VIEW <name>" with "AS" */
-	else if (strcasecmp(prev3_wd, "CREATE") == 0 &&
-			 strcasecmp(prev2_wd, "VIEW") == 0)
+	else if (pg_strcasecmp(prev3_wd, "CREATE") == 0 &&
+			 pg_strcasecmp(prev2_wd, "VIEW") == 0)
 		COMPLETE_WITH_CONST("AS");
 	/* Complete "CREATE VIEW <sth> AS with "SELECT" */
-	else if (strcasecmp(prev4_wd, "CREATE") == 0 &&
-			 strcasecmp(prev3_wd, "VIEW") == 0 &&
-			 strcasecmp(prev_wd, "AS") == 0)
+	else if (pg_strcasecmp(prev4_wd, "CREATE") == 0 &&
+			 pg_strcasecmp(prev3_wd, "VIEW") == 0 &&
+			 pg_strcasecmp(prev_wd, "AS") == 0)
 		COMPLETE_WITH_CONST("SELECT");
 
 /* DELETE */
@@ -885,19 +885,19 @@ psql_completion(char *text, int start, int end)
 	 * Complete DELETE with FROM (only if the word before that is not "ON"
 	 * (cf. rules) or "BEFORE" or "AFTER" (cf. triggers) or GRANT)
 	 */
-	else if (strcasecmp(prev_wd, "DELETE") == 0 &&
-			 !(strcasecmp(prev2_wd, "ON") == 0 ||
-			   strcasecmp(prev2_wd, "GRANT") == 0 ||
-			   strcasecmp(prev2_wd, "BEFORE") == 0 ||
-			   strcasecmp(prev2_wd, "AFTER") == 0))
+	else if (pg_strcasecmp(prev_wd, "DELETE") == 0 &&
+			 !(pg_strcasecmp(prev2_wd, "ON") == 0 ||
+			   pg_strcasecmp(prev2_wd, "GRANT") == 0 ||
+			   pg_strcasecmp(prev2_wd, "BEFORE") == 0 ||
+			   pg_strcasecmp(prev2_wd, "AFTER") == 0))
 		COMPLETE_WITH_CONST("FROM");
 	/* Complete DELETE FROM with a list of tables */
-	else if (strcasecmp(prev2_wd, "DELETE") == 0 &&
-			 strcasecmp(prev_wd, "FROM") == 0)
+	else if (pg_strcasecmp(prev2_wd, "DELETE") == 0 &&
+			 pg_strcasecmp(prev_wd, "FROM") == 0)
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
 	/* Complete DELETE FROM <table> with "WHERE" (perhaps a safe idea?) */
-	else if (strcasecmp(prev3_wd, "DELETE") == 0 &&
-			 strcasecmp(prev2_wd, "FROM") == 0)
+	else if (pg_strcasecmp(prev3_wd, "DELETE") == 0 &&
+			 pg_strcasecmp(prev2_wd, "FROM") == 0)
 		COMPLETE_WITH_CONST("WHERE");
 
 /* EXPLAIN */
@@ -906,15 +906,15 @@ psql_completion(char *text, int start, int end)
 	 * Complete EXPLAIN [VERBOSE] (which you'd have to type yourself) with
 	 * the list of SQL commands
 	 */
-	else if (strcasecmp(prev_wd, "EXPLAIN") == 0 ||
-			 (strcasecmp(prev2_wd, "EXPLAIN") == 0 &&
-			  strcasecmp(prev_wd, "VERBOSE") == 0))
+	else if (pg_strcasecmp(prev_wd, "EXPLAIN") == 0 ||
+			 (pg_strcasecmp(prev2_wd, "EXPLAIN") == 0 &&
+			  pg_strcasecmp(prev_wd, "VERBOSE") == 0))
 		COMPLETE_WITH_LIST(sql_commands);
 
 /* FETCH && MOVE */
 	/* Complete FETCH with one of FORWARD, BACKWARD, RELATIVE */
-	else if (strcasecmp(prev_wd, "FETCH") == 0 ||
-			 strcasecmp(prev_wd, "MOVE") == 0)
+	else if (pg_strcasecmp(prev_wd, "FETCH") == 0 ||
+			 pg_strcasecmp(prev_wd, "MOVE") == 0)
 	{
 		static const char * const list_FETCH1[] =
 		{"FORWARD", "BACKWARD", "RELATIVE", NULL};
@@ -922,8 +922,8 @@ psql_completion(char *text, int start, int end)
 		COMPLETE_WITH_LIST(list_FETCH1);
 	}
 	/* Complete FETCH <sth> with one of ALL, NEXT, PRIOR */
-	else if (strcasecmp(prev2_wd, "FETCH") == 0 ||
-			 strcasecmp(prev2_wd, "MOVE") == 0)
+	else if (pg_strcasecmp(prev2_wd, "FETCH") == 0 ||
+			 pg_strcasecmp(prev2_wd, "MOVE") == 0)
 	{
 		static const char * const list_FETCH2[] =
 		{"ALL", "NEXT", "PRIOR", NULL};
@@ -935,8 +935,8 @@ psql_completion(char *text, int start, int end)
 	 * Complete FETCH <sth1> <sth2> with "FROM" or "TO". (Is there a
 	 * difference? If not, remove one.)
 	 */
-	else if (strcasecmp(prev3_wd, "FETCH") == 0 ||
-			 strcasecmp(prev3_wd, "MOVE") == 0)
+	else if (pg_strcasecmp(prev3_wd, "FETCH") == 0 ||
+			 pg_strcasecmp(prev3_wd, "MOVE") == 0)
 	{
 		static const char * const list_FROMTO[] =
 		{"FROM", "TO", NULL};
@@ -946,8 +946,8 @@ psql_completion(char *text, int start, int end)
 
 /* GRANT && REVOKE*/
 	/* Complete GRANT/REVOKE with a list of privileges */
-	else if (strcasecmp(prev_wd, "GRANT") == 0 ||
-			 strcasecmp(prev_wd, "REVOKE") == 0)
+	else if (pg_strcasecmp(prev_wd, "GRANT") == 0 ||
+			 pg_strcasecmp(prev_wd, "REVOKE") == 0)
 	{
 		static const char * const list_privileg[] =
 		{"SELECT", "INSERT", "UPDATE", "DELETE", "RULE", "REFERENCES",
@@ -956,8 +956,8 @@ psql_completion(char *text, int start, int end)
 		COMPLETE_WITH_LIST(list_privileg);
 	}
 	/* Complete GRANT/REVOKE <sth> with "ON" */
-	else if (strcasecmp(prev2_wd, "GRANT") == 0 ||
-			 strcasecmp(prev2_wd, "REVOKE") == 0)
+	else if (pg_strcasecmp(prev2_wd, "GRANT") == 0 ||
+			 pg_strcasecmp(prev2_wd, "REVOKE") == 0)
 		COMPLETE_WITH_CONST("ON");
 
 	/*
@@ -971,9 +971,9 @@ psql_completion(char *text, int start, int end)
 	 * implemented here will only work if the privilege list contains
 	 * exactly one privilege
 	 */
-	else if ((strcasecmp(prev3_wd, "GRANT") == 0 ||
-			  strcasecmp(prev3_wd, "REVOKE") == 0) &&
-			 strcasecmp(prev_wd, "ON") == 0)
+	else if ((pg_strcasecmp(prev3_wd, "GRANT") == 0 ||
+			  pg_strcasecmp(prev3_wd, "REVOKE") == 0) &&
+			 pg_strcasecmp(prev_wd, "ON") == 0)
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsv,
 								   " UNION SELECT 'DATABASE'"
 								   " UNION SELECT 'FUNCTION'"
@@ -981,17 +981,17 @@ psql_completion(char *text, int start, int end)
 								   " UNION SELECT 'SCHEMA'");
 
 	/* Complete "GRANT/REVOKE * ON * " with "TO" */
-	else if ((strcasecmp(prev4_wd, "GRANT") == 0 ||
-			  strcasecmp(prev4_wd, "REVOKE") == 0) &&
-			 strcasecmp(prev2_wd, "ON") == 0)
+	else if ((pg_strcasecmp(prev4_wd, "GRANT") == 0 ||
+			  pg_strcasecmp(prev4_wd, "REVOKE") == 0) &&
+			 pg_strcasecmp(prev2_wd, "ON") == 0)
 	{
-		if (strcasecmp(prev_wd, "DATABASE") == 0)
+		if (pg_strcasecmp(prev_wd, "DATABASE") == 0)
 			COMPLETE_WITH_QUERY(Query_for_list_of_databases);
-		else if (strcasecmp(prev_wd, "FUNCTION") == 0)
+		else if (pg_strcasecmp(prev_wd, "FUNCTION") == 0)
 			COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
-		else if (strcasecmp(prev_wd, "LANGUAGE") == 0)
+		else if (pg_strcasecmp(prev_wd, "LANGUAGE") == 0)
 			COMPLETE_WITH_QUERY(Query_for_list_of_languages);
-		else if (strcasecmp(prev_wd, "SCHEMA") == 0)
+		else if (pg_strcasecmp(prev_wd, "SCHEMA") == 0)
 			COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
 		else
 			COMPLETE_WITH_CONST("TO");
@@ -1005,24 +1005,24 @@ psql_completion(char *text, int start, int end)
 
 /* INSERT */
 	/* Complete INSERT with "INTO" */
-	else if (strcasecmp(prev_wd, "INSERT") == 0)
+	else if (pg_strcasecmp(prev_wd, "INSERT") == 0)
 		COMPLETE_WITH_CONST("INTO");
 	/* Complete INSERT INTO with table names */
-	else if (strcasecmp(prev2_wd, "INSERT") == 0 &&
-			 strcasecmp(prev_wd, "INTO") == 0)
+	else if (pg_strcasecmp(prev2_wd, "INSERT") == 0 &&
+			 pg_strcasecmp(prev_wd, "INTO") == 0)
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
 	/* Complete "INSERT INTO <table> (" with attribute names */
 	else if (rl_line_buffer[start - 1] == '(' &&
-			 strcasecmp(prev3_wd, "INSERT") == 0 &&
-			 strcasecmp(prev2_wd, "INTO") == 0)
+			 pg_strcasecmp(prev3_wd, "INSERT") == 0 &&
+			 pg_strcasecmp(prev2_wd, "INTO") == 0)
 		COMPLETE_WITH_ATTR(prev_wd);
 
 	/*
 	 * Complete INSERT INTO <table> with "VALUES" or "SELECT" or "DEFAULT
 	 * VALUES"
 	 */
-	else if (strcasecmp(prev3_wd, "INSERT") == 0 &&
-			 strcasecmp(prev2_wd, "INTO") == 0)
+	else if (pg_strcasecmp(prev3_wd, "INSERT") == 0 &&
+			 pg_strcasecmp(prev2_wd, "INTO") == 0)
 	{
 		static const char * const list_INSERT[] =
 		{"DEFAULT VALUES", "SELECT", "VALUES", NULL};
@@ -1030,8 +1030,8 @@ psql_completion(char *text, int start, int end)
 		COMPLETE_WITH_LIST(list_INSERT);
 	}
 	/* Complete INSERT INTO <table> (attribs) with "VALUES" or "SELECT" */
-	else if (strcasecmp(prev4_wd, "INSERT") == 0 &&
-			 strcasecmp(prev3_wd, "INTO") == 0 &&
+	else if (pg_strcasecmp(prev4_wd, "INSERT") == 0 &&
+			 pg_strcasecmp(prev3_wd, "INTO") == 0 &&
 			 prev_wd[strlen(prev_wd) - 1] == ')')
 	{
 		static const char * const list_INSERT[] =
@@ -1041,31 +1041,31 @@ psql_completion(char *text, int start, int end)
 	}
 
 	/* Insert an open parenthesis after "VALUES" */
-	else if (strcasecmp(prev_wd, "VALUES") == 0 &&
-			 strcasecmp(prev2_wd, "DEFAULT") != 0)
+	else if (pg_strcasecmp(prev_wd, "VALUES") == 0 &&
+			 pg_strcasecmp(prev2_wd, "DEFAULT") != 0)
 		COMPLETE_WITH_CONST("(");
 
 /* LOCK */
 	/* Complete LOCK [TABLE] with a list of tables */
-	else if (strcasecmp(prev_wd, "LOCK") == 0 ||
-			 (strcasecmp(prev_wd, "TABLE") == 0 &&
-			  strcasecmp(prev2_wd, "LOCK") == 0))
+	else if (pg_strcasecmp(prev_wd, "LOCK") == 0 ||
+			 (pg_strcasecmp(prev_wd, "TABLE") == 0 &&
+			  pg_strcasecmp(prev2_wd, "LOCK") == 0))
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
 
 	/* For the following, handle the case of a single table only for now */
 
 	/* Complete LOCK [TABLE] <table> with "IN" */
-	else if ((strcasecmp(prev2_wd, "LOCK") == 0 &&
-			  strcasecmp(prev_wd, "TABLE")) ||
-			 (strcasecmp(prev2_wd, "TABLE") == 0 &&
-			  strcasecmp(prev3_wd, "LOCK") == 0))
+	else if ((pg_strcasecmp(prev2_wd, "LOCK") == 0 &&
+			  pg_strcasecmp(prev_wd, "TABLE")) ||
+			 (pg_strcasecmp(prev2_wd, "TABLE") == 0 &&
+			  pg_strcasecmp(prev3_wd, "LOCK") == 0))
 		COMPLETE_WITH_CONST("IN");
 
 	/* Complete LOCK [TABLE] <table> IN with a lock mode */
-	else if (strcasecmp(prev_wd, "IN") == 0 &&
-			 (strcasecmp(prev3_wd, "LOCK") == 0 ||
-			  (strcasecmp(prev3_wd, "TABLE") == 0 &&
-			   strcasecmp(prev4_wd, "LOCK") == 0)))
+	else if (pg_strcasecmp(prev_wd, "IN") == 0 &&
+			 (pg_strcasecmp(prev3_wd, "LOCK") == 0 ||
+			  (pg_strcasecmp(prev3_wd, "TABLE") == 0 &&
+			   pg_strcasecmp(prev4_wd, "LOCK") == 0)))
 	{
 		static const char * const lock_modes[] =
 		{"ACCESS SHARE MODE",
@@ -1078,24 +1078,24 @@ psql_completion(char *text, int start, int end)
 	}
 
 /* NOTIFY */
-	else if (strcasecmp(prev_wd, "NOTIFY") == 0)
+	else if (pg_strcasecmp(prev_wd, "NOTIFY") == 0)
 		COMPLETE_WITH_QUERY("SELECT pg_catalog.quote_ident(relname) FROM pg_catalog.pg_listener WHERE substring(pg_catalog.quote_ident(relname),1,%d)='%s'");
 
 /* REINDEX */
-	else if (strcasecmp(prev_wd, "REINDEX") == 0)
+	else if (pg_strcasecmp(prev_wd, "REINDEX") == 0)
 	{
 		static const char * const list_REINDEX[] =
 		{"TABLE", "DATABASE", "INDEX", NULL};
 
 		COMPLETE_WITH_LIST(list_REINDEX);
 	}
-	else if (strcasecmp(prev2_wd, "REINDEX") == 0)
+	else if (pg_strcasecmp(prev2_wd, "REINDEX") == 0)
 	{
-		if (strcasecmp(prev_wd, "TABLE") == 0)
+		if (pg_strcasecmp(prev_wd, "TABLE") == 0)
 			COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
-		else if (strcasecmp(prev_wd, "DATABASE") == 0)
+		else if (pg_strcasecmp(prev_wd, "DATABASE") == 0)
 			COMPLETE_WITH_QUERY(Query_for_list_of_databases);
-		else if (strcasecmp(prev_wd, "INDEX") == 0)
+		else if (pg_strcasecmp(prev_wd, "INDEX") == 0)
 			COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);
 	}
 
@@ -1104,68 +1104,68 @@ psql_completion(char *text, int start, int end)
 
 /* SET, RESET, SHOW */
 	/* Complete with a variable name */
-	else if ((strcasecmp(prev_wd, "SET") == 0 &&
-			  strcasecmp(prev3_wd, "UPDATE") != 0) ||
-			 strcasecmp(prev_wd, "RESET") == 0 ||
-			 strcasecmp(prev_wd, "SHOW") == 0)
+	else if ((pg_strcasecmp(prev_wd, "SET") == 0 &&
+			  pg_strcasecmp(prev3_wd, "UPDATE") != 0) ||
+			 pg_strcasecmp(prev_wd, "RESET") == 0 ||
+			 pg_strcasecmp(prev_wd, "SHOW") == 0)
 		COMPLETE_WITH_LIST(pgsql_variables);
 	/* Complete "SET TRANSACTION" */
-	else if ((strcasecmp(prev2_wd, "SET") == 0 &&
-			  strcasecmp(prev_wd, "TRANSACTION") == 0)
-			 || (strcasecmp(prev2_wd, "START") == 0
-				 && strcasecmp(prev_wd, "TRANSACTION") == 0)
-			 || (strcasecmp(prev2_wd, "BEGIN") == 0
-				 && strcasecmp(prev_wd, "WORK") == 0)
-			 || (strcasecmp(prev2_wd, "BEGIN") == 0
-				 && strcasecmp(prev_wd, "TRANSACTION") == 0)
-			 || (strcasecmp(prev4_wd, "SESSION") == 0
-				 && strcasecmp(prev3_wd, "CHARACTERISTICS") == 0
-				 && strcasecmp(prev2_wd, "AS") == 0
-				 && strcasecmp(prev_wd, "TRANSACTION") == 0))
+	else if ((pg_strcasecmp(prev2_wd, "SET") == 0 &&
+			  pg_strcasecmp(prev_wd, "TRANSACTION") == 0)
+			 || (pg_strcasecmp(prev2_wd, "START") == 0
+				 && pg_strcasecmp(prev_wd, "TRANSACTION") == 0)
+			 || (pg_strcasecmp(prev2_wd, "BEGIN") == 0
+				 && pg_strcasecmp(prev_wd, "WORK") == 0)
+			 || (pg_strcasecmp(prev2_wd, "BEGIN") == 0
+				 && pg_strcasecmp(prev_wd, "TRANSACTION") == 0)
+			 || (pg_strcasecmp(prev4_wd, "SESSION") == 0
+				 && pg_strcasecmp(prev3_wd, "CHARACTERISTICS") == 0
+				 && pg_strcasecmp(prev2_wd, "AS") == 0
+				 && pg_strcasecmp(prev_wd, "TRANSACTION") == 0))
 	{
 		static const char * const my_list[] =
 		{"ISOLATION", "READ", NULL};
 
 		COMPLETE_WITH_LIST(my_list);
 	}
-	else if ((strcasecmp(prev3_wd, "SET") == 0
-			  || strcasecmp(prev3_wd, "START") == 0
-			  || (strcasecmp(prev4_wd, "CHARACTERISTICS") == 0
-				  && strcasecmp(prev3_wd, "AS") == 0))
-			 && strcasecmp(prev2_wd, "TRANSACTION") == 0
-			 && strcasecmp(prev_wd, "ISOLATION") == 0)
+	else if ((pg_strcasecmp(prev3_wd, "SET") == 0
+			  || pg_strcasecmp(prev3_wd, "START") == 0
+			  || (pg_strcasecmp(prev4_wd, "CHARACTERISTICS") == 0
+				  && pg_strcasecmp(prev3_wd, "AS") == 0))
+			 && pg_strcasecmp(prev2_wd, "TRANSACTION") == 0
+			 && pg_strcasecmp(prev_wd, "ISOLATION") == 0)
 		COMPLETE_WITH_CONST("LEVEL");
-	else if ((strcasecmp(prev4_wd, "SET") == 0
-			  || strcasecmp(prev4_wd, "START") == 0
-			  || strcasecmp(prev4_wd, "AS") == 0)
-			 && strcasecmp(prev3_wd, "TRANSACTION") == 0
-			 && strcasecmp(prev2_wd, "ISOLATION") == 0
-			 && strcasecmp(prev_wd, "LEVEL") == 0)
+	else if ((pg_strcasecmp(prev4_wd, "SET") == 0
+			  || pg_strcasecmp(prev4_wd, "START") == 0
+			  || pg_strcasecmp(prev4_wd, "AS") == 0)
+			 && pg_strcasecmp(prev3_wd, "TRANSACTION") == 0
+			 && pg_strcasecmp(prev2_wd, "ISOLATION") == 0
+			 && pg_strcasecmp(prev_wd, "LEVEL") == 0)
 	{
 		static const char * const my_list[] =
 		{"READ", "REPEATABLE", "SERIALIZABLE", NULL};
 
 		COMPLETE_WITH_LIST(my_list);
 	}
-	else if (strcasecmp(prev4_wd, "TRANSACTION") == 0 &&
-			 strcasecmp(prev3_wd, "ISOLATION") == 0 &&
-			 strcasecmp(prev2_wd, "LEVEL") == 0 &&
-			 strcasecmp(prev_wd, "READ") == 0)
+	else if (pg_strcasecmp(prev4_wd, "TRANSACTION") == 0 &&
+			 pg_strcasecmp(prev3_wd, "ISOLATION") == 0 &&
+			 pg_strcasecmp(prev2_wd, "LEVEL") == 0 &&
+			 pg_strcasecmp(prev_wd, "READ") == 0)
 	{
 		static const char * const my_list[] =
 		{"UNCOMMITTED", "COMMITTED", NULL};
 
 		COMPLETE_WITH_LIST(my_list);
 	}
-	else if (strcasecmp(prev4_wd, "TRANSACTION") == 0 &&
-			 strcasecmp(prev3_wd, "ISOLATION") == 0 &&
-			 strcasecmp(prev2_wd, "LEVEL") == 0 &&
-			 strcasecmp(prev_wd, "REPEATABLE") == 0)
+	else if (pg_strcasecmp(prev4_wd, "TRANSACTION") == 0 &&
+			 pg_strcasecmp(prev3_wd, "ISOLATION") == 0 &&
+			 pg_strcasecmp(prev2_wd, "LEVEL") == 0 &&
+			 pg_strcasecmp(prev_wd, "REPEATABLE") == 0)
 		COMPLETE_WITH_CONST("READ");
-	else if ((strcasecmp(prev3_wd, "SET") == 0 ||
-			  strcasecmp(prev3_wd, "AS") == 0) &&
-			 strcasecmp(prev2_wd, "TRANSACTION") == 0 &&
-			 strcasecmp(prev_wd, "READ") == 0)
+	else if ((pg_strcasecmp(prev3_wd, "SET") == 0 ||
+			  pg_strcasecmp(prev3_wd, "AS") == 0) &&
+			 pg_strcasecmp(prev2_wd, "TRANSACTION") == 0 &&
+			 pg_strcasecmp(prev_wd, "READ") == 0)
 	{
 		static const char * const my_list[] =
 		{"ONLY", "WRITE", NULL};
@@ -1173,8 +1173,8 @@ psql_completion(char *text, int start, int end)
 		COMPLETE_WITH_LIST(my_list);
 	}
 	/* Complete SET CONSTRAINTS <foo> with DEFERRED|IMMEDIATE */
-	else if (strcasecmp(prev3_wd, "SET") == 0 &&
-			 strcasecmp(prev2_wd, "CONSTRAINTS") == 0)
+	else if (pg_strcasecmp(prev3_wd, "SET") == 0 &&
+			 pg_strcasecmp(prev2_wd, "CONSTRAINTS") == 0)
 	{
 		static const char * const constraint_list[] =
 		{"DEFERRED", "IMMEDIATE", NULL};
@@ -1182,8 +1182,8 @@ psql_completion(char *text, int start, int end)
 		COMPLETE_WITH_LIST(constraint_list);
 	}
 	/* Complete SET SESSION with AUTHORIZATION or CHARACTERISTICS... */
-	else if (strcasecmp(prev2_wd, "SET") == 0 &&
-			 strcasecmp(prev_wd, "SESSION") == 0)
+	else if (pg_strcasecmp(prev2_wd, "SET") == 0 &&
+			 pg_strcasecmp(prev_wd, "SESSION") == 0)
 	{
 		static const char * const my_list[] =
 		{"AUTHORIZATION", "CHARACTERISTICS AS TRANSACTION", NULL};
@@ -1191,19 +1191,19 @@ psql_completion(char *text, int start, int end)
 		COMPLETE_WITH_LIST(my_list);
 	}
 	/* Complete SET SESSION AUTHORIZATION with username */
-	else if (strcasecmp(prev3_wd, "SET") == 0
-			 && strcasecmp(prev2_wd, "SESSION") == 0
-			 && strcasecmp(prev_wd, "AUTHORIZATION") == 0)
+	else if (pg_strcasecmp(prev3_wd, "SET") == 0
+			 && pg_strcasecmp(prev2_wd, "SESSION") == 0
+			 && pg_strcasecmp(prev_wd, "AUTHORIZATION") == 0)
 		COMPLETE_WITH_QUERY(Query_for_list_of_users);
 	/* Complete SET <var> with "TO" */
-	else if (strcasecmp(prev2_wd, "SET") == 0 &&
-			 strcasecmp(prev4_wd, "UPDATE") != 0)
+	else if (pg_strcasecmp(prev2_wd, "SET") == 0 &&
+			 pg_strcasecmp(prev4_wd, "UPDATE") != 0)
 		COMPLETE_WITH_CONST("TO");
 	/* Suggest possible variable values */
-	else if (strcasecmp(prev3_wd, "SET") == 0 &&
-		   (strcasecmp(prev_wd, "TO") == 0 || strcmp(prev_wd, "=") == 0))
+	else if (pg_strcasecmp(prev3_wd, "SET") == 0 &&
+		   (pg_strcasecmp(prev_wd, "TO") == 0 || strcmp(prev_wd, "=") == 0))
 	{
-		if (strcasecmp(prev2_wd, "DateStyle") == 0)
+		if (pg_strcasecmp(prev2_wd, "DateStyle") == 0)
 		{
 			static const char * const my_list[] =
 			{"ISO", "SQL", "Postgres", "German",
@@ -1213,7 +1213,7 @@ psql_completion(char *text, int start, int end)
 
 			COMPLETE_WITH_LIST(my_list);
 		}
-		else if (strcasecmp(prev2_wd, "GEQO") == 0)
+		else if (pg_strcasecmp(prev2_wd, "GEQO") == 0)
 		{
 			static const char * const my_list[] =
 			{"ON", "OFF", "DEFAULT", NULL};
@@ -1230,23 +1230,23 @@ psql_completion(char *text, int start, int end)
 	}
 
 /* START TRANSACTION */
-	else if (strcasecmp(prev_wd, "START") == 0)
+	else if (pg_strcasecmp(prev_wd, "START") == 0)
 		COMPLETE_WITH_CONST("TRANSACTION");
 
 /* TRUNCATE */
-	else if (strcasecmp(prev_wd, "TRUNCATE") == 0)
+	else if (pg_strcasecmp(prev_wd, "TRUNCATE") == 0)
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
 
 /* UNLISTEN */
-	else if (strcasecmp(prev_wd, "UNLISTEN") == 0)
+	else if (pg_strcasecmp(prev_wd, "UNLISTEN") == 0)
 		COMPLETE_WITH_QUERY("SELECT pg_catalog.quote_ident(relname) FROM pg_catalog.pg_listener WHERE substring(pg_catalog.quote_ident(relname),1,%d)='%s' UNION SELECT '*'");
 
 /* UPDATE */
 	/* If prev. word is UPDATE suggest a list of tables */
-	else if (strcasecmp(prev_wd, "UPDATE") == 0)
+	else if (pg_strcasecmp(prev_wd, "UPDATE") == 0)
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
 	/* Complete UPDATE <table> with "SET" */
-	else if (strcasecmp(prev2_wd, "UPDATE") == 0)
+	else if (pg_strcasecmp(prev2_wd, "UPDATE") == 0)
 		COMPLETE_WITH_CONST("SET");
 
 	/*
@@ -1254,29 +1254,29 @@ psql_completion(char *text, int start, int end)
 	 * _first_ word) the word before it was (hopefully) a table name and
 	 * we'll now make a list of attributes.
 	 */
-	else if (strcasecmp(prev_wd, "SET") == 0)
+	else if (pg_strcasecmp(prev_wd, "SET") == 0)
 		COMPLETE_WITH_ATTR(prev2_wd);
 
 /* VACUUM */
-	else if (strcasecmp(prev_wd, "VACUUM") == 0)
+	else if (pg_strcasecmp(prev_wd, "VACUUM") == 0)
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables,
 								   " UNION SELECT 'FULL'"
 								   " UNION SELECT 'ANALYZE'"
 								   " UNION SELECT 'VERBOSE'");
-	else if (strcasecmp(prev2_wd, "VACUUM") == 0 &&
-			 (strcasecmp(prev_wd, "FULL") == 0 ||
-			  strcasecmp(prev_wd, "ANALYZE") == 0 ||
-			  strcasecmp(prev_wd, "VERBOSE") == 0))
+	else if (pg_strcasecmp(prev2_wd, "VACUUM") == 0 &&
+			 (pg_strcasecmp(prev_wd, "FULL") == 0 ||
+			  pg_strcasecmp(prev_wd, "ANALYZE") == 0 ||
+			  pg_strcasecmp(prev_wd, "VERBOSE") == 0))
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
 
 /* WHERE */
 	/* Simple case of the word before the where being the table name */
-	else if (strcasecmp(prev_wd, "WHERE") == 0)
+	else if (pg_strcasecmp(prev_wd, "WHERE") == 0)
 		COMPLETE_WITH_ATTR(prev2_wd);
 
 /* ... FROM ... */
 /* TODO: also include SRF ? */
-	else if (strcasecmp(prev_wd, "FROM") == 0)
+	else if (pg_strcasecmp(prev_wd, "FROM") == 0)
 		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsv, NULL);
 
 
@@ -1345,7 +1345,7 @@ psql_completion(char *text, int start, int end)
 
 		for (i = 0; words_after_create[i].name; i++)
 		{
-			if (strcasecmp(prev_wd, words_after_create[i].name) == 0)
+			if (pg_strcasecmp(prev_wd, words_after_create[i].name) == 0)
 			{
 				if (words_after_create[i].query)
 					COMPLETE_WITH_QUERY(words_after_create[i].query);
@@ -1415,7 +1415,7 @@ create_command_generator(const char *text, int state)
 
 	/* find something that matches */
 	while ((name = words_after_create[list_index++].name))
-		if (strncasecmp(name, text, string_length) == 0)
+		if (pg_strncasecmp(name, text, string_length) == 0)
 			return pg_strdup(name);
 
 	/* if nothing matches, return NULL */
@@ -1616,7 +1616,7 @@ _complete_from_query(int is_schema_query, const char *text, int state)
 
 		while (list_index < PQntuples(result) &&
 			   (item = PQgetvalue(result, list_index++, 0)))
-			if (strncasecmp(text, item, string_length) == 0)
+			if (pg_strncasecmp(text, item, string_length) == 0)
 				return pg_strdup(item);
 	}
 
@@ -1662,7 +1662,7 @@ complete_from_list(const char *text, int state)
 		}
 
 		/* Second pass is case insensitive, don't bother counting matches */
-		if (!casesensitive && strncasecmp(text, item, string_length) == 0)
+		if (!casesensitive && pg_strncasecmp(text, item, string_length) == 0)
 			return pg_strdup(item);
 	}
 
diff --git a/src/include/c.h b/src/include/c.h
index b3ee88968d02a7af3810fe3cbe4aed7f850371eb..d607677aa3f6c92efb188fd072ef7e6a5be8b71f 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -12,7 +12,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/c.h,v 1.163 2004/05/05 21:18:29 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/c.h,v 1.164 2004/05/07 00:24:58 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -720,10 +720,6 @@ extern int	vsnprintf(char *str, size_t count, const char *fmt, va_list args);
 #define memmove(d, s, c)		bcopy(s, d, c)
 #endif
 
-#ifndef HAVE_UNSETENV
-extern void unsetenv(const char *name);
-#endif
-
 #ifndef DLLIMPORT
 #define DLLIMPORT				/* no special DLL markers on most ports */
 #endif
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index aea533ad83f7bfbaea9307fd04d4ec1927a9bd20..e8158a678a3d3e66df6f04d8c472aa5fb4866a09 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -385,9 +385,6 @@
 /* Define to 1 if you have the <stdlib.h> header file. */
 #undef HAVE_STDLIB_H
 
-/* Define to 1 if you have the `strcasecmp' function. */
-#undef HAVE_STRCASECMP
-
 /* Define to 1 if you have the `strdup' function. */
 #undef HAVE_STRDUP
 
diff --git a/src/include/port.h b/src/include/port.h
index 4fb42bf74dd8033c3f152393bac8eb7e023c8324..2f5123483bf204b7f2d92698b8f79f95c4748dc2 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/port.h,v 1.27 2004/04/30 17:52:07 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/port.h,v 1.28 2004/05/07 00:24:58 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -30,6 +30,12 @@ extern char *get_progname(char *argv0);
 /* Portable delay handling */
 extern void pg_usleep(long microsec);
 
+/* Portable SQL-like case-independent comparisons and conversions */
+extern int	pg_strcasecmp(const char *s1, const char *s2);
+extern int	pg_strncasecmp(const char *s1, const char *s2, size_t n);
+extern unsigned char pg_toupper(unsigned char ch);
+extern unsigned char pg_tolower(unsigned char ch);
+
 /* Portable prompt handling */
 extern char *simple_prompt(const char *prompt, int maxlen, bool echo);
 
@@ -130,10 +136,6 @@ extern double rint(double x);
 extern int	inet_aton(const char *cp, struct in_addr * addr);
 #endif
 
-#ifndef HAVE_STRCASECMP
-extern int	strcasecmp(char *s1, char *s2);
-#endif
-
 #ifndef HAVE_STRDUP
 extern char *strdup(char const *);
 #endif
@@ -142,6 +144,10 @@ extern char *strdup(char const *);
 extern long random(void);
 #endif
 
+#ifndef HAVE_UNSETENV
+extern void unsetenv(const char *name);
+#endif
+
 #ifndef HAVE_SRANDOM
 extern void srandom(unsigned int seed);
 #endif
diff --git a/src/include/port/qnx4.h b/src/include/port/qnx4.h
index 68deca4a1c3794fba3fa81a1bf6b253e0613b63d..94ae9a87c17c3605addedaa24767f721f46e3555 100644
--- a/src/include/port/qnx4.h
+++ b/src/include/port/qnx4.h
@@ -7,8 +7,6 @@
 
 #undef HAVE_GETRUSAGE
 
-#define strncasecmp strnicmp
-
 typedef u_short ushort;
 
 extern int	isnan(double dsrc);
diff --git a/src/include/port/ultrix4.h b/src/include/port/ultrix4.h
index 2dbbe6ceecdde819a9204dc90a052732adc12a31..4600dd36bd268ea38e888d68df1033b9ec901cc5 100644
--- a/src/include/port/ultrix4.h
+++ b/src/include/port/ultrix4.h
@@ -26,9 +26,6 @@
 #include <sys/types.h>			/* Declare various types, e.g. size_t,
 								 * fd_set */
 
-extern int	strcasecmp(const char *, const char *);
-extern void bzero(void *, size_t);
-
 extern int	fp_class_d(double);
 extern long random(void);
 
diff --git a/src/include/regex/regcustom.h b/src/include/regex/regcustom.h
index 2d111f796becc1b234909dac209825b5f7946ac8..9b0c691de037a77f65ffaa28a362add28ce5192e 100644
--- a/src/include/regex/regcustom.h
+++ b/src/include/regex/regcustom.h
@@ -25,7 +25,7 @@
  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $PostgreSQL: pgsql/src/include/regex/regcustom.h,v 1.3 2003/11/29 22:41:10 pgsql Exp $
+ * $PostgreSQL: pgsql/src/include/regex/regcustom.h,v 1.4 2004/05/07 00:24:58 tgl Exp $
  */
 
 /* headers if any */
@@ -59,10 +59,10 @@ typedef int celt;				/* type to hold chr, MCCE number, or
 #define CHR_MAX 0xfffffffe		/* CHR_MAX-CHR_MIN+1 should fit in uchr */
 
 /* functions operating on chr */
-#define iscalnum(x) pg_isalnum(x)
-#define iscalpha(x) pg_isalpha(x)
-#define iscdigit(x) pg_isdigit(x)
-#define iscspace(x) pg_isspace(x)
+#define iscalnum(x) pg_wc_isalnum(x)
+#define iscalpha(x) pg_wc_isalpha(x)
+#define iscdigit(x) pg_wc_isdigit(x)
+#define iscspace(x) pg_wc_isspace(x)
 
 /* and pick up the standard header */
 #include "regex.h"
diff --git a/src/interfaces/ecpg/pgtypeslib/datetime.c b/src/interfaces/ecpg/pgtypeslib/datetime.c
index b4c4a6daa92721ff30488a613ba64077e32a5e12..a8a26cd4439947e84f0c56485ac435d3276665a5 100644
--- a/src/interfaces/ecpg/pgtypeslib/datetime.c
+++ b/src/interfaces/ecpg/pgtypeslib/datetime.c
@@ -495,7 +495,7 @@ PGTYPESdate_defmt_asc(date * d, char *fmt, char *str)
 
 		/* convert the whole string to lower case */
 		for (i = 0; str_copy[i]; i++)
-			str_copy[i] = (char) tolower((unsigned char) str_copy[i]);
+			str_copy[i] = (char) pg_tolower((unsigned char) str_copy[i]);
 	}
 
 	/* look for numerical tokens */
@@ -565,7 +565,7 @@ PGTYPESdate_defmt_asc(date * d, char *fmt, char *str)
 		{
 			for (j = 0; j < PGTYPES_DATE_MONTH_MAXLENGTH; j++)
 			{
-				month_lower_tmp[j] = (char) tolower((unsigned char) list[i][j]);
+				month_lower_tmp[j] = (char) pg_tolower((unsigned char) list[i][j]);
 				if (!month_lower_tmp[j])
 				{
 					/* properly terminated */
diff --git a/src/interfaces/ecpg/pgtypeslib/dt_common.c b/src/interfaces/ecpg/pgtypeslib/dt_common.c
index 04aaa70ccfcfbc46be72bbc192923cf64784a527..eaa0538f5539c32d2a5f314d50b3b463be733f63 100644
--- a/src/interfaces/ecpg/pgtypeslib/dt_common.c
+++ b/src/interfaces/ecpg/pgtypeslib/dt_common.c
@@ -1847,7 +1847,7 @@ ParseDateTime(char *timestr, char *lowstr,
 				{
 					ftype[nf] = DTK_DATE;
 					while (isalnum((unsigned char) *(*endstr)) || (*(*endstr) == *dp))
-						*lp++ = tolower((unsigned char) *(*endstr)++);
+						*lp++ = pg_tolower((unsigned char) *(*endstr)++);
 				}
 			}
 
@@ -1875,9 +1875,9 @@ ParseDateTime(char *timestr, char *lowstr,
 		else if (isalpha((unsigned char) *(*endstr)))
 		{
 			ftype[nf] = DTK_STRING;
-			*lp++ = tolower((unsigned char) *(*endstr)++);
+			*lp++ = pg_tolower((unsigned char) *(*endstr)++);
 			while (isalpha((unsigned char) *(*endstr)))
-				*lp++ = tolower((unsigned char) *(*endstr)++);
+				*lp++ = pg_tolower((unsigned char) *(*endstr)++);
 
 			/*
 			 * Full date string with leading text month? Could also be a
@@ -1919,9 +1919,9 @@ ParseDateTime(char *timestr, char *lowstr,
 			else if (isalpha((unsigned char) *(*endstr)))
 			{
 				ftype[nf] = DTK_SPECIAL;
-				*lp++ = tolower((unsigned char) *(*endstr)++);
+				*lp++ = pg_tolower((unsigned char) *(*endstr)++);
 				while (isalpha((unsigned char) *(*endstr)))
-					*lp++ = tolower((unsigned char) *(*endstr)++);
+					*lp++ = pg_tolower((unsigned char) *(*endstr)++);
 			}
 			/* otherwise something wrong... */
 			else
@@ -3115,7 +3115,7 @@ PGTYPEStimestamp_defmt_scan(char **str, char *fmt, timestamp *d,
 				 */
 				for (j = 0; !err && j < szdatetktbl; j++)
 				{
-					if (strcasecmp(datetktbl[j].token, scan_val.str_val) == 0)
+					if (pg_strcasecmp(datetktbl[j].token, scan_val.str_val) == 0)
 					{
 						/*
 						 * tz calculates the offset for the seconds, the
diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y
index 3dd7d8b361a7f6e96303608d17c94b52ba090b04..8bec01187906a015b5d07826ff1cc6c8137ba136 100644
--- a/src/interfaces/ecpg/preproc/preproc.y
+++ b/src/interfaces/ecpg/preproc/preproc.y
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.279 2004/05/05 15:03:04 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.280 2004/05/07 00:24:59 tgl Exp $ */
 
 /* Copyright comment */
 %{
@@ -609,7 +609,7 @@ stmt:  AlterDatabaseSetStmt		{ output_statement($1, 0, connection); }
 				/* Informix also has a CLOSE DATABASE command that
 				   essantially works like a DISCONNECT CURRENT 
 				   as far as I know. */
-				if (strcasecmp($1+strlen("close "), "database") == 0)
+				if (pg_strcasecmp($1+strlen("close "), "database") == 0)
 				{
 					if (connection)
 		                                mmerror(PARSE_ERROR, ET_ERROR, "no at option for close database statement.\n");
diff --git a/src/interfaces/libpq/Makefile b/src/interfaces/libpq/Makefile
index 2c8a4fcf71c3dab361ba862be51ffbc183c769fb..3a5a4f99757ce8014621adb927a64118a48a6034 100644
--- a/src/interfaces/libpq/Makefile
+++ b/src/interfaces/libpq/Makefile
@@ -4,7 +4,7 @@
 #
 # Copyright (c) 1994, Regents of the University of California
 #
-# $PostgreSQL: pgsql/src/interfaces/libpq/Makefile,v 1.103 2004/04/25 20:57:32 momjian Exp $
+# $PostgreSQL: pgsql/src/interfaces/libpq/Makefile,v 1.104 2004/05/07 00:24:59 tgl Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -24,7 +24,7 @@ override CFLAGS += $(PTHREAD_CFLAGS)
 OBJS= fe-auth.o fe-connect.o fe-exec.o fe-misc.o fe-print.o fe-lobj.o \
       fe-protocol2.o fe-protocol3.o pqexpbuffer.o pqsignal.o fe-secure.o \
       dllist.o md5.o ip.o wchar.o encnames.o \
-      $(filter crypt.o getaddrinfo.o inet_aton.o noblock.o snprintf.o strerror.o open.o path.o thread.o, $(LIBOBJS))
+      $(filter crypt.o getaddrinfo.o inet_aton.o noblock.o pgstrcasecmp.o snprintf.o strerror.o open.o path.o thread.o, $(LIBOBJS))
 ifeq ($(PORTNAME), win32)
 OBJS+=win32.o
 endif
@@ -53,7 +53,7 @@ backend_src = $(top_srcdir)/src/backend
 # For port modules, this only happens if configure decides the module
 # is needed (see filter hack in OBJS, above).
 
-crypt.c getaddrinfo.c inet_aton.c noblock.c snprintf.c strerror.c open.c path.c thread.c: % : $(top_srcdir)/src/port/%
+crypt.c getaddrinfo.c inet_aton.c noblock.c pgstrcasecmp.c snprintf.c strerror.c open.c path.c thread.c: % : $(top_srcdir)/src/port/%
 	rm -f $@ && $(LN_S) $< .
 
 md5.c ip.c: % : $(backend_src)/libpq/%
@@ -79,4 +79,4 @@ uninstall: uninstall-lib
 	rm -f $(DESTDIR)$(includedir)/libpq-fe.h $(DESTDIR)$(includedir_internal)/libpq-int.h $(DESTDIR)$(includedir_internal)/pqexpbuffer.h
 
 clean distclean maintainer-clean: clean-lib
-	rm -f $(OBJS) crypt.c getaddrinfo.c inet_aton.c noblock.c snprintf.c strerror.c open.c path.c thread.c dllist.c md5.c ip.c encnames.c wchar.c
+	rm -f $(OBJS) crypt.c getaddrinfo.c inet_aton.c noblock.c pgstrcasecmp.c snprintf.c strerror.c open.c path.c thread.c dllist.c md5.c ip.c encnames.c wchar.c
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 6e8c2153e0aef3d1d16a2be812687d964e58c25e..1da5bc1ad653e80424afb1ab38626239e4a77f49 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-exec.c,v 1.158 2004/03/14 22:00:54 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-exec.c,v 1.159 2004/05/07 00:24:59 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1904,8 +1904,7 @@ PQfnumber(const PGresult *res, const char *field_name)
 		}
 		else
 		{
-			if (isupper((unsigned char) c))
-				c = tolower((unsigned char) c);
+			c = pg_tolower((unsigned char) c);
 			*optr++ = c;
 		}
 	}
diff --git a/src/interfaces/libpq/fe-protocol2.c b/src/interfaces/libpq/fe-protocol2.c
index 369481b3386c6ef9216660f57c050c48219fb6f1..0101c1690857a848f5619127b2e04eb1cc8cdb62 100644
--- a/src/interfaces/libpq/fe-protocol2.c
+++ b/src/interfaces/libpq/fe-protocol2.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-protocol2.c,v 1.10 2004/03/05 01:53:59 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-protocol2.c,v 1.11 2004/05/07 00:24:59 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -117,7 +117,7 @@ pqSetenvPoll(PGconn *conn)
 
 						if ((val = getenv(conn->next_eo->envName)))
 						{
-							if (strcasecmp(val, "default") == 0)
+							if (pg_strcasecmp(val, "default") == 0)
 								sprintf(setQuery, "SET %s = DEFAULT",
 										conn->next_eo->pgName);
 							else
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index 1f9621a9b17dd61a018e01dc3ed780a46091caf6..9969c589a02813df0cc868ec61e4ff972271a58e 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-protocol3.c,v 1.12 2004/03/21 22:29:11 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-protocol3.c,v 1.13 2004/05/07 00:24:59 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1471,7 +1471,7 @@ build_startup_packet(const PGconn *conn, char *packet,
 
 		if ((val = getenv(next_eo->envName)) != NULL)
 		{
-			if (strcasecmp(val, "default") != 0)
+			if (pg_strcasecmp(val, "default") != 0)
 			{
 				if (packet)
 					strcpy(packet + packet_len, next_eo->pgName);
diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c
index 83edb06c26e6dae8988d5452d3833c2b36abab99..ffdae2a519f3b16d51813c7308887709dd5f921f 100644
--- a/src/interfaces/libpq/fe-secure.c
+++ b/src/interfaces/libpq/fe-secure.c
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.39 2004/03/27 03:08:42 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.40 2004/05/07 00:24:59 tgl Exp $
  *
  * NOTES
  *	  The client *requires* a valid server certificate.  Since
@@ -544,7 +544,7 @@ verify_peer(PGconn *conn)
 	 */
 	for (s = h->h_aliases; *s != NULL; s++)
 	{
-		if (strcasecmp(conn->peer_cn, *s) == 0)
+		if (pg_strcasecmp(conn->peer_cn, *s) == 0)
 			return 0;
 	}
 
diff --git a/src/interfaces/libpq/win32.h b/src/interfaces/libpq/win32.h
index 350b350b48d88d486f1f49517965b516751a4578..06fdfdded075ec94fc6ec2826b560213fc3feb77 100644
--- a/src/interfaces/libpq/win32.h
+++ b/src/interfaces/libpq/win32.h
@@ -2,18 +2,11 @@
 #define __win32_h_included
 
 /*
- * strcasecmp() is not in Windows, stricmp is, though
- */
-#define strcasecmp(a,b) stricmp(a,b)
-#define strncasecmp(a,b,c) _strnicmp(a,b,c)
-
-/*
- * Some other compat functions
+ * Some compatibility functions
  */
 #ifdef __BORLANDC__
 #define _timeb timeb
 #define _ftime(a) ftime(a)
-#define _strnicmp(a,b,c) strnicmp(a,b,c)
 #define _errno errno
 #else
 /* open provided elsewhere */
diff --git a/src/pl/plpython/plpython.c b/src/pl/plpython/plpython.c
index 010f1e1645ec541261e5be0dee406e175c26732c..f660adf2973971d538f5093f42448d2e88cb927d 100644
--- a/src/pl/plpython/plpython.c
+++ b/src/pl/plpython/plpython.c
@@ -29,7 +29,7 @@
  * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  *
  * IDENTIFICATION
- *	$PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.46 2004/04/01 21:28:46 tgl Exp $
+ *	$PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.47 2004/05/07 00:24:59 tgl Exp $
  *
  *********************************************************************
  */
@@ -443,9 +443,9 @@ PLy_trigger_handler(FunctionCallInfo fcinfo, PLyProcedure * proc)
 			elog(ERROR, "expected trigger to return None or a String");
 
 		srv = PyString_AsString(plrv);
-		if (strcasecmp(srv, "SKIP") == 0)
+		if (pg_strcasecmp(srv, "SKIP") == 0)
 			rv = NULL;
-		else if (strcasecmp(srv, "MODIFY") == 0)
+		else if (pg_strcasecmp(srv, "MODIFY") == 0)
 		{
 			TriggerData *tdata = (TriggerData *) fcinfo->context;
 
@@ -455,7 +455,7 @@ PLy_trigger_handler(FunctionCallInfo fcinfo, PLyProcedure * proc)
 			else
 				elog(WARNING, "ignoring modified tuple in DELETE trigger");
 		}
-		else if (strcasecmp(srv, "OK"))
+		else if (pg_strcasecmp(srv, "OK") != 0)
 		{
 			/*
 			 * hmmm, perhaps they only read the pltcl page, not a
diff --git a/src/port/pgstrcasecmp.c b/src/port/pgstrcasecmp.c
new file mode 100644
index 0000000000000000000000000000000000000000..6ac07804af4d3c9c5247874369f216b81444f130
--- /dev/null
+++ b/src/port/pgstrcasecmp.c
@@ -0,0 +1,125 @@
+/*-------------------------------------------------------------------------
+ *
+ * pgstrcasecmp.c
+ *	   Portable SQL-like case-independent comparisons and conversions.
+ *
+ * SQL99 specifies Unicode-aware case normalization, which we don't yet
+ * have the infrastructure for.  Instead we use tolower() to provide a
+ * locale-aware translation.  However, there are some locales where this
+ * is not right either (eg, Turkish may do strange things with 'i' and
+ * 'I').  Our current compromise is to use tolower() for characters with
+ * the high bit set, and use an ASCII-only downcasing for 7-bit
+ * characters.
+ *
+ * NB: this code should match downcase_truncate_identifier() in scansup.c.
+ *
+ *
+ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
+ *
+ * $PostgreSQL: pgsql/src/port/pgstrcasecmp.c,v 1.1 2004/05/07 00:24:59 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include <ctype.h>
+
+
+/*
+ * Case-independent comparison of two null-terminated strings.
+ */
+int
+pg_strcasecmp(const char *s1, const char *s2)
+{
+	for (;;)
+	{
+		unsigned char	ch1 = (unsigned char) *s1++;
+		unsigned char	ch2 = (unsigned char) *s2++;
+
+		if (ch1 != ch2)
+		{
+			if (ch1 >= 'A' && ch1 <= 'Z')
+				ch1 += 'a' - 'A';
+			else if (ch1 >= 0x80 && isupper(ch1))
+				ch1 = tolower(ch1);
+
+			if (ch2 >= 'A' && ch2 <= 'Z')
+				ch2 += 'a' - 'A';
+			else if (ch2 >= 0x80 && isupper(ch2))
+				ch2 = tolower(ch2);
+
+			if (ch1 != ch2)
+				return (int) ch1 - (int) ch2;
+		}
+		if (ch1 == 0)
+			break;
+	}
+	return 0;
+}
+
+/*
+ * Case-independent comparison of two not-necessarily-null-terminated strings.
+ * At most n bytes will be examined from each string.
+ */
+int
+pg_strncasecmp(const char *s1, const char *s2, size_t n)
+{
+	while (n-- > 0)
+	{
+		unsigned char	ch1 = (unsigned char) *s1++;
+		unsigned char	ch2 = (unsigned char) *s2++;
+
+		if (ch1 != ch2)
+		{
+			if (ch1 >= 'A' && ch1 <= 'Z')
+				ch1 += 'a' - 'A';
+			else if (ch1 >= 0x80 && isupper(ch1))
+				ch1 = tolower(ch1);
+
+			if (ch2 >= 'A' && ch2 <= 'Z')
+				ch2 += 'a' - 'A';
+			else if (ch2 >= 0x80 && isupper(ch2))
+				ch2 = tolower(ch2);
+
+			if (ch1 != ch2)
+				return (int) ch1 - (int) ch2;
+		}
+		if (ch1 == 0)
+			break;
+	}
+	return 0;
+}
+
+/*
+ * Fold a character to upper case.
+ *
+ * Unlike some versions of toupper(), this is safe to apply to characters
+ * that aren't upper case letters.  Note however that the whole thing is
+ * a bit bogus for multibyte character sets.
+ */
+unsigned char
+pg_toupper(unsigned char ch)
+{
+	if (ch >= 'a' && ch <= 'z')
+		ch += 'A' - 'a';
+	else if (ch >= 0x80 && islower(ch))
+		ch = toupper(ch);
+	return ch;
+}
+
+/*
+ * Fold a character to lower case.
+ *
+ * Unlike some versions of tolower(), this is safe to apply to characters
+ * that aren't lower case letters.  Note however that the whole thing is
+ * a bit bogus for multibyte character sets.
+ */
+unsigned char
+pg_tolower(unsigned char ch)
+{
+	if (ch >= 'A' && ch <= 'Z')
+		ch += 'a' - 'A';
+	else if (ch >= 0x80 && isupper(ch))
+		ch = tolower(ch);
+	return ch;
+}
diff --git a/src/port/strcasecmp.c b/src/port/strcasecmp.c
deleted file mode 100644
index a89a84019dd69f75ffdb0e8f9dfa1839992af7a3..0000000000000000000000000000000000000000
--- a/src/port/strcasecmp.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/* $PostgreSQL: pgsql/src/port/strcasecmp.c,v 1.4 2003/11/29 22:41:31 pgsql Exp $ */
-
-/*
- * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
- * Portions Copyright (c) 1987 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of California at Berkeley. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific written prior permission. This software
- * is provided ``as is'' without express or implied warranty.
- */
-
-#include <sys/types.h>
-#include <string.h>
-
-/*
- * This array is designed for mapping upper and lower case letter
- * together for a case independent comparison.	The mappings are
- * based upon ascii character sequences.
- */
-static unsigned char charmap[] = {
-	'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
-	'\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
-	'\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
-	'\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
-	'\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
-	'\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
-	'\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
-	'\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
-	'\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
-	'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
-	'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
-	'\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
-	'\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
-	'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
-	'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
-	'\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
-	'\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
-	'\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
-	'\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
-	'\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
-	'\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
-	'\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
-	'\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
-	'\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
-	'\300', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
-	'\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
-	'\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
-	'\370', '\371', '\372', '\333', '\334', '\335', '\336', '\337',
-	'\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
-	'\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
-	'\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
-	'\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
-};
-
-int
-strcasecmp(char *s1, char *s2)
-{
-	unsigned char u1,
-				u2;
-
-	for (;;)
-	{
-		u1 = (unsigned char) *s1++;
-		u2 = (unsigned char) *s2++;
-		if (charmap[u1] != charmap[u2])
-			return charmap[u1] - charmap[u2];
-		if (u1 == '\0')
-			return 0;
-	}
-}