From 607cd930d5095f914aa6d3f23d29a41cedcf92af Mon Sep 17 00:00:00 2001
From: "Thomas G. Lockhart" <lockhart@fourpalms.org>
Date: Sat, 3 Oct 1998 02:33:51 +0000
Subject: [PATCH] Changes from Michael Meskes: Check strdup calls for out of
 memory. Set library version to 2.6.2 Synced preproc.y and keywords.c with
 gram.y and keywords.c yet again. Set version to 2.4.3

---
 src/interfaces/ecpg/lib/Makefile.in    |   2 +-
 src/interfaces/ecpg/lib/ecpglib.c      |  22 ++-
 src/interfaces/ecpg/preproc/Makefile   |   6 +-
 src/interfaces/ecpg/preproc/extern.h   |   1 +
 src/interfaces/ecpg/preproc/keywords.c |  22 ++-
 src/interfaces/ecpg/preproc/pgc.l      |   1 -
 src/interfaces/ecpg/preproc/preproc.y  | 206 ++++++++++++++-----------
 src/interfaces/ecpg/preproc/type.c     |  15 ++
 src/interfaces/ecpg/test/test2.pgc     |   2 +-
 9 files changed, 177 insertions(+), 100 deletions(-)

diff --git a/src/interfaces/ecpg/lib/Makefile.in b/src/interfaces/ecpg/lib/Makefile.in
index 41151927356..fa7849b3c2a 100644
--- a/src/interfaces/ecpg/lib/Makefile.in
+++ b/src/interfaces/ecpg/lib/Makefile.in
@@ -5,7 +5,7 @@ PQ_INCLUDE=-I$(SRCDIR)/interfaces/libpq
 
 SO_MAJOR_VERSION=2
 SO_MINOR_VERSION=6
-SO_PATCHLEVEL=1
+SO_PATCHLEVEL=2
 
 PORTNAME=@PORTNAME@
 
diff --git a/src/interfaces/ecpg/lib/ecpglib.c b/src/interfaces/ecpg/lib/ecpglib.c
index 4b7ed87c1ff..f982d5103cb 100644
--- a/src/interfaces/ecpg/lib/ecpglib.c
+++ b/src/interfaces/ecpg/lib/ecpglib.c
@@ -148,6 +148,22 @@ ecpg_alloc(long size, int lineno)
 	return (new);
 }
 
+static char *
+ecpg_strdup(const char *string, int lineno)
+{
+	char	   *new = strdup(string);
+
+	if (!new)
+	{
+		ECPGfinish(actual_connection);
+		ECPGlog("out of memory\n");
+		register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno);
+		return NULL;
+	}
+
+	return (new);
+}
+
 /* This function returns a newly malloced string that has the ' and \
    in the argument quoted with \.
  */
@@ -246,7 +262,7 @@ ECPGexecute(struct statement * stmt)
 
 	memcpy((char *) &sqlca, (char *) &sqlca_init, sizeof(sqlca));
 
-	copiedquery = strdup(stmt->command);
+	copiedquery = ecpg_strdup(stmt->command, stmt->lineno);
 
 	/*
 	 * Now, if the type is one of the fill in types then we take the
@@ -914,9 +930,9 @@ ECPGconnect(int lineno, const char *dbname, const char *user, const char *passwd
 
 	/* add connection to our list */
 	if (connection_name != NULL)
-		this->name = strdup(connection_name);
+		this->name = ecpg_strdup(connection_name, lineno);
 	else
-		this->name = strdup(dbname);
+		this->name = ecpg_strdup(dbname, lineno);
 
 	if (all_connections == NULL)
 		this->next = NULL;
diff --git a/src/interfaces/ecpg/preproc/Makefile b/src/interfaces/ecpg/preproc/Makefile
index c35817fd3e0..6b385ee39d5 100644
--- a/src/interfaces/ecpg/preproc/Makefile
+++ b/src/interfaces/ecpg/preproc/Makefile
@@ -3,7 +3,7 @@ include $(SRCDIR)/Makefile.global
 
 MAJOR_VERSION=2
 MINOR_VERSION=4
-PATCHLEVEL=2
+PATCHLEVEL=3
 
 CFLAGS+=-I../include -DMAJOR_VERSION=$(MAJOR_VERSION) \
 	-DMINOR_VERSION=$(MINOR_VERSION) -DPATCHLEVEL=$(PATCHLEVEL) \
@@ -27,6 +27,10 @@ uninstall:
 ecpg: $(OBJ)
 	$(CC) -o ecpg $(OBJ) $(LEXLIB) $(LDFLAGS)
 
+pgc.c: pgc.l
+	$(LEX) $<
+	mv lex.yy.c pgc.c
+
 y.tab.h y.tab.c: preproc.y
 	$(YACC) $(YFLAGS) $<
 
diff --git a/src/interfaces/ecpg/preproc/extern.h b/src/interfaces/ecpg/preproc/extern.h
index 86ee5361217..c7bb651a586 100644
--- a/src/interfaces/ecpg/preproc/extern.h
+++ b/src/interfaces/ecpg/preproc/extern.h
@@ -67,6 +67,7 @@ extern void lex_init(void);
 extern char *input_filename;
 extern int	yyparse(void);
 extern void *mm_alloc(size_t), *mm_realloc(void *, size_t);
+extern char *mm_strdup(const char *);
 ScanKeyword *ScanECPGKeywordLookup(char *);
 ScanKeyword *ScanCKeywordLookup(char *);
 extern void yyerror(char *);
diff --git a/src/interfaces/ecpg/preproc/keywords.c b/src/interfaces/ecpg/preproc/keywords.c
index 30918b9fc90..8398d94452a 100644
--- a/src/interfaces/ecpg/preproc/keywords.c
+++ b/src/interfaces/ecpg/preproc/keywords.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.5 1998/09/21 05:52:53 scrappy Exp $
+ *	  $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.6 1998/10/03 02:33:36 thomas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -29,8 +29,9 @@
  *		 search is used to locate entries.
  */
 static ScanKeyword ScanKeywords[] = {
-	/* name					value			*/
+	/* name, value */
 	{"abort", ABORT_TRANS},
+	{"absolute", ABSOLUTE},
 	{"action", ACTION},
 	{"add", ADD},
 	{"after", AFTER},
@@ -40,7 +41,6 @@ static ScanKeyword ScanKeywords[] = {
 	{"analyze", ANALYZE},
 	{"and", AND},
 	{"any", ANY},
-	{"archive", ARCHIVE},
 	{"as", AS},
 	{"asc", ASC},
 	{"backward", BACKWARD},
@@ -67,7 +67,9 @@ static ScanKeyword ScanKeywords[] = {
 	{"createdb", CREATEDB},
 	{"createuser", CREATEUSER},
 	{"cross", CROSS},
-	{"current", CURRENT},
+	{"current", CURRENT},		/* 6.4 to 6.5 is migration time! CURRENT
+								 * will be removed in 6.5! Use OLD keyword
+								 * in rules. Jan */
 	{"current_date", CURRENT_DATE},
 	{"current_time", CURRENT_TIME},
 	{"current_timestamp", CURRENT_TIMESTAMP},
@@ -87,6 +89,7 @@ static ScanKeyword ScanKeywords[] = {
 	{"double", DOUBLE},
 	{"drop", DROP},
 	{"each", EACH},
+	{"encoding", ENCODING},
 	{"end", END_TRANS},
 	{"execute", EXECUTE},
 	{"exists", EXISTS},
@@ -113,6 +116,7 @@ static ScanKeyword ScanKeywords[] = {
 	{"inherits", INHERITS},
 	{"inner", INNER_P},
 	{"insert", INSERT},
+	{"insensitive", INSENSITIVE},
 	{"instead", INSTEAD},
 	{"interval", INTERVAL},
 	{"into", INTO},
@@ -136,10 +140,12 @@ static ScanKeyword ScanKeywords[] = {
 	{"minvalue", MINVALUE},
 	{"month", MONTH_P},
 	{"move", MOVE},
+	{"names", NAMES},
 	{"national", NATIONAL},
 	{"natural", NATURAL},
 	{"nchar", NCHAR},
 	{"new", NEW},
+	{"next", NEXT},
 	{"no", NO},
 	{"nocreatedb", NOCREATEDB},
 	{"nocreateuser", NOCREATEUSER},
@@ -152,7 +158,9 @@ static ScanKeyword ScanKeywords[] = {
 	{"numeric", NUMERIC},
 	{"of", OF},
 	{"oids", OIDS},
+	{"old", CURRENT},
 	{"on", ON},
+	{"only", ONLY},
 	{"operator", OPERATOR},
 	{"option", OPTION},
 	{"or", OR},
@@ -163,12 +171,15 @@ static ScanKeyword ScanKeywords[] = {
 	{"position", POSITION},
 	{"precision", PRECISION},
 	{"primary", PRIMARY},
+	{"prior", PRIOR},
 	{"privileges", PRIVILEGES},
 	{"procedural", PROCEDURAL},
 	{"procedure", PROCEDURE},
 	{"public", PUBLIC},
+	{"read", READ},
 	{"recipe", RECIPE},
 	{"references", REFERENCES},
+	{"relative", RELATIVE},
 	{"rename", RENAME},
 	{"reset", RESET},
 	{"returns", RETURNS},
@@ -177,9 +188,11 @@ static ScanKeyword ScanKeywords[] = {
 	{"rollback", ROLLBACK},
 	{"row", ROW},
 	{"rule", RULE},
+	{"scroll", SCROLL},
 	{"second", SECOND_P},
 	{"select", SELECT},
 	{"sequence", SEQUENCE},
+	{"serial", SERIAL},
 	{"set", SET},
 	{"setof", SETOF},
 	{"show", SHOW},
@@ -190,6 +203,7 @@ static ScanKeyword ScanKeywords[] = {
 	{"substring", SUBSTRING},
 	{"table", TABLE},
 	{"time", TIME},
+	{"timestamp", TIMESTAMP},
 	{"timezone_hour", TIMEZONE_HOUR},
 	{"timezone_minute", TIMEZONE_MINUTE},
 	{"to", TO},
diff --git a/src/interfaces/ecpg/preproc/pgc.l b/src/interfaces/ecpg/preproc/pgc.l
index a7794cfbb0c..2af1e3e522b 100644
--- a/src/interfaces/ecpg/preproc/pgc.l
+++ b/src/interfaces/ecpg/preproc/pgc.l
@@ -34,7 +34,6 @@
 #undef yywrap
 #endif /* yywrap */
 
-int debugging = 0;
 extern YYSTYPE yylval;
 int llen;
 char literal[MAX_PARSE_BUFFER];
diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y
index 17a370aaebf..387ba1e1439 100644
--- a/src/interfaces/ecpg/preproc/preproc.y
+++ b/src/interfaces/ecpg/preproc/preproc.y
@@ -100,7 +100,7 @@ new_variable(const char * name, struct ECPGtype * type)
 {
     struct variable * p = (struct variable*) mm_alloc(sizeof(struct variable));
 
-    p->name = strdup(name);
+    p->name = mm_strdup(name);
     p->type = type;
     p->brace_level = braces_open;
 
@@ -528,57 +528,52 @@ output_statement(char * stmt, int mode)
 %token		TYPECAST
 
 /* Keywords (in SQL92 reserved words) */
-%token  ABSOLUTE, ACTION, ADD, ALL, ALTER, AND, ANY AS, ASC,
+%token  ABSOLUTE, ACTION, ADD, ALL, ALTER, AND, ANY, AS, ASC,
                 BEGIN_TRANS, BETWEEN, BOTH, BY,
                 CASCADE, CAST, CHAR, CHARACTER, CHECK, CLOSE, COLLATE, COLUMN, COMMIT, 
                 CONSTRAINT, CREATE, CROSS, CURRENT, CURRENT_DATE, CURRENT_TIME, 
                 CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
                 DAY_P, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DOUBLE, DROP,
                 END_TRANS, EXECUTE, EXISTS, EXTRACT,
-                FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
+                FALSE_P, FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
                 GRANT, GROUP, HAVING, HOUR_P,
                 IN, INNER_P, INSENSITIVE, INSERT, INTERVAL, INTO, IS,
                 JOIN, KEY, LANGUAGE, LEADING, LEFT, LIKE, LOCAL,
                 MATCH, MINUTE_P, MONTH_P, NAMES,
-                NATIONAL, NATURAL, NCHAR, NEXT, NO, NOT, NOTIFY, NULL_P, NUMERIC,
+                NATIONAL, NATURAL, NCHAR, NEXT, NO, NOT, NULL_P, NUMERIC,
                 OF, ON, ONLY, OPTION, OR, ORDER, OUTER_P,
                 PARTIAL, POSITION, PRECISION, PRIMARY, PRIOR, PRIVILEGES, PROCEDURE, PUBLIC,
                 READ, REFERENCES, RELATIVE, REVOKE, RIGHT, ROLLBACK,
                 SCROLL, SECOND_P, SELECT, SET, SUBSTRING,
                 TABLE, TIME, TIMESTAMP, TIMEZONE_HOUR, TIMEZONE_MINUTE,
-		TO, TRAILING, TRANSACTION, TRIM,
+		TO, TRAILING, TRANSACTION, TRIM, TRUE_P,
                 UNION, UNIQUE, UPDATE, USER, USING,
                 VALUES, VARCHAR, VARYING, VIEW,
                 WHERE, WITH, WORK, YEAR_P, ZONE
 
 /* Keywords (in SQL3 reserved words) */
-%token  FALSE_P, TRIGGER, TRUE_P
+%token  TRIGGER
 
 /* Keywords (in SQL92 non-reserved words) */
 %token  TYPE_P
 
-/* Keywords for Postgres support (not in SQL92 reserved words) */
-%token  ABORT_TRANS, AFTER, AGGREGATE, ANALYZE,
-                BACKWARD, BEFORE, BINARY, CACHE, CLUSTER, COPY, CYCLE,
-                DATABASE, DELIMITERS, DO, EACH, EXPLAIN, EXTEND,
+/* Keywords for Postgres support (not in SQL92 reserved words)
+ *
+ * The CREATEDB and CREATEUSER tokens should go away
+ * when some sort of pg_privileges relation is introduced.
+ * - Todd A. Brandys 1998-01-01?
+ */
+%token  ABORT_TRANS, AFTER, AGGREGATE, ANALYZE, BACKWARD, BEFORE, BINARY,
+		CACHE, CLUSTER, COPY, CREATEDB, CREATEUSER, CYCLE,
+                DATABASE, DELIMITERS, DO, EACH, ENCODING, EXPLAIN, EXTEND,
                 FORWARD, FUNCTION, HANDLER,
                 INCREMENT, INDEX, INHERITS, INSTEAD, ISNULL,
-                LANCOMPILER, LISTEN, UNLISTEN, LOAD, LOCK_P, LOCATION, MAXVALUE, MINVALUE, MOVE,
-                NEW, NONE, NOTHING, NOTNULL, OIDS, OPERATOR, PROCEDURAL,
+                LANCOMPILER, LISTEN, UNLISTEN, LOAD, LOCATION, LOCK_P, MAXVALUE, MINVALUE, MOVE,
+                NEW,  NOCREATEDB, NOCREATEUSER, NONE, NOTHING, NOTIFY, NOTNULL,
+		OIDS, OPERATOR, PASSWORD, PROCEDURAL,
                 RECIPE, RENAME, RESET, RETURNS, ROW, RULE,
                 SERIAL, SEQUENCE, SETOF, SHOW, START, STATEMENT, STDIN, STDOUT, TRUSTED,
-                VACUUM, VERBOSE, VERSION, ENCODING
-
-/* Keywords (obsolete; retain through next version for parser - thomas 1997-12-0 4) */
-%token  ARCHIVE
-
-/*
- * Tokens for pg_passwd support.  The CREATEDB and CREATEUSER tokens should go a way
- * when some sort of pg_privileges relation is introduced.
- *
- *                                    Todd A. Brandys
- */
-%token  PASSWORD, CREATEDB, NOCREATEDB, CREATEUSER, NOCREATEUSER, VALID, UNTIL
+                UNLISTEN, UNTIL, VACUUM, VALID, VERBOSE, VERSION
 
 /* Special keywords, not in the query language - see the "lex" file */
 %token <str>    IDENT SCONST Op CSTRING CVARIABLE CPP_LINE
@@ -615,7 +610,7 @@ output_statement(char * stmt, int mode)
 
 %type  <str>	Iconst Fconst Sconst TransactionStmt CreateStmt UserId
 %type  <str>	CreateAsElement OptCreateAs CreateAsList CreateAsStmt
-%type  <str>	OptArchiveType OptInherit key_reference key_action
+%type  <str>	OptInherit key_reference key_action
 %type  <str>    key_match constraint_expr ColLabel SpecialRuleRelation
 %type  <str> 	ColId default_expr ColQualifier columnDef ColQualList
 %type  <str>    ColConstraint ColConstraintElem default_list NumericOnly FloatOnly
@@ -1059,9 +1054,9 @@ copy_delimiter:  USING DELIMITERS Sconst		{ $$ = cat2_str(make1_str("using delim
  *****************************************************************************/
 
 CreateStmt:  CREATE TABLE relation_name '(' OptTableElementList ')'
-				OptInherit OptArchiveType
+				OptInherit
 				{
-					$$ = cat5_str(make1_str("create table"), $3,  make3_str(make1_str("("), $5, make1_str(")")), $7, $8);
+					$$ = cat4_str(make1_str("create table"), $3,  make3_str(make1_str("("), $5, make1_str(")")), $7);
 				}
 		;
 
@@ -1424,14 +1419,6 @@ OptInherit:  INHERITS '(' relation_name_list ')' { $$ = make3_str(make1_str("inh
 		| /*EMPTY*/ { $$ = make1_str(""); }
 		;
 
-/*
- *	"ARCHIVE" keyword was removed in 6.3, but we keep it for now
- *  so people can upgrade with old pg_dump scripts. - momjian 1997-11-20(?)
- */
-OptArchiveType:  ARCHIVE '=' NONE { $$ = make1_str("archive = none"); }
-		| /*EMPTY*/	  { $$ = make1_str(""); }			
-		;
-
 CreateAsStmt:  CREATE TABLE relation_name OptCreateAs AS SubSelect
 		{
 			$$ = cat5_str(make1_str("create table"), $3, $4, make1_str("as"), $6); 
@@ -2481,14 +2468,14 @@ CursorStmt:  DECLARE name opt_cursor CURSOR FOR
 			        	/* initial definition */
 				        this->next = cur;
 				        this->name = $2;
-				        this->command = cat4_str(cat5_str(cat5_str(make1_str("declare"), strdup($2), $3, make1_str("cursor for select"), $7), $8, $9, $10, $11), $12, $13, $14);
+				        this->command = cat4_str(cat5_str(cat5_str(make1_str("declare"), mm_strdup($2), $3, make1_str("cursor for select"), $7), $8, $9, $10, $11), $12, $13, $14);
 					this->argsinsert = argsinsert;
 					this->argsresult = argsresult;
 					argsinsert = argsresult = NULL;
 											
 			        	cur = this;
 					
-					$$ = cat3_str(make1_str("/*"), strdup(this->command), make1_str("*/"));
+					$$ = cat3_str(make1_str("/*"), mm_strdup(this->command), make1_str("*/"));
 				}
 		;
 
@@ -3847,53 +3834,77 @@ TypeId:  ColId
  *  list due to shift/reduce conflicts in yacc. If so, move
  *  down to the ColLabel entity. - thomas 1997-11-06
  */
-ColId:  ident							{ $$ = $1; }
-		| datetime						{ $$ = $1; }
-		| ABSOLUTE						{ $$ = make1_str("absolute"); }
-		| ACTION						{ $$ = make1_str("action"); }
-		| CACHE							{ $$ = make1_str("cache"); }
-		| CYCLE							{ $$ = make1_str("cycle"); }
-		| DATABASE						{ $$ = make1_str("database"); }
-		| DELIMITERS					{ $$ = make1_str("delimiters"); }
-		| DOUBLE						{ $$ = make1_str("double"); }
-		| EACH							{ $$ = make1_str("each"); }
-		| ENCODING							{ $$ = make1_str("encoding"); }
-		| FUNCTION						{ $$ = make1_str("function"); }
-		| INCREMENT						{ $$ = make1_str("increment"); }
-		| INDEX							{ $$ = make1_str("index"); }
-		| INSENSITIVE						{ $$ = make1_str("insensitive"); }
-		| KEY							{ $$ = make1_str("key"); }
-		| LANGUAGE						{ $$ = make1_str("language"); }
-		| LOCATION						{ $$ = make1_str("location"); }
-		| MATCH							{ $$ = make1_str("match"); }
-		| MAXVALUE						{ $$ = make1_str("maxvalue"); }
-		| MINVALUE						{ $$ = make1_str("minvalue"); }
-		| NEXT							{ $$ = make1_str("next"); }
-		| OF							{ $$ = make1_str("of"); }
-		| ONLY							{ $$ = make1_str("only"); }
-		| OPERATOR						{ $$ = make1_str("operator"); }
-		| OPTION						{ $$ = make1_str("option"); }
-		| PASSWORD						{ $$ = make1_str("password"); }
-		| PRIOR							{ $$ = make1_str("prior"); }
-		| PRIVILEGES						{ $$ = make1_str("privileges"); }
-		| READ							{ $$ = make1_str("read"); }
-		| RECIPE						{ $$ = make1_str("recipe"); }
-		| RELATIVE						{ $$ = make1_str("relative"); }
-		| ROW							{ $$ = make1_str("row"); }
-		| SCROLL						{ $$ = make1_str("scroll"); }
-		| SERIAL						{ $$ = make1_str("serial"); }
-		| START							{ $$ = make1_str("start"); }
-		| STATEMENT						{ $$ = make1_str("statement"); }
-		| TIME							{ $$ = make1_str("time"); }
-		| TIMEZONE_HOUR                                 { $$ = make1_str("timezone_hour"); }
-                | TIMEZONE_MINUTE                               { $$ = make1_str("timezone_minute"); }
-		| TRIGGER						{ $$ = make1_str("trigger"); }
-		| TYPE_P						{ $$ = make1_str("type"); }
-		| VALID							{ $$ = make1_str("valid"); }
-		| VERSION						{ $$ = make1_str("version"); }
-		| ZONE							{ $$ = make1_str("zone"); }
+ColId:  ident					{ $$ = $1; }
+		| datetime			{ $$ = $1; }
+		| ABSOLUTE			{ $$ = make1_str("absolute"); }
+		| ACTION			{ $$ = make1_str("action"); }
+		| AFTER				{ $$ = make1_str("after"); }
+		| AGGREGATE			{ $$ = make1_str("aggregate"); }
+		| BACKWARD			{ $$ = make1_str("backward"); }
+		| BEFORE			{ $$ = make1_str("before"); }
+		| CACHE				{ $$ = make1_str("cache"); }
+		| CREATEDB			{ $$ = make1_str("createdb"); }
+		| CREATEUSER			{ $$ = make1_str("createuser"); }
+		| CYCLE				{ $$ = make1_str("cycle"); }
+		| DATABASE			{ $$ = make1_str("database"); }
+		| DELIMITERS			{ $$ = make1_str("delimiters"); }
+		| DOUBLE			{ $$ = make1_str("double"); }
+		| EACH				{ $$ = make1_str("each"); }
+		| ENCODING			{ $$ = make1_str("encoding"); }
+		| FORWARD			{ $$ = make1_str("forward"); }
+		| FUNCTION			{ $$ = make1_str("function"); }
+		| HANDLER			{ $$ = make1_str("handler"); }
+		| INCREMENT			{ $$ = make1_str("increment"); }
+		| INDEX				{ $$ = make1_str("index"); }
+		| INHERITS			{ $$ = make1_str("inherits"); }
+		| INSENSITIVE			{ $$ = make1_str("insensitive"); }
+		| INSTEAD			{ $$ = make1_str("instead"); }
+		| ISNULL			{ $$ = make1_str("isnull"); }
+		| KEY				{ $$ = make1_str("key"); }
+		| LANGUAGE			{ $$ = make1_str("language"); }
+		| LANCOMPILER			{ $$ = make1_str("lancompiler"); }
+		| LOCATION			{ $$ = make1_str("location"); }
+		| MATCH				{ $$ = make1_str("match"); }
+		| MAXVALUE			{ $$ = make1_str("maxvalue"); }
+		| MINVALUE			{ $$ = make1_str("minvalue"); }
+		| NEXT				{ $$ = make1_str("next"); }
+		| NOCREATEDB			{ $$ = make1_str("nocreatedb"); }
+		| NOCREATEUSER			{ $$ = make1_str("nocreateuser"); }
+		| NOTHING			{ $$ = make1_str("nothing"); }
+		| NOTNULL			{ $$ = make1_str("notnull"); }
+		| OF				{ $$ = make1_str("of"); }
+		| OIDS				{ $$ = make1_str("oids"); }
+		| ONLY				{ $$ = make1_str("only"); }
+		| OPERATOR			{ $$ = make1_str("operator"); }
+		| OPTION			{ $$ = make1_str("option"); }
+		| PASSWORD			{ $$ = make1_str("password"); }
+		| PRIOR				{ $$ = make1_str("prior"); }
+		| PRIVILEGES			{ $$ = make1_str("privileges"); }
+		| PROCEDURAL			{ $$ = make1_str("procedural"); }
+		| READ				{ $$ = make1_str("read"); }
+		| RECIPE			{ $$ = make1_str("recipe"); }
+		| RELATIVE			{ $$ = make1_str("relative"); }
+		| RENAME			{ $$ = make1_str("rename"); }
+		| RETURNS			{ $$ = make1_str("returns"); }
+		| ROW				{ $$ = make1_str("row"); }
+		| RULE				{ $$ = make1_str("rule"); }
+		| SCROLL			{ $$ = make1_str("scroll"); }
+		| SEQUENCE                      { $$ = make1_str("sequence"); }
+		| SERIAL			{ $$ = make1_str("serial"); }
+		| START				{ $$ = make1_str("start"); }
+		| STATEMENT			{ $$ = make1_str("statement"); }
+		| STDIN                         { $$ = make1_str("stdin"); }
+		| STDOUT                        { $$ = make1_str("stdout"); }
+		| TIME				{ $$ = make1_str("time"); }
+		| TIMEZONE_HOUR                 { $$ = make1_str("timezone_hour"); }
+                | TIMEZONE_MINUTE               { $$ = make1_str("timezone_minute"); }
+		| TRIGGER			{ $$ = make1_str("trigger"); }
+		| TRUSTED			{ $$ = make1_str("trusted"); }
+		| TYPE_P			{ $$ = make1_str("type"); }
+		| VALID				{ $$ = make1_str("valid"); }
+		| VERSION			{ $$ = make1_str("version"); }
+		| ZONE				{ $$ = make1_str("zone"); }
 		;
-
 /* Column label
  * Allowed labels in "AS" clauses.
  * Include TRUE/FALSE SQL3 reserved words for Postgres backward
@@ -3905,20 +3916,37 @@ ColId:  ident							{ $$ = $1; }
  *  when used as a full identifier. - thomas 1997-11-06
  */
 ColLabel:  ColId						{ $$ = $1; }
-		| ARCHIVE						{ $$ = make1_str("archive"); }
+		| ABORT_TRANS                                   { $$ = make1_str("abort"); }
+		| ANALYZE                                       { $$ = make1_str("analyze"); }
+		| BINARY                                        { $$ = make1_str("binary"); }
 		| CLUSTER						{ $$ = make1_str("cluster"); }
 		| CONSTRAINT					{ $$ = make1_str("constraint"); }
+		| COPY							{ $$ = make1_str("copy"); }
 		| CROSS							{ $$ = make1_str("cross"); }
+		| CURRENT							{ $$ = make1_str("current"); }
+		| DO							{ $$ = make1_str("do"); }
+		| EXPLAIN							{ $$ = make1_str("explain"); }
+		| EXTEND							{ $$ = make1_str("extend"); }
+		| FALSE_P							{ $$ = make1_str("false"); }
 		| FOREIGN						{ $$ = make1_str("foreign"); }
 		| GROUP							{ $$ = make1_str("group"); }
+		| LISTEN							{ $$ = make1_str("listen"); }
 		| LOAD							{ $$ = make1_str("load"); }
+		| LOCK_P							{ $$ = make1_str("lock"); }
+		| MOVE							{ $$ = make1_str("move"); }
+		| NEW							{ $$ = make1_str("new"); }
+		| NONE							{ $$ = make1_str("none"); }
 		| ORDER							{ $$ = make1_str("order"); }
 		| POSITION						{ $$ = make1_str("position"); }
 		| PRECISION						{ $$ = make1_str("precision"); }
+		| RESET							{ $$ = make1_str("reset"); }
+		| SETOF							{ $$ = make1_str("setof"); }
+		| SHOW							{ $$ = make1_str("show"); }
 		| TABLE							{ $$ = make1_str("table"); }
 		| TRANSACTION					{ $$ = make1_str("transaction"); }
 		| TRUE_P						{ $$ = make1_str("true"); }
-		| FALSE_P						{ $$ = make1_str("false"); }
+		| VACUUM					{ $$ = make1_str("vacuum"); }
+		| VERBOSE						{ $$ = make1_str("verbose"); }
 		;
 
 SpecialRuleRelation:  CURRENT
@@ -3980,7 +4008,7 @@ storage_clause : S_EXTERN	{ $$ = "extern"; }
 type: simple_type
 		{
 			$$.type_enum = $1;
-			$$.type_str = strdup(ECPGtype_name($1));
+			$$.type_str = mm_strdup(ECPGtype_name($1));
 		}
 	| struct_type
 		{
@@ -4215,7 +4243,7 @@ connection_target: database_name opt_server opt_port
 		}
 	| Sconst
 		{
-		  $$ = strdup($1);
+		  $$ = mm_strdup($1);
 		  $$[0] = '\"';
 		  $$[strlen($$) - 1] = '\"';
 		  free($1);
@@ -4431,7 +4459,7 @@ action : SQL_CONTINUE {
        | DO name '(' dotext ')' {
 	$<action>$.code = W_DO;
 	$<action>$.command = make4_str($2, make1_str("("), $4, make1_str(")"));
-	$<action>$.str = cat2_str(make1_str("do"), strdup($<action>$.command));
+	$<action>$.str = cat2_str(make1_str("do"), mm_strdup($<action>$.command));
 }
        | DO SQL_BREAK {
         $<action>$.code = W_BREAK;
@@ -4441,7 +4469,7 @@ action : SQL_CONTINUE {
        | SQL_CALL name '(' dotext ')' {
 	$<action>$.code = W_DO;
 	$<action>$.command = make4_str($2, make1_str("("), $4, make1_str(")"));
-	$<action>$.str = cat2_str(make1_str("call"), strdup($<action>$.command));
+	$<action>$.str = cat2_str(make1_str("call"), mm_strdup($<action>$.command));
 }
 
 /* some other stuff for ecpg */
diff --git a/src/interfaces/ecpg/preproc/type.c b/src/interfaces/ecpg/preproc/type.c
index 73ec51e21e3..cf68d8d60a4 100644
--- a/src/interfaces/ecpg/preproc/type.c
+++ b/src/interfaces/ecpg/preproc/type.c
@@ -20,6 +20,21 @@ mm_alloc(size_t size)
 	return ptr;
 }
 
+/* strdup + error check */
+char *
+mm_strdup(const char *string)
+{
+	char	   *new = strdup(string);
+
+	if (new == NULL)
+	{
+		fprintf(stderr, "Out of memory\n");
+		exit(OUT_OF_MEMORY);
+	}
+
+	return new;
+}
+
 /* duplicate memberlist */
 static struct ECPGstruct_member *
 struct_member_dup(struct ECPGstruct_member * rm)
diff --git a/src/interfaces/ecpg/test/test2.pgc b/src/interfaces/ecpg/test/test2.pgc
index 89d938730b8..7d939426b97 100644
--- a/src/interfaces/ecpg/test/test2.pgc
+++ b/src/interfaces/ecpg/test/test2.pgc
@@ -52,7 +52,7 @@ exec sql declare cur cursor for
 
 	while (1) {
 		strcpy(msg, "fetch");
-		exec sql fetch cur into :personal:ind_personal, :married:ind_married;
+		exec sql fetch in cur into :personal:ind_personal, :married:ind_married;
                 printf ("%8.8s was born %d (age = %d) %s%s\n", personal.name.arr, personal.birth.born, personal.birth.age, ind_married ? "" : "and married ", ind_married ? "" : married);
 	}
 
-- 
GitLab