diff --git a/src/interfaces/ecpg/preproc/ecpg.addons b/src/interfaces/ecpg/preproc/ecpg.addons
index ca3efad..982ce78 100644
--- a/src/interfaces/ecpg/preproc/ecpg.addons
+++ b/src/interfaces/ecpg/preproc/ecpg.addons
@@ -15,7 +15,7 @@ ECPG: stmtClosePortalStmt block
 			}
 		}
 
-		output_statement($1, 0, ECPGst_normal);
+		$1 = $1;
 	}
 ECPG: stmtDeallocateStmt block
 	{
@@ -25,7 +25,11 @@ ECPG: stmtDeclareCursorStmt block
 	{ output_simple_statement($1); }
 ECPG: stmtDiscardStmt block
 ECPG: stmtFetchStmt block
-	{ output_statement($1, 1, ECPGst_normal); }
+	{
+		/* g_cursor_name is set in the fetch_args block and freed in the output_cursor_statement */
+		output_cursor_statement(ECPGcst_fetch, g_cursor_name, NULL, $1, 1, ECPGst_normal);
+		g_cursor_name = NULL;
+	}
 ECPG: stmtDeleteStmt block
 ECPG: stmtInsertStmt block
 ECPG: stmtSelectStmt block
@@ -63,6 +67,10 @@ ECPG: stmtViewStmt rule
 		whenever_action(2);
 		free($1);
 	}
+	| ECPGDeclareStmt
+	{
+		output_declare_statement($1);
+	}
 	| ECPGCursorStmt
 	{
 		output_simple_statement($1);
@@ -132,7 +140,14 @@ ECPG: stmtViewStmt rule
 		if ((ptr = add_additional_variables($1, true)) != NULL)
 		{
 			connection = ptr->connection ? mm_strdup(ptr->connection) : NULL;
-			output_statement(mm_strdup(ptr->command), 0, ECPGst_normal);
+			if (ptr->prepared_name)
+			{
+				output_cursor_statement(ECPGcst_open, $1, mm_strdup(ptr->prepared_name), mm_strdup(ptr->command), 0, ECPGst_normal);
+			}
+			else
+			{
+				output_cursor_statement(ECPGcst_open, $1, NULL, mm_strdup(ptr->command), 0, ECPGst_normal);
+			}
 			ptr->opened = true;
 		}
 	}
@@ -204,6 +219,7 @@ ECPG: var_valueNumericOnly addon
 		}
 ECPG: fetch_argscursor_name addon
 		add_additional_variables($1, false);
+		g_cursor_name = mm_strdup($1);
 		if ($1[0] == ':')
 		{
 			free($1);
@@ -211,6 +227,7 @@ ECPG: fetch_argscursor_name addon
 		}
 ECPG: fetch_argsfrom_incursor_name addon
 		add_additional_variables($2, false);
+		g_cursor_name = mm_strdup($2);
 		if ($2[0] == ':')
 		{
 			free($2);
@@ -222,6 +239,7 @@ ECPG: fetch_argsFIRST_Popt_from_incursor_name addon
 ECPG: fetch_argsLAST_Popt_from_incursor_name addon
 ECPG: fetch_argsALLopt_from_incursor_name addon
 		add_additional_variables($3, false);
+		g_cursor_name = mm_strdup($3);
 		if ($3[0] == ':')
 		{
 			free($3);
@@ -229,6 +247,7 @@ ECPG: fetch_argsALLopt_from_incursor_name addon
 		}
 ECPG: fetch_argsSignedIconstopt_from_incursor_name addon
 		add_additional_variables($3, false);
+		g_cursor_name = mm_strdup($3);
 		if ($3[0] == ':')
 		{
 			free($3);
@@ -242,6 +261,7 @@ ECPG: fetch_argsSignedIconstopt_from_incursor_name addon
 ECPG: fetch_argsFORWARDALLopt_from_incursor_name addon
 ECPG: fetch_argsBACKWARDALLopt_from_incursor_name addon
 		add_additional_variables($4, false);
+		g_cursor_name = mm_strdup($4);
 		if ($4[0] == ':')
 		{
 			free($4);
@@ -252,6 +272,7 @@ ECPG: fetch_argsRELATIVE_PSignedIconstopt_from_incursor_name addon
 ECPG: fetch_argsFORWARDSignedIconstopt_from_incursor_name addon
 ECPG: fetch_argsBACKWARDSignedIconstopt_from_incursor_name addon
 		add_additional_variables($4, false);
+		g_cursor_name = mm_strdup($4);
 		if ($4[0] == ':')
 		{
 			free($4);
@@ -304,6 +325,7 @@ ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectSt
 		}
 
 		this = (struct cursor *) mm_alloc(sizeof(struct cursor));
+		memset(this, 0 ,sizeof(struct cursor));
 
 		this->next = cur;
 		this->name = $2;
@@ -336,8 +358,31 @@ ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectSt
 	}
 ECPG: ClosePortalStmtCLOSEcursor_name block
 	{
+		char *stmt = NULL;
+		char *cursor_name = NULL;
 		char *cursor_marker = $2[0] == ':' ? mm_strdup("$0") : $2;
-		$$ = cat2_str(mm_strdup("close"), cursor_marker);
+
+		cursor_name = mm_strdup($2);
+
+		stmt = cat2_str(mm_strdup("close"), cursor_marker);
+
+		if (INFORMIX_MODE)
+		{
+			if (pg_strcasecmp(stmt+strlen("close "), "database") == 0)
+			{
+				if (connection)
+					mmerror(PARSE_ERROR, ET_ERROR, "AT option not allowed in CLOSE DATABASE statement");
+
+				fprintf(base_yyout, "{ ECPGdisconnect(__LINE__, \"CURRENT\");");
+				whenever_action(2);
+				free(stmt);
+				break;
+			}
+		}
+
+		output_cursor_statement(ECPGcst_close, cursor_name, NULL, stmt, 0, ECPGst_normal);
+
+		$$ = EMPTY;
 	}
 ECPG: opt_hold block
 	{
@@ -416,48 +461,56 @@ ECPG: FetchStmtMOVEfetch_args rule
 	{
 		char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3;
 		add_additional_variables($3, false);
+		g_cursor_name = mm_strdup($3);
 		$$ = cat_str(2, mm_strdup("fetch forward"), cursor_marker);
 	}
 	| FETCH FORWARD from_in cursor_name opt_ecpg_fetch_into
 	{
 		char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4;
 		add_additional_variables($4, false);
+		g_cursor_name = mm_strdup($4);
 		$$ = cat_str(2, mm_strdup("fetch forward from"), cursor_marker);
 	}
 	| FETCH BACKWARD cursor_name opt_ecpg_fetch_into
 	{
 		char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3;
 		add_additional_variables($3, false);
+		g_cursor_name = mm_strdup($3);
 		$$ = cat_str(2, mm_strdup("fetch backward"), cursor_marker);
 	}
 	| FETCH BACKWARD from_in cursor_name opt_ecpg_fetch_into
 	{
 		char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4;
 		add_additional_variables($4, false);
+		g_cursor_name = mm_strdup($4);
 		$$ = cat_str(2, mm_strdup("fetch backward from"), cursor_marker);
 	}
 	| MOVE FORWARD cursor_name
 	{
 		char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3;
 		add_additional_variables($3, false);
+		g_cursor_name = mm_strdup($3);
 		$$ = cat_str(2, mm_strdup("move forward"), cursor_marker);
 	}
 	| MOVE FORWARD from_in cursor_name
 	{
 		char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4;
 		add_additional_variables($4, false);
+		g_cursor_name = mm_strdup($4);
 		$$ = cat_str(2, mm_strdup("move forward from"), cursor_marker);
 	}
 	| MOVE BACKWARD cursor_name
 	{
 		char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3;
 		add_additional_variables($3, false);
+		g_cursor_name = mm_strdup($3);
 		$$ = cat_str(2, mm_strdup("move backward"), cursor_marker);
 	}
 	| MOVE BACKWARD from_in cursor_name
 	{
 		char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4;
 		add_additional_variables($4, false);
+		g_cursor_name = mm_strdup($4);
 		$$ = cat_str(2, mm_strdup("move backward from"), cursor_marker);
 	}
 ECPG: limit_clauseLIMITselect_limit_value','select_offset_value block
diff --git a/src/interfaces/ecpg/preproc/ecpg.c b/src/interfaces/ecpg/preproc/ecpg.c
index fa80bb2..2bda505 100644
--- a/src/interfaces/ecpg/preproc/ecpg.c
+++ b/src/interfaces/ecpg/preproc/ecpg.c
@@ -28,6 +28,7 @@ struct _include_path *include_paths = NULL;
 struct cursor *cur = NULL;
 struct typedefs *types = NULL;
 struct _defines *defines = NULL;
+struct declared_name_st *g_declared_list = NULL;
 
 static void
 help(const char *progname)
@@ -111,6 +112,48 @@ add_preprocessor_define(char *define)
 	defines->next = pd;
 }
 
+static void
+free_argument(struct arguments *arg)
+{
+	if (arg == NULL)
+		return;
+
+	free_argument(arg->next);
+
+	/*
+	 *  Don't free variables in it because the original codes don't free it either
+	 *  variables are static structures instead of allocating
+	 */
+	free(arg);
+}
+
+static void
+free_cursor(struct cursor *c)
+{
+	if (c == NULL)
+		return;
+
+	free_cursor(c->next);
+	free_argument(c->argsinsert);
+	free_argument(c->argsresult);
+
+	free(c->name);
+	free(c->function);
+	free(c->command);
+	free(c->prepared_name);
+	free(c);
+}
+
+static void
+free_declared_stmt(struct declared_name_st *st)
+{
+	if (st == NULL)
+		return;
+
+	free_declared_stmt(st->next);
+	free(st);
+}
+
 #define ECPG_GETOPT_LONG_REGRESSION		1
 int
 main(int argc, char *const argv[])
@@ -343,29 +386,18 @@ main(int argc, char *const argv[])
 				struct typedefs *typeptr;
 
 				/* remove old cursor definitions if any are still there */
-				for (ptr = cur; ptr != NULL;)
+				if (cur)
 				{
-					struct cursor *this = ptr;
-					struct arguments *l1,
-							   *l2;
-
-					free(ptr->command);
-					free(ptr->connection);
-					free(ptr->name);
-					for (l1 = ptr->argsinsert; l1; l1 = l2)
-					{
-						l2 = l1->next;
-						free(l1);
-					}
-					for (l1 = ptr->argsresult; l1; l1 = l2)
-					{
-						l2 = l1->next;
-						free(l1);
-					}
-					ptr = ptr->next;
-					free(this);
+					free_cursor(cur);
+					cur = NULL;
+				}
+
+				/* remove old declared statements if any are still there */
+				if (g_declared_list)
+				{
+					free_declared_stmt(g_declared_list);
+					g_declared_list = NULL;
 				}
-				cur = NULL;
 
 				/* remove non-pertinent old defines as well */
 				while (defines && !defines->pertinent)
@@ -479,6 +511,18 @@ main(int argc, char *const argv[])
 
 			free(input_filename);
 		}
+
+		if(g_declared_list)
+		{
+			free_declared_stmt(g_declared_list);
+			g_declared_list = NULL;
+		}
+
+		if(cur)
+		{
+			free_cursor(cur);
+			cur = NULL;
+		}
 	}
 	return ret_value;
 }
diff --git a/src/interfaces/ecpg/preproc/ecpg.header b/src/interfaces/ecpg/preproc/ecpg.header
index 2562366..0cebf56 100644
--- a/src/interfaces/ecpg/preproc/ecpg.header
+++ b/src/interfaces/ecpg/preproc/ecpg.header
@@ -38,6 +38,7 @@ char *current_function;
 int ecpg_internal_var = 0;
 char	*connection = NULL;
 char	*input_filename = NULL;
+char	*g_cursor_name = NULL;
 
 static int	FoundInto = 0;
 static int	initializer = 0;
diff --git a/src/interfaces/ecpg/preproc/ecpg.trailer b/src/interfaces/ecpg/preproc/ecpg.trailer
index 1c10879..af15b88 100644
--- a/src/interfaces/ecpg/preproc/ecpg.trailer
+++ b/src/interfaces/ecpg/preproc/ecpg.trailer
@@ -284,6 +284,38 @@ prepared_name: name
 		;
 
 /*
+ * Declare Statement
+ */
+ECPGDeclareStmt: DECLARE prepared_name STATEMENT
+		{
+			struct declared_name_st *ptr = NULL;
+
+			/* Check whether the declared name has been defined or not */
+			for (ptr = g_declared_list; ptr != NULL; ptr = ptr->next)
+			{
+				if (strcmp($2, ptr->name) == 0)
+				{
+					/* re-definition is a bug */
+					mmerror(PARSE_ERROR, ET_ERROR, "declared name %s is already defined", ptr->name);
+				}
+			}
+
+			/* Add a new declared name into the g_declared_list */
+			ptr = NULL;
+			ptr = (struct declared_name_st *) mm_alloc(sizeof(struct declared_name_st));
+			if (ptr)
+			{
+				/* initial definition */
+				ptr->name = $2;
+				ptr->next = g_declared_list;
+				g_declared_list = ptr;
+			}
+
+			$$ = mm_strdup($2);
+		}
+;
+
+/*
  * Declare a prepared cursor. The syntax is different from the standard
  * declare statement, so we create a new rule.
  */
@@ -309,6 +341,7 @@ ECPGCursorStmt:  DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared
 			}
 
 			this = (struct cursor *) mm_alloc(sizeof(struct cursor));
+			memset(this, 0 ,sizeof(struct cursor));
 
 			/* initial definition */
 			this->next = cur;
@@ -318,6 +351,7 @@ ECPGCursorStmt:  DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared
 			this->command =  cat_str(6, mm_strdup("declare"), cursor_marker, $3, mm_strdup("cursor"), $5, mm_strdup("for $1"));
 			this->argsresult = NULL;
 			this->argsresult_oos = NULL;
+			this->prepared_name = $7;
 
 			thisquery->type = &ecpg_query;
 			thisquery->brace_level = 0;
diff --git a/src/interfaces/ecpg/preproc/ecpg.type b/src/interfaces/ecpg/preproc/ecpg.type
index ac6aa00..978be84 100644
--- a/src/interfaces/ecpg/preproc/ecpg.type
+++ b/src/interfaces/ecpg/preproc/ecpg.type
@@ -9,6 +9,7 @@
 %type <str> ECPGDeallocateDescr
 %type <str> ECPGDeclaration
 %type <str> ECPGDeclare
+%type <str> ECPGDeclareStmt
 %type <str> ECPGDescribe
 %type <str> ECPGDisconnect
 %type <str> ECPGExecuteImmediateStmt
diff --git a/src/interfaces/ecpg/preproc/extern.h b/src/interfaces/ecpg/preproc/extern.h
index 0ce3a6e..dcfdc06 100644
--- a/src/interfaces/ecpg/preproc/extern.h
+++ b/src/interfaces/ecpg/preproc/extern.h
@@ -50,6 +50,7 @@ extern struct _include_path *include_paths;
 extern struct cursor *cur;
 extern struct typedefs *types;
 extern struct _defines *defines;
+extern struct declared_name_st *g_declared_list;
 extern struct ECPGtype ecpg_no_indicator;
 extern struct variable no_indicator;
 extern struct arguments *argsinsert;
@@ -72,6 +73,8 @@ extern void output_statement(char *, int, enum ECPG_statement_type);
 extern void output_prepare_statement(char *, char *);
 extern void output_deallocate_prepare_statement(char *);
 extern void output_simple_statement(char *);
+extern void output_declare_statement(char *);
+extern void output_cursor_statement(int , char *, char *, char *, int , enum ECPG_statement_type);
 extern char *hashline_number(void);
 extern int	base_yyparse(void);
 extern int	base_yylex(void);
diff --git a/src/interfaces/ecpg/preproc/output.c b/src/interfaces/ecpg/preproc/output.c
index 59d5d30..65e94b8 100644
--- a/src/interfaces/ecpg/preproc/output.c
+++ b/src/interfaces/ecpg/preproc/output.c
@@ -5,6 +5,7 @@
 #include "extern.h"
 
 static void output_escaped_str(char *cmd, bool quoted);
+static void output_cursor_name(char *str);
 
 void
 output_line_number(void)
@@ -195,7 +196,16 @@ static void
 output_escaped_str(char *str, bool quoted)
 {
 	int			i = 0;
-	int			len = strlen(str);
+	int			len = 0;
+
+	if (str == NULL)
+	{
+		fputs("NULL", base_yyout);
+
+		return;
+	}
+
+	len = strlen(str);
 
 	if (quoted && str[0] == '"' && str[len - 1] == '"') /* do not escape quotes
 														 * at beginning and end
@@ -244,3 +254,147 @@ output_escaped_str(char *str, bool quoted)
 	if (quoted && str[0] == '"' && str[len] == '"')
 		fputs("\"", base_yyout);
 }
+
+/*
+ * This is a tool function used by the output_cursor_statement function to print
+ * cursor name after the string such as "ECPGopen(","ECPGfetch(","ECPGclose(".
+ */
+static void
+output_cursor_name(char *str)
+{
+	int			i = 0;
+	int			len = 0;
+
+	if (str == NULL)
+	{
+		fputs("NULL", base_yyout);
+
+		return;
+	}
+
+	len = strlen(str);
+	fputs("\"", base_yyout);
+	if (str[0] == '\"' && str[len - 1] == '\"')
+	{
+		i = 1;
+		len--;
+		fputs("\\\"", base_yyout);
+
+		/* output this char by char as we have to filter " and \n */
+		for (; i < len; i++)
+		{
+			if (str[i] == '"')
+				fputs("\\\"", base_yyout);
+			else if (str[i] == '\n')
+				fputs("\\\n", base_yyout);
+			else if (str[i] == '\\')
+			{
+				int			j = i;
+
+				/*
+				 * check whether this is a continuation line if it is, do not
+				 * output anything because newlines are escaped anyway
+				 */
+
+				/* accept blanks after the '\' as some other compilers do too */
+				do
+				{
+					j++;
+				} while (str[j] == ' ' || str[j] == '\t');
+
+				if ((str[j] != '\n') && (str[j] != '\r' || str[j + 1] != '\n'))		/* not followed by a
+																					 * newline */
+					fputs("\\\\",base_yyout);
+			}
+			else if (str[i] == '\r' && str[i + 1] == '\n')
+			{
+				fputs("\\\r\n", base_yyout);
+				i++;
+			}
+			else
+				fputc(str[i], base_yyout);
+		}
+
+		fputs("\\\"", base_yyout);
+	}
+	else
+		fputs(str, base_yyout);
+
+	fputs("\"", base_yyout);
+}
+
+/*
+ * Translate the EXEC SQL DECLARE STATEMENT into ECPGdeclare function
+ */
+void
+output_declare_statement(char *name)
+{
+	/* connection is set in "at:" token in ecpg.trailer file */
+	fprintf(base_yyout, "{ ECPGdeclare(__LINE__, %s, ", connection ? connection : "NULL");
+	output_escaped_str(name, true);
+	fputs(");", base_yyout);
+
+	whenever_action(2);
+	free(name);
+	if (connection != NULL)
+		free(connection);
+}
+
+/*
+ * Translate the EXEC SQL CURSOR STATEMENT such as OPEN/FETCH/CLOSE cursor into
+ * ECPGopen/ECPGfetch/ECPGclose function
+ */
+void
+output_cursor_statement(int cursor_stmt, char *cursor_name, char *prepared_name, char *stmt, int whenever_mode, enum ECPG_statement_type st)
+{
+	switch(cursor_stmt)
+	{
+		case ECPGcst_open:
+			fprintf(base_yyout, "{ ECPGopen(");
+			output_cursor_name(cursor_name);
+			fprintf(base_yyout, ", ");
+			output_escaped_str(prepared_name, true);
+			fprintf(base_yyout, ", __LINE__, %d, %d, %s, %d, ",
+					compat, force_indicator, connection ? connection : "NULL", questionmarks);
+			break;
+		case ECPGcst_fetch:
+			fprintf(base_yyout, "{ ECPGfetch(");
+			output_cursor_name(cursor_name);
+			fprintf(base_yyout, ", __LINE__, %d, %d, %s, %d, ",
+					compat, force_indicator, connection ? connection : "NULL", questionmarks);
+			break;
+		case ECPGcst_close:
+			fprintf(base_yyout, "{ ECPGclose(");
+			output_cursor_name(cursor_name);
+			fprintf(base_yyout, ", __LINE__, %d, %d, %s, %d, ",
+					compat, force_indicator, connection ? connection : "NULL", questionmarks);
+			break;
+	}
+
+	if (st == ECPGst_execute || st == ECPGst_exec_immediate)
+		fprintf(base_yyout, "%s, %s, ", ecpg_statement_type_name[st], stmt);
+	else
+	{
+		if (st == ECPGst_prepnormal && auto_prepare)
+			fputs("ECPGst_prepnormal, \"", base_yyout);
+		else
+			fputs("ECPGst_normal, \"", base_yyout);
+
+		output_escaped_str(stmt, false);
+		fputs("\", ", base_yyout);
+	}
+
+	/* dump variables to C file */
+	dump_variables(argsinsert, 1);
+	fputs("ECPGt_EOIT, ", base_yyout);
+	dump_variables(argsresult, 1);
+	fputs("ECPGt_EORT);", base_yyout);
+	reset_variables();
+
+	whenever_action(whenever_mode | 2);
+	free(cursor_name);
+	free(prepared_name);
+	free(stmt);
+	if (connection != NULL)
+		free(connection);
+}
\ No newline at end of file
diff --git a/src/interfaces/ecpg/preproc/type.h b/src/interfaces/ecpg/preproc/type.h
index cd0d1da..1b6ddfb 100644
--- a/src/interfaces/ecpg/preproc/type.h
+++ b/src/interfaces/ecpg/preproc/type.h
@@ -129,6 +129,7 @@ struct cursor
 	char	   *command;
 	char	   *connection;
 	bool		opened;
+	char	   *prepared_name;
 	struct arguments *argsinsert;
 	struct arguments *argsinsert_oos;
 	struct arguments *argsresult;
@@ -136,6 +137,13 @@ struct cursor
 	struct cursor *next;
 };
 
+/* structure to store declared name */
+struct declared_name_st
+{
+	char	   *name; /* declared name */
+	struct declared_name_st *next;
+};
+
 struct typedefs
 {
 	char	   *name;
