diff --git a/doc/src/sgml/ecpg.sgml b/doc/src/sgml/ecpg.sgml
index f23a83dbc3..69a55ac819 100644
--- a/doc/src/sgml/ecpg.sgml
+++ b/doc/src/sgml/ecpg.sgml
@@ -3891,7 +3891,7 @@ EXEC SQL DESCRIBE prepared_statement INTO mysqlda;
      <step><simpara>Fetch rows from the cursor, and store them into an output SQLDA.</simpara></step>
      <step><simpara>Read values from the output SQLDA into the host variables (with conversion if necessary).</simpara></step>
      <step><simpara>Close the cursor.</simpara></step>
-     <step><simpara>Free the memory area allocated for the input SQLDA.</simpara></step>
+     <step><simpara>Free the memory area allocated for the input and output SQLDAs.</simpara></step>
     </procedure>
 
    <sect3>
@@ -4208,6 +4208,18 @@ switch (v.sqltype)
 
     ...
 }
+</programlisting>
+    </para>
+    <para>
+     Finally after using output SQLDA, the allocated memory area must be freed explicity.
+<programlisting>
+ECPGfreeSQLDA(sqlda1);
+</programlisting>
+    </para>
+    <para>
+     Alternatively, use the standard C library's free() function as in the example below.
+<programlisting>
+free(sqlda1);
 </programlisting>
     </para>
    </sect3>
@@ -4290,8 +4302,13 @@ EXEC SQL OPEN cur1 USING DESCRIPTOR sqlda2;
 
     <para>
      Finally, after using input SQLDAs, the allocated memory space
-     must be freed explicitly, unlike SQLDAs used for receiving query
-     results.
+     must be freed explicitly.
+<programlisting>
+ECPGfreeSQLDA(sqlda2);
+</programlisting>
+    </para>
+    <para>
+     Alternatively, use the standard C library's free() function as in the example below.
 <programlisting>
 free(sqlda2);
 </programlisting>
@@ -4583,6 +4600,7 @@ main(void)
         }
     }
 
+    ECPGfreeSQLDA(sqlda1);
     EXEC SQL CLOSE cur1;
     EXEC SQL COMMIT;
 
@@ -5871,6 +5889,20 @@ ECPG = ecpg
      if a single connection is being used.
     </para>
    </listitem>
+   <listitem>
+     <para>
+      <function>ECPGfreeSQLDA(sqlda_t *<replaceable>sqlda_ptr</replaceable>)</function>
+      free allocated memory area of an SQLDA.
+      Alternatively, you can use the standard C library's free() function.
+     </para>
+     <note>
+     <para>
+      If the result set contains more than one record, an SQLDA corresponding to each records is saved as linked list.
+      There is a possibility to free allocated memory area doubly and cause the application crash,
+      because ECPGfreeSQLDA() releases all SQLDAs associated with the specified the SQLDA.
+     </para>
+     </note>
+   </listitem>
   </itemizedlist>
  </sect1>
 
@@ -8275,7 +8307,7 @@ EXEC SQL INCLUDE sqlda.h;
 
     EXEC SQL CLOSE mycursor;
 
-    free(sqlda); /* The main structure is all to be free(),
+    free(sqlda); /* The main structure is all to be free() or ECPGfreeSQLDA(),
                   * sqlda and sqlda-&gt;sqlvar is in one allocated area */
 </programlisting>
     For more information, see the <literal>sqlda.h</literal> header and the
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 39813de991..d59bd5bb00 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -3406,7 +3406,7 @@ RemovePartitionKeyByRelId(Oid relid)
  * pg_partitioned_table.
  *
  * Also, invalidate the parent's relcache, so that the next rebuild will load
- * the new partition's info into its partition descriptor.  If there is a
+ * the new partition's info into its partition descriptor.  If there is a
  * default partition, we must invalidate its relcache entry as well.
  */
 void
diff --git a/src/interfaces/ecpg/ecpglib/exports.txt b/src/interfaces/ecpg/ecpglib/exports.txt
index 69e96179d5..439090cc2b 100644
--- a/src/interfaces/ecpg/ecpglib/exports.txt
+++ b/src/interfaces/ecpg/ecpglib/exports.txt
@@ -29,3 +29,5 @@ ECPGget_PGconn			 26
 ECPGtransactionStatus		 27
 ECPGset_var			 28
 ECPGget_var			 29
+ECPGfreeSQLDA_native		 30
+ECPGfreeSQLDA_informix		 31
diff --git a/src/interfaces/ecpg/ecpglib/sqlda.c b/src/interfaces/ecpg/ecpglib/sqlda.c
index 317d22fa4e..c5c37044ac 100644
--- a/src/interfaces/ecpg/ecpglib/sqlda.c
+++ b/src/interfaces/ecpg/ecpglib/sqlda.c
@@ -588,3 +588,31 @@ ecpg_set_native_sqlda(int lineno, struct sqlda_struct **_sqlda, const PGresult *
 		offset = next_offset;
 	}
 }
+
+void
+ECPGfreeSQLDA_native(struct sqlda_struct *sqlda_ptr)
+{
+	struct sqlda_struct *ptr1 = sqlda_ptr;
+	struct sqlda_struct *ptr2;
+
+	while (ptr1)
+	{
+		ptr2 = ptr1->desc_next;
+		free(ptr1);
+		ptr1 = ptr2;
+	}
+}
+
+void
+ECPGfreeSQLDA_informix(struct sqlda_compat *sqlda_ptr)
+{
+	struct sqlda_compat *ptr1 = sqlda_ptr;
+	struct sqlda_compat *ptr2;
+
+	while (ptr1)
+	{
+		ptr2 = ptr1->desc_next;
+		free(ptr1);
+		ptr1 = ptr2;
+	}
+}
diff --git a/src/interfaces/ecpg/include/ecpglib.h b/src/interfaces/ecpg/include/ecpglib.h
index 8a601996d2..f89f72e5d7 100644
--- a/src/interfaces/ecpg/include/ecpglib.h
+++ b/src/interfaces/ecpg/include/ecpglib.h
@@ -11,6 +11,8 @@
 #include "ecpgtype.h"
 #include "sqlca.h"
 #include <string.h>
+#include "sqlda-native.h"
+#include "sqlda-compat.h"
 
 #ifdef ENABLE_NLS
 extern char *ecpg_gettext(const char *msgid) pg_attribute_format_arg(1);
@@ -89,6 +91,9 @@ void	   *ECPGget_var(int number);
 /* dynamic result allocation */
 void		ECPGfree_auto_mem(void);
 
+void ECPGfreeSQLDA_native(struct sqlda_struct *);
+void ECPGfreeSQLDA_compat(struct sqlda_compat *);
+
 #ifdef ENABLE_THREAD_SAFETY
 void		ecpg_pthreads_init(void);
 #endif
diff --git a/src/interfaces/ecpg/include/sqlda.h b/src/interfaces/ecpg/include/sqlda.h
index d810e739e2..c35efacb00 100644
--- a/src/interfaces/ecpg/include/sqlda.h
+++ b/src/interfaces/ecpg/include/sqlda.h
@@ -7,12 +7,14 @@
 typedef struct sqlvar_compat sqlvar_t;
 typedef struct sqlda_compat sqlda_t;
 
+#define ECPGfreeSQLDA(sqlda) ECPGfreeSQLDA_informix(sqlda)
 #else
 
 #include "sqlda-native.h"
 typedef struct sqlvar_struct sqlvar_t;
 typedef struct sqlda_struct sqlda_t;
 
+#define ECPGfreeSQLDA(sqlda) ECPGfreeSQLDA_native(sqlda)
 #endif
 
 #endif							/* ECPG_SQLDA_H */
diff --git a/src/interfaces/ecpg/test/compat_informix/describe.pgc b/src/interfaces/ecpg/test/compat_informix/describe.pgc
index 4ee7254dff..f9d2f7fa9d 100644
--- a/src/interfaces/ecpg/test/compat_informix/describe.pgc
+++ b/src/interfaces/ecpg/test/compat_informix/describe.pgc
@@ -125,9 +125,9 @@ exec sql end declare section;
 	strcpy(msg, "deallocate");
 	exec sql deallocate descriptor desc1;
 	exec sql deallocate descriptor desc2;
-	free(sqlda1);
-	free(sqlda2);
-	free(sqlda3);
+	ECPGfreeSQLDA(sqlda1);
+	ECPGfreeSQLDA(sqlda2);
+	ECPGfreeSQLDA(sqlda3);
 
 	exec sql deallocate prepare st_id1;
 
@@ -178,9 +178,9 @@ exec sql end declare section;
 	strcpy(msg, "deallocate");
 	exec sql deallocate descriptor desc1;
 	exec sql deallocate descriptor desc2;
-	free(sqlda1);
-	free(sqlda2);
-	free(sqlda3);
+	ECPGfreeSQLDA(sqlda1);
+	ECPGfreeSQLDA(sqlda2);
+	ECPGfreeSQLDA(sqlda3);
 
 	exec sql deallocate prepare st_id2;
 
diff --git a/src/interfaces/ecpg/test/compat_informix/sqlda.pgc b/src/interfaces/ecpg/test/compat_informix/sqlda.pgc
index 87e0110aed..8ab2304e93 100644
--- a/src/interfaces/ecpg/test/compat_informix/sqlda.pgc
+++ b/src/interfaces/ecpg/test/compat_informix/sqlda.pgc
@@ -120,7 +120,7 @@ exec sql end declare section;
 	strcpy(msg, "deallocate");
 	exec sql deallocate prepare st_id1;
 
-	free(outp_sqlda);
+	ECPGfreeSQLDA(outp_sqlda);
 
 	/* SQLDA test for getting all records from a table
 	   using the Informix-specific FETCH ... USING DESCRIPTOR
@@ -157,7 +157,7 @@ exec sql end declare section;
 	strcpy(msg, "deallocate");
 	exec sql deallocate prepare st_id2;
 
-	free(outp_sqlda);
+	ECPGfreeSQLDA(outp_sqlda);
 
 	/* SQLDA test for getting one record using an input descriptor */
 
@@ -189,8 +189,8 @@ exec sql end declare section;
 	exec sql deallocate prepare st_id3;
 
 	free(inp_sqlda->sqlvar);
-	free(inp_sqlda);
-	free(outp_sqlda);
+	ECPGfreeSQLDA(inp_sqlda);
+	ECPGfreeSQLDA(outp_sqlda);
 
 	/* SQLDA test for getting one record using an input descriptor
 	 * on a named connection
@@ -229,8 +229,8 @@ exec sql end declare section;
 	exec sql deallocate prepare st_id4;
 
 	free(inp_sqlda->sqlvar);
-	free(inp_sqlda);
-	free(outp_sqlda);
+	ECPGfreeSQLDA(inp_sqlda);
+	ECPGfreeSQLDA(outp_sqlda);
 
 	strcpy(msg, "disconnect");
 	exec sql disconnect con2;
diff --git a/src/interfaces/ecpg/test/expected/compat_informix-describe.c b/src/interfaces/ecpg/test/expected/compat_informix-describe.c
index 031a2d776c..31d323c9ad 100644
--- a/src/interfaces/ecpg/test/expected/compat_informix-describe.c
+++ b/src/interfaces/ecpg/test/expected/compat_informix-describe.c
@@ -33,12 +33,14 @@
 typedef struct sqlvar_compat sqlvar_t;
 typedef struct sqlda_compat sqlda_t;
 
+#define ECPGfreeSQLDA(sqlda) ECPGfreeSQLDA_informix(sqlda)
 #else
 
 #include "sqlda-native.h"
 typedef struct sqlvar_struct sqlvar_t;
 typedef struct sqlda_struct sqlda_t;
 
+#define ECPGfreeSQLDA(sqlda) ECPGfreeSQLDA_native(sqlda)
 #endif
 
 #endif							/* ECPG_SQLDA_H */
@@ -297,9 +299,9 @@ if (sqlca.sqlcode < 0) exit (1);
 if (sqlca.sqlcode < 0) exit (1);
 #line 127 "describe.pgc"
 
-	free(sqlda1);
-	free(sqlda2);
-	free(sqlda3);
+	ECPGfreeSQLDA(sqlda1);
+	ECPGfreeSQLDA(sqlda2);
+	ECPGfreeSQLDA(sqlda3);
 
 	{ ECPGdeallocate(__LINE__, 1, NULL, "st_id1");
 #line 132 "describe.pgc"
@@ -426,9 +428,9 @@ if (sqlca.sqlcode < 0) exit (1);
 if (sqlca.sqlcode < 0) exit (1);
 #line 180 "describe.pgc"
 
-	free(sqlda1);
-	free(sqlda2);
-	free(sqlda3);
+	ECPGfreeSQLDA(sqlda1);
+	ECPGfreeSQLDA(sqlda2);
+	ECPGfreeSQLDA(sqlda3);
 
 	{ ECPGdeallocate(__LINE__, 1, NULL, "st_id2");
 #line 185 "describe.pgc"
diff --git a/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c b/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
index ad3188d1e6..88e03ed602 100644
--- a/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
+++ b/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
@@ -35,12 +35,14 @@
 typedef struct sqlvar_compat sqlvar_t;
 typedef struct sqlda_compat sqlda_t;
 
+#define ECPGfreeSQLDA(sqlda) ECPGfreeSQLDA_informix(sqlda)
 #else
 
 #include "sqlda-native.h"
 typedef struct sqlvar_struct sqlvar_t;
 typedef struct sqlda_struct sqlda_t;
 
+#define ECPGfreeSQLDA(sqlda) ECPGfreeSQLDA_native(sqlda)
 #endif
 
 #endif							/* ECPG_SQLDA_H */
@@ -294,7 +296,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 #line 121 "sqlda.pgc"
 
 
-	free(outp_sqlda);
+	ECPGfreeSQLDA(outp_sqlda);
 
 	/* SQLDA test for getting all records from a table
 	   using the Informix-specific FETCH ... USING DESCRIPTOR
@@ -369,7 +371,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 #line 158 "sqlda.pgc"
 
 
-	free(outp_sqlda);
+	ECPGfreeSQLDA(outp_sqlda);
 
 	/* SQLDA test for getting one record using an input descriptor */
 
@@ -420,8 +422,8 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	free(inp_sqlda->sqlvar);
-	free(inp_sqlda);
-	free(outp_sqlda);
+	ECPGfreeSQLDA(inp_sqlda);
+	ECPGfreeSQLDA(outp_sqlda);
 
 	/* SQLDA test for getting one record using an input descriptor
 	 * on a named connection
@@ -489,8 +491,8 @@ if (sqlca.sqlcode < 0) exit (1);}
 
 
 	free(inp_sqlda->sqlvar);
-	free(inp_sqlda);
-	free(outp_sqlda);
+	ECPGfreeSQLDA(inp_sqlda);
+	ECPGfreeSQLDA(outp_sqlda);
 
 	strcpy(msg, "disconnect");
 	{ ECPGdisconnect(__LINE__, "con2");
diff --git a/src/interfaces/ecpg/test/expected/sql-describe.c b/src/interfaces/ecpg/test/expected/sql-describe.c
index b79a6f4016..e364db8575 100644
--- a/src/interfaces/ecpg/test/expected/sql-describe.c
+++ b/src/interfaces/ecpg/test/expected/sql-describe.c
@@ -31,12 +31,14 @@
 typedef struct sqlvar_compat sqlvar_t;
 typedef struct sqlda_compat sqlda_t;
 
+#define ECPGfreeSQLDA(sqlda) ECPGfreeSQLDA_informix(sqlda)
 #else
 
 #include "sqlda-native.h"
 typedef struct sqlvar_struct sqlvar_t;
 typedef struct sqlda_struct sqlda_t;
 
+#define ECPGfreeSQLDA(sqlda) ECPGfreeSQLDA_native(sqlda)
 #endif
 
 #endif							/* ECPG_SQLDA_H */
@@ -295,9 +297,9 @@ if (sqlca.sqlcode < 0) exit (1);
 if (sqlca.sqlcode < 0) exit (1);
 #line 127 "describe.pgc"
 
-	free(sqlda1);
-	free(sqlda2);
-	free(sqlda3);
+	ECPGfreeSQLDA(sqlda1);
+	ECPGfreeSQLDA(sqlda2);
+	ECPGfreeSQLDA(sqlda3);
 
 	{ ECPGdeallocate(__LINE__, 0, NULL, "st_id1");
 #line 132 "describe.pgc"
@@ -424,9 +426,9 @@ if (sqlca.sqlcode < 0) exit (1);
 if (sqlca.sqlcode < 0) exit (1);
 #line 180 "describe.pgc"
 
-	free(sqlda1);
-	free(sqlda2);
-	free(sqlda3);
+	ECPGfreeSQLDA(sqlda1);
+	ECPGfreeSQLDA(sqlda2);
+	ECPGfreeSQLDA(sqlda3);
 
 	{ ECPGdeallocate(__LINE__, 0, NULL, "st_id2");
 #line 185 "describe.pgc"
diff --git a/src/interfaces/ecpg/test/expected/sql-sqlda.c b/src/interfaces/ecpg/test/expected/sql-sqlda.c
index 090aaf1a45..3613267de2 100644
--- a/src/interfaces/ecpg/test/expected/sql-sqlda.c
+++ b/src/interfaces/ecpg/test/expected/sql-sqlda.c
@@ -33,12 +33,14 @@
 typedef struct sqlvar_compat sqlvar_t;
 typedef struct sqlda_compat sqlda_t;
 
+#define ECPGfreeSQLDA(sqlda) ECPGfreeSQLDA_informix(sqlda)
 #else
 
 #include "sqlda-native.h"
 typedef struct sqlvar_struct sqlvar_t;
 typedef struct sqlda_struct sqlda_t;
 
+#define ECPGfreeSQLDA(sqlda) ECPGfreeSQLDA_native(sqlda)
 #endif
 
 #endif							/* ECPG_SQLDA_H */
@@ -312,7 +314,7 @@ if (sqlca.sqlcode < 0) exit (1);}
 #line 133 "sqlda.pgc"
 
 
-	free(outp_sqlda);
+	ECPGfreeSQLDA(outp_sqlda);
 
 	/* SQLDA test for getting ALL records into the sqlda list */
 
@@ -429,8 +431,8 @@ if (sqlca.sqlcode < 0) exit (1);}
 #line 200 "sqlda.pgc"
 
 
-	free(inp_sqlda);
-	free(outp_sqlda);
+	ECPGfreeSQLDA(inp_sqlda);
+	ECPGfreeSQLDA(outp_sqlda);
 
 	/* SQLDA test for getting one record using an input descriptor
 	 * on a named connection
@@ -498,8 +500,8 @@ if (sqlca.sqlcode < 0) exit (1);}
 #line 240 "sqlda.pgc"
 
 
-	free(inp_sqlda);
-	free(outp_sqlda);
+	ECPGfreeSQLDA(inp_sqlda);
+	ECPGfreeSQLDA(outp_sqlda);
 
 	strcpy(msg, "disconnect");
 	{ ECPGdisconnect(__LINE__, "con2");
diff --git a/src/interfaces/ecpg/test/sql/describe.pgc b/src/interfaces/ecpg/test/sql/describe.pgc
index 87d6bd9a29..130642cfa7 100644
--- a/src/interfaces/ecpg/test/sql/describe.pgc
+++ b/src/interfaces/ecpg/test/sql/describe.pgc
@@ -125,9 +125,9 @@ exec sql end declare section;
 	strcpy(msg, "deallocate");
 	exec sql deallocate descriptor desc1;
 	exec sql deallocate descriptor desc2;
-	free(sqlda1);
-	free(sqlda2);
-	free(sqlda3);
+	ECPGfreeSQLDA(sqlda1);
+	ECPGfreeSQLDA(sqlda2);
+	ECPGfreeSQLDA(sqlda3);
 
 	exec sql deallocate prepare st_id1;
 
@@ -178,9 +178,9 @@ exec sql end declare section;
 	strcpy(msg, "deallocate");
 	exec sql deallocate descriptor desc1;
 	exec sql deallocate descriptor desc2;
-	free(sqlda1);
-	free(sqlda2);
-	free(sqlda3);
+	ECPGfreeSQLDA(sqlda1);
+	ECPGfreeSQLDA(sqlda2);
+	ECPGfreeSQLDA(sqlda3);
 
 	exec sql deallocate prepare st_id2;
 
diff --git a/src/interfaces/ecpg/test/sql/sqlda.pgc b/src/interfaces/ecpg/test/sql/sqlda.pgc
index 2ea5121ac5..20ddd156a8 100644
--- a/src/interfaces/ecpg/test/sql/sqlda.pgc
+++ b/src/interfaces/ecpg/test/sql/sqlda.pgc
@@ -132,7 +132,7 @@ exec sql end declare section;
 	strcpy(msg, "deallocate");
 	exec sql deallocate prepare st_id1;
 
-	free(outp_sqlda);
+	ECPGfreeSQLDA(outp_sqlda);
 
 	/* SQLDA test for getting ALL records into the sqlda list */
 
@@ -199,8 +199,8 @@ exec sql end declare section;
 	strcpy(msg, "deallocate");
 	exec sql deallocate prepare st_id3;
 
-	free(inp_sqlda);
-	free(outp_sqlda);
+	ECPGfreeSQLDA(inp_sqlda);
+	ECPGfreeSQLDA(outp_sqlda);
 
 	/* SQLDA test for getting one record using an input descriptor
 	 * on a named connection
@@ -239,8 +239,8 @@ exec sql end declare section;
 	strcpy(msg, "deallocate");
 	exec sql deallocate prepare st_id4;
 
-	free(inp_sqlda);
-	free(outp_sqlda);
+	ECPGfreeSQLDA(inp_sqlda);
+	ECPGfreeSQLDA(outp_sqlda);
 
 	strcpy(msg, "disconnect");
 	exec sql disconnect con2;
