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;