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;
Fetch rows from the cursor, and store them into an output SQLDA.
Read values from the output SQLDA into the host variables (with conversion if necessary).
Close the cursor.
- Free the memory area allocated for the input SQLDA.
+ Free the memory area allocated for the input and output SQLDAs.
@@ -4208,6 +4208,18 @@ switch (v.sqltype)
...
}
+
+
+
+ Finally after using output SQLDA, the allocated memory area must be freed explicity.
+
+ECPGfreeSQLDA(sqlda1);
+
+
+
+ Alternatively, use the standard C library's free() function as in the example below.
+
+free(sqlda1);
@@ -4290,8 +4302,13 @@ EXEC SQL OPEN cur1 USING DESCRIPTOR sqlda2;
Finally, after using input SQLDAs, the allocated memory space
- must be freed explicitly, unlike SQLDAs used for receiving query
- results.
+ must be freed explicitly.
+
+ECPGfreeSQLDA(sqlda2);
+
+
+
+ Alternatively, use the standard C library's free() function as in the example below.
free(sqlda2);
@@ -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.
+
+
+ ECPGfreeSQLDA(sqlda_t *sqlda_ptr)
+ free allocated memory area of an SQLDA.
+ Alternatively, you can use the standard C library's free() function.
+
+
+
+ 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.
+
+
+
@@ -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->sqlvar is in one allocated area */
For more information, see the sqlda.h 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
+#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;