Add const qualifiers to internal range type APIs
This patch adds const qualifiers to internal range type APIs. It
doesn't require any new casts or remove any old ones.
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
Attachments:
0001-Add-const-qualifiers-to-internal-range-type-APIs.patchtext/plain; charset=UTF-8; name=0001-Add-const-qualifiers-to-internal-range-type-APIs.patch; x-mac-creator=0; x-mac-type=0Download
From 0251dbcc534aee40a201fe35b0093b06c8ecb5ff Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Mon, 28 Oct 2019 10:00:33 +0100
Subject: [PATCH] Add const qualifiers to internal range type APIs
---
src/backend/utils/adt/rangetypes.c | 34 ++++++-------
src/backend/utils/adt/rangetypes_gist.c | 8 +--
src/backend/utils/adt/rangetypes_selfuncs.c | 52 ++++++++++----------
src/backend/utils/adt/rangetypes_spgist.c | 24 ++++-----
src/include/utils/rangetypes.h | 54 ++++++++++-----------
5 files changed, 86 insertions(+), 86 deletions(-)
diff --git a/src/backend/utils/adt/rangetypes.c b/src/backend/utils/adt/rangetypes.c
index e5c7e5c7ee..461c428413 100644
--- a/src/backend/utils/adt/rangetypes.c
+++ b/src/backend/utils/adt/rangetypes.c
@@ -554,7 +554,7 @@ elem_contained_by_range(PG_FUNCTION_ARGS)
/* equality (internal version) */
bool
-range_eq_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
+range_eq_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
{
RangeBound lower1,
lower2;
@@ -599,7 +599,7 @@ range_eq(PG_FUNCTION_ARGS)
/* inequality (internal version) */
bool
-range_ne_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
+range_ne_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
{
return (!range_eq_internal(typcache, r1, r2));
}
@@ -645,7 +645,7 @@ range_contained_by(PG_FUNCTION_ARGS)
/* strictly left of? (internal version) */
bool
-range_before_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
+range_before_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
{
RangeBound lower1,
lower2;
@@ -683,7 +683,7 @@ range_before(PG_FUNCTION_ARGS)
/* strictly right of? (internal version) */
bool
-range_after_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
+range_after_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
{
RangeBound lower1,
lower2;
@@ -779,7 +779,7 @@ bounds_adjacent(TypeCacheEntry *typcache, RangeBound boundA, RangeBound boundB)
/* adjacent to (but not overlapping)? (internal version) */
bool
-range_adjacent_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
+range_adjacent_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
{
RangeBound lower1,
lower2;
@@ -822,7 +822,7 @@ range_adjacent(PG_FUNCTION_ARGS)
/* overlaps? (internal version) */
bool
-range_overlaps_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
+range_overlaps_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
{
RangeBound lower1,
lower2;
@@ -868,7 +868,7 @@ range_overlaps(PG_FUNCTION_ARGS)
/* does not extend to right of? (internal version) */
bool
-range_overleft_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
+range_overleft_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
{
RangeBound lower1,
lower2;
@@ -909,7 +909,7 @@ range_overleft(PG_FUNCTION_ARGS)
/* does not extend to left of? (internal version) */
bool
-range_overright_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
+range_overright_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
{
RangeBound lower1,
lower2;
@@ -1696,7 +1696,7 @@ range_serialize(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper,
* RangeBound structs will be pointers into the given range object.
*/
void
-range_deserialize(TypeCacheEntry *typcache, RangeType *range,
+range_deserialize(TypeCacheEntry *typcache, const RangeType *range,
RangeBound *lower, RangeBound *upper, bool *empty)
{
char flags;
@@ -1711,7 +1711,7 @@ range_deserialize(TypeCacheEntry *typcache, RangeType *range,
Assert(RangeTypeGetOid(range) == typcache->type_id);
/* fetch the flag byte from datum's last byte */
- flags = *((char *) range + VARSIZE(range) - 1);
+ flags = *((const char *) range + VARSIZE(range) - 1);
/* fetch information about range's element type */
typlen = typcache->rngelemtype->typlen;
@@ -1763,7 +1763,7 @@ range_deserialize(TypeCacheEntry *typcache, RangeType *range,
* the full results of range_deserialize.
*/
char
-range_get_flags(RangeType *range)
+range_get_flags(const RangeType *range)
{
/* fetch the flag byte from datum's last byte */
return *((char *) range + VARSIZE(range) - 1);
@@ -1832,7 +1832,7 @@ make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper,
* but one is an upper bound and the other a lower bound.
*/
int
-range_cmp_bounds(TypeCacheEntry *typcache, RangeBound *b1, RangeBound *b2)
+range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
{
int32 result;
@@ -1906,8 +1906,8 @@ range_cmp_bounds(TypeCacheEntry *typcache, RangeBound *b1, RangeBound *b2)
* infinity is plus or minus.
*/
int
-range_cmp_bound_values(TypeCacheEntry *typcache, RangeBound *b1,
- RangeBound *b2)
+range_cmp_bound_values(TypeCacheEntry *typcache, const RangeBound *b1,
+ const RangeBound *b2)
{
/*
* First, handle cases involving infinity, which don't require invoking
@@ -2300,7 +2300,7 @@ range_bound_escape(const char *value)
* the necessary typcache entry.
*/
bool
-range_contains_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
+range_contains_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
{
RangeBound lower1;
RangeBound upper1;
@@ -2332,7 +2332,7 @@ range_contains_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
}
bool
-range_contained_by_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
+range_contained_by_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
{
return range_contains_internal(typcache, r2, r1);
}
@@ -2341,7 +2341,7 @@ range_contained_by_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *
* Test whether range r contains a specific element value.
*/
bool
-range_contains_elem_internal(TypeCacheEntry *typcache, RangeType *r, Datum val)
+range_contains_elem_internal(TypeCacheEntry *typcache, const RangeType *r, Datum val)
{
RangeBound lower;
RangeBound upper;
diff --git a/src/backend/utils/adt/rangetypes_gist.c b/src/backend/utils/adt/rangetypes_gist.c
index 6f93ce64da..cf73f4d8c1 100644
--- a/src/backend/utils/adt/rangetypes_gist.c
+++ b/src/backend/utils/adt/rangetypes_gist.c
@@ -137,10 +137,10 @@ typedef struct
static RangeType *range_super_union(TypeCacheEntry *typcache, RangeType *r1,
RangeType *r2);
static bool range_gist_consistent_int(TypeCacheEntry *typcache,
- StrategyNumber strategy, RangeType *key,
+ StrategyNumber strategy, const RangeType *key,
Datum query);
static bool range_gist_consistent_leaf(TypeCacheEntry *typcache,
- StrategyNumber strategy, RangeType *key,
+ StrategyNumber strategy, const RangeType *key,
Datum query);
static void range_gist_fallback_split(TypeCacheEntry *typcache,
GistEntryVector *entryvec,
@@ -764,7 +764,7 @@ range_super_union(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
*/
static bool
range_gist_consistent_int(TypeCacheEntry *typcache, StrategyNumber strategy,
- RangeType *key, Datum query)
+ const RangeType *key, Datum query)
{
switch (strategy)
{
@@ -836,7 +836,7 @@ range_gist_consistent_int(TypeCacheEntry *typcache, StrategyNumber strategy,
*/
static bool
range_gist_consistent_leaf(TypeCacheEntry *typcache, StrategyNumber strategy,
- RangeType *key, Datum query)
+ const RangeType *key, Datum query)
{
switch (strategy)
{
diff --git a/src/backend/utils/adt/rangetypes_selfuncs.c b/src/backend/utils/adt/rangetypes_selfuncs.c
index 640c7f0bc6..ab4f86e3fd 100644
--- a/src/backend/utils/adt/rangetypes_selfuncs.c
+++ b/src/backend/utils/adt/rangetypes_selfuncs.c
@@ -31,33 +31,33 @@
#include "utils/typcache.h"
static double calc_rangesel(TypeCacheEntry *typcache, VariableStatData *vardata,
- RangeType *constval, Oid operator);
+ const RangeType *constval, Oid operator);
static double default_range_selectivity(Oid operator);
static double calc_hist_selectivity(TypeCacheEntry *typcache,
- VariableStatData *vardata, RangeType *constval,
+ VariableStatData *vardata, const RangeType *constval,
Oid operator);
static double calc_hist_selectivity_scalar(TypeCacheEntry *typcache,
- RangeBound *constbound,
- RangeBound *hist, int hist_nvalues,
+ const RangeBound *constbound,
+ const RangeBound *hist, int hist_nvalues,
bool equal);
-static int rbound_bsearch(TypeCacheEntry *typcache, RangeBound *value,
- RangeBound *hist, int hist_length, bool equal);
-static float8 get_position(TypeCacheEntry *typcache, RangeBound *value,
- RangeBound *hist1, RangeBound *hist2);
+static int rbound_bsearch(TypeCacheEntry *typcache, const RangeBound *value,
+ const RangeBound *hist, int hist_length, bool equal);
+static float8 get_position(TypeCacheEntry *typcache, const RangeBound *value,
+ const RangeBound *hist1, const RangeBound *hist2);
static float8 get_len_position(double value, double hist1, double hist2);
-static float8 get_distance(TypeCacheEntry *typcache, RangeBound *bound1,
- RangeBound *bound2);
+static float8 get_distance(TypeCacheEntry *typcache, const RangeBound *bound1,
+ const RangeBound *bound2);
static int length_hist_bsearch(Datum *length_hist_values,
int length_hist_nvalues, double value, bool equal);
static double calc_length_hist_frac(Datum *length_hist_values,
int length_hist_nvalues, double length1, double length2, bool equal);
static double calc_hist_selectivity_contained(TypeCacheEntry *typcache,
- RangeBound *lower, RangeBound *upper,
- RangeBound *hist_lower, int hist_nvalues,
+ const RangeBound *lower, RangeBound *upper,
+ const RangeBound *hist_lower, int hist_nvalues,
Datum *length_hist_values, int length_hist_nvalues);
static double calc_hist_selectivity_contains(TypeCacheEntry *typcache,
- RangeBound *lower, RangeBound *upper,
- RangeBound *hist_lower, int hist_nvalues,
+ const RangeBound *lower, const RangeBound *upper,
+ const RangeBound *hist_lower, int hist_nvalues,
Datum *length_hist_values, int length_hist_nvalues);
/*
@@ -229,7 +229,7 @@ rangesel(PG_FUNCTION_ARGS)
static double
calc_rangesel(TypeCacheEntry *typcache, VariableStatData *vardata,
- RangeType *constval, Oid operator)
+ const RangeType *constval, Oid operator)
{
double hist_selec;
double selec;
@@ -371,7 +371,7 @@ calc_rangesel(TypeCacheEntry *typcache, VariableStatData *vardata,
*/
static double
calc_hist_selectivity(TypeCacheEntry *typcache, VariableStatData *vardata,
- RangeType *constval, Oid operator)
+ const RangeType *constval, Oid operator)
{
AttStatsSlot hslot;
AttStatsSlot lslot;
@@ -586,8 +586,8 @@ calc_hist_selectivity(TypeCacheEntry *typcache, VariableStatData *vardata,
* is true) a given const in a histogram of range bounds.
*/
static double
-calc_hist_selectivity_scalar(TypeCacheEntry *typcache, RangeBound *constbound,
- RangeBound *hist, int hist_nvalues, bool equal)
+calc_hist_selectivity_scalar(TypeCacheEntry *typcache, const RangeBound *constbound,
+ const RangeBound *hist, int hist_nvalues, bool equal)
{
Selectivity selec;
int index;
@@ -618,7 +618,7 @@ calc_hist_selectivity_scalar(TypeCacheEntry *typcache, RangeBound *constbound,
* interpolation of portion of bounds which are less or equal to given bound.
*/
static int
-rbound_bsearch(TypeCacheEntry *typcache, RangeBound *value, RangeBound *hist,
+rbound_bsearch(TypeCacheEntry *typcache, const RangeBound *value, const RangeBound *hist,
int hist_length, bool equal)
{
int lower = -1,
@@ -673,8 +673,8 @@ length_hist_bsearch(Datum *length_hist_values, int length_hist_nvalues,
* Get relative position of value in histogram bin in [0,1] range.
*/
static float8
-get_position(TypeCacheEntry *typcache, RangeBound *value, RangeBound *hist1,
- RangeBound *hist2)
+get_position(TypeCacheEntry *typcache, const RangeBound *value, const RangeBound *hist1,
+ const RangeBound *hist2)
{
bool has_subdiff = OidIsValid(typcache->rng_subdiff_finfo.fn_oid);
float8 position;
@@ -795,7 +795,7 @@ get_len_position(double value, double hist1, double hist2)
* Measure distance between two range bounds.
*/
static float8
-get_distance(TypeCacheEntry *typcache, RangeBound *bound1, RangeBound *bound2)
+get_distance(TypeCacheEntry *typcache, const RangeBound *bound1, const RangeBound *bound2)
{
bool has_subdiff = OidIsValid(typcache->rng_subdiff_finfo.fn_oid);
@@ -999,8 +999,8 @@ calc_length_hist_frac(Datum *length_hist_values, int length_hist_nvalues,
*/
static double
calc_hist_selectivity_contained(TypeCacheEntry *typcache,
- RangeBound *lower, RangeBound *upper,
- RangeBound *hist_lower, int hist_nvalues,
+ const RangeBound *lower, RangeBound *upper,
+ const RangeBound *hist_lower, int hist_nvalues,
Datum *length_hist_values, int length_hist_nvalues)
{
int i,
@@ -1109,8 +1109,8 @@ calc_hist_selectivity_contained(TypeCacheEntry *typcache,
*/
static double
calc_hist_selectivity_contains(TypeCacheEntry *typcache,
- RangeBound *lower, RangeBound *upper,
- RangeBound *hist_lower, int hist_nvalues,
+ const RangeBound *lower, const RangeBound *upper,
+ const RangeBound *hist_lower, int hist_nvalues,
Datum *length_hist_values, int length_hist_nvalues)
{
int i,
diff --git a/src/backend/utils/adt/rangetypes_spgist.c b/src/backend/utils/adt/rangetypes_spgist.c
index 8bb730ce8e..f70e39360d 100644
--- a/src/backend/utils/adt/rangetypes_spgist.c
+++ b/src/backend/utils/adt/rangetypes_spgist.c
@@ -43,15 +43,15 @@
#include "utils/datum.h"
#include "utils/rangetypes.h"
-static int16 getQuadrant(TypeCacheEntry *typcache, RangeType *centroid,
- RangeType *tst);
+static int16 getQuadrant(TypeCacheEntry *typcache, const RangeType *centroid,
+ const RangeType *tst);
static int bound_cmp(const void *a, const void *b, void *arg);
-static int adjacent_inner_consistent(TypeCacheEntry *typcache,
- RangeBound *arg, RangeBound *centroid,
- RangeBound *prev);
-static int adjacent_cmp_bounds(TypeCacheEntry *typcache, RangeBound *arg,
- RangeBound *centroid);
+static int adjacent_inner_consistent(TypeCacheEntry *typcache,
+ const RangeBound *arg, const RangeBound *centroid,
+ const RangeBound *prev);
+static int adjacent_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *arg,
+ const RangeBound *centroid);
/*
* SP-GiST 'config' interface function.
@@ -92,7 +92,7 @@ spg_range_quad_config(PG_FUNCTION_ARGS)
*----------
*/
static int16
-getQuadrant(TypeCacheEntry *typcache, RangeType *centroid, RangeType *tst)
+getQuadrant(TypeCacheEntry *typcache, const RangeType *centroid, const RangeType *tst)
{
RangeBound centroidLower,
centroidUpper;
@@ -785,8 +785,8 @@ spg_range_quad_inner_consistent(PG_FUNCTION_ARGS)
* For the "left" case, returns -1, and for the "right" case, returns 1.
*/
static int
-adjacent_cmp_bounds(TypeCacheEntry *typcache, RangeBound *arg,
- RangeBound *centroid)
+adjacent_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *arg,
+ const RangeBound *centroid)
{
int cmp;
@@ -887,8 +887,8 @@ adjacent_cmp_bounds(TypeCacheEntry *typcache, RangeBound *arg,
*----------
*/
static int
-adjacent_inner_consistent(TypeCacheEntry *typcache, RangeBound *arg,
- RangeBound *centroid, RangeBound *prev)
+adjacent_inner_consistent(TypeCacheEntry *typcache, const RangeBound *arg,
+ const RangeBound *centroid, const RangeBound *prev)
{
if (prev)
{
diff --git a/src/include/utils/rangetypes.h b/src/include/utils/rangetypes.h
index 580e476501..11ed19ccfd 100644
--- a/src/include/utils/rangetypes.h
+++ b/src/include/utils/rangetypes.h
@@ -92,46 +92,46 @@ typedef struct
* prototypes for functions defined in rangetypes.c
*/
-extern bool range_contains_elem_internal(TypeCacheEntry *typcache, RangeType *r, Datum val);
+extern bool range_contains_elem_internal(TypeCacheEntry *typcache, const RangeType *r, Datum val);
/* internal versions of the above */
-extern bool range_eq_internal(TypeCacheEntry *typcache, RangeType *r1,
- RangeType *r2);
-extern bool range_ne_internal(TypeCacheEntry *typcache, RangeType *r1,
- RangeType *r2);
-extern bool range_contains_internal(TypeCacheEntry *typcache, RangeType *r1,
- RangeType *r2);
-extern bool range_contained_by_internal(TypeCacheEntry *typcache, RangeType *r1,
- RangeType *r2);
-extern bool range_before_internal(TypeCacheEntry *typcache, RangeType *r1,
- RangeType *r2);
-extern bool range_after_internal(TypeCacheEntry *typcache, RangeType *r1,
- RangeType *r2);
-extern bool range_adjacent_internal(TypeCacheEntry *typcache, RangeType *r1,
- RangeType *r2);
-extern bool range_overlaps_internal(TypeCacheEntry *typcache, RangeType *r1,
- RangeType *r2);
-extern bool range_overleft_internal(TypeCacheEntry *typcache, RangeType *r1,
- RangeType *r2);
-extern bool range_overright_internal(TypeCacheEntry *typcache, RangeType *r1,
- RangeType *r2);
+extern bool range_eq_internal(TypeCacheEntry *typcache, const RangeType *r1,
+ const RangeType *r2);
+extern bool range_ne_internal(TypeCacheEntry *typcache, const RangeType *r1,
+ const RangeType *r2);
+extern bool range_contains_internal(TypeCacheEntry *typcache, const RangeType *r1,
+ const RangeType *r2);
+extern bool range_contained_by_internal(TypeCacheEntry *typcache, const RangeType *r1,
+ const RangeType *r2);
+extern bool range_before_internal(TypeCacheEntry *typcache, const RangeType *r1,
+ const RangeType *r2);
+extern bool range_after_internal(TypeCacheEntry *typcache, const RangeType *r1,
+ const RangeType *r2);
+extern bool range_adjacent_internal(TypeCacheEntry *typcache, const RangeType *r1,
+ const RangeType *r2);
+extern bool range_overlaps_internal(TypeCacheEntry *typcache, const RangeType *r1,
+ const RangeType *r2);
+extern bool range_overleft_internal(TypeCacheEntry *typcache, const RangeType *r1,
+ const RangeType *r2);
+extern bool range_overright_internal(TypeCacheEntry *typcache, const RangeType *r1,
+ const RangeType *r2);
/* assorted support functions */
extern TypeCacheEntry *range_get_typcache(FunctionCallInfo fcinfo,
Oid rngtypid);
extern RangeType *range_serialize(TypeCacheEntry *typcache, RangeBound *lower,
RangeBound *upper, bool empty);
-extern void range_deserialize(TypeCacheEntry *typcache, RangeType *range,
+extern void range_deserialize(TypeCacheEntry *typcache, const RangeType *range,
RangeBound *lower, RangeBound *upper,
bool *empty);
-extern char range_get_flags(RangeType *range);
+extern char range_get_flags(const RangeType *range);
extern void range_set_contain_empty(RangeType *range);
extern RangeType *make_range(TypeCacheEntry *typcache, RangeBound *lower,
RangeBound *upper, bool empty);
-extern int range_cmp_bounds(TypeCacheEntry *typcache, RangeBound *b1,
- RangeBound *b2);
-extern int range_cmp_bound_values(TypeCacheEntry *typcache, RangeBound *b1,
- RangeBound *b2);
+extern int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1,
+ const RangeBound *b2);
+extern int range_cmp_bound_values(TypeCacheEntry *typcache, const RangeBound *b1,
+ const RangeBound *b2);
extern bool bounds_adjacent(TypeCacheEntry *typcache, RangeBound bound1,
RangeBound bound2);
extern RangeType *make_empty_range(TypeCacheEntry *typcache);
base-commit: 61ecea45e50bcd3b87d4e905719e63e41d6321ce
--
2.23.0
On Mon, Oct 28, 2019 at 5:01 AM Peter Eisentraut
<peter.eisentraut@2ndquadrant.com> wrote:
This patch adds const qualifiers to internal range type APIs. It
doesn't require any new casts or remove any old ones.
Just out of curiosity, what is the motivation for this?
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
On 2019-10-28 14:05, Robert Haas wrote:
On Mon, Oct 28, 2019 at 5:01 AM Peter Eisentraut
<peter.eisentraut@2ndquadrant.com> wrote:This patch adds const qualifiers to internal range type APIs. It
doesn't require any new casts or remove any old ones.Just out of curiosity, what is the motivation for this?
I don't remember. :-)
I had this code lying around from earlier "adventures in const",
probably related to unconstify() and that work, and it seemed sensible
and self-contained enough to finish up and submit.
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
On 2019-10-29 16:48:24 +0100, Peter Eisentraut wrote:
On 2019-10-28 14:05, Robert Haas wrote:
Just out of curiosity, what is the motivation for this?
I don't remember. :-)
I had this code lying around from earlier "adventures in const", probably
related to unconstify() and that work, and it seemed sensible and
self-contained enough to finish up and submit.
+1
On 2019-10-29 21:11, Andres Freund wrote:
On 2019-10-29 16:48:24 +0100, Peter Eisentraut wrote:
On 2019-10-28 14:05, Robert Haas wrote:
Just out of curiosity, what is the motivation for this?
I don't remember. :-)
I had this code lying around from earlier "adventures in const", probably
related to unconstify() and that work, and it seemed sensible and
self-contained enough to finish up and submit.+1
committed
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services