diff --git a/src/interfaces/ecpg/ChangeLog b/src/interfaces/ecpg/ChangeLog
index 1f3bf095e44462a5782535e91d36f5ee5f0be8a4..1dbed255367fb33fb0c134238dc6fc3d3b17111a 100644
--- a/src/interfaces/ecpg/ChangeLog
+++ b/src/interfaces/ecpg/ChangeLog
@@ -2225,5 +2225,9 @@ Tue, 14 Aug 2007 11:46:51 +0200
 	- Use '$n' for positional variables, '?' is still possible via ecpg
 	  option.
 	- Cleaned up the sources a little bit.
+
+Wed, 22 Aug 2007 08:41:33 +0200
+
+	- More cleaning up and removed some duplicates.
 	- Set ecpg library version to 6.0.
 	- Set ecpg version to 4.4.
diff --git a/src/interfaces/ecpg/pgtypeslib/dt.h b/src/interfaces/ecpg/pgtypeslib/dt.h
index 83f8c520c274b31807a828300b1167071e70a52d..c75775ffb5b49391f3c430930d377a14b3df9d8e 100644
--- a/src/interfaces/ecpg/pgtypeslib/dt.h
+++ b/src/interfaces/ecpg/pgtypeslib/dt.h
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/dt.h,v 1.37 2007/08/14 10:01:53 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/dt.h,v 1.38 2007/08/22 08:20:58 meskes Exp $ */
 
 #ifndef DT_H
 #define DT_H
@@ -310,31 +310,24 @@ do { \
 #define TIMESTAMP_IS_NOEND(j)	((j) == DT_NOEND)
 #define TIMESTAMP_NOT_FINITE(j) (TIMESTAMP_IS_NOBEGIN(j) || TIMESTAMP_IS_NOEND(j))
 
-int DecodeTimeOnly(char **field, int *ftype,
-			   int nf, int *dtype,
-			   struct tm * tm, fsec_t *fsec, int *tzp);
-
-int DecodeInterval(char **field, int *ftype,
-			   int nf, int *dtype,
-			   struct tm * tm, fsec_t *fsec);
-
-int			EncodeTimeOnly(struct tm * tm, fsec_t fsec, int *tzp, int style, char *str);
-int			EncodeDateTime(struct tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, char *str, bool);
-int			EncodeInterval(struct tm * tm, fsec_t fsec, int style, char *str);
-
-int			tm2timestamp(struct tm *, fsec_t, int *, timestamp *);
-
-int			DecodeUnits(int field, char *lowtoken, int *val);
-
-bool		CheckDateTokenTables(void);
-
-int			EncodeDateOnly(struct tm *, int, char *, bool);
-void		GetEpochTime(struct tm *);
-int			ParseDateTime(char *, char *, char **, int *, int, int *, char **);
-int			DecodeDateTime(char **, int *, int, int *, struct tm *, fsec_t *, bool);
-void		j2date(int, int *, int *, int *);
-void		GetCurrentDateTime(struct tm *);
-int			date2j(int, int, int);
+int DecodeTimeOnly(char **, int *, int, int *, struct tm *, fsec_t *, int *);
+int DecodeInterval(char **, int *, int, int *, struct tm *, fsec_t *);
+int DecodeTime(char *, int, int *, struct tm *, fsec_t *);
+int EncodeTimeOnly(struct tm *, fsec_t, int *, int, char *);
+int EncodeDateTime(struct tm *, fsec_t, int *, char **, int, char *, bool);
+int EncodeInterval(struct tm *, fsec_t, int, char *);
+int tm2timestamp(struct tm *, fsec_t, int *, timestamp *);
+int DecodeUnits(int field, char *lowtoken, int *val);
+bool CheckDateTokenTables(void);
+int EncodeDateOnly(struct tm *, int, char *, bool);
+void GetEpochTime(struct tm *);
+int ParseDateTime(char *, char *, char **, int *, int, int *, char **);
+int DecodeDateTime(char **, int *, int, int *, struct tm *, fsec_t *, bool);
+void j2date(int, int *, int *, int *);
+void GetCurrentDateTime(struct tm *);
+int date2j(int, int, int);
+void TrimTrailingZeros(char *);
+void dt2time(double, int *, int *, int *, fsec_t *);
 
 extern char *pgtypes_date_weekdays_short[];
 extern char *pgtypes_date_months[];
diff --git a/src/interfaces/ecpg/pgtypeslib/dt_common.c b/src/interfaces/ecpg/pgtypeslib/dt_common.c
index 53dc325a465bbb44623d6e7737d9501cfe840304..299186ec02a23431e78527d682c5fe792c289432 100644
--- a/src/interfaces/ecpg/pgtypeslib/dt_common.c
+++ b/src/interfaces/ecpg/pgtypeslib/dt_common.c
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/dt_common.c,v 1.41 2007/08/14 10:01:53 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/dt_common.c,v 1.42 2007/08/22 08:20:58 meskes Exp $ */
 
 #include "postgres_fe.h"
 
@@ -743,7 +743,7 @@ EncodeDateOnly(struct tm * tm, int style, char *str, bool EuroDates)
 	return TRUE;
 }	/* EncodeDateOnly() */
 
-static void
+void
 TrimTrailingZeros(char *str)
 {
 	int			len = strlen(str);
@@ -1090,7 +1090,7 @@ GetCurrentDateTime(struct tm * tm)
 	abstime2tm(time(NULL), &tz, tm, NULL);
 }
 
-static void
+void
 dt2time(double jd, int *hour, int *min, int *sec, fsec_t *fsec)
 {
 #ifdef HAVE_INT64_TIMESTAMP
@@ -1469,7 +1469,7 @@ DecodeDate(char *str, int fmask, int *tmask, struct tm * tm, bool EuroDates)
  * Only check the lower limit on hours, since this same code
  *	can be used to represent time spans.
  */
-static int
+int
 DecodeTime(char *str, int fmask, int *tmask, struct tm * tm, fsec_t *fsec)
 {
 	char	   *cp;
diff --git a/src/interfaces/ecpg/pgtypeslib/interval.c b/src/interfaces/ecpg/pgtypeslib/interval.c
index 534acdcc5fd77379325acffb05f2c64f312ca289..a8f1899fdb3c08bd6280a790dcb3814ac6ee6a1e 100644
--- a/src/interfaces/ecpg/pgtypeslib/interval.c
+++ b/src/interfaces/ecpg/pgtypeslib/interval.c
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/interval.c,v 1.36 2006/10/04 00:30:11 momjian Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/interval.c,v 1.37 2007/08/22 08:20:58 meskes Exp $ */
 
 #include "postgres_fe.h"
 #include <time.h>
@@ -13,90 +13,6 @@
 #include "pgtypes_error.h"
 #include "pgtypes_interval.h"
 
-/* TrimTrailingZeros()
- * ... resulting from printing numbers with full precision.
- */
-static void
-TrimTrailingZeros(char *str)
-{
-	int			len = strlen(str);
-
-	/* chop off trailing zeros... but leave at least 2 fractional digits */
-	while (*(str + len - 1) == '0' && *(str + len - 3) != '.')
-	{
-		len--;
-		*(str + len) = '\0';
-	}
-}
-
-/* DecodeTime()
- * Decode time string which includes delimiters.
- * Only check the lower limit on hours, since this same code
- *	can be used to represent time spans.
- */
-static int
-DecodeTime(char *str, int fmask, int *tmask, struct tm * tm, fsec_t *fsec)
-{
-	char	   *cp;
-
-	*tmask = DTK_TIME_M;
-
-	tm->tm_hour = strtol(str, &cp, 10);
-	if (*cp != ':')
-		return -1;
-	str = cp + 1;
-	tm->tm_min = strtol(str, &cp, 10);
-	if (*cp == '\0')
-	{
-		tm->tm_sec = 0;
-		*fsec = 0;
-	}
-	else if (*cp != ':')
-		return -1;
-	else
-	{
-		str = cp + 1;
-		tm->tm_sec = strtol(str, &cp, 10);
-		if (*cp == '\0')
-			*fsec = 0;
-		else if (*cp == '.')
-		{
-#ifdef HAVE_INT64_TIMESTAMP
-			char		fstr[MAXDATELEN + 1];
-
-			/*
-			 * OK, we have at most six digits to work with. Let's construct a
-			 * string and then do the conversion to an integer.
-			 */
-			strncpy(fstr, (cp + 1), 7);
-			strcpy(fstr + strlen(fstr), "000000");
-			*(fstr + 6) = '\0';
-			*fsec = strtol(fstr, &cp, 10);
-#else
-			str = cp;
-			*fsec = strtod(str, &cp);
-#endif
-			if (*cp != '\0')
-				return -1;
-		}
-		else
-			return -1;
-	}
-
-	/* do a sanity check */
-#ifdef HAVE_INT64_TIMESTAMP
-	if (tm->tm_hour < 0 || tm->tm_min < 0 || tm->tm_min > 59 ||
-		tm->tm_sec < 0 || tm->tm_sec > 59 || *fsec >= USECS_PER_SEC)
-		return -1;
-#else
-	if (tm->tm_hour < 0 || tm->tm_min < 0 || tm->tm_min > 59 ||
-		tm->tm_sec < 0 || tm->tm_sec > 59 || *fsec >= 1)
-		return -1;
-#endif
-
-	return 0;
-}	/* DecodeTime() */
-
 /* DecodeInterval()
  * Interpret previously parsed fields for general time interval.
  * Return 0 if decoded and -1 if problems.
diff --git a/src/interfaces/ecpg/pgtypeslib/timestamp.c b/src/interfaces/ecpg/pgtypeslib/timestamp.c
index 4ec94672bb9402941ed77b38d5d7179d272b03eb..03aa5f07d08795abdec6c95c44efecc384390afa 100644
--- a/src/interfaces/ecpg/pgtypeslib/timestamp.c
+++ b/src/interfaces/ecpg/pgtypeslib/timestamp.c
@@ -97,36 +97,6 @@ SetEpochTimestamp(void)
 	return dt;
 }	/* SetEpochTimestamp() */
 
-static void
-dt2time(timestamp jd, int *hour, int *min, int *sec, fsec_t *fsec)
-{
-#ifdef HAVE_INT64_TIMESTAMP
-	int64		time;
-#else
-	double		time;
-#endif
-
-	time = jd;
-
-#ifdef HAVE_INT64_TIMESTAMP
-	*hour = time / USECS_PER_HOUR;
-	time -= (*hour) * USECS_PER_HOUR;
-	*min = time / USECS_PER_MINUTE;
-	time -= (*min) * USECS_PER_MINUTE;
-	*sec = time / USECS_PER_SEC;
-	*fsec = time - *sec * USECS_PER_SEC;
-	*sec = time / USECS_PER_SEC;
-	*fsec = time - *sec * USECS_PER_SEC;
-#else
-	*hour = time / SECS_PER_HOUR;
-	time -= (*hour) * SECS_PER_HOUR;
-	*min = time / SECS_PER_MINUTE;
-	time -= (*min) * SECS_PER_MINUTE;
-	*sec = time;
-	*fsec = time - *sec;
-#endif
-}	/* dt2time() */
-
 /* timestamp2tm()
  * Convert timestamp data type to POSIX time structure.
  * Note that year is _not_ 1900-based, but is an explicit full value.
diff --git a/src/interfaces/ecpg/preproc/Makefile b/src/interfaces/ecpg/preproc/Makefile
index 6d8826608798eed09923b908a93def199228bd27..16f26fafdeb7719559452d8940dae6abb15883a7 100644
--- a/src/interfaces/ecpg/preproc/Makefile
+++ b/src/interfaces/ecpg/preproc/Makefile
@@ -4,7 +4,7 @@
 #
 # Copyright (c) 1998-2007, PostgreSQL Global Development Group
 #
-# $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/Makefile,v 1.127 2007/08/14 10:01:53 meskes Exp $
+# $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/Makefile,v 1.128 2007/08/22 08:20:58 meskes Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -27,7 +27,7 @@ override CFLAGS += -Wno-error
 endif
 override CFLAGS += $(PTHREAD_CFLAGS)
 
-OBJS=	preproc.o type.o ecpg.o ecpg_keywords.o output.o parser.o \
+OBJS=	preproc.o type.o ecpg.o output.o parser.o \
 	keywords.o c_keywords.o ../ecpglib/typename.o descriptor.o variable.o \
 	$(WIN32RES)
 
@@ -57,7 +57,7 @@ else
 	@$(missing) flex $< $@
 endif
 
-c_keywords.o ecpg_keywords.o keywords.o preproc.o parser.o: preproc.h
+c_keywords.o keywords.o preproc.o parser.o: preproc.h
 
 parser.c: $(top_srcdir)/src/backend/parser/parser.c
 	rm -f $@ && $(LN_S) $< .
diff --git a/src/interfaces/ecpg/preproc/c_keywords.c b/src/interfaces/ecpg/preproc/c_keywords.c
index e58831008d8b8ae7528af6ffb4739f7f7a312f5e..bd76ac15e64690223482c1158e236edc20612bc9 100644
--- a/src/interfaces/ecpg/preproc/c_keywords.c
+++ b/src/interfaces/ecpg/preproc/c_keywords.c
@@ -3,7 +3,7 @@
  * keywords.c
  *	  lexical token lookup for reserved words in postgres embedded SQL
  *
- * $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/c_keywords.c,v 1.20 2007/05/10 09:53:16 meskes Exp $
+ * $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/c_keywords.c,v 1.21 2007/08/22 08:20:58 meskes Exp $
  * §
  *-------------------------------------------------------------------------
  */
@@ -20,7 +20,7 @@
  * !!WARNING!!: This list must be sorted, because binary
  *		 search is used to locate entries.
  */
-static ScanKeyword ScanKeywords[] = {
+static const ScanKeyword ScanCKeywords[] = {
 	/* name					value			*/
 	{"VARCHAR", VARCHAR},
 	{"auto", S_AUTO},
@@ -50,25 +50,8 @@ static ScanKeyword ScanKeywords[] = {
 	{"year", YEAR_P},
 };
 
-ScanKeyword *
+const ScanKeyword *
 ScanCKeywordLookup(char *text)
 {
-	ScanKeyword *low = &ScanKeywords[0];
-	ScanKeyword *high = endof(ScanKeywords) - 1;
-	ScanKeyword *middle;
-	int			difference;
-
-	while (low <= high)
-	{
-		middle = low + (high - low) / 2;
-		difference = strcmp(middle->name, text);
-		if (difference == 0)
-			return middle;
-		else if (difference < 0)
-			low = middle + 1;
-		else
-			high = middle - 1;
-	}
-
-	return NULL;
+	return DoLookup(text, &ScanCKeywords[0], endof(ScanCKeywords) - 1);
 }
diff --git a/src/interfaces/ecpg/preproc/ecpg_keywords.c b/src/interfaces/ecpg/preproc/ecpg_keywords.c
index 3244880151b138124a874e98e685babc25d078e5..6155bc1f7359b7e1129df29903c47ba23580e5a5 100644
--- a/src/interfaces/ecpg/preproc/ecpg_keywords.c
+++ b/src/interfaces/ecpg/preproc/ecpg_keywords.c
@@ -4,17 +4,10 @@
  *	  lexical token lookup for reserved words in postgres embedded SQL
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg_keywords.c,v 1.35 2007/06/12 07:55:56 meskes Exp $
+ *	  $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg_keywords.c,v 1.36 2007/08/22 08:20:58 meskes Exp $
  *
  *-------------------------------------------------------------------------
  */
-#include "postgres_fe.h"
-
-#include <ctype.h>
-
-#include "extern.h"
-#include "preproc.h"
-
 
 /*
  * List of (keyword-name, keyword-token-value) pairs.
@@ -22,7 +15,7 @@
  * !!WARNING!!: This list must be sorted, because binary
  *		 search is used to locate entries.
  */
-static ScanKeyword ScanKeywords[] = {
+static const ScanKeyword ScanECPGKeywords[] = {
 	/* name					value			*/
 	{"allocate", SQL_ALLOCATE},
 	{"autocommit", SQL_AUTOCOMMIT},
@@ -71,69 +64,3 @@ static ScanKeyword ScanKeywords[] = {
 	{"whenever", SQL_WHENEVER},
 };
 
-/*
- * ScanECPGKeywordLookup - see if a given word is a keyword
- *
- * Returns a pointer to the ScanKeyword table entry, or NULL if no match.
- *
- * The match is done case-insensitively.  Note that we deliberately use a
- * dumbed-down case conversion that will only translate 'A'-'Z' into 'a'-'z',
- * even if we are in a locale where tolower() would produce more or different
- * translations.  This is to conform to the SQL99 spec, which says that
- * keywords are to be matched in this way even though non-keyword identifiers
- * receive a different case-normalization mapping.
- */
-ScanKeyword *
-ScanECPGKeywordLookup(char *text)
-{
-	int			len,
-				i;
-	char		word[NAMEDATALEN];
-	ScanKeyword *low;
-	ScanKeyword *high;
-
-	len = strlen(text);
-	/* We assume all keywords are shorter than NAMEDATALEN. */
-	if (len >= NAMEDATALEN)
-		return NULL;
-
-	/*
-	 * Apply an ASCII-only downcasing.	We must not use tolower() since it may
-	 * produce the wrong translation in some locales (eg, Turkish), and we
-	 * don't trust isupper() very much either.  In an ASCII-based encoding the
-	 * tests against A and Z are sufficient, but we also check isupper() so
-	 * that we will work correctly under EBCDIC.  The actual case conversion
-	 * step should work for either ASCII or EBCDIC.
-	 */
-	for (i = 0; i < len; i++)
-	{
-		char		ch = text[i];
-
-		if (ch >= 'A' && ch <= 'Z' && isupper((unsigned char) ch))
-			ch += 'a' - 'A';
-		word[i] = ch;
-	}
-	word[len] = '\0';
-
-	/*
-	 * Now do a binary search using plain strcmp() comparison.
-	 */
-	low = &ScanKeywords[0];
-	high = endof(ScanKeywords) - 1;
-	while (low <= high)
-	{
-		ScanKeyword *middle;
-		int			difference;
-
-		middle = low + (high - low) / 2;
-		difference = strcmp(middle->name, word);
-		if (difference == 0)
-			return middle;
-		else if (difference < 0)
-			low = middle + 1;
-		else
-			high = middle - 1;
-	}
-
-	return NULL;
-}
diff --git a/src/interfaces/ecpg/preproc/extern.h b/src/interfaces/ecpg/preproc/extern.h
index 8b5b864611063d1db4aafa25b0e223db01396f72..ecd646100eb951fd202ca2c033c28c68ff9e2e24 100644
--- a/src/interfaces/ecpg/preproc/extern.h
+++ b/src/interfaces/ecpg/preproc/extern.h
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/extern.h,v 1.68 2007/08/14 10:54:57 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/extern.h,v 1.69 2007/08/22 08:20:58 meskes Exp $ */
 
 #ifndef _ECPG_PREPROC_EXTERN_H
 #define _ECPG_PREPROC_EXTERN_H
@@ -74,8 +74,7 @@ extern void base_yyerror(const char *);
 extern void *mm_alloc(size_t), *mm_realloc(void *, size_t);
 extern char *mm_strdup(const char *);
 extern void mmerror(int, enum errortype, char *,...);
-extern ScanKeyword *ScanECPGKeywordLookup(char *);
-extern ScanKeyword *ScanCKeywordLookup(char *);
+extern const ScanKeyword *ScanCKeywordLookup(char *);
 extern void output_get_descr_header(char *);
 extern void output_get_descr(char *, char *);
 extern void output_set_descr_header(char *);
@@ -97,7 +96,8 @@ extern void check_indicator(struct ECPGtype *);
 extern void remove_typedefs(int);
 extern void remove_variables(int);
 extern struct variable *new_variable(const char *, struct ECPGtype *, int);
-extern ScanKeyword *ScanKeywordLookup(char *text);
+extern const ScanKeyword *ScanKeywordLookup(char *text);
+extern const ScanKeyword *DoLookup(char *, const ScanKeyword *,const ScanKeyword *);
 extern void scanner_init(const char *);
 extern void parser_init(void);
 extern void scanner_finish(void);
diff --git a/src/interfaces/ecpg/preproc/keywords.c b/src/interfaces/ecpg/preproc/keywords.c
index f2f3094e06c090922ee284ba52aa218684e7b1d3..5c87e5cd13b21167ef80cf94b281c213f2f2433d 100644
--- a/src/interfaces/ecpg/preproc/keywords.c
+++ b/src/interfaces/ecpg/preproc/keywords.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.80 2007/06/12 07:55:56 meskes Exp $
+ *	  $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.81 2007/08/22 08:20:58 meskes Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -19,6 +19,8 @@
 #include "extern.h"
 #include "preproc.h"
 
+/* compile both keyword lists in one file because they are always scanned together */
+#include "ecpg_keywords.c"
 
 /*
  * List of (keyword-name, keyword-token-value) pairs.
@@ -26,7 +28,7 @@
  * !!WARNING!!: This list must be sorted, because binary
  *		 search is used to locate entries.
  */
-static ScanKeyword ScanKeywords[] = {
+static const ScanKeyword ScanPGSQLKeywords[] = {
 	/* name, value */
 	{"abort", ABORT_P},
 	{"absolute", ABSOLUTE_P},
@@ -395,6 +397,31 @@ static ScanKeyword ScanKeywords[] = {
 	{"zone", ZONE},
 };
 
+
+/*
+ * Now do a binary search using plain strcmp() comparison.
+ */
+const ScanKeyword *
+DoLookup(char *word, const ScanKeyword *low, const ScanKeyword *high)
+{
+	while (low <= high)
+	{
+		const ScanKeyword *middle;
+		int			difference;
+
+		middle = low + (high - low) / 2;
+		difference = strcmp(middle->name, word);
+		if (difference == 0)
+			return middle;
+		else if (difference < 0)
+			low = middle + 1;
+		else
+			high = middle - 1;
+	}
+
+	return NULL;
+}
+
 /*
  * ScanKeywordLookup - see if a given word is a keyword
  *
@@ -407,14 +434,13 @@ static ScanKeyword ScanKeywords[] = {
  * keywords are to be matched in this way even though non-keyword identifiers
  * receive a different case-normalization mapping.
  */
-ScanKeyword *
+const ScanKeyword *
 ScanKeywordLookup(char *text)
 {
 	int			len,
 				i;
 	char		word[NAMEDATALEN];
-	ScanKeyword *low;
-	ScanKeyword *high;
+	const ScanKeyword *res;
 
 	len = strlen(text);
 	/* We assume all keywords are shorter than NAMEDATALEN. */
@@ -438,22 +464,10 @@ ScanKeywordLookup(char *text)
 	/*
 	 * Now do a binary search using plain strcmp() comparison.
 	 */
-	low = &ScanKeywords[0];
-	high = endof(ScanKeywords) - 1;
-	while (low <= high)
-	{
-		ScanKeyword *middle;
-		int			difference;
-
-		middle = low + (high - low) / 2;
-		difference = strcmp(middle->name, word);
-		if (difference == 0)
-			return middle;
-		else if (difference < 0)
-			low = middle + 1;
-		else
-			high = middle - 1;
-	}
+	res = DoLookup(word, &ScanPGSQLKeywords[0], endof(ScanPGSQLKeywords) - 1);
+	if (res)
+		return res;
 
-	return NULL;
+	return DoLookup(word, &ScanECPGKeywords[0], endof(ScanECPGKeywords) - 1);
 }
+
diff --git a/src/interfaces/ecpg/preproc/pgc.l b/src/interfaces/ecpg/preproc/pgc.l
index 23f22071225d6403e8605dcfc65ee0a934ce8c80..c9ba3431ce68d41eda386e677fda5000bf1fb0b7 100644
--- a/src/interfaces/ecpg/preproc/pgc.l
+++ b/src/interfaces/ecpg/preproc/pgc.l
@@ -12,7 +12,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.153 2007/08/14 10:01:53 meskes Exp $
+ *	  $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.154 2007/08/22 08:20:58 meskes Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -49,6 +49,7 @@ static void addlitchar (unsigned char);
 static void parse_include (void);
 static void check_escape_warning(void);
 static bool ecpg_isspace(char ch);
+static bool isdefine(void);
 
 char *token_start;
 int state_before;
@@ -681,41 +682,15 @@ cppline			{space}*#(.*\\{space})*.*{newline}
 						return(CVARIABLE);
 					}
 <SQL>{identifier}	{
-						ScanKeyword    *keyword;
-						struct _defines *ptr;
+						const ScanKeyword    *keyword;
 						
-						/* How about a DEFINE? */
-						for (ptr = defines; ptr; ptr = ptr->next)
-						{
-							if (strcmp(yytext, ptr->old) == 0 && ptr->used == NULL)
-							{
-								struct _yy_buffer *yb;
-
-								yb = mm_alloc(sizeof(struct _yy_buffer));
-
-								yb->buffer =  YY_CURRENT_BUFFER;
-								yb->lineno = yylineno;
-								yb->filename = mm_strdup(input_filename);
-								yb->next = yy_buffer;
-								
-								ptr->used = yy_buffer = yb;
-
-								yy_scan_string(ptr->new);
-								break;
-							}
-						}
-						if (ptr == NULL)
+						if (!isdefine())
 						{
-							/* Is it an SQL keyword? */
+							/* Is it an SQL/ECPG keyword? */
 							keyword = ScanKeywordLookup(yytext);
 							if (keyword != NULL)
 								return keyword->value;
 
-							/* Is it an ECPG keyword? */
-							keyword = ScanECPGKeywordLookup( yytext);
-							if (keyword != NULL)
-								return keyword->value;
-
 							/* Is it a C keyword? */
 							keyword = ScanCKeywordLookup(yytext);
 							if (keyword != NULL)
@@ -775,39 +750,9 @@ cppline			{space}*#(.*\\{space})*.*{newline}
 						return(CPP_LINE);
 					}
 <C>{identifier} 	{
-						ScanKeyword		*keyword;
-						struct _defines *ptr;
-
-						if (INFORMIX_MODE)
-						{
-							/* Informix uses SQL defines only in SQL space */
-							ptr = NULL;
-						}
-						else
-						{
-							/* is it a define? */
-							for (ptr = defines; ptr; ptr = ptr->next)
-							{
-								if (strcmp(yytext, ptr->old) == 0 && ptr->used == NULL)
-								{
-									struct _yy_buffer *yb;
-
-									yb = mm_alloc(sizeof(struct _yy_buffer));
-
-									yb->buffer =  YY_CURRENT_BUFFER;
-									yb->lineno = yylineno;
-									yb->filename = mm_strdup(input_filename);
-									yb->next = yy_buffer;
+						const ScanKeyword		*keyword;
 
-									ptr->used = yy_buffer = yb;
-
-									yy_scan_string(ptr->new);
-									break;
-								}
-							}
-						}
-
-						if (ptr == NULL)
+						if (INFORMIX_MODE || !isdefine())
 						{
 							keyword = ScanCKeywordLookup(yytext);
 							if (keyword != NULL)
@@ -1359,6 +1304,33 @@ ecpg_isspace(char ch)
 	return false;
 }
 
+static bool isdefine(void)
+{
+	struct _defines *ptr;
+
+	/* is it a define? */
+	for (ptr = defines; ptr; ptr = ptr->next)
+	{
+		if (strcmp(yytext, ptr->old) == 0 && ptr->used == NULL)
+		{
+			struct _yy_buffer *yb;
+
+			yb = mm_alloc(sizeof(struct _yy_buffer));
+
+			yb->buffer =  YY_CURRENT_BUFFER;
+			yb->lineno = yylineno;
+			yb->filename = mm_strdup(input_filename);
+			yb->next = yy_buffer;
+
+			ptr->used = yy_buffer = yb;
+
+			yy_scan_string(ptr->new);
+			return true;
+		}
+	}
+
+	return false;
+}
 
 /*
  * Called before any actual parsing is done
diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y
index 6d665392f5e4815c12177a51b18eebd00df9a764..ffbb7f7844dcd296ffd4e32027ad85048ad4906d 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.349 2007/08/14 10:01:53 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.350 2007/08/22 08:20:58 meskes Exp $ */
 
 /* Copyright comment */
 %{
@@ -319,6 +319,51 @@ add_additional_variables(char *name, bool insert)
 
 	return ptr;
 }
+
+static void
+add_typedef(char *name, char * dimension, char * length, enum ECPGttype type_enum, char *type_dimension, char *type_index, int initializer, int array)
+{
+	/* add entry to list */
+	struct typedefs *ptr, *this;
+
+	if ((type_enum == ECPGt_struct ||
+	     type_enum == ECPGt_union) &&
+	    initializer == 1)
+		mmerror(PARSE_ERROR, ET_ERROR, "Initializer not allowed in typedef command");
+	else
+	{
+		for (ptr = types; ptr != NULL; ptr = ptr->next)
+		{
+			if (strcmp(name, ptr->name) == 0)
+				/* re-definition is a bug */
+				mmerror(PARSE_ERROR, ET_ERROR, "Type %s already defined", name);
+		}
+		adjust_array(type_enum, &dimension, &length, type_dimension, type_index, array, true);
+
+		this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
+
+		/* initial definition */
+		this->next = types;
+		this->name = name;
+		this->brace_level = braces_open;
+		this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
+		this->type->type_enum = type_enum;
+		this->type->type_str = mm_strdup(name);
+		this->type->type_dimension = dimension; /* dimension of array */
+		this->type->type_index = length;	/* length of string */
+		this->type->type_sizeof = ECPGstruct_sizeof;
+		this->struct_member_list = (type_enum == ECPGt_struct || type_enum == ECPGt_union) ?
+		ECPGstruct_member_dup(struct_member_list[struct_level]) : NULL;
+
+		if (type_enum != ECPGt_varchar &&
+			type_enum != ECPGt_char &&
+			type_enum != ECPGt_unsigned_char &&
+			atoi(this->type->type_index) >= 0)
+			mmerror(PARSE_ERROR, ET_ERROR, "No multidimensional array support for simple data types");
+
+		types = this;
+	}
+}
 %}
 
 %name-prefix="base_yy"
@@ -597,7 +642,7 @@ add_additional_variables(char *name, bool insert)
 %type  <str>	var_declaration type_declaration single_vt_declaration
 %type  <str>	ECPGSetAutocommit on_off variable_declarations ECPGDescribe
 %type  <str>	ECPGAllocateDescr ECPGDeallocateDescr symbol opt_output
-%type  <str>	ECPGGetDescriptorHeader ECPGColLabel single_var_declaration
+%type  <str>	ECPGGetDescriptorHeader ECPGColLabel 
 %type  <str>	reserved_keyword unreserved_keyword ecpg_interval opt_ecpg_using
 %type  <str>	col_name_keyword precision opt_scale ECPGExecuteImmediateStmt
 %type  <str>	ECPGTypeName using_list ECPGColLabelCommon UsingConst 
@@ -5124,40 +5169,7 @@ ECPGExecuteImmediateStmt: EXECUTE IMMEDIATE execstring
 ECPGVarDeclaration: single_vt_declaration;
 
 single_vt_declaration: type_declaration		{ $$ = $1; }
-		| single_var_declaration	{ $$ = $1; }
-		;
-
-single_var_declaration: storage_declaration
-		var_type
-		{
-			actual_type[struct_level].type_enum = $2.type_enum;
-			actual_type[struct_level].type_dimension = $2.type_dimension;
-			actual_type[struct_level].type_index = $2.type_index;
-			actual_type[struct_level].type_sizeof = $2.type_sizeof;
-
-			actual_startline[struct_level] = hashline_number();
-		}
-		variable_list ';'
-		{
-			$$ = cat_str(5, actual_startline[struct_level], $1, $2.type_str, $4, make_str(";\n"));
-		}
-		| var_type
-		{
-			actual_type[struct_level].type_enum = $1.type_enum;
-			actual_type[struct_level].type_dimension = $1.type_dimension;
-			actual_type[struct_level].type_index = $1.type_index;
-			actual_type[struct_level].type_sizeof = $1.type_sizeof;
-
-			actual_startline[struct_level] = hashline_number();
-		}
-		variable_list ';'
-		{
-			$$ = cat_str(4, actual_startline[struct_level], $1.type_str, $3, make_str(";\n"));
-		}
-		| struct_union_type_with_symbol ';'
-		{
-			$$ = cat2_str($1, make_str(";"));
-		}
+		| var_declaration		{ $$ = $1; }
 		;
 
 precision:	NumConst	{ $$ = $1; };
@@ -5214,50 +5226,9 @@ type_declaration: S_TYPEDEF
 	}
 	var_type opt_pointer ECPGColLabelCommon opt_array_bounds ';'
 	{
-		/* add entry to list */
-		struct typedefs *ptr, *this;
-		char * dimension = $6.index1;
-		char * length = $6.index2;
-
-		if (($3.type_enum == ECPGt_struct ||
-		     $3.type_enum == ECPGt_union) &&
-		    initializer == 1)
-			mmerror(PARSE_ERROR, ET_ERROR, "Initializer not allowed in typedef command");
-		else
-		{
-			for (ptr = types; ptr != NULL; ptr = ptr->next)
-			{
-				if (strcmp($5, ptr->name) == 0)
-			        	/* re-definition is a bug */
-					mmerror(PARSE_ERROR, ET_ERROR, "Type %s already defined", $5);
-			}
-			adjust_array($3.type_enum, &dimension, &length, $3.type_dimension, $3.type_index, *$4?1:0, true);
-
-			this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
+		add_typedef($5, $6.index1, $6.index2, $3.type_enum, $3.type_dimension, $3.type_index, initializer, *$4 ? 1 : 0);
 
-			/* initial definition */
-			this->next = types;
-			this->name = $5;
-			this->brace_level = braces_open;
-			this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
-			this->type->type_enum = $3.type_enum;
-			this->type->type_str = mm_strdup($5);
-			this->type->type_dimension = dimension; /* dimension of array */
-			this->type->type_index = length;	/* length of string */
-			this->type->type_sizeof = ECPGstruct_sizeof;
-			this->struct_member_list = ($3.type_enum == ECPGt_struct || $3.type_enum == ECPGt_union) ?
-			ECPGstruct_member_dup(struct_member_list[struct_level]) : NULL;
-
-			if ($3.type_enum != ECPGt_varchar &&
-				$3.type_enum != ECPGt_char &&
-				$3.type_enum != ECPGt_unsigned_char &&
-				atoi(this->type->type_index) >= 0)
-				mmerror(PARSE_ERROR, ET_ERROR, "No multidimensional array support for simple data types");
-
-			types = this;
-		}
-
-		fprintf(yyout, "typedef %s %s %s %s;\n", $3.type_str, *$4?"*":"", $5, $6.str);
+		fprintf(yyout, "typedef %s %s %s %s;\n", $3.type_str, *$4 ? "*" : "", $5, $6.str);
 		output_line_number();
 		$$ = make_str("");
 	};
@@ -6046,49 +6017,7 @@ ECPGTypedef: TYPE_P
 		}
 		ECPGColLabelCommon IS var_type opt_array_bounds opt_reference
 		{
-			/* add entry to list */
-			struct typedefs *ptr, *this;
-			char *dimension = $6.index1;
-			char *length = $6.index2;
-
-			if (($5.type_enum == ECPGt_struct ||
-				 $5.type_enum == ECPGt_union) &&
-				initializer == 1)
-				mmerror(PARSE_ERROR, ET_ERROR, "Initializer not allowed in EXEC SQL TYPE command");
-			else
-			{
-				for (ptr = types; ptr != NULL; ptr = ptr->next)
-				{
-					if (strcmp($3, ptr->name) == 0)
-						/* re-definition is a bug */
-						mmerror(PARSE_ERROR, ET_ERROR, "Type %s already defined", $3);
-				}
-
-				adjust_array($5.type_enum, &dimension, &length, $5.type_dimension, $5.type_index, *$7?1:0, false);
-
-				this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
-
-				/* initial definition */
-				this->next = types;
-				this->name = $3;
-				this->brace_level = braces_open;
-				this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
-				this->type->type_enum = $5.type_enum;
-				this->type->type_str = mm_strdup($3);
-				this->type->type_dimension = dimension; /* dimension of array */
-				this->type->type_index = length;	/* length of string */
-				this->type->type_sizeof = ECPGstruct_sizeof;
-				this->struct_member_list = ($5.type_enum == ECPGt_struct || $5.type_enum == ECPGt_union) ?
-					ECPGstruct_member_dup(struct_member_list[struct_level]) : NULL;
-
-				if ($5.type_enum != ECPGt_varchar &&
-					$5.type_enum != ECPGt_char &&
-					$5.type_enum != ECPGt_unsigned_char &&
-					atoi(this->type->type_index) >= 0)
-					mmerror(PARSE_ERROR, ET_ERROR, "No multidimensional array support for simple data types");
-
-				types = this;
-			}
+			add_typedef($3, $6.index1, $6.index2, $5.type_enum, $5.type_dimension, $5.type_index, initializer, *$7 ? 1 : 0);
 
 			if (auto_create_c == false)
 				$$ = cat_str(7, make_str("/* exec sql type"), mm_strdup($3), make_str("is"), mm_strdup($5.type_str), mm_strdup($6.str), $7, make_str("*/"));
diff --git a/src/interfaces/ecpg/preproc/type.c b/src/interfaces/ecpg/preproc/type.c
index 464c54ed648ea7f07beab32034b2e1e0eb981f72..18708217e039aa7b9c83e05d7369a3be0a6aeffc 100644
--- a/src/interfaces/ecpg/preproc/type.c
+++ b/src/interfaces/ecpg/preproc/type.c
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/type.c,v 1.73 2007/08/14 10:01:53 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/type.c,v 1.74 2007/08/22 08:20:58 meskes Exp $ */
 
 #include "postgres_fe.h"
 
@@ -80,7 +80,7 @@ ECPGmake_struct_member(char *name, struct ECPGtype * type, struct ECPGstruct_mem
 			   *ne =
 	(struct ECPGstruct_member *) mm_alloc(sizeof(struct ECPGstruct_member));
 
-	ne->name = strdup(name);
+	ne->name = mm_strdup(name);
 	ne->type = type;
 	ne->next = NULL;