From a93ca469fa63d48e702a792f947d4ba9795e4b6e Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@enterprisedb.com>
Date: Mon, 11 Jun 2018 14:05:28 +1200
Subject: [PATCH] Add PGTYPESchar_free() to avoid cross-module problems on
 Windows.

On Windows, it is sometimes important for corresponding malloc() and free()
calls to be made from the same DLL, since some build options can result in
multiple allocators being active at the same time.  For that reason we already
provided PQfreemem().  This commit adds a similar function for freeing string
results allocated by the pgtypes library.

Author: Takayuki Tsunakawa
Reviewed-By: Kyotaro Horiguchi
Discussion: https://postgr.es/m/0A3221C70F24FB45833433255569204D1F8AD5D6%40G01JPEXMBYT05
---
 doc/src/sgml/ecpg.sgml                        | 19 ++++-
 src/interfaces/ecpg/include/Makefile          |  2 +-
 src/interfaces/ecpg/include/pgtypes.h         | 17 ++++
 src/interfaces/ecpg/include/pgtypes_date.h    |  1 +
 .../ecpg/include/pgtypes_interval.h           |  1 +
 src/interfaces/ecpg/include/pgtypes_numeric.h |  2 +
 .../ecpg/include/pgtypes_timestamp.h          |  1 +
 src/interfaces/ecpg/pgtypeslib/common.c       | 10 +++
 src/interfaces/ecpg/pgtypeslib/exports.txt    |  1 +
 .../ecpg/test/expected/pgtypeslib-dt_test.c   | 84 +++++++++----------
 .../ecpg/test/expected/pgtypeslib-dt_test2.c  | 12 +--
 .../ecpg/test/expected/pgtypeslib-num_test.c  | 10 +--
 .../ecpg/test/expected/pgtypeslib-num_test2.c | 26 +++---
 .../ecpg/test/expected/preproc-outofscope.c   |  2 +
 src/interfaces/ecpg/test/expected/sql-sqlda.c |  4 +-
 .../ecpg/test/pgtypeslib/dt_test.pgc          | 84 +++++++++----------
 .../ecpg/test/pgtypeslib/dt_test2.pgc         | 12 +--
 .../ecpg/test/pgtypeslib/num_test.pgc         | 10 +--
 .../ecpg/test/pgtypeslib/num_test2.pgc        | 26 +++---
 src/interfaces/ecpg/test/sql/sqlda.pgc        |  2 +-
 20 files changed, 190 insertions(+), 136 deletions(-)
 create mode 100644 src/interfaces/ecpg/include/pgtypes.h

diff --git a/doc/src/sgml/ecpg.sgml b/doc/src/sgml/ecpg.sgml
index f23a83dbc35..ab21577ebfb 100644
--- a/doc/src/sgml/ecpg.sgml
+++ b/doc/src/sgml/ecpg.sgml
@@ -1951,11 +1951,24 @@ EXEC SQL SELECT started, duration INTO :ts1, :iv1 FROM datetbl WHERE d=:date1;
 PGTYPEStimestamp_add_interval(&ts1, &iv1, &tsout);
 out = PGTYPEStimestamp_to_asc(&tsout);
 printf("Started + duration: %s\n", out);
-free(out);
+PGTYPESchar_free(out);
 ]]>
 </programlisting>
   </para>
 
+  <sect2 id="ecpg-pgtypes-cstrings">
+   <title>Character Strings</title>
+   <para>
+   Some functions such as <function>PGTYPESnumeric_to_asc</function> return
+   a pointer to a freshly allocated character string. These results should be
+   freed with <function>PGTYPESchar_free</function> instead of
+   <function>free</function>. (This is a change from earlier releases of
+   <productname>PostgreSQL</productname> and is necessary on Windows, where
+   memory allocation and release sometimes need to be done by the same
+   library.)
+   </para>
+  </sect2>
+
   <sect2 id="ecpg-pgtypes-numeric">
    <title>The numeric Type</title>
    <para>
@@ -2029,6 +2042,7 @@ char *PGTYPESnumeric_to_asc(numeric *num, int dscale);
 </synopsis>
        The numeric value will be printed with <literal>dscale</literal> decimal
        digits, with rounding applied if necessary.
+       The result must be freed with <function>PGTYPESchar_free()</function>.
       </para>
      </listitem>
     </varlistentry>
@@ -2419,6 +2433,7 @@ char *PGTYPESdate_to_asc(date dDate);
         The function receives the date <literal>dDate</literal> as its only parameter.
         It will output the date in the form <literal>1999-01-18</literal>, i.e., in the
         <literal>YYYY-MM-DD</literal> format.
+        The result must be freed with <function>PGTYPESchar_free()</function>.
        </para>
       </listitem>
      </varlistentry>
@@ -2841,6 +2856,7 @@ char *PGTYPEStimestamp_to_asc(timestamp tstamp);
         The function receives the timestamp <literal>tstamp</literal> as
         its only argument and returns an allocated string that contains the
         textual representation of the timestamp.
+        The result must be freed with <function>PGTYPESchar_free()</function>.
        </para>
       </listitem>
      </varlistentry>
@@ -3349,6 +3365,7 @@ char *PGTYPESinterval_to_asc(interval *span);
         The function converts the interval variable that <literal>span</literal>
         points to into a C char*. The output looks like this example:
         <literal>@ 1 day 12 hours 59 mins 10 secs</literal>.
+        The result must be freed with <function>PGTYPESchar_free()</function>.
        </para>
       </listitem>
      </varlistentry>
diff --git a/src/interfaces/ecpg/include/Makefile b/src/interfaces/ecpg/include/Makefile
index e92e56f26f3..9c68bf3c477 100644
--- a/src/interfaces/ecpg/include/Makefile
+++ b/src/interfaces/ecpg/include/Makefile
@@ -14,7 +14,7 @@ install: all installdirs install-headers
 
 .PHONY: install-headers
 ecpg_headers = ecpgerrno.h ecpglib.h ecpgtype.h sqlca.h sql3types.h ecpg_informix.h \
-	pgtypes_error.h pgtypes_numeric.h pgtypes_timestamp.h pgtypes_date.h pgtypes_interval.h \
+	pgtypes_error.h pgtypes_numeric.h pgtypes_timestamp.h pgtypes_date.h pgtypes_interval.h pgtypes.h \
 	sqlda.h sqlda-compat.h sqlda-native.h
 informix_headers = datetime.h decimal.h sqltypes.h
 
diff --git a/src/interfaces/ecpg/include/pgtypes.h b/src/interfaces/ecpg/include/pgtypes.h
new file mode 100644
index 00000000000..dbf759b45f5
--- /dev/null
+++ b/src/interfaces/ecpg/include/pgtypes.h
@@ -0,0 +1,17 @@
+/* src/interfaces/ecpg/include/pgtypes.h */
+
+#ifndef PGTYPES_H
+#define PGTYPES_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+extern void PGTYPESchar_free(char *ptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif							/* PGTYPES_H */
diff --git a/src/interfaces/ecpg/include/pgtypes_date.h b/src/interfaces/ecpg/include/pgtypes_date.h
index caf8a33d125..c668097466e 100644
--- a/src/interfaces/ecpg/include/pgtypes_date.h
+++ b/src/interfaces/ecpg/include/pgtypes_date.h
@@ -3,6 +3,7 @@
 #ifndef PGTYPES_DATETIME
 #define PGTYPES_DATETIME
 
+#include <pgtypes.h>
 #include <pgtypes_timestamp.h>
 
 typedef long date;
diff --git a/src/interfaces/ecpg/include/pgtypes_interval.h b/src/interfaces/ecpg/include/pgtypes_interval.h
index 5747736fe16..3b17cd1d115 100644
--- a/src/interfaces/ecpg/include/pgtypes_interval.h
+++ b/src/interfaces/ecpg/include/pgtypes_interval.h
@@ -4,6 +4,7 @@
 #define PGTYPES_INTERVAL
 
 #include <ecpg_config.h>
+#include <pgtypes.h>
 
 #ifndef C_H
 
diff --git a/src/interfaces/ecpg/include/pgtypes_numeric.h b/src/interfaces/ecpg/include/pgtypes_numeric.h
index 56c46ea2729..5c763a9eb61 100644
--- a/src/interfaces/ecpg/include/pgtypes_numeric.h
+++ b/src/interfaces/ecpg/include/pgtypes_numeric.h
@@ -1,6 +1,8 @@
 #ifndef PGTYPES_NUMERIC
 #define PGTYPES_NUMERIC
 
+#include <pgtypes.h>
+
 #define NUMERIC_POS						0x0000
 #define NUMERIC_NEG						0x4000
 #define NUMERIC_NAN						0xC000
diff --git a/src/interfaces/ecpg/include/pgtypes_timestamp.h b/src/interfaces/ecpg/include/pgtypes_timestamp.h
index 1545be4ee9b..3e298378912 100644
--- a/src/interfaces/ecpg/include/pgtypes_timestamp.h
+++ b/src/interfaces/ecpg/include/pgtypes_timestamp.h
@@ -3,6 +3,7 @@
 #ifndef PGTYPES_TIMESTAMP
 #define PGTYPES_TIMESTAMP
 
+#include <pgtypes.h>
 /* pgtypes_interval.h includes ecpg_config.h */
 #include <pgtypes_interval.h>
 
diff --git a/src/interfaces/ecpg/pgtypeslib/common.c b/src/interfaces/ecpg/pgtypeslib/common.c
index ae29b6c4ab8..c373039f4a9 100644
--- a/src/interfaces/ecpg/pgtypeslib/common.c
+++ b/src/interfaces/ecpg/pgtypeslib/common.c
@@ -3,6 +3,7 @@
 #include "postgres_fe.h"
 
 #include "extern.h"
+#include "pgtypes.h"
 
 /* Return value is zero-filled. */
 char *
@@ -138,3 +139,12 @@ pgtypes_fmt_replace(union un_fmt_comb replace_val, int replace_type, char **outp
 	}
 	return 0;
 }
+
+/* Functions declared in pgtypes.h. */
+
+/* Just frees memory (mostly needed for Windows) */
+void
+PGTYPESchar_free(char *ptr)
+{
+	free(ptr);
+}
diff --git a/src/interfaces/ecpg/pgtypeslib/exports.txt b/src/interfaces/ecpg/pgtypeslib/exports.txt
index 70ef01a8a7d..2d5ec17656a 100644
--- a/src/interfaces/ecpg/pgtypeslib/exports.txt
+++ b/src/interfaces/ecpg/pgtypeslib/exports.txt
@@ -45,3 +45,4 @@ PGTYPEStimestamp_from_asc       42
 PGTYPEStimestamp_sub            43
 PGTYPEStimestamp_sub_interval   44
 PGTYPEStimestamp_to_asc         45
+PGTYPESchar_free                46
diff --git a/src/interfaces/ecpg/test/expected/pgtypeslib-dt_test.c b/src/interfaces/ecpg/test/expected/pgtypeslib-dt_test.c
index 3f90022b544..1509a56fd85 100644
--- a/src/interfaces/ecpg/test/expected/pgtypeslib-dt_test.c
+++ b/src/interfaces/ecpg/test/expected/pgtypeslib-dt_test.c
@@ -113,18 +113,18 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 
 	text = PGTYPESdate_to_asc(date1);
 	printf ("Date: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf ("timestamp: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	iv1 = PGTYPESinterval_from_asc("13556 days 12 hours 34 minutes 14 seconds ", NULL);
 	PGTYPESinterval_copy(iv1, &iv2);
 	text = PGTYPESinterval_to_asc(&iv2);
 	printf ("interval: %s\n", text);
 	PGTYPESinterval_free(iv1);
-	free(text);
+	PGTYPESchar_free(text);
 
 	PGTYPESdate_mdyjul(mdy, &date2);
 	printf("m: %d, d: %d, y: %d\n", mdy[0], mdy[1], mdy[2]);
@@ -144,7 +144,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 	PGTYPESdate_fmt_asc(date1, fmt, out);
 	printf("date_day of %s is %d\n", text, PGTYPESdate_dayofweek(date1));
 	printf("Above date in format \"%s\" is \"%s\"\n", fmt, out);
-	free(text);
+	PGTYPESchar_free(text);
 	free(out);
 
 	out = (char*) malloc(48);
@@ -164,7 +164,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 	PGTYPESdate_defmt_asc(&date1, fmt, in);
 	text = PGTYPESdate_to_asc(date1);
 	printf("date_defmt_asc1: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	date1 = 0;
 	fmt = "mmmm. dd. yyyy";
@@ -172,7 +172,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 	PGTYPESdate_defmt_asc(&date1, fmt, in);
 	text = PGTYPESdate_to_asc(date1);
 	printf("date_defmt_asc2: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	date1 = 0;
 	fmt = "yy/mm/dd";
@@ -180,7 +180,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 	PGTYPESdate_defmt_asc(&date1, fmt, in);
 	text = PGTYPESdate_to_asc(date1);
 	printf("date_defmt_asc3: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	date1 = 0;
 	fmt = "yy/mm/dd";
@@ -188,7 +188,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 	PGTYPESdate_defmt_asc(&date1, fmt, in);
 	text = PGTYPESdate_to_asc(date1);
 	printf("date_defmt_asc4: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	date1 = 0;
 	fmt = "dd-mm-yy";
@@ -196,7 +196,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 	PGTYPESdate_defmt_asc(&date1, fmt, in);
 	text = PGTYPESdate_to_asc(date1);
 	printf("date_defmt_asc5: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	date1 = 0;
 	fmt = "mmddyy";
@@ -204,7 +204,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 	PGTYPESdate_defmt_asc(&date1, fmt, in);
 	text = PGTYPESdate_to_asc(date1);
 	printf("date_defmt_asc6: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	date1 = 0;
 	fmt = "mmm. dd. yyyy";
@@ -212,7 +212,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 	PGTYPESdate_defmt_asc(&date1, fmt, in);
 	text = PGTYPESdate_to_asc(date1);
 	printf("date_defmt_asc7: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	date1 = 0;
 	fmt = "mmm. dd. yyyy";
@@ -220,7 +220,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 	PGTYPESdate_defmt_asc(&date1, fmt, in);
 	text = PGTYPESdate_to_asc(date1);
 	printf("date_defmt_asc8: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	date1 = 0;
 	fmt = "mm yy   dd.";
@@ -228,7 +228,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 	PGTYPESdate_defmt_asc(&date1, fmt, in);
 	text = PGTYPESdate_to_asc(date1);
 	printf("date_defmt_asc9: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	date1 = 0;
 	fmt = "yyyy fierj mm   dd.";
@@ -236,7 +236,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 	PGTYPESdate_defmt_asc(&date1, fmt, in);
 	text = PGTYPESdate_to_asc(date1);
 	printf("date_defmt_asc10: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	date1 = 0;
 	fmt = "mm/dd/yy";
@@ -244,28 +244,28 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 	PGTYPESdate_defmt_asc(&date1, fmt, in);
 	text = PGTYPESdate_to_asc(date1);
 	printf("date_defmt_asc12: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	PGTYPEStimestamp_current(&ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	/* can't output this in regression mode */
 	/* printf("timestamp_current: Now: %s\n", text); */
-	free(text);
+	PGTYPESchar_free(text);
 
 	ts1 = PGTYPEStimestamp_from_asc("96-02-29", NULL);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_to_asc1: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	ts1 = PGTYPEStimestamp_from_asc("1994-02-11 3:10:35", NULL);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_to_asc2: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	ts1 = PGTYPEStimestamp_from_asc("1994-02-11 26:10:35", NULL);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_to_asc3: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 /*	abc-03:10:35-def-02/11/94-gh  */
 /*      12345678901234567890123456789 */
@@ -280,161 +280,161 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "%a %b %d %H:%M:%S %z %Y";
 	in =  "Tue Jul 22 17:28:44 +0200 2003";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "%a %b %d %H:%M:%S %z %Y";
 	in =  "Tue Feb 29 17:28:44 +0200 2000";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "%a %b %d %H:%M:%S %z %Y";
 	in =  "Tue Feb 29 17:28:44 +0200 1900";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error (should be error!): %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "%a %b %d %H:%M:%S %z %Y";
 	in =  "Tue Feb 29 17:28:44 +0200 1996";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "%b %d %H:%M:%S %z %Y";
 	in =  "      Jul 31 17:28:44 +0200 1996";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "%b %d %H:%M:%S %z %Y";
 	in =  "      Jul 32 17:28:44 +0200 1996";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error (should be error!): %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "%a %b %d %H:%M:%S %z %Y";
 	in =  "Tue Feb 29 17:28:44 +0200 1997";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error (should be error!): %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "%";
 	in =  "Tue Jul 22 17:28:44 +0200 2003";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error (should be error!): %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "a %";
 	in =  "Tue Jul 22 17:28:44 +0200 2003";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error (should be error!): %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "%b, %d %H_%M`%S %z %Y";
 	in =  "    Jul, 22 17_28 `44 +0200  2003  ";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "%a %b %%%d %H:%M:%S %Z %Y";
 	in =  "Tue Jul %22 17:28:44 CEST 2003";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "%a %b %%%d %H:%M:%S %Z %Y";
 	in =  "Tue Jul %22 17:28:44 CEST 2003";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "abc%n %C %B %%%d %H:%M:%S %Z %Y";
 	in =  "abc\n   19 October %22 17:28:44 CEST 2003";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "abc%n %C %B %%%d %H:%M:%S %Z %y";
 	in =  "abc\n   18 October %34 17:28:44 CEST 80";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error (should be error!): %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "";
 	in =  "abc\n   18 October %34 17:28:44 CEST 80";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error (should be error!): %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = NULL;
 	in =  "1980-04-12 3:49:44      ";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, NULL) = %s, error: %d\n", in, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "%B %d, %Y. Time: %I:%M%p";
 	in =  "July 14, 1988. Time: 9:15am";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	in = "September 6 at 01:30 pm in the year 1983";
 	fmt = "%B %d at %I:%M %p in the year %Y";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	in = "  1976, July 14. Time: 9:15am";
 	fmt = "%Y,   %B %d. Time: %I:%M %p";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	in = "  1976, July 14. Time: 9:15 am";
 	fmt = "%Y,   %B %d. Time: %I:%M%p";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	in = "  1976, P.M. July 14. Time: 9:15";
 	fmt = "%Y, %P  %B %d. Time: %I:%M";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	in = "1234567890";
 	fmt = "%s";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	{ ECPGtrans(__LINE__, NULL, "rollback");
 #line 365 "dt_test.pgc"
diff --git a/src/interfaces/ecpg/test/expected/pgtypeslib-dt_test2.c b/src/interfaces/ecpg/test/expected/pgtypeslib-dt_test2.c
index 4024980f1ed..b3e1e7519df 100644
--- a/src/interfaces/ecpg/test/expected/pgtypeslib-dt_test2.c
+++ b/src/interfaces/ecpg/test/expected/pgtypeslib-dt_test2.c
@@ -110,14 +110,14 @@ main(void)
 	text = PGTYPEStimestamp_to_asc(ts1);
 
 	printf("timestamp: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	date1 = PGTYPESdate_from_timestamp(ts1);
 	dc = PGTYPESdate_new();
 	*dc = date1;
 	text = PGTYPESdate_to_asc(*dc);
 	printf("Date of timestamp: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 	PGTYPESdate_free(dc);
 
 	for (i = 0; dates[i]; i++)
@@ -132,7 +132,7 @@ main(void)
 					i, err ? "-" : text,
 					endptr ? 'N' : 'Y',
 					err ? 'T' : 'F');
-		free(text);
+		PGTYPESchar_free(text);
 		if (!err)
 		{
 			for (j = 0; times[j]; j++)
@@ -147,7 +147,7 @@ main(void)
 				text = PGTYPEStimestamp_to_asc(ts1);
 				printf("TS[%d,%d]: %s\n",
 				       i, j, errno ? "-" : text);
-				free(text);
+				PGTYPESchar_free(text);
 				free(t);
 			}
 		}
@@ -171,13 +171,13 @@ main(void)
 			continue;
 		text = PGTYPESinterval_to_asc(i1);
 		printf("interval[%d]: %s\n", i, text ? text : "-");
-		free(text);
+		PGTYPESchar_free(text);
 
 		ic = PGTYPESinterval_new();
 		PGTYPESinterval_copy(i1, ic);
 		text = PGTYPESinterval_to_asc(i1);
 		printf("interval_copy[%d]: %s\n", i, text ? text : "-");
-		free(text);
+		PGTYPESchar_free(text);
 		PGTYPESinterval_free(ic);
 		PGTYPESinterval_free(i1);
 	}
diff --git a/src/interfaces/ecpg/test/expected/pgtypeslib-num_test.c b/src/interfaces/ecpg/test/expected/pgtypeslib-num_test.c
index 47c320291f2..1b1239eacad 100644
--- a/src/interfaces/ecpg/test/expected/pgtypeslib-num_test.c
+++ b/src/interfaces/ecpg/test/expected/pgtypeslib-num_test.c
@@ -78,7 +78,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 	PGTYPESnumeric_from_int(1407, value1);
 	text = PGTYPESnumeric_to_asc(value1, -1);
 	printf("from int = %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 	PGTYPESnumeric_free(value1);
 
 	value1 = PGTYPESnumeric_from_asc("2369.7", NULL);
@@ -87,12 +87,12 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 	PGTYPESnumeric_add(value1, value2, res);
 	text = PGTYPESnumeric_to_asc(res, -1);
 	printf("add = %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	PGTYPESnumeric_sub(res, value2, res);
 	text = PGTYPESnumeric_to_asc(res, -1);
 	printf("sub = %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 	PGTYPESnumeric_free(value2);
 
 	des = PGTYPESnumeric_new();
@@ -122,7 +122,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 	PGTYPESnumeric_mul(res, des, res);
 	text = PGTYPESnumeric_to_asc(res, -1);
 	printf("mul = %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 	PGTYPESnumeric_free(des);
 
 	value2 = PGTYPESnumeric_from_asc("10000", NULL);
@@ -139,7 +139,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
 	i = PGTYPESnumeric_to_long(value1, &l1) | PGTYPESnumeric_to_long(value2, &l2);
 	printf("to long(%d) = %ld %ld\n", i, l1, l2);
 
-	free(text);
+	PGTYPESchar_free(text);
 	PGTYPESnumeric_free(value1);
 	PGTYPESnumeric_free(value2);
 	PGTYPESnumeric_free(res);
diff --git a/src/interfaces/ecpg/test/expected/pgtypeslib-num_test2.c b/src/interfaces/ecpg/test/expected/pgtypeslib-num_test2.c
index d31834e2c03..aaab4ad7d70 100644
--- a/src/interfaces/ecpg/test/expected/pgtypeslib-num_test2.c
+++ b/src/interfaces/ecpg/test/expected/pgtypeslib-num_test2.c
@@ -77,21 +77,21 @@ main(void)
 
 		text = PGTYPESnumeric_to_asc(num, -1);
 		if (!text) check_errno();
-		printf("num[%d,1]: %s\n", i, text); free(text);
+		printf("num[%d,1]: %s\n", i, text); PGTYPESchar_free(text);
 		text = PGTYPESnumeric_to_asc(num, 0);
 		if (!text) check_errno();
-		printf("num[%d,2]: %s\n", i, text); free(text);
+		printf("num[%d,2]: %s\n", i, text); PGTYPESchar_free(text);
 		text = PGTYPESnumeric_to_asc(num, 1);
 		if (!text) check_errno();
-		printf("num[%d,3]: %s\n", i, text); free(text);
+		printf("num[%d,3]: %s\n", i, text); PGTYPESchar_free(text);
 		text = PGTYPESnumeric_to_asc(num, 2);
 		if (!text) check_errno();
-		printf("num[%d,4]: %s\n", i, text); free(text);
+		printf("num[%d,4]: %s\n", i, text); PGTYPESchar_free(text);
 
 		nin = PGTYPESnumeric_new();
 		text = PGTYPESnumeric_to_asc(nin, 2);
 		if (!text) check_errno();
-		printf("num[%d,5]: %s\n", i, text); free(text);
+		printf("num[%d,5]: %s\n", i, text); PGTYPESchar_free(text);
 
 		r = PGTYPESnumeric_to_long(num, &l);
 		if (r) check_errno();
@@ -103,7 +103,7 @@ main(void)
 			text = PGTYPESnumeric_to_asc(nin, 2);
 			q = PGTYPESnumeric_cmp(num, nin);
 			printf("num[%d,7]: %s (r: %d - cmp: %d)\n", i, text, r, q);
-			free(text);
+			PGTYPESchar_free(text);
 		}
 
 		r = PGTYPESnumeric_to_int(num, &k);
@@ -116,7 +116,7 @@ main(void)
 			text = PGTYPESnumeric_to_asc(nin, 2);
 			q = PGTYPESnumeric_cmp(num, nin);
 			printf("num[%d,9]: %s (r: %d - cmp: %d)\n", i, text, r, q);
-			free(text);
+			PGTYPESchar_free(text);
 		}
 
 		if (i != 6)
@@ -147,7 +147,7 @@ main(void)
 			text = PGTYPESnumeric_to_asc(nin, 2);
 			q = PGTYPESnumeric_cmp(num, nin);
 			printf("num[%d,12]: %s (r: %d - cmp: %d)\n", i, text, r, q);
-			free(text);
+			PGTYPESchar_free(text);
 		}
 
 		PGTYPESdecimal_free(dec);
@@ -173,7 +173,7 @@ main(void)
 			{
 				text = PGTYPESnumeric_to_asc(a, 10);
 				printf("num[a,%d,%d]: %s\n", i, j, text);
-				free(text);
+				PGTYPESchar_free(text);
 			}
 			r = PGTYPESnumeric_sub(numarr[i], numarr[j], s);
 			if (r)
@@ -185,7 +185,7 @@ main(void)
 			{
 				text = PGTYPESnumeric_to_asc(s, 10);
 				printf("num[s,%d,%d]: %s\n", i, j, text);
-				free(text);
+				PGTYPESchar_free(text);
 			}
 			r = PGTYPESnumeric_mul(numarr[i], numarr[j], m);
 			if (r)
@@ -197,7 +197,7 @@ main(void)
 			{
 				text = PGTYPESnumeric_to_asc(m, 10);
 				printf("num[m,%d,%d]: %s\n", i, j, text);
-				free(text);
+				PGTYPESchar_free(text);
 			}
 			r = PGTYPESnumeric_div(numarr[i], numarr[j], d);
 			if (r)
@@ -209,7 +209,7 @@ main(void)
 			{
 				text = PGTYPESnumeric_to_asc(d, 10);
 				printf("num[d,%d,%d]: %s\n", i, j, text);
-				free(text);
+				PGTYPESchar_free(text);
 			}
 
 			PGTYPESnumeric_free(a);
@@ -223,7 +223,7 @@ main(void)
 	{
 		text = PGTYPESnumeric_to_asc(numarr[i], -1);
 		printf("%d: %s\n", i, text);
-		free(text);
+		PGTYPESchar_free(text);
 		PGTYPESnumeric_free(numarr[i]);
 	}
 	free(numarr);
diff --git a/src/interfaces/ecpg/test/expected/preproc-outofscope.c b/src/interfaces/ecpg/test/expected/preproc-outofscope.c
index ef4dadaf9d2..b23107714c9 100644
--- a/src/interfaces/ecpg/test/expected/preproc-outofscope.c
+++ b/src/interfaces/ecpg/test/expected/preproc-outofscope.c
@@ -28,6 +28,8 @@
 #ifndef PGTYPES_NUMERIC
 #define PGTYPES_NUMERIC
 
+#include <pgtypes.h>
+
 #define NUMERIC_POS						0x0000
 #define NUMERIC_NEG						0x4000
 #define NUMERIC_NAN						0xC000
diff --git a/src/interfaces/ecpg/test/expected/sql-sqlda.c b/src/interfaces/ecpg/test/expected/sql-sqlda.c
index 090aaf1a45d..398dcedccf5 100644
--- a/src/interfaces/ecpg/test/expected/sql-sqlda.c
+++ b/src/interfaces/ecpg/test/expected/sql-sqlda.c
@@ -50,6 +50,8 @@ typedef struct sqlda_struct sqlda_t;
 #ifndef PGTYPES_NUMERIC
 #define PGTYPES_NUMERIC
 
+#include <pgtypes.h>
+
 #define NUMERIC_POS						0x0000
 #define NUMERIC_NEG						0x4000
 #define NUMERIC_NAN						0xC000
@@ -166,7 +168,7 @@ dump_sqlda(sqlda_t *sqlda)
 
 				val = PGTYPESnumeric_to_asc((numeric*)sqlda->sqlvar[i].sqldata, -1);
 				printf("name sqlda descriptor: '%s' value NUMERIC '%s'\n", sqlda->sqlvar[i].sqlname.data, val);
-				free(val);
+				PGTYPESchar_free(val);
 				break;
 			}
 		}
diff --git a/src/interfaces/ecpg/test/pgtypeslib/dt_test.pgc b/src/interfaces/ecpg/test/pgtypeslib/dt_test.pgc
index 1cc156c3dcd..95632fffeef 100644
--- a/src/interfaces/ecpg/test/pgtypeslib/dt_test.pgc
+++ b/src/interfaces/ecpg/test/pgtypeslib/dt_test.pgc
@@ -39,18 +39,18 @@ main(void)
 
 	text = PGTYPESdate_to_asc(date1);
 	printf ("Date: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf ("timestamp: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	iv1 = PGTYPESinterval_from_asc("13556 days 12 hours 34 minutes 14 seconds ", NULL);
 	PGTYPESinterval_copy(iv1, &iv2);
 	text = PGTYPESinterval_to_asc(&iv2);
 	printf ("interval: %s\n", text);
 	PGTYPESinterval_free(iv1);
-	free(text);
+	PGTYPESchar_free(text);
 
 	PGTYPESdate_mdyjul(mdy, &date2);
 	printf("m: %d, d: %d, y: %d\n", mdy[0], mdy[1], mdy[2]);
@@ -70,7 +70,7 @@ main(void)
 	PGTYPESdate_fmt_asc(date1, fmt, out);
 	printf("date_day of %s is %d\n", text, PGTYPESdate_dayofweek(date1));
 	printf("Above date in format \"%s\" is \"%s\"\n", fmt, out);
-	free(text);
+	PGTYPESchar_free(text);
 	free(out);
 
 	out = (char*) malloc(48);
@@ -90,7 +90,7 @@ main(void)
 	PGTYPESdate_defmt_asc(&date1, fmt, in);
 	text = PGTYPESdate_to_asc(date1);
 	printf("date_defmt_asc1: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	date1 = 0;
 	fmt = "mmmm. dd. yyyy";
@@ -98,7 +98,7 @@ main(void)
 	PGTYPESdate_defmt_asc(&date1, fmt, in);
 	text = PGTYPESdate_to_asc(date1);
 	printf("date_defmt_asc2: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	date1 = 0;
 	fmt = "yy/mm/dd";
@@ -106,7 +106,7 @@ main(void)
 	PGTYPESdate_defmt_asc(&date1, fmt, in);
 	text = PGTYPESdate_to_asc(date1);
 	printf("date_defmt_asc3: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	date1 = 0;
 	fmt = "yy/mm/dd";
@@ -114,7 +114,7 @@ main(void)
 	PGTYPESdate_defmt_asc(&date1, fmt, in);
 	text = PGTYPESdate_to_asc(date1);
 	printf("date_defmt_asc4: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	date1 = 0;
 	fmt = "dd-mm-yy";
@@ -122,7 +122,7 @@ main(void)
 	PGTYPESdate_defmt_asc(&date1, fmt, in);
 	text = PGTYPESdate_to_asc(date1);
 	printf("date_defmt_asc5: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	date1 = 0;
 	fmt = "mmddyy";
@@ -130,7 +130,7 @@ main(void)
 	PGTYPESdate_defmt_asc(&date1, fmt, in);
 	text = PGTYPESdate_to_asc(date1);
 	printf("date_defmt_asc6: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	date1 = 0;
 	fmt = "mmm. dd. yyyy";
@@ -138,7 +138,7 @@ main(void)
 	PGTYPESdate_defmt_asc(&date1, fmt, in);
 	text = PGTYPESdate_to_asc(date1);
 	printf("date_defmt_asc7: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	date1 = 0;
 	fmt = "mmm. dd. yyyy";
@@ -146,7 +146,7 @@ main(void)
 	PGTYPESdate_defmt_asc(&date1, fmt, in);
 	text = PGTYPESdate_to_asc(date1);
 	printf("date_defmt_asc8: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	date1 = 0;
 	fmt = "mm yy   dd.";
@@ -154,7 +154,7 @@ main(void)
 	PGTYPESdate_defmt_asc(&date1, fmt, in);
 	text = PGTYPESdate_to_asc(date1);
 	printf("date_defmt_asc9: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	date1 = 0;
 	fmt = "yyyy fierj mm   dd.";
@@ -162,7 +162,7 @@ main(void)
 	PGTYPESdate_defmt_asc(&date1, fmt, in);
 	text = PGTYPESdate_to_asc(date1);
 	printf("date_defmt_asc10: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	date1 = 0;
 	fmt = "mm/dd/yy";
@@ -170,28 +170,28 @@ main(void)
 	PGTYPESdate_defmt_asc(&date1, fmt, in);
 	text = PGTYPESdate_to_asc(date1);
 	printf("date_defmt_asc12: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	PGTYPEStimestamp_current(&ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	/* can't output this in regression mode */
 	/* printf("timestamp_current: Now: %s\n", text); */
-	free(text);
+	PGTYPESchar_free(text);
 
 	ts1 = PGTYPEStimestamp_from_asc("96-02-29", NULL);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_to_asc1: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	ts1 = PGTYPEStimestamp_from_asc("1994-02-11 3:10:35", NULL);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_to_asc2: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	ts1 = PGTYPEStimestamp_from_asc("1994-02-11 26:10:35", NULL);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_to_asc3: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 /*	abc-03:10:35-def-02/11/94-gh  */
 /*      12345678901234567890123456789 */
@@ -206,161 +206,161 @@ main(void)
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "%a %b %d %H:%M:%S %z %Y";
 	in =  "Tue Jul 22 17:28:44 +0200 2003";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "%a %b %d %H:%M:%S %z %Y";
 	in =  "Tue Feb 29 17:28:44 +0200 2000";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "%a %b %d %H:%M:%S %z %Y";
 	in =  "Tue Feb 29 17:28:44 +0200 1900";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error (should be error!): %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "%a %b %d %H:%M:%S %z %Y";
 	in =  "Tue Feb 29 17:28:44 +0200 1996";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "%b %d %H:%M:%S %z %Y";
 	in =  "      Jul 31 17:28:44 +0200 1996";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "%b %d %H:%M:%S %z %Y";
 	in =  "      Jul 32 17:28:44 +0200 1996";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error (should be error!): %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "%a %b %d %H:%M:%S %z %Y";
 	in =  "Tue Feb 29 17:28:44 +0200 1997";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error (should be error!): %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "%";
 	in =  "Tue Jul 22 17:28:44 +0200 2003";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error (should be error!): %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "a %";
 	in =  "Tue Jul 22 17:28:44 +0200 2003";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error (should be error!): %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "%b, %d %H_%M`%S %z %Y";
 	in =  "    Jul, 22 17_28 `44 +0200  2003  ";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "%a %b %%%d %H:%M:%S %Z %Y";
 	in =  "Tue Jul %22 17:28:44 CEST 2003";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "%a %b %%%d %H:%M:%S %Z %Y";
 	in =  "Tue Jul %22 17:28:44 CEST 2003";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "abc%n %C %B %%%d %H:%M:%S %Z %Y";
 	in =  "abc\n   19 October %22 17:28:44 CEST 2003";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "abc%n %C %B %%%d %H:%M:%S %Z %y";
 	in =  "abc\n   18 October %34 17:28:44 CEST 80";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error (should be error!): %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "";
 	in =  "abc\n   18 October %34 17:28:44 CEST 80";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error (should be error!): %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = NULL;
 	in =  "1980-04-12 3:49:44      ";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, NULL) = %s, error: %d\n", in, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	fmt = "%B %d, %Y. Time: %I:%M%p";
 	in =  "July 14, 1988. Time: 9:15am";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	in = "September 6 at 01:30 pm in the year 1983";
 	fmt = "%B %d at %I:%M %p in the year %Y";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	in = "  1976, July 14. Time: 9:15am";
 	fmt = "%Y,   %B %d. Time: %I:%M %p";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	in = "  1976, July 14. Time: 9:15 am";
 	fmt = "%Y,   %B %d. Time: %I:%M%p";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	in = "  1976, P.M. July 14. Time: 9:15";
 	fmt = "%Y, %P  %B %d. Time: %I:%M";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	in = "1234567890";
 	fmt = "%s";
 	i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
 	text = PGTYPEStimestamp_to_asc(ts1);
 	printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
-	free(text);
+	PGTYPESchar_free(text);
 
 	exec sql rollback;
         exec sql disconnect;
diff --git a/src/interfaces/ecpg/test/pgtypeslib/dt_test2.pgc b/src/interfaces/ecpg/test/pgtypeslib/dt_test2.pgc
index 9e1f432823f..62b934b07ee 100644
--- a/src/interfaces/ecpg/test/pgtypeslib/dt_test2.pgc
+++ b/src/interfaces/ecpg/test/pgtypeslib/dt_test2.pgc
@@ -75,14 +75,14 @@ main(void)
 	text = PGTYPEStimestamp_to_asc(ts1);
 
 	printf("timestamp: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	date1 = PGTYPESdate_from_timestamp(ts1);
 	dc = PGTYPESdate_new();
 	*dc = date1;
 	text = PGTYPESdate_to_asc(*dc);
 	printf("Date of timestamp: %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 	PGTYPESdate_free(dc);
 
 	for (i = 0; dates[i]; i++)
@@ -97,7 +97,7 @@ main(void)
 					i, err ? "-" : text,
 					endptr ? 'N' : 'Y',
 					err ? 'T' : 'F');
-		free(text);
+		PGTYPESchar_free(text);
 		if (!err)
 		{
 			for (j = 0; times[j]; j++)
@@ -112,7 +112,7 @@ main(void)
 				text = PGTYPEStimestamp_to_asc(ts1);
 				printf("TS[%d,%d]: %s\n",
 				       i, j, errno ? "-" : text);
-				free(text);
+				PGTYPESchar_free(text);
 				free(t);
 			}
 		}
@@ -136,13 +136,13 @@ main(void)
 			continue;
 		text = PGTYPESinterval_to_asc(i1);
 		printf("interval[%d]: %s\n", i, text ? text : "-");
-		free(text);
+		PGTYPESchar_free(text);
 
 		ic = PGTYPESinterval_new();
 		PGTYPESinterval_copy(i1, ic);
 		text = PGTYPESinterval_to_asc(i1);
 		printf("interval_copy[%d]: %s\n", i, text ? text : "-");
-		free(text);
+		PGTYPESchar_free(text);
 		PGTYPESinterval_free(ic);
 		PGTYPESinterval_free(i1);
 	}
diff --git a/src/interfaces/ecpg/test/pgtypeslib/num_test.pgc b/src/interfaces/ecpg/test/pgtypeslib/num_test.pgc
index d276f70772b..98912704947 100644
--- a/src/interfaces/ecpg/test/pgtypeslib/num_test.pgc
+++ b/src/interfaces/ecpg/test/pgtypeslib/num_test.pgc
@@ -38,7 +38,7 @@ main(void)
 	PGTYPESnumeric_from_int(1407, value1);
 	text = PGTYPESnumeric_to_asc(value1, -1);
 	printf("from int = %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 	PGTYPESnumeric_free(value1);
 
 	value1 = PGTYPESnumeric_from_asc("2369.7", NULL);
@@ -47,12 +47,12 @@ main(void)
 	PGTYPESnumeric_add(value1, value2, res);
 	text = PGTYPESnumeric_to_asc(res, -1);
 	printf("add = %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 
 	PGTYPESnumeric_sub(res, value2, res);
 	text = PGTYPESnumeric_to_asc(res, -1);
 	printf("sub = %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 	PGTYPESnumeric_free(value2);
 
 	des = PGTYPESnumeric_new();
@@ -68,7 +68,7 @@ main(void)
 	PGTYPESnumeric_mul(res, des, res);
 	text = PGTYPESnumeric_to_asc(res, -1);
 	printf("mul = %s\n", text);
-	free(text);
+	PGTYPESchar_free(text);
 	PGTYPESnumeric_free(des);
 
 	value2 = PGTYPESnumeric_from_asc("10000", NULL);
@@ -85,7 +85,7 @@ main(void)
 	i = PGTYPESnumeric_to_long(value1, &l1) | PGTYPESnumeric_to_long(value2, &l2);
 	printf("to long(%d) = %ld %ld\n", i, l1, l2);
 
-	free(text);
+	PGTYPESchar_free(text);
 	PGTYPESnumeric_free(value1);
 	PGTYPESnumeric_free(value2);
 	PGTYPESnumeric_free(res);
diff --git a/src/interfaces/ecpg/test/pgtypeslib/num_test2.pgc b/src/interfaces/ecpg/test/pgtypeslib/num_test2.pgc
index 16ca6a44a5e..edc0c8c0578 100644
--- a/src/interfaces/ecpg/test/pgtypeslib/num_test2.pgc
+++ b/src/interfaces/ecpg/test/pgtypeslib/num_test2.pgc
@@ -59,21 +59,21 @@ main(void)
 
 		text = PGTYPESnumeric_to_asc(num, -1);
 		if (!text) check_errno();
-		printf("num[%d,1]: %s\n", i, text); free(text);
+		printf("num[%d,1]: %s\n", i, text); PGTYPESchar_free(text);
 		text = PGTYPESnumeric_to_asc(num, 0);
 		if (!text) check_errno();
-		printf("num[%d,2]: %s\n", i, text); free(text);
+		printf("num[%d,2]: %s\n", i, text); PGTYPESchar_free(text);
 		text = PGTYPESnumeric_to_asc(num, 1);
 		if (!text) check_errno();
-		printf("num[%d,3]: %s\n", i, text); free(text);
+		printf("num[%d,3]: %s\n", i, text); PGTYPESchar_free(text);
 		text = PGTYPESnumeric_to_asc(num, 2);
 		if (!text) check_errno();
-		printf("num[%d,4]: %s\n", i, text); free(text);
+		printf("num[%d,4]: %s\n", i, text); PGTYPESchar_free(text);
 
 		nin = PGTYPESnumeric_new();
 		text = PGTYPESnumeric_to_asc(nin, 2);
 		if (!text) check_errno();
-		printf("num[%d,5]: %s\n", i, text); free(text);
+		printf("num[%d,5]: %s\n", i, text); PGTYPESchar_free(text);
 
 		r = PGTYPESnumeric_to_long(num, &l);
 		if (r) check_errno();
@@ -85,7 +85,7 @@ main(void)
 			text = PGTYPESnumeric_to_asc(nin, 2);
 			q = PGTYPESnumeric_cmp(num, nin);
 			printf("num[%d,7]: %s (r: %d - cmp: %d)\n", i, text, r, q);
-			free(text);
+			PGTYPESchar_free(text);
 		}
 
 		r = PGTYPESnumeric_to_int(num, &k);
@@ -98,7 +98,7 @@ main(void)
 			text = PGTYPESnumeric_to_asc(nin, 2);
 			q = PGTYPESnumeric_cmp(num, nin);
 			printf("num[%d,9]: %s (r: %d - cmp: %d)\n", i, text, r, q);
-			free(text);
+			PGTYPESchar_free(text);
 		}
 
 		if (i != 6)
@@ -129,7 +129,7 @@ main(void)
 			text = PGTYPESnumeric_to_asc(nin, 2);
 			q = PGTYPESnumeric_cmp(num, nin);
 			printf("num[%d,12]: %s (r: %d - cmp: %d)\n", i, text, r, q);
-			free(text);
+			PGTYPESchar_free(text);
 		}
 
 		PGTYPESdecimal_free(dec);
@@ -155,7 +155,7 @@ main(void)
 			{
 				text = PGTYPESnumeric_to_asc(a, 10);
 				printf("num[a,%d,%d]: %s\n", i, j, text);
-				free(text);
+				PGTYPESchar_free(text);
 			}
 			r = PGTYPESnumeric_sub(numarr[i], numarr[j], s);
 			if (r)
@@ -167,7 +167,7 @@ main(void)
 			{
 				text = PGTYPESnumeric_to_asc(s, 10);
 				printf("num[s,%d,%d]: %s\n", i, j, text);
-				free(text);
+				PGTYPESchar_free(text);
 			}
 			r = PGTYPESnumeric_mul(numarr[i], numarr[j], m);
 			if (r)
@@ -179,7 +179,7 @@ main(void)
 			{
 				text = PGTYPESnumeric_to_asc(m, 10);
 				printf("num[m,%d,%d]: %s\n", i, j, text);
-				free(text);
+				PGTYPESchar_free(text);
 			}
 			r = PGTYPESnumeric_div(numarr[i], numarr[j], d);
 			if (r)
@@ -191,7 +191,7 @@ main(void)
 			{
 				text = PGTYPESnumeric_to_asc(d, 10);
 				printf("num[d,%d,%d]: %s\n", i, j, text);
-				free(text);
+				PGTYPESchar_free(text);
 			}
 
 			PGTYPESnumeric_free(a);
@@ -205,7 +205,7 @@ main(void)
 	{
 		text = PGTYPESnumeric_to_asc(numarr[i], -1);
 		printf("%d: %s\n", i, text);
-		free(text);
+		PGTYPESchar_free(text);
 		PGTYPESnumeric_free(numarr[i]);
 	}
 	free(numarr);
diff --git a/src/interfaces/ecpg/test/sql/sqlda.pgc b/src/interfaces/ecpg/test/sql/sqlda.pgc
index 2ea5121ac56..ec4d256b390 100644
--- a/src/interfaces/ecpg/test/sql/sqlda.pgc
+++ b/src/interfaces/ecpg/test/sql/sqlda.pgc
@@ -53,7 +53,7 @@ dump_sqlda(sqlda_t *sqlda)
 
 				val = PGTYPESnumeric_to_asc((numeric*)sqlda->sqlvar[i].sqldata, -1);
 				printf("name sqlda descriptor: '%s' value NUMERIC '%s'\n", sqlda->sqlvar[i].sqlname.data, val);
-				free(val);
+				PGTYPESchar_free(val);
 				break;
 			}
 		}
-- 
2.17.0

