From b641f68a96138162935756ed708367e2f162f0a2 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Mon, 12 Dec 2011 01:38:42 +0100
Subject: [PATCH] Release memory in inet functions

This is now neccessary because since a recent commit ("Make
DatumGetInetP() unpack inet datums") those functions actually allocate
memory. Thats not allowed in btree support functions.
---
 src/backend/utils/adt/network.c |   77 +++++++++++++++++++++++++++++----------
 1 files changed, 58 insertions(+), 19 deletions(-)

diff --git a/src/backend/utils/adt/network.c b/src/backend/utils/adt/network.c
index e929d6b..7ee2d2b 100644
--- a/src/backend/utils/adt/network.c
+++ b/src/backend/utils/adt/network.c
@@ -460,7 +460,11 @@ network_cmp(PG_FUNCTION_ARGS)
 	inet	   *a1 = PG_GETARG_INET_P(0);
 	inet	   *a2 = PG_GETARG_INET_P(1);
 
-	PG_RETURN_INT32(network_cmp_internal(a1, a2));
+	int32 r = network_cmp_internal(a1, a2);
+
+	PG_FREE_IF_COPY(a1, 0);
+	PG_FREE_IF_COPY(a2, 1);
+	PG_RETURN_INT32(r);
 }
 
 /*
@@ -472,7 +476,11 @@ network_lt(PG_FUNCTION_ARGS)
 	inet	   *a1 = PG_GETARG_INET_P(0);
 	inet	   *a2 = PG_GETARG_INET_P(1);
 
-	PG_RETURN_BOOL(network_cmp_internal(a1, a2) < 0);
+	bool r = network_cmp_internal(a1, a2) < 0;
+
+	PG_FREE_IF_COPY(a1, 0);
+	PG_FREE_IF_COPY(a2, 1);
+	PG_RETURN_BOOL(r);
 }
 
 Datum
@@ -481,7 +489,11 @@ network_le(PG_FUNCTION_ARGS)
 	inet	   *a1 = PG_GETARG_INET_P(0);
 	inet	   *a2 = PG_GETARG_INET_P(1);
 
-	PG_RETURN_BOOL(network_cmp_internal(a1, a2) <= 0);
+	bool r = network_cmp_internal(a1, a2) <= 0;
+
+	PG_FREE_IF_COPY(a1, 0);
+	PG_FREE_IF_COPY(a2, 1);
+	PG_RETURN_BOOL(r);
 }
 
 Datum
@@ -490,7 +502,11 @@ network_eq(PG_FUNCTION_ARGS)
 	inet	   *a1 = PG_GETARG_INET_P(0);
 	inet	   *a2 = PG_GETARG_INET_P(1);
 
-	PG_RETURN_BOOL(network_cmp_internal(a1, a2) == 0);
+	bool r = network_cmp_internal(a1, a2) == 0;
+
+	PG_FREE_IF_COPY(a1, 0);
+	PG_FREE_IF_COPY(a2, 1);
+	PG_RETURN_BOOL(r);
 }
 
 Datum
@@ -499,7 +515,11 @@ network_ge(PG_FUNCTION_ARGS)
 	inet	   *a1 = PG_GETARG_INET_P(0);
 	inet	   *a2 = PG_GETARG_INET_P(1);
 
-	PG_RETURN_BOOL(network_cmp_internal(a1, a2) >= 0);
+	bool r = network_cmp_internal(a1, a2) >= 0;
+
+	PG_FREE_IF_COPY(a1, 0);
+	PG_FREE_IF_COPY(a2, 1);
+	PG_RETURN_BOOL(r);
 }
 
 Datum
@@ -508,7 +528,11 @@ network_gt(PG_FUNCTION_ARGS)
 	inet	   *a1 = PG_GETARG_INET_P(0);
 	inet	   *a2 = PG_GETARG_INET_P(1);
 
-	PG_RETURN_BOOL(network_cmp_internal(a1, a2) > 0);
+	bool r = network_cmp_internal(a1, a2) > 0;
+
+	PG_FREE_IF_COPY(a1, 0);
+	PG_FREE_IF_COPY(a2, 1);
+	PG_RETURN_BOOL(r);
 }
 
 Datum
@@ -517,7 +541,11 @@ network_ne(PG_FUNCTION_ARGS)
 	inet	   *a1 = PG_GETARG_INET_P(0);
 	inet	   *a2 = PG_GETARG_INET_P(1);
 
-	PG_RETURN_BOOL(network_cmp_internal(a1, a2) != 0);
+	bool r = network_cmp_internal(a1, a2) != 0;
+
+	PG_FREE_IF_COPY(a1, 0);
+	PG_FREE_IF_COPY(a2, 1);
+	PG_RETURN_BOOL(r);
 }
 
 /*
@@ -541,14 +569,17 @@ network_sub(PG_FUNCTION_ARGS)
 {
 	inet	   *a1 = PG_GETARG_INET_P(0);
 	inet	   *a2 = PG_GETARG_INET_P(1);
+	bool        r = false;
 
 	if (ip_family(a1) == ip_family(a2))
 	{
-		PG_RETURN_BOOL(ip_bits(a1) > ip_bits(a2)
-					 && bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a2)) == 0);
+		r = ip_bits(a1) > ip_bits(a2)
+			&& bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a2)) == 0;
 	}
 
-	PG_RETURN_BOOL(false);
+	PG_FREE_IF_COPY(a1, 0);
+	PG_FREE_IF_COPY(a2, 1);
+	PG_RETURN_BOOL(r);
 }
 
 Datum
@@ -556,14 +587,17 @@ network_subeq(PG_FUNCTION_ARGS)
 {
 	inet	   *a1 = PG_GETARG_INET_P(0);
 	inet	   *a2 = PG_GETARG_INET_P(1);
+	bool        r = false;
 
 	if (ip_family(a1) == ip_family(a2))
 	{
-		PG_RETURN_BOOL(ip_bits(a1) >= ip_bits(a2)
-					 && bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a2)) == 0);
+		r = ip_bits(a1) >= ip_bits(a2)
+			&& bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a2)) == 0;
 	}
 
-	PG_RETURN_BOOL(false);
+	PG_FREE_IF_COPY(a1, 0);
+	PG_FREE_IF_COPY(a2, 1);
+	PG_RETURN_BOOL(r);
 }
 
 Datum
@@ -574,11 +608,13 @@ network_sup(PG_FUNCTION_ARGS)
 
 	if (ip_family(a1) == ip_family(a2))
 	{
-		PG_RETURN_BOOL(ip_bits(a1) < ip_bits(a2)
-					 && bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a1)) == 0);
+		r = ip_bits(a1) < ip_bits(a2)
+			&& bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a1)) == 0;
 	}
 
-	PG_RETURN_BOOL(false);
+	PG_FREE_IF_COPY(a1, 0);
+	PG_FREE_IF_COPY(a2, 1);
+	PG_RETURN_BOOL(r);
 }
 
 Datum
@@ -586,14 +622,17 @@ network_supeq(PG_FUNCTION_ARGS)
 {
 	inet	   *a1 = PG_GETARG_INET_P(0);
 	inet	   *a2 = PG_GETARG_INET_P(1);
+	bool        r = false;
 
 	if (ip_family(a1) == ip_family(a2))
 	{
-		PG_RETURN_BOOL(ip_bits(a1) <= ip_bits(a2)
-					 && bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a1)) == 0);
+		r = ip_bits(a1) <= ip_bits(a2)
+			&& bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a1)) == 0;
 	}
 
-	PG_RETURN_BOOL(false);
+	PG_FREE_IF_COPY(a1, 0);
+	PG_FREE_IF_COPY(a2, 1);
+	PG_RETURN_BOOL(r);
 }
 
 /*
-- 
1.7.6.409.ge7a85.dirty

