From f7563e97108b66b58a2f81ac491a9f8c328bb303 Mon Sep 17 00:00:00 2001
From: Michael Meskes <meskes@postgresql.org>
Date: Tue, 20 May 2008 23:17:32 +0000
Subject: [PATCH] Synced parser. Made ecpg parser use backend provided keyword
 list. Changed whenever test so exit value is 0.

---
 src/interfaces/ecpg/ChangeLog                 |   7 +
 src/interfaces/ecpg/preproc/Makefile          |  11 +-
 src/interfaces/ecpg/preproc/c_keywords.c      |  60 +--
 src/interfaces/ecpg/preproc/ecpg_keywords.c   | 178 +++++--
 src/interfaces/ecpg/preproc/extern.h          |   9 +-
 src/interfaces/ecpg/preproc/keywords.c        | 476 ------------------
 src/interfaces/ecpg/preproc/pgc.l             |   4 +-
 src/interfaces/ecpg/preproc/preproc.y         |  78 +--
 src/interfaces/ecpg/preproc/type.h            |   8 +-
 .../ecpg/test/expected/connect-test1.stderr   |  40 +-
 .../ecpg/test/expected/preproc-whenever.c     |  16 +-
 .../test/expected/preproc-whenever.stderr     |  12 +-
 src/interfaces/ecpg/test/preproc/whenever.pgc |   4 +-
 13 files changed, 274 insertions(+), 629 deletions(-)
 delete mode 100644 src/interfaces/ecpg/preproc/keywords.c

diff --git a/src/interfaces/ecpg/ChangeLog b/src/interfaces/ecpg/ChangeLog
index 0572925d08d..1b3d619017c 100644
--- a/src/interfaces/ecpg/ChangeLog
+++ b/src/interfaces/ecpg/ChangeLog
@@ -2351,6 +2351,13 @@ Mon, 12 May 2008 18:19:08 +0200
 
 	- Check for non-existant connection in prepare statement handling.
 	- Do not close files that weren't opened.
+
+Tue, 20 May 2008 17:31:01 +0200
+
+	- Synced parser.
+	- Made ecpg parser use backend provided keyword list. One less file to
+	  sync manually.
+	- Changed whenever test so exit value is 0.
 	- Set pgtypes library version to 3.1.
 	- Set compat library version to 3.1.
 	- Set ecpg library version to 6.2.
diff --git a/src/interfaces/ecpg/preproc/Makefile b/src/interfaces/ecpg/preproc/Makefile
index f03e69fa1d6..6dd0fa6266d 100644
--- a/src/interfaces/ecpg/preproc/Makefile
+++ b/src/interfaces/ecpg/preproc/Makefile
@@ -4,7 +4,7 @@
 #
 # Copyright (c) 1998-2008, PostgreSQL Global Development Group
 #
-# $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/Makefile,v 1.132 2008/03/18 17:46:23 petere Exp $
+# $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/Makefile,v 1.133 2008/05/20 23:17:32 meskes Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -25,7 +25,7 @@ override CPPFLAGS := -I../include -I$(top_srcdir)/src/interfaces/ecpg/include \
 override CFLAGS += $(PTHREAD_CFLAGS)
 
 OBJS=	preproc.o type.o ecpg.o output.o parser.o \
-	keywords.o c_keywords.o ../ecpglib/typename.o descriptor.o variable.o \
+	keywords.o c_keywords.o ecpg_keywords.o ../ecpglib/typename.o descriptor.o variable.o \
 	$(WIN32RES)
 
 all: submake-libpgport ecpg
@@ -56,6 +56,11 @@ endif
 
 c_keywords.o keywords.o preproc.o parser.o: preproc.h
 
+# instead of maintaining our own list, take the one from the backend
+# we cannot just link it in, but must copy and make some minor changes
+keywords.c: % : $(top_srcdir)/src/backend/parser/%
+	sed -e 's/#include "parser\/parse.h"/#include "preproc.h"/' $< > $@
+
 distprep: $(srcdir)/preproc.c $(srcdir)/preproc.h $(srcdir)/pgc.c
 
 install: all installdirs
@@ -68,7 +73,7 @@ uninstall:
 	rm -f '$(DESTDIR)$(bindir)/ecpg$(X)'
 
 clean distclean:
-	rm -f *.o ecpg$(X)
+	rm -f keywords.c *.o ecpg$(X)
 # garbage from partial builds
 	@rm -f y.tab.c y.tab.h
 # garbage from development
diff --git a/src/interfaces/ecpg/preproc/c_keywords.c b/src/interfaces/ecpg/preproc/c_keywords.c
index bd76ac15e64..3ab4f0ed95f 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.21 2007/08/22 08:20:58 meskes Exp $
+ * $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/c_keywords.c,v 1.22 2008/05/20 23:17:32 meskes Exp $
  * ยง
  *-------------------------------------------------------------------------
  */
@@ -21,37 +21,39 @@
  *		 search is used to locate entries.
  */
 static const ScanKeyword ScanCKeywords[] = {
-	/* name					value			*/
-	{"VARCHAR", VARCHAR},
-	{"auto", S_AUTO},
-	{"bool", SQL_BOOL},
-	{"char", CHAR_P},
-	{"const", S_CONST},
-	{"enum", ENUM_P},
-	{"extern", S_EXTERN},
-	{"float", FLOAT_P},
-	{"hour", HOUR_P},
-	{"int", INT_P},
-	{"long", SQL_LONG},
-	{"minute", MINUTE_P},
-	{"month", MONTH_P},
-	{"register", S_REGISTER},
-	{"second", SECOND_P},
-	{"short", SQL_SHORT},
-	{"signed", SQL_SIGNED},
-	{"static", S_STATIC},
-	{"struct", SQL_STRUCT},
-	{"to", TO},
-	{"typedef", S_TYPEDEF},
-	{"union", UNION},
-	{"unsigned", SQL_UNSIGNED},
-	{"varchar", VARCHAR},
-	{"volatile", S_VOLATILE},
-	{"year", YEAR_P},
+	/* name, value, category */
+	/* category is not needed in ecpg, it is only here so we can share
+         * the data structure with the backend */
+	{"VARCHAR", VARCHAR, 0},
+	{"auto", S_AUTO, 0},
+	{"bool", SQL_BOOL, 0},
+	{"char", CHAR_P, 0},
+	{"const", S_CONST, 0},
+	{"enum", ENUM_P, 0},
+	{"extern", S_EXTERN, 0},
+	{"float", FLOAT_P, 0},
+	{"hour", HOUR_P, 0},
+	{"int", INT_P, 0},
+	{"long", SQL_LONG, 0},
+	{"minute", MINUTE_P, 0},
+	{"month", MONTH_P, 0},
+	{"register", S_REGISTER, 0},
+	{"second", SECOND_P, 0},
+	{"short", SQL_SHORT, 0},
+	{"signed", SQL_SIGNED, 0},
+	{"static", S_STATIC, 0},
+	{"struct", SQL_STRUCT, 0},
+	{"to", TO, 0},
+	{"typedef", S_TYPEDEF, 0},
+	{"union", UNION, 0},
+	{"unsigned", SQL_UNSIGNED, 0},
+	{"varchar", VARCHAR, 0},
+	{"volatile", S_VOLATILE, 0},
+	{"year", YEAR_P, 0},
 };
 
 const ScanKeyword *
-ScanCKeywordLookup(char *text)
+ScanCKeywordLookup(const char *text)
 {
 	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 98179fe39fc..3d8db405379 100644
--- a/src/interfaces/ecpg/preproc/ecpg_keywords.c
+++ b/src/interfaces/ecpg/preproc/ecpg_keywords.c
@@ -4,11 +4,18 @@
  *	  lexical token lookup for reserved words in postgres embedded SQL
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg_keywords.c,v 1.37 2007/11/15 21:14:45 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg_keywords.c,v 1.38 2008/05/20 23:17:32 meskes Exp $
  *
  *-------------------------------------------------------------------------
  */
 
+#include "postgres_fe.h"
+
+#include <ctype.h>
+
+#include "extern.h"
+#include "preproc.h"
+
 /*
  * List of (keyword-name, keyword-token-value) pairs.
  *
@@ -16,50 +23,129 @@
  *		 search is used to locate entries.
  */
 static const ScanKeyword ScanECPGKeywords[] = {
-	/* name					value			*/
-	{"allocate", SQL_ALLOCATE},
-	{"autocommit", SQL_AUTOCOMMIT},
-	{"bool", SQL_BOOL},
-	{"break", SQL_BREAK},
-	{"call", SQL_CALL},
-	{"cardinality", SQL_CARDINALITY},
-	{"connect", SQL_CONNECT},
-	{"continue", SQL_CONTINUE},
-	{"count", SQL_COUNT},
-	{"data", SQL_DATA},
-	{"datetime_interval_code", SQL_DATETIME_INTERVAL_CODE},
-	{"datetime_interval_precision", SQL_DATETIME_INTERVAL_PRECISION},
-	{"describe", SQL_DESCRIBE},
-	{"descriptor", SQL_DESCRIPTOR},
-	{"disconnect", SQL_DISCONNECT},
-	{"found", SQL_FOUND},
-	{"free", SQL_FREE},
-	{"go", SQL_GO},
-	{"goto", SQL_GOTO},
-	{"identified", SQL_IDENTIFIED},
-	{"indicator", SQL_INDICATOR},
-	{"key_member", SQL_KEY_MEMBER},
-	{"length", SQL_LENGTH},
-	{"long", SQL_LONG},
-	{"nullable", SQL_NULLABLE},
-	{"octet_length", SQL_OCTET_LENGTH},
-	{"open", SQL_OPEN},
-	{"output", SQL_OUTPUT},
-	{"reference", SQL_REFERENCE},
-	{"returned_length", SQL_RETURNED_LENGTH},
-	{"returned_octet_length", SQL_RETURNED_OCTET_LENGTH},
-	{"scale", SQL_SCALE},
-	{"section", SQL_SECTION},
-	{"short", SQL_SHORT},
-	{"signed", SQL_SIGNED},
-	{"sql", SQL_SQL},			/* strange thing, used for into sql descriptor
+	/* name, value, category */
+	/* category is not needed in ecpg, it is only here so we can share
+	 * the data structure with the backend */
+	{"allocate", SQL_ALLOCATE, 0},
+	{"autocommit", SQL_AUTOCOMMIT, 0},
+	{"bool", SQL_BOOL, 0},
+	{"break", SQL_BREAK, 0},
+	{"call", SQL_CALL, 0},
+	{"cardinality", SQL_CARDINALITY, 0},
+	{"connect", SQL_CONNECT, 0},
+	{"count", SQL_COUNT, 0},
+	{"data", SQL_DATA, 0},
+	{"datetime_interval_code", SQL_DATETIME_INTERVAL_CODE, 0},
+	{"datetime_interval_precision", SQL_DATETIME_INTERVAL_PRECISION, 0},
+	{"describe", SQL_DESCRIBE, 0},
+	{"descriptor", SQL_DESCRIPTOR, 0},
+	{"disconnect", SQL_DISCONNECT, 0},
+	{"found", SQL_FOUND, 0},
+	{"free", SQL_FREE, 0},
+	{"get", SQL_GET, 0},
+	{"go", SQL_GO, 0},
+	{"goto", SQL_GOTO, 0},
+	{"identified", SQL_IDENTIFIED, 0},
+	{"indicator", SQL_INDICATOR, 0},
+	{"key_member", SQL_KEY_MEMBER, 0},
+	{"length", SQL_LENGTH, 0},
+	{"long", SQL_LONG, 0},
+	{"nullable", SQL_NULLABLE, 0},
+	{"octet_length", SQL_OCTET_LENGTH, 0},
+	{"open", SQL_OPEN, 0},
+	{"output", SQL_OUTPUT, 0},
+	{"reference", SQL_REFERENCE, 0},
+	{"returned_length", SQL_RETURNED_LENGTH, 0},
+	{"returned_octet_length", SQL_RETURNED_OCTET_LENGTH, 0},
+	{"scale", SQL_SCALE, 0},
+	{"section", SQL_SECTION, 0},
+	{"short", SQL_SHORT, 0},
+	{"signed", SQL_SIGNED, 0},
+	{"sql", SQL_SQL, 0},			/* strange thing, used for into sql descriptor
 								 * MYDESC; */
-	{"sqlerror", SQL_SQLERROR},
-	{"sqlprint", SQL_SQLPRINT},
-	{"sqlwarning", SQL_SQLWARNING},
-	{"stop", SQL_STOP},
-	{"struct", SQL_STRUCT},
-	{"unsigned", SQL_UNSIGNED},
-	{"var", SQL_VAR},
-	{"whenever", SQL_WHENEVER},
+	{"sqlerror", SQL_SQLERROR, 0},
+	{"sqlprint", SQL_SQLPRINT, 0},
+	{"sqlwarning", SQL_SQLWARNING, 0},
+	{"stop", SQL_STOP, 0},
+	{"struct", SQL_STRUCT, 0},
+	{"unsigned", SQL_UNSIGNED, 0},
+	{"var", SQL_VAR, 0},
+	{"whenever", SQL_WHENEVER, 0},
 };
+
+/* This is all taken from src/backend/parser/keyword.c and adjusted for our needs. */
+/*
+ * Do a binary search using plain strcmp() comparison.
+ */
+const ScanKeyword *
+DoLookup(const 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;
+}
+
+/*
+ * 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.
+ */
+const ScanKeyword *
+ScanECPGKeywordLookup(const char *text)
+{
+	int			len,
+				i;
+	char		word[NAMEDATALEN];
+	const ScanKeyword *res;
+
+	/* First check SQL symbols defined by the backend. */
+
+	res = ScanKeywordLookup(text);
+	if (res)
+		return res;
+
+	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).
+	 */
+	for (i = 0; i < len; i++)
+	{
+		char		ch = text[i];
+
+		if (ch >= 'A' && ch <= 'Z')
+			ch += 'a' - 'A';
+		word[i] = ch;
+	}
+	word[len] = '\0';
+
+	/*
+	 * Now do a binary search using plain strcmp() comparison.
+	 */
+
+	return DoLookup(word, &ScanECPGKeywords[0], endof(ScanECPGKeywords) - 1);
+}
diff --git a/src/interfaces/ecpg/preproc/extern.h b/src/interfaces/ecpg/preproc/extern.h
index c9097c87eec..7f55441da34 100644
--- a/src/interfaces/ecpg/preproc/extern.h
+++ b/src/interfaces/ecpg/preproc/extern.h
@@ -1,9 +1,10 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/extern.h,v 1.70 2007/11/15 21:14:45 momjian Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/extern.h,v 1.71 2008/05/20 23:17:32 meskes Exp $ */
 
 #ifndef _ECPG_PREPROC_EXTERN_H
 #define _ECPG_PREPROC_EXTERN_H
 
 #include "type.h"
+#include "parser/keywords.h"
 
 #include <errno.h>
 #ifndef CHAR_BIT
@@ -74,7 +75,6 @@ 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 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 *);
@@ -96,8 +96,9 @@ 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 const ScanKeyword *ScanKeywordLookup(char *text);
-extern const ScanKeyword *DoLookup(char *, const ScanKeyword *, const ScanKeyword *);
+extern const ScanKeyword *ScanCKeywordLookup(const char *);
+extern const ScanKeyword *ScanECPGKeywordLookup(const char *text);
+extern const ScanKeyword *DoLookup(const 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
deleted file mode 100644
index 8a92bdf5c46..00000000000
--- a/src/interfaces/ecpg/preproc/keywords.c
+++ /dev/null
@@ -1,476 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * keywords.c
- *	  lexical token lookup for reserved words in PostgreSQL
- *
- * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- *
- * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.85 2008/01/01 19:45:59 momjian Exp $
- *
- *-------------------------------------------------------------------------
- */
-#include "postgres_fe.h"
-
-#include <ctype.h>
-
-#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.
- *
- * !!WARNING!!: This list must be sorted, because binary
- *		 search is used to locate entries.
- */
-static const ScanKeyword ScanPGSQLKeywords[] = {
-	/* name, value */
-	{"abort", ABORT_P},
-	{"absolute", ABSOLUTE_P},
-	{"access", ACCESS},
-	{"action", ACTION},
-	{"add", ADD_P},
-	{"admin", ADMIN},
-	{"after", AFTER},
-	{"aggregate", AGGREGATE},
-	{"all", ALL},
-	{"also", ALSO},
-	{"alter", ALTER},
-	{"always", ALWAYS},
-	{"analyse", ANALYSE},		/* British spelling */
-	{"analyze", ANALYZE},
-	{"and", AND},
-	{"any", ANY},
-	{"array", ARRAY},
-	{"as", AS},
-	{"asc", ASC},
-	{"assertion", ASSERTION},
-	{"assignment", ASSIGNMENT},
-	{"asymmetric", ASYMMETRIC},
-	{"at", AT},
-	{"authorization", AUTHORIZATION},
-	{"backward", BACKWARD},
-	{"before", BEFORE},
-	{"begin", BEGIN_P},
-	{"between", BETWEEN},
-	{"bigint", BIGINT},
-	{"binary", BINARY},
-	{"bit", BIT},
-	{"boolean", BOOLEAN_P},
-	{"both", BOTH},
-	{"by", BY},
-	{"cache", CACHE},
-	{"called", CALLED},
-	{"cascade", CASCADE},
-	{"cascaded", CASCADED},
-	{"case", CASE},
-	{"cast", CAST},
-	{"chain", CHAIN},
-	{"char", CHAR_P},
-	{"character", CHARACTER},
-	{"characteristics", CHARACTERISTICS},
-	{"check", CHECK},
-	{"checkpoint", CHECKPOINT},
-	{"class", CLASS},
-	{"close", CLOSE},
-	{"cluster", CLUSTER},
-	{"coalesce", COALESCE},
-	{"collate", COLLATE},
-	{"column", COLUMN},
-	{"comment", COMMENT},
-	{"commit", COMMIT},
-	{"committed", COMMITTED},
-	{"concurrently", CONCURRENTLY},
-	{"configuration", CONFIGURATION},
-	{"connection", CONNECTION},
-	{"constraint", CONSTRAINT},
-	{"constraints", CONSTRAINTS},
-	{"content", CONTENT_P},
-	{"conversion", CONVERSION_P},
-	{"copy", COPY},
-	{"cost", COST},
-	{"create", CREATE},
-	{"createdb", CREATEDB},
-	{"createrole", CREATEROLE},
-	{"createuser", CREATEUSER},
-	{"cross", CROSS},
-	{"csv", CSV},
-	{"current", CURRENT_P},
-	{"current_date", CURRENT_DATE},
-	{"current_role", CURRENT_ROLE},
-	{"current_time", CURRENT_TIME},
-	{"current_timestamp", CURRENT_TIMESTAMP},
-	{"cursor", CURSOR},
-	{"cycle", CYCLE},
-	{"database", DATABASE},
-	{"day", DAY_P},
-	{"deallocate", DEALLOCATE},
-	{"dec", DEC},
-	{"decimal", DECIMAL_P},
-	{"declare", DECLARE},
-	{"default", DEFAULT},
-	{"defaults", DEFAULTS},
-	{"deferrable", DEFERRABLE},
-	{"deferred", DEFERRED},
-	{"definer", DEFINER},
-	{"delete", DELETE_P},
-	{"delimiter", DELIMITER},
-	{"delimiters", DELIMITERS},
-	{"desc", DESC},
-	{"dictionary", DICTIONARY},
-	{"disable", DISABLE_P},
-	{"discard", DISCARD},
-	{"distinct", DISTINCT},
-	{"do", DO},
-	{"document", DOCUMENT_P},
-	{"domain", DOMAIN_P},
-	{"double", DOUBLE_P},
-	{"drop", DROP},
-	{"each", EACH},
-	{"else", ELSE},
-	{"enable", ENABLE_P},
-	{"encoding", ENCODING},
-	{"encrypted", ENCRYPTED},
-	{"end", END_P},
-	{"enum", ENUM_P},
-	{"escape", ESCAPE},
-	{"except", EXCEPT},
-	{"excluding", EXCLUDING},
-	{"exclusive", EXCLUSIVE},
-	{"execute", EXECUTE},
-	{"exists", EXISTS},
-	{"explain", EXPLAIN},
-	{"external", EXTERNAL},
-	{"extract", EXTRACT},
-	{"false", FALSE_P},
-	{"family", FAMILY},
-	{"fetch", FETCH},
-	{"first", FIRST_P},
-	{"float", FLOAT_P},
-	{"for", FOR},
-	{"force", FORCE},
-	{"foreign", FOREIGN},
-	{"forward", FORWARD},
-	{"freeze", FREEZE},
-	{"from", FROM},
-	{"full", FULL},
-	{"function", FUNCTION},
-	{"get", GET},
-	{"global", GLOBAL},
-	{"grant", GRANT},
-	{"granted", GRANTED},
-	{"greatest", GREATEST},
-	{"group", GROUP_P},
-	{"handler", HANDLER},
-	{"having", HAVING},
-	{"header", HEADER_P},
-	{"hold", HOLD},
-	{"hour", HOUR_P},
-	{"if", IF_P},
-	{"ilike", ILIKE},
-	{"immediate", IMMEDIATE},
-	{"immutable", IMMUTABLE},
-	{"implicit", IMPLICIT_P},
-	{"in", IN_P},
-	{"including", INCLUDING},
-	{"increment", INCREMENT},
-	{"index", INDEX},
-	{"indexes", INDEXES},
-	{"inherit", INHERIT},
-	{"inherits", INHERITS},
-	{"initially", INITIALLY},
-	{"inner", INNER_P},
-	{"inout", INOUT},
-	{"input", INPUT_P},
-	{"insensitive", INSENSITIVE},
-	{"insert", INSERT},
-	{"instead", INSTEAD},
-	{"int", INT_P},
-	{"integer", INTEGER},
-	{"intersect", INTERSECT},
-	{"interval", INTERVAL},
-	{"into", INTO},
-	{"invoker", INVOKER},
-	{"is", IS},
-	{"isnull", ISNULL},
-	{"isolation", ISOLATION},
-	{"join", JOIN},
-	{"key", KEY},
-	{"lancompiler", LANCOMPILER},
-	{"language", LANGUAGE},
-	{"large", LARGE_P},
-	{"last", LAST_P},
-	{"leading", LEADING},
-	{"least", LEAST},
-	{"left", LEFT},
-	{"level", LEVEL},
-	{"like", LIKE},
-	{"limit", LIMIT},
-	{"listen", LISTEN},
-	{"load", LOAD},
-	{"local", LOCAL},
-	{"location", LOCATION},
-	{"lock", LOCK_P},
-	{"login", LOGIN_P},
-	{"mapping", MAPPING},
-	{"match", MATCH},
-	{"maxvalue", MAXVALUE},
-	{"minute", MINUTE_P},
-	{"minvalue", MINVALUE},
-	{"mode", MODE},
-	{"month", MONTH_P},
-	{"move", MOVE},
-	{"name", NAME_P},
-	{"names", NAMES},
-	{"national", NATIONAL},
-	{"natural", NATURAL},
-	{"nchar", NCHAR},
-	{"new", NEW},
-	{"next", NEXT},
-	{"no", NO},
-	{"nocreatedb", NOCREATEDB},
-	{"nocreaterole", NOCREATEROLE},
-	{"nocreateuser", NOCREATEUSER},
-	{"noinherit", NOINHERIT},
-	{"nologin", NOLOGIN_P},
-	{"none", NONE},
-	{"nosuperuser", NOSUPERUSER},
-	{"not", NOT},
-	{"nothing", NOTHING},
-	{"notify", NOTIFY},
-	{"notnull", NOTNULL},
-	{"nowait", NOWAIT},
-	{"null", NULL_P},
-	{"nullif", NULLIF},
-	{"nulls", NULLS_P},
-	{"numeric", NUMERIC},
-	{"object", OBJECT_P},
-	{"of", OF},
-	{"off", OFF},
-	{"offset", OFFSET},
-	{"oids", OIDS},
-	{"old", OLD},
-	{"on", ON},
-	{"only", ONLY},
-	{"operator", OPERATOR},
-	{"option", OPTION},
-	{"or", OR},
-	{"order", ORDER},
-	{"out", OUT_P},
-	{"outer", OUTER_P},
-	{"overlaps", OVERLAPS},
-	{"owned", OWNED},
-	{"owner", OWNER},
-	{"parser", PARSER},
-	{"partial", PARTIAL},
-	{"password", PASSWORD},
-	{"placing", PLACING},
-	{"plans", PLANS},
-	{"position", POSITION},
-	{"precision", PRECISION},
-	{"prepare", PREPARE},
-	{"prepared", PREPARED},
-	{"preserve", PRESERVE},
-	{"primary", PRIMARY},
-	{"prior", PRIOR},
-	{"privileges", PRIVILEGES},
-	{"procedural", PROCEDURAL},
-	{"procedure", PROCEDURE},
-	{"quote", QUOTE},
-	{"read", READ},
-	{"real", REAL},
-	{"reassign", REASSIGN},
-	{"recheck", RECHECK},
-	{"references", REFERENCES},
-	{"reindex", REINDEX},
-	{"relative", RELATIVE_P},
-	{"release", RELEASE},
-	{"rename", RENAME},
-	{"repeatable", REPEATABLE},
-	{"replace", REPLACE},
-	{"replica", REPLICA},
-	{"reset", RESET},
-	{"restart", RESTART},
-	{"restrict", RESTRICT},
-	{"returning", RETURNING},
-	{"returns", RETURNS},
-	{"revoke", REVOKE},
-	{"right", RIGHT},
-	{"role", ROLE},
-	{"rollback", ROLLBACK},
-	{"row", ROW},
-	{"rows", ROWS},
-	{"rule", RULE},
-	{"savepoint", SAVEPOINT},
-	{"schema", SCHEMA},
-	{"scroll", SCROLL},
-	{"search", SEARCH},
-	{"second", SECOND_P},
-	{"security", SECURITY},
-	{"select", SELECT},
-	{"sequence", SEQUENCE},
-	{"serializable", SERIALIZABLE},
-	{"session", SESSION},
-	{"session_user", SESSION_USER},
-	{"set", SET},
-	{"setof", SETOF},
-	{"share", SHARE},
-	{"show", SHOW},
-	{"similar", SIMILAR},
-	{"simple", SIMPLE},
-	{"smallint", SMALLINT},
-	{"some", SOME},
-	{"stable", STABLE},
-	{"standalone", STANDALONE_P},
-	{"start", START},
-	{"statement", STATEMENT},
-	{"statistics", STATISTICS},
-	{"stdin", STDIN},
-	{"stdout", STDOUT},
-	{"storage", STORAGE},
-	{"strict", STRICT_P},
-	{"strip", STRIP_P},
-	{"substring", SUBSTRING},
-	{"superuser", SUPERUSER_P},
-	{"symmetric", SYMMETRIC},
-	{"sysid", SYSID},
-	{"system", SYSTEM_P},
-	{"table", TABLE},
-	{"tablespace", TABLESPACE},
-	{"temp", TEMP},
-	{"template", TEMPLATE},
-	{"temporary", TEMPORARY},
-	{"text", TEXT_P},
-	{"then", THEN},
-	{"time", TIME},
-	{"timestamp", TIMESTAMP},
-	{"to", TO},
-	{"trailing", TRAILING},
-	{"transaction", TRANSACTION},
-	{"treat", TREAT},
-	{"trigger", TRIGGER},
-	{"trim", TRIM},
-	{"true", TRUE_P},
-	{"truncate", TRUNCATE},
-	{"trusted", TRUSTED},
-	{"type", TYPE_P},
-	{"uncommitted", UNCOMMITTED},
-	{"unencrypted", UNENCRYPTED},
-	{"union", UNION},
-	{"unique", UNIQUE},
-	{"unknown", UNKNOWN},
-	{"unlisten", UNLISTEN},
-	{"until", UNTIL},
-	{"update", UPDATE},
-	{"user", USER},
-	{"using", USING},
-	{"vacuum", VACUUM},
-	{"valid", VALID},
-	{"validator", VALIDATOR},
-	{"value", VALUE_P},
-	{"values", VALUES},
-	{"varchar", VARCHAR},
-	{"varying", VARYING},
-	{"verbose", VERBOSE},
-	{"version", VERSION_P},
-	{"view", VIEW},
-	{"volatile", VOLATILE},
-	{"when", WHEN},
-	{"where", WHERE},
-	{"whitespace", WHITESPACE_P},
-	{"with", WITH},
-	{"without", WITHOUT},
-	{"work", WORK},
-	{"write", WRITE},
-	{"xml", XML_P},
-	{"xmlattributes", XMLATTRIBUTES},
-	{"xmlconcat", XMLCONCAT},
-	{"xmlelement", XMLELEMENT},
-	{"xmlforest", XMLFOREST},
-	{"xmlparse", XMLPARSE},
-	{"xmlpi", XMLPI},
-	{"xmlroot", XMLROOT},
-	{"xmlserialize", XMLSERIALIZE},
-	{"year", YEAR_P},
-	{"yes", YES_P},
-	{"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
- *
- * 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.
- */
-const ScanKeyword *
-ScanKeywordLookup(char *text)
-{
-	int			len,
-				i;
-	char		word[NAMEDATALEN];
-	const ScanKeyword *res;
-
-	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).
-	 */
-	for (i = 0; i < len; i++)
-	{
-		char		ch = text[i];
-
-		if (ch >= 'A' && ch <= 'Z')
-			ch += 'a' - 'A';
-		word[i] = ch;
-	}
-	word[len] = '\0';
-
-	/*
-	 * Now do a binary search using plain strcmp() comparison.
-	 */
-	res = DoLookup(word, &ScanPGSQLKeywords[0], endof(ScanPGSQLKeywords) - 1);
-	if (res)
-		return res;
-
-	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 be6f7b0d140..a08eb8e2035 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.165 2008/05/16 15:20:04 petere Exp $
+ *	  $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.166 2008/05/20 23:17:32 meskes Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -680,7 +680,7 @@ cppline			{space}*#(.*\\{space})*.*{newline}
 						if (!isdefine())
 						{
 							/* Is it an SQL/ECPG keyword? */
-							keyword = ScanKeywordLookup(yytext);
+							keyword = ScanECPGKeywordLookup(yytext);
 							if (keyword != NULL)
 								return keyword->value;
 
diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y
index 49acea7640c..3d39b74580c 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.365 2008/05/16 15:20:04 petere Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.366 2008/05/20 23:17:32 meskes Exp $ */
 
 /* Copyright comment */
 %{
@@ -392,11 +392,11 @@ add_typedef(char *name, char * dimension, char * length, enum ECPGttype type_enu
 /* special embedded SQL token */
 %token	SQL_ALLOCATE SQL_AUTOCOMMIT SQL_BOOL SQL_BREAK
 		SQL_CALL SQL_CARDINALITY SQL_CONNECT
-		SQL_CONTINUE SQL_COUNT SQL_DATA
+		SQL_COUNT SQL_DATA
 		SQL_DATETIME_INTERVAL_CODE
 		SQL_DATETIME_INTERVAL_PRECISION SQL_DESCRIBE
 		SQL_DESCRIPTOR SQL_DISCONNECT SQL_FOUND
-		SQL_FREE SQL_GO SQL_GOTO SQL_IDENTIFIED
+		SQL_FREE SQL_GET SQL_GO SQL_GOTO SQL_IDENTIFIED
 		SQL_INDICATOR SQL_KEY_MEMBER SQL_LENGTH
 		SQL_LONG SQL_NULLABLE SQL_OCTET_LENGTH
 		SQL_OPEN SQL_OUTPUT SQL_REFERENCE
@@ -427,7 +427,7 @@ add_typedef(char *name, char * dimension, char * length, enum ECPGttype type_enu
 	CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
 	CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
 	COMMITTED CONCURRENTLY CONFIGURATION CONNECTION CONSTRAINT CONSTRAINTS 
-	CONTENT_P CONVERSION_P COPY COST CREATE CREATEDB
+	CONTENT_P CONTINUE_P CONVERSION_P COPY COST CREATE CREATEDB
 	CREATEROLE CREATEUSER CROSS CSV CURRENT_P CURRENT_DATE CURRENT_ROLE
 	CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
 
@@ -441,14 +441,14 @@ add_typedef(char *name, char * dimension, char * length, enum ECPGttype type_enu
 	FALSE_P FAMILY FETCH FIRST_P FLOAT_P FOR FORCE FOREIGN FORWARD FREEZE FROM
 	FULL FUNCTION
 
-	GET GLOBAL GRANT GRANTED GREATEST GROUP_P
+	GLOBAL GRANT GRANTED GREATEST GROUP_P
 
 	HANDLER HAVING HEADER_P HOLD HOUR_P
 
-	IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P INCLUDING INCREMENT
-	INDEX INDEXES INHERIT INHERITS INITIALLY INNER_P INOUT INPUT_P
-	INSENSITIVE INSERT INSTEAD INT_P INTEGER INTERSECT
-	INTERVAL INTO INVOKER IS ISNULL ISOLATION
+	IDENTITY_P IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P
+	INCLUDING INCREMENT INDEX INDEXES INHERIT INHERITS INITIALLY
+	INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER
+	INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION
 
 	JOIN
 
@@ -555,7 +555,7 @@ add_typedef(char *name, char * dimension, char * length, enum ECPGttype type_enu
 %type  <str>	ConstraintElem key_actions ColQualList cluster_index_specification
 %type  <str>	target_list target_el alias_clause type_func_name_keyword
 %type  <str>	qualified_name database_name alter_using type_function_name
-%type  <str>	access_method attr_name index_name name func_name
+%type  <str>	access_method attr_name index_name name func_name opt_restart_seqs
 %type  <str>	file_name AexprConst c_expr ConstTypename var_list
 %type  <str>	a_expr b_expr TruncateStmt CommentStmt OnCommitOption opt_by
 %type  <str>	opt_indirection expr_list extract_list extract_arg
@@ -1862,6 +1862,8 @@ OptSeqElem:  CACHE NumConst
 			{ $$ = cat2_str(make_str("owned by"), $3); }
 		| START opt_with NumConst
 			{ $$ = cat_str(3, make_str("start"), $2, $3); }
+		| RESTART
+			{ $$ = make_str("restart"); }
 		| RESTART opt_with NumConst
 			{ $$ = cat_str(3, make_str("restart"), $2, $3); }
 		;
@@ -2179,7 +2181,10 @@ opt_opfamily:  FAMILY any_name		{ $$ = cat2_str(make_str("family"), $2); }
                        | /*EMPTY*/	{ $$ = EMPTY; }
                ;
 
-opt_recheck:   RECHECK	{ $$ = make_str("recheck"); }
+opt_recheck:   RECHECK		{ 
+					mmerror(PARSE_ERROR, ET_WARNING, "no longer supported RECHECK OPTION will be passed to backend");
+					$$ = make_str("recheck");
+				}
 		|  /*EMPTY*/    { $$ = EMPTY; }
 		;
 
@@ -2282,10 +2287,16 @@ attrs: '.' attr_name		{ $$ = cat2_str(make_str("."), $2); }
  *				   truncate table relname1, relname2, ....
  *
  *****************************************************************************/
-TruncateStmt:  TRUNCATE opt_table qualified_name_list opt_drop_behavior
-			{ $$ = cat_str(4, make_str("truncate table"), $2, $3, $4); }
+TruncateStmt:  TRUNCATE opt_table qualified_name_list opt_restart_seqs opt_drop_behavior
+			{ $$ = cat_str(5, make_str("truncate table"), $2, $3, $4, $5); }
 		;
 
+opt_restart_seqs:
+			CONTINUE_P IDENTITY_P	{ $$ = cat2_str(make_str("continue"), make_str("identity")); }
+			| RESTART IDENTITY_P	{ $$ = cat2_str(make_str("restart"), make_str("identity")); }
+			| /* EMPTY */		{ $$ = EMPTY; }
+			;
+
 /*****************************************************************************
  *
  *		QUERY:
@@ -2852,6 +2863,8 @@ RenameStmt:  ALTER AGGREGATE func_name aggr_args RENAME TO name
 			{ $$ = cat_str(4, make_str("alter text search template"), $5, make_str("rename to"), $8); }
 		| ALTER TEXT_P SEARCH CONFIGURATION any_name RENAME TO name
 			{ $$ = cat_str(4, make_str("alter text search configuration"), $5, make_str("rename to"), $8); }
+		| ALTER TYPE_P any_name RENAME TO name
+			{ $$ = cat_str(4, make_str("alter type"), $3, make_str("rename to"), $6); }
 		;
 
 opt_column:  COLUMN			{ $$ = make_str("column"); }
@@ -2960,6 +2973,7 @@ event:	SELECT				{ $$ = make_str("select"); }
 		| UPDATE			{ $$ = make_str("update"); }
 		| DELETE_P			{ $$ = make_str("delete"); }
 		| INSERT			{ $$ = make_str("insert"); }
+		| TRUNCATE			{ $$ = make_str("truncate"); }
 		;
 
 opt_instead:  INSTEAD		{ $$ = make_str("instead"); }
@@ -4538,29 +4552,26 @@ expr_list:	a_expr
 			{ $$ = cat_str(3, $1, make_str(","), $3); }
 		;
 
-extract_list:  extract_arg FROM a_expr
-			{ $$ = cat_str(3, $1, make_str("from"), $3); }
-		| /* EMPTY */
-			{ $$ = EMPTY; }
-		;
-
 type_list:	 Typename
 			{ $$ = $1; }
 		| type_list ',' Typename
 			{ $$ = cat_str(3, $1, ',', $3); }
 		;
 
+array_expr: '[' expr_list ']'			{ $$ = cat_str(3, make_str("["), $2, make_str("]")); }
+		| '[' array_expr_list ']'	{ $$ = cat_str(3, make_str("["), $2, make_str("]")); }
+		| '[' ']'			{ $$ = make_str("[]"); }
+		;
+
 array_expr_list: array_expr				{ $$ = $1; }
 		| array_expr_list ',' array_expr	{ $$ = cat_str(3, $1, make_str(","), $3); }
 		;
 
-
-array_expr: '[' expr_list ']'			{ $$ = cat_str(3, make_str("["), $2, make_str("]")); }
-		| '[' array_expr_list ']'	{ $$ = cat_str(3, make_str("["), $2, make_str("]")); }
+extract_list:  extract_arg FROM a_expr
+			{ $$ = cat_str(3, $1, make_str("from"), $3); }
+		| /* EMPTY */
+			{ $$ = EMPTY; }
 		;
-/* Allow delimited string SCONST in extract_arg as an SQL extension.
- * - thomas 2001-04-12
- */
 
 extract_arg:  ident				{ $$ = $1; }
 		| YEAR_P				{ $$ = make_str("year"); }
@@ -4703,6 +4714,14 @@ target_list:  target_list ',' target_el
 
 target_el:	a_expr AS ColLabel
 			{ $$ = cat_str(3, $1, make_str("as"), $3); }
+		/*
+		 * We support omitting AS only for column labels that aren't
+		 * any known keyword.  There is an ambiguity against postfix
+		 * operators: is "a ! b" an infix expression, or a postfix
+		 * expression and a column label?  We prefer to resolve this
+		 * as an infix expression, which we accomplish by assigning
+		 * IDENT a precedence higher than POSTFIXOP.
+		 */
 		| a_expr IDENT
 			{ $$ = cat_str(3, $1, make_str("as"), $2); }
 		| a_expr
@@ -5999,7 +6018,7 @@ ECPGDeallocateDescr:	DEALLOCATE SQL_DESCRIPTOR quoted_ident_stringvar
  * manipulate a descriptor header
  */
 
-ECPGGetDescriptorHeader: GET SQL_DESCRIPTOR quoted_ident_stringvar ECPGGetDescHeaderItems
+ECPGGetDescriptorHeader: SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar ECPGGetDescHeaderItems
 			{  $$ = $3; }
 		;
 
@@ -6034,7 +6053,7 @@ desc_header_item:	SQL_COUNT			{ $$ = ECPGd_count; }
  * manipulate a descriptor
  */
 
-ECPGGetDescriptor:	GET SQL_DESCRIPTOR quoted_ident_stringvar VALUE_P IntConstVar ECPGGetDescItems
+ECPGGetDescriptor:	SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar VALUE_P IntConstVar ECPGGetDescItems
 			{  $$.str = $5; $$.name = $3; }
 		;
 
@@ -6214,7 +6233,7 @@ ECPGWhenever: SQL_WHENEVER SQL_SQLERROR action
 		}
 		;
 
-action : SQL_CONTINUE
+action : CONTINUE_P
 		{
 			$<action>$.code = W_NOTHING;
 			$<action>$.command = NULL;
@@ -6280,7 +6299,6 @@ ECPGKeywords: ECPGKeywords_vanames	{ $$ = $1; }
 ECPGKeywords_vanames:  SQL_BREAK		{ $$ = make_str("break"); }
 		| SQL_CALL						{ $$ = make_str("call"); }
 		| SQL_CARDINALITY				{ $$ = make_str("cardinality"); }
-		| SQL_CONTINUE					{ $$ = make_str("continue"); }
 		| SQL_COUNT						{ $$ = make_str("count"); }
 		| SQL_DATA						{ $$ = make_str("data"); }
 		| SQL_DATETIME_INTERVAL_CODE	{ $$ = make_str("datetime_interval_code"); }
@@ -6467,6 +6485,7 @@ ECPGunreserved_con:	  ABORT_P			{ $$ = make_str("abort"); }
 /*		| CONNECTION		{ $$ = make_str("connection"); }*/
 		| CONSTRAINTS		{ $$ = make_str("constraints"); }
 		| CONTENT_P		{ $$ = make_str("content"); }
+		| CONTINUE_P		{ $$ = make_str("continue"); }
 		| CONVERSION_P		{ $$ = make_str("conversion"); }
 		| COPY				{ $$ = make_str("copy"); }
 		| COST				{ $$ = make_str("cost"); }
@@ -6515,6 +6534,7 @@ ECPGunreserved_con:	  ABORT_P			{ $$ = make_str("abort"); }
 		| HEADER_P			{ $$ = make_str("header"); }
 		| HOLD				{ $$ = make_str("hold"); }
 /*		| HOUR_P			{ $$ = make_str("hour"); }*/
+		| IDENTITY_P			{ $$ = make_str("identity"); }
 		| IF_P				{ $$ = make_str("if"); }
 		| IMMEDIATE			{ $$ = make_str("immediate"); }
 		| IMMUTABLE			{ $$ = make_str("immutable"); }
diff --git a/src/interfaces/ecpg/preproc/type.h b/src/interfaces/ecpg/preproc/type.h
index 89195077bae..28cbbe62d7b 100644
--- a/src/interfaces/ecpg/preproc/type.h
+++ b/src/interfaces/ecpg/preproc/type.h
@@ -1,5 +1,5 @@
 /*
- * $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/type.h,v 1.49 2008/05/17 01:28:25 adunstan Exp $ 
+ * $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/type.h,v 1.50 2008/05/20 23:17:32 meskes Exp $ 
  */
 #ifndef _ECPG_PREPROC_TYPE_H
 #define _ECPG_PREPROC_TYPE_H
@@ -190,10 +190,4 @@ struct fetch_desc
 	char	   *name;
 };
 
-typedef struct ScanKeyword
-{
-	char	   *name;
-	int			value;
-} ScanKeyword;
-
 #endif   /* _ECPG_PREPROC_TYPE_H */
diff --git a/src/interfaces/ecpg/test/expected/connect-test1.stderr b/src/interfaces/ecpg/test/expected/connect-test1.stderr
index 30ebfac6074..3737d5c6813 100644
--- a/src/interfaces/ecpg/test/expected/connect-test1.stderr
+++ b/src/interfaces/ecpg/test/expected/connect-test1.stderr
@@ -2,68 +2,68 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: opening database connectdb on <DEFAULT> port <DEFAULT>  
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute line 23: QUERY: alter user connectuser  encrypted password 'connectpw' with 0 parameter on connection main 
+[NO_PID]: ecpg_execute on line 23: query: alter user connectuser  encrypted password 'connectpw'; with 0 parameter(s) on connection main
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute line 23: using PQexec
+[NO_PID]: ecpg_execute on line 23: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute line 23 Ok: ALTER ROLE
+[NO_PID]: ecpg_execute on line 23: OK: ALTER ROLE
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_finish: Connection main closed.
+[NO_PID]: ecpg_finish: connection main closed
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: opening database connectdb on localhost port <DEFAULT>  
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_finish: Connection main closed.
+[NO_PID]: ecpg_finish: connection main closed
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: opening database <DEFAULT> on localhost port <DEFAULT>  for user connectdb
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_finish: Connection main closed.
+[NO_PID]: ecpg_finish: connection main closed
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: opening database connectdb on localhost port <REGRESSION_PORT>  
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_finish: Connection main closed.
+[NO_PID]: ecpg_finish: connection main closed
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: opening database <DEFAULT> on localhost port <REGRESSION_PORT>  for user connectdb
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_finish: Connection main closed.
+[NO_PID]: ecpg_finish: connection main closed
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: opening database connectdb on <DEFAULT> port <REGRESSION_PORT>  
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_finish: Connection main closed.
+[NO_PID]: ecpg_finish: connection main closed
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: opening database <DEFAULT> on <DEFAULT> port <REGRESSION_PORT>  for user connectdb
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_finish: Connection main closed.
+[NO_PID]: ecpg_finish: connection main closed
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: opening database connectdb on localhost port <REGRESSION_PORT>  for user connectuser
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_finish: Connection connectdb closed.
+[NO_PID]: ecpg_finish: connection connectdb closed
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: opening database <DEFAULT> on localhost port <REGRESSION_PORT>  for user connectdb
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_finish: Connection (null) closed.
+[NO_PID]: ecpg_finish: connection (null) closed
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: opening database connectdb on localhost port <REGRESSION_PORT>  for user connectuser
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_finish: Connection connectdb closed.
+[NO_PID]: ecpg_finish: connection connectdb closed
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: opening database connectdb on <DEFAULT> port <REGRESSION_PORT>  for user connectuser
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_finish: Connection connectdb closed.
+[NO_PID]: ecpg_finish: connection connectdb closed
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: opening database connectdb on <DEFAULT> port <REGRESSION_PORT> with options connect_timeout=14 for user connectuser
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_finish: Connection connectdb closed.
+[NO_PID]: ecpg_finish: connection connectdb closed
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: opening database nonexistant on localhost port <REGRESSION_PORT>  for user connectuser
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: could not open database: FATAL:  database "nonexistant" does not exist
 
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_finish: Connection nonexistant closed.
+[NO_PID]: ecpg_finish: connection nonexistant closed
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: raising sqlcode -402 in line 62, 'Could not connect to database nonexistant in line 62.'.
+[NO_PID]: raising sqlcode -402 on line 62: could not connect to database "nonexistant" on line 62
 [NO_PID]: sqlca: code: -402, state: 08001
-[NO_PID]: raising sqlcode -220 in line 63, 'No such connection CURRENT in line 63.'.
+[NO_PID]: raising sqlcode -220 on line 63: no such connection CURRENT on line 63
 [NO_PID]: sqlca: code: -220, state: 08003
 [NO_PID]: ECPGconnect: opening database connectdb on localhost port <REGRESSION_PORT>  for user connectuser
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -72,9 +72,9 @@
 	TCP/IP connections on port 20?
 
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_finish: Connection connectdb closed.
+[NO_PID]: ecpg_finish: connection connectdb closed
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: raising sqlcode -402 in line 66, 'Could not connect to database connectdb in line 66.'.
+[NO_PID]: raising sqlcode -402 on line 66: could not connect to database "connectdb" on line 66
 [NO_PID]: sqlca: code: -402, state: 08001
 [NO_PID]: ECPGconnect: opening database connectdb on <DEFAULT> port <REGRESSION_PORT>  for user connectuser
 [NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/preproc-whenever.c b/src/interfaces/ecpg/test/expected/preproc-whenever.c
index c3459205372..9f15b7708b9 100644
--- a/src/interfaces/ecpg/test/expected/preproc-whenever.c
+++ b/src/interfaces/ecpg/test/expected/preproc-whenever.c
@@ -220,25 +220,27 @@ if (sqlca.sqlcode < 0) goto error;}
 	/* exec sql whenever sqlerror  stop ; */
 #line 61 "whenever.pgc"
 
-	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select  *  from nonexistant   ", ECPGt_EOIT, 
+	/* This cannot fail, thus we don't get an exit value not equal 0. */
+	/* However, it still test the precompiler output. */
+	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select  1     ", ECPGt_EOIT, 
 	ECPGt_int,&(i),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
-#line 62 "whenever.pgc"
+#line 64 "whenever.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') warn (  );
-#line 62 "whenever.pgc"
+#line 64 "whenever.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
-#line 62 "whenever.pgc"
+#line 64 "whenever.pgc"
 
 	{ ECPGtrans(__LINE__, NULL, "rollback");
-#line 63 "whenever.pgc"
+#line 65 "whenever.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') warn (  );
-#line 63 "whenever.pgc"
+#line 65 "whenever.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
-#line 63 "whenever.pgc"
+#line 65 "whenever.pgc"
 
 	exit (0);
 }	
diff --git a/src/interfaces/ecpg/test/expected/preproc-whenever.stderr b/src/interfaces/ecpg/test/expected/preproc-whenever.stderr
index 519cd8f6840..207e5fa766a 100644
--- a/src/interfaces/ecpg/test/expected/preproc-whenever.stderr
+++ b/src/interfaces/ecpg/test/expected/preproc-whenever.stderr
@@ -82,11 +82,13 @@ sql error: relation "nonexistant" does not exist on line 47
 [NO_PID]: sqlca: code: -400, state: 42P01
 [NO_PID]: ECPGtrans on line 59: action "rollback"; connection "regress1"
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 62: query: select  *  from nonexistant   ; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 64: query: select  1     ; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 62: using PQexec
+[NO_PID]: ecpg_execute on line 64: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_check_PQresult on line 62: ERROR:  relation "nonexistant" does not exist
+[NO_PID]: ecpg_execute on line 64: correctly got 1 tuples with 1 fields
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 64: RESULT: 1 offset: -1; array: yes
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGtrans on line 65: action "rollback"; connection "regress1"
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: raising sqlstate 42P01 (sqlcode -400) on line 62: relation "nonexistant" does not exist on line 62
-[NO_PID]: sqlca: code: -400, state: 42P01
diff --git a/src/interfaces/ecpg/test/preproc/whenever.pgc b/src/interfaces/ecpg/test/preproc/whenever.pgc
index ad563278044..bba78ee0233 100644
--- a/src/interfaces/ecpg/test/preproc/whenever.pgc
+++ b/src/interfaces/ecpg/test/preproc/whenever.pgc
@@ -59,7 +59,9 @@ int main(void)
 	exec sql rollback;
 
 	exec sql whenever sqlerror stop;
-	exec sql select * into :i from nonexistant;
+	/* This cannot fail, thus we don't get an exit value not equal 0. */
+	/* However, it still test the precompiler output. */
+	exec sql select 1 into :i;
 	exec sql rollback;
 	exit (0);
 }	
-- 
GitLab