diff --git a/contrib/btree_gist/btree_bit.c b/contrib/btree_gist/btree_bit.c
index 0b220ae2bb7fd333d9d332f49f5ce6bdd3f5c464..459c4d60b0df6676a15a9cb348657e47fa040931 100644
--- a/contrib/btree_gist/btree_bit.c
+++ b/contrib/btree_gist/btree_bit.c
@@ -67,7 +67,7 @@ static bytea *
 gbt_bit_xfrm(bytea *leaf)
 {
 	bytea	   *out = leaf;
-	int			s = VARBITBYTES(leaf) + VARHDRSZ;
+	int			s = INTALIGN(VARBITBYTES(leaf) + VARHDRSZ);
 
 	out = palloc(s);
 	VARATT_SIZEP(out) = s;
@@ -126,8 +126,7 @@ Datum
 gbt_bit_consistent(PG_FUNCTION_ARGS)
 {
 	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
-	GBT_VARKEY *ktst = (GBT_VARKEY *) DatumGetPointer(entry->key);
-	GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(PG_DETOAST_DATUM(entry->key));
+	GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
 	void	   *qtst = (void *) DatumGetPointer(PG_GETARG_DATUM(1));
 	void	   *query = (void *) DatumGetByteaP(PG_GETARG_DATUM(1));
 	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
@@ -144,8 +143,6 @@ gbt_bit_consistent(PG_FUNCTION_ARGS)
 		pfree(q);
 	}
 
-	if (ktst != key)
-		pfree(key);
 	if (qtst != query)
 		pfree(query);
 	PG_RETURN_BOOL(retval);
diff --git a/contrib/btree_gist/btree_bytea.c b/contrib/btree_gist/btree_bytea.c
index 3671acd24c8bd60f7a5ccf3e6c8610c35ffb52ed..2d2169412ee225ad287a5641f7b38c05a6f35fe0 100644
--- a/contrib/btree_gist/btree_bytea.c
+++ b/contrib/btree_gist/btree_bytea.c
@@ -96,8 +96,7 @@ Datum
 gbt_bytea_consistent(PG_FUNCTION_ARGS)
 {
 	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
-	GBT_VARKEY *ktst = (GBT_VARKEY *) DatumGetPointer(entry->key);
-	GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(PG_DETOAST_DATUM(entry->key));
+	GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
 	void	   *qtst = (void *) DatumGetPointer(PG_GETARG_DATUM(1));
 	void	   *query = (void *) DatumGetByteaP(PG_GETARG_DATUM(1));
 	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
@@ -106,8 +105,6 @@ gbt_bytea_consistent(PG_FUNCTION_ARGS)
 
 	retval = gbt_var_consistent(&r, query, &strategy, GIST_LEAF(entry), &tinfo);
 
-	if (ktst != key)
-		pfree(key);
 	if (qtst != query)
 		pfree(query);
 	PG_RETURN_BOOL(retval);
diff --git a/contrib/btree_gist/btree_gist.sql.in b/contrib/btree_gist/btree_gist.sql.in
index 5dafe15960bd90ef9155dfcd817934173d9e63c2..a5f7ae3ffa0728bb09466e9c7f66bf6e6394641f 100644
--- a/contrib/btree_gist/btree_gist.sql.in
+++ b/contrib/btree_gist/btree_gist.sql.in
@@ -107,6 +107,11 @@ RETURNS internal
 AS 'MODULE_PATHNAME'
 LANGUAGE 'C';
 
+CREATE FUNCTION gbt_var_decompress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE 'C';
+
 CREATE FUNCTION gbt_oid_penalty(internal,internal,internal)
 RETURNS internal
 AS 'MODULE_PATHNAME'
@@ -893,7 +898,7 @@ AS
 	FUNCTION	1	gbt_text_consistent (internal, text, int2),
 	FUNCTION	2	gbt_text_union (bytea, internal),
 	FUNCTION	3	gbt_text_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	4	gbt_var_decompress (internal),
 	FUNCTION	5	gbt_text_penalty (internal, internal, internal),
 	FUNCTION	6	gbt_text_picksplit (internal, internal),
 	FUNCTION	7	gbt_text_same (internal, internal, internal),
@@ -912,7 +917,7 @@ AS
 	FUNCTION	1	gbt_bpchar_consistent (internal, bpchar , int2),
 	FUNCTION	2	gbt_text_union (bytea, internal),
 	FUNCTION	3	gbt_bpchar_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	4	gbt_var_decompress (internal),
 	FUNCTION	5	gbt_text_penalty (internal, internal, internal),
 	FUNCTION	6	gbt_text_picksplit (internal, internal),
 	FUNCTION	7	gbt_text_same (internal, internal, internal),
@@ -969,7 +974,7 @@ AS
 	FUNCTION	1	gbt_bytea_consistent (internal, bytea, int2),
 	FUNCTION	2	gbt_bytea_union (bytea, internal),
 	FUNCTION	3	gbt_bytea_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	4	gbt_var_decompress (internal),
 	FUNCTION	5	gbt_bytea_penalty (internal, internal, internal),
 	FUNCTION	6	gbt_bytea_picksplit (internal, internal),
 	FUNCTION	7	gbt_bytea_same (internal, internal, internal),
@@ -1026,7 +1031,7 @@ AS
 	FUNCTION	1	gbt_numeric_consistent (internal, numeric, int2),
 	FUNCTION	2	gbt_numeric_union (bytea, internal),
 	FUNCTION	3	gbt_numeric_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	4	gbt_var_decompress (internal),
 	FUNCTION	5	gbt_numeric_penalty (internal, internal, internal),
 	FUNCTION	6	gbt_numeric_picksplit (internal, internal),
 	FUNCTION	7	gbt_numeric_same (internal, internal, internal),
@@ -1081,7 +1086,7 @@ AS
 	FUNCTION	1	gbt_bit_consistent (internal, bit, int2),
 	FUNCTION	2	gbt_bit_union (bytea, internal),
 	FUNCTION	3	gbt_bit_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	4	gbt_var_decompress (internal),
 	FUNCTION	5	gbt_bit_penalty (internal, internal, internal),
 	FUNCTION	6	gbt_bit_picksplit (internal, internal),
 	FUNCTION	7	gbt_bit_same (internal, internal, internal),
@@ -1100,7 +1105,7 @@ AS
 	FUNCTION	1	gbt_bit_consistent (internal, bit, int2),
 	FUNCTION	2	gbt_bit_union (bytea, internal),
 	FUNCTION	3	gbt_bit_compress (internal),
-	FUNCTION	4	gbt_decompress (internal),
+	FUNCTION	4	gbt_var_decompress (internal),
 	FUNCTION	5	gbt_bit_penalty (internal, internal, internal),
 	FUNCTION	6	gbt_bit_picksplit (internal, internal),
 	FUNCTION	7	gbt_bit_same (internal, internal, internal),
diff --git a/contrib/btree_gist/btree_numeric.c b/contrib/btree_gist/btree_numeric.c
index 8b54b931d5b81456367a88911a8d7bbf18999d7d..6818c5c0e304c2ab21eeb951fe3bdd2d751a064f 100644
--- a/contrib/btree_gist/btree_numeric.c
+++ b/contrib/btree_gist/btree_numeric.c
@@ -97,8 +97,7 @@ gbt_numeric_consistent(PG_FUNCTION_ARGS)
 {
 
 	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
-	GBT_VARKEY *ktst = (GBT_VARKEY *) DatumGetPointer(entry->key);
-	GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(PG_DETOAST_DATUM(entry->key));
+	GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
 	void	   *qtst = (void *) DatumGetPointer(PG_GETARG_DATUM(1));
 	void	   *query = (void *) DatumGetNumeric(PG_GETARG_DATUM(1));
 	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
@@ -107,8 +106,6 @@ gbt_numeric_consistent(PG_FUNCTION_ARGS)
 
 	retval = gbt_var_consistent(&r, query, &strategy, GIST_LEAF(entry), &tinfo);
 
-	if (ktst != key)
-		pfree(key);
 	if (qtst != query)
 		pfree(query);
 	PG_RETURN_BOOL(retval);
diff --git a/contrib/btree_gist/btree_text.c b/contrib/btree_gist/btree_text.c
index d2603e1d9110fc0e836b07862090365937aef2cc..8124362a882688ffbbd8cef401ac2ecad89024fd 100644
--- a/contrib/btree_gist/btree_text.c
+++ b/contrib/btree_gist/btree_text.c
@@ -59,64 +59,9 @@ gbt_textlt(const void *a, const void *b)
 static int32
 gbt_textcmp(const bytea *a, const bytea *b)
 {
-	return strcmp(VARDATA(a), VARDATA(b));
+	return DatumGetInt32(DirectFunctionCall2(bttextcmp, PointerGetDatum(a), PointerGetDatum(b)));
 }
 
-
-/*
- * Converts data of leaf using strxfrm ( locale support )
-*/
-
-static bytea *
-gbt_text_xfrm(bytea *leaf)
-{
-	bytea	   *out = leaf;
-	int32		ilen = VARSIZE(leaf) - VARHDRSZ;
-	int32		olen;
-	char	   *sin;
-	char	   *sou;
-
-	sin = palloc(ilen + 1);
-	memcpy(sin, (void *) VARDATA(leaf), ilen);
-	sin[ilen] = '\0';
-
-	olen = strxfrm(NULL, &sin[0], 0) + 1;
-	sou = palloc(olen);
-	olen = strxfrm(sou, &sin[0], olen);
-	olen += VARHDRSZ;
-	out = palloc(olen + 1);
-	out->vl_len = olen + 1;
-	memcpy((void *) VARDATA(out), sou, olen - VARHDRSZ);
-	((char *) out)[olen] = '\0';
-
-	pfree(sou);
-	pfree(sin);
-
-	return out;
-}
-
-
-static GBT_VARKEY *
-gbt_text_l2n(GBT_VARKEY * leaf)
-{
-
-	GBT_VARKEY *out = leaf;
-	GBT_VARKEY_R r = gbt_var_key_readable(leaf);
-	bytea	   *o;
-
-	o = gbt_text_xfrm(r.lower);
-	r.lower = r.upper = o;
-	out = gbt_var_key_copy(&r, TRUE);
-	pfree(o);
-
-	return out;
-
-}
-
-
-
-
-
 static const gbtree_vinfo tinfo =
 {
 	gbt_t_text,
@@ -128,7 +73,7 @@ static const gbtree_vinfo tinfo =
 	gbt_textle,
 	gbt_textlt,
 	gbt_textcmp,
-	gbt_text_l2n
+	NULL
 };
 
 
@@ -157,14 +102,13 @@ gbt_bpchar_compress(PG_FUNCTION_ARGS)
 	{
 
 		Datum		d = DirectFunctionCall1(rtrim1, entry->key);
-		GISTENTRY  *trim = palloc(sizeof(GISTENTRY));
+		GISTENTRY  	trim;
 
-		gistentryinit(*trim, d,
+		gistentryinit(trim, d,
 					  entry->rel, entry->page,
 					  entry->offset, VARSIZE(DatumGetPointer(d)), TRUE);
-		retval = gbt_var_compress(trim, &tinfo);
+		retval = gbt_var_compress(&trim, &tinfo);
 
-		pfree(trim);
 		pfree(DatumGetPointer(d));
 	}
 	else
@@ -179,27 +123,15 @@ Datum
 gbt_text_consistent(PG_FUNCTION_ARGS)
 {
 	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
-	GBT_VARKEY *ktst = (GBT_VARKEY *) DatumGetPointer(entry->key);
-	GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(PG_DETOAST_DATUM(entry->key));
+	GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
 	void	   *qtst = (void *) DatumGetPointer(PG_GETARG_DATUM(1));
 	void	   *query = (void *) DatumGetTextP(PG_GETARG_DATUM(1));
 	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
 	bool		retval = FALSE;
 	GBT_VARKEY_R r = gbt_var_key_readable(key);
 
-	if (GIST_LEAF(entry))
-		retval = gbt_var_consistent(&r, query, &strategy, TRUE, &tinfo);
-	else
-	{
-		bytea	   *q = gbt_text_xfrm((bytea *) query);
+	retval = gbt_var_consistent(&r, query, &strategy, GIST_LEAF(entry), &tinfo);
 
-		retval = gbt_var_consistent(&r, (void *) q, &strategy, FALSE, &tinfo);
-		if (q != query)
-			pfree(q);
-	}
-
-	if (ktst != key)
-		pfree(key);
 	if (qtst != query)
 		pfree(query);
 
@@ -211,8 +143,7 @@ Datum
 gbt_bpchar_consistent(PG_FUNCTION_ARGS)
 {
 	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
-	GBT_VARKEY *ktst = (GBT_VARKEY *) DatumGetPointer(entry->key);
-	GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(PG_DETOAST_DATUM(entry->key));
+	GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(entry->key);
 	void	   *qtst = (void *) DatumGetPointer(PG_GETARG_DATUM(1));
 	void	   *query = (void *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(1)));
 	void	   *trim = (void *) DatumGetPointer(DirectFunctionCall1(rtrim1, PointerGetDatum(query)));
@@ -220,21 +151,10 @@ gbt_bpchar_consistent(PG_FUNCTION_ARGS)
 	bool		retval = FALSE;
 	GBT_VARKEY_R r = gbt_var_key_readable(key);
 
-	if (GIST_LEAF(entry))
-		retval = gbt_var_consistent(&r, trim, &strategy, TRUE, &tinfo);
-	else
-	{
-		bytea	   *q = gbt_text_xfrm((bytea *) trim);
-
-		retval = gbt_var_consistent(&r, (void *) q, &strategy, FALSE, &tinfo);
-		if (q != trim)
-			pfree(q);
-	}
+	retval = gbt_var_consistent(&r, trim, &strategy, GIST_LEAF(entry), &tinfo);
 
 	pfree(trim);
 
-	if (ktst != key)
-		pfree(key);
 	if (qtst != query)
 		pfree(query);
 	PG_RETURN_BOOL(retval);
diff --git a/contrib/btree_gist/btree_utils_var.c b/contrib/btree_gist/btree_utils_var.c
index f5198392c40556aad4a1edd7e2ae42b0d9fb332b..d7686526a28ec74802255678c9ac10e612389064 100644
--- a/contrib/btree_gist/btree_utils_var.c
+++ b/contrib/btree_gist/btree_utils_var.c
@@ -2,6 +2,30 @@
 #include "utils/pg_locale.h"
 #include "btree_utils_var.h"
 
+PG_FUNCTION_INFO_V1(gbt_var_decompress);
+Datum           gbt_var_decompress(PG_FUNCTION_ARGS);
+
+
+Datum
+gbt_var_decompress(PG_FUNCTION_ARGS)
+{
+        GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+        GBT_VARKEY   *key = (GBT_VARKEY *) DatumGetPointer(PG_DETOAST_DATUM(entry->key));
+
+        if (key != (GBT_VARKEY *) DatumGetPointer(entry->key))
+        {
+                GISTENTRY  *retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
+
+                gistentryinit(*retval, PointerGetDatum(key),
+                                          entry->rel, entry->page,
+                                          entry->offset, VARSIZE(key), FALSE);
+
+                PG_RETURN_POINTER(retval);
+        }
+
+        PG_RETURN_POINTER(entry);
+}
+
 /* Returns a better readable representaion of variable key ( sets pointer ) */
 
 extern		GBT_VARKEY_R
@@ -265,12 +289,8 @@ gbt_var_compress(GISTENTRY *entry, const gbtree_vinfo * tinfo)
 					  entry->offset, VARSIZE(r), TRUE);
 	}
 	else
-	{
 		retval = entry;
 
-
-	}
-
 	return (retval);
 }
 
@@ -282,27 +302,20 @@ gbt_var_union(const GistEntryVector *entryvec, int32 *size, const gbtree_vinfo *
 
 	int			i = 0,
 				numranges = entryvec->n;
-	GBT_VARKEY *cur,
-			   *tst = NULL;
+	GBT_VARKEY *cur;
 	Datum		out;
 	GBT_VARKEY_R rk;
 
 	*size = sizeof(GBT_VARKEY);
 
-	tst = (GBT_VARKEY *) DatumGetPointer((entryvec->vector[0].key));
-	cur = (GBT_VARKEY *) DatumGetPointer(PG_DETOAST_DATUM((entryvec->vector[0].key)));
+	cur = (GBT_VARKEY *) DatumGetPointer(entryvec->vector[0].key);
 	rk = gbt_var_key_readable(cur);
 	out = PointerGetDatum(gbt_var_key_copy(&rk, TRUE));
-	if (tst != cur)
-		pfree(cur);
 
 	for (i = 1; i < numranges; i++)
 	{
-		tst = (GBT_VARKEY *) DatumGetPointer((entryvec->vector[i].key));
-		cur = (GBT_VARKEY *) DatumGetPointer(PG_DETOAST_DATUM((entryvec->vector[i].key)));
+		cur = (GBT_VARKEY *) DatumGetPointer(entryvec->vector[i].key);
 		gbt_var_bin_union(&out, cur, tinfo);
-		if (tst != cur)
-			pfree(cur);
 	}
 
 
@@ -328,10 +341,8 @@ extern bool
 gbt_var_same(bool *result, const Datum d1, const Datum d2, const gbtree_vinfo * tinfo)
 {
 
-	GBT_VARKEY *tst1 = (GBT_VARKEY *) DatumGetPointer(d1);
-	GBT_VARKEY *t1 = (GBT_VARKEY *) DatumGetPointer(PG_DETOAST_DATUM(d1));
-	GBT_VARKEY *tst2 = (GBT_VARKEY *) DatumGetPointer(d2);
-	GBT_VARKEY *t2 = (GBT_VARKEY *) DatumGetPointer(PG_DETOAST_DATUM(d2));
+	GBT_VARKEY *t1 = (GBT_VARKEY *) DatumGetPointer(d1);
+	GBT_VARKEY *t2 = (GBT_VARKEY *) DatumGetPointer(d2);
 	GBT_VARKEY_R r1,
 				r2;
 
@@ -346,11 +357,6 @@ gbt_var_same(bool *result, const Datum d1, const Datum d2, const gbtree_vinfo *
 	else
 		*result = (t1 == NULL && t2 == NULL) ? TRUE : FALSE;
 
-	if (tst1 != t1)
-		pfree(t1);
-	if (tst2 != t2)
-		pfree(t2);
-
 	PG_RETURN_POINTER(result);
 }
 
@@ -360,10 +366,8 @@ extern float *
 gbt_var_penalty(float *res, const GISTENTRY *o, const GISTENTRY *n, const gbtree_vinfo * tinfo)
 {
 
-	GBT_VARKEY *orgt = (GBT_VARKEY *) DatumGetPointer(o->key);
-	GBT_VARKEY *orge = (GBT_VARKEY *) DatumGetPointer(PG_DETOAST_DATUM(o->key));
-	GBT_VARKEY *newt = (GBT_VARKEY *) DatumGetPointer(n->key);
-	GBT_VARKEY *newe = (GBT_VARKEY *) DatumGetPointer(PG_DETOAST_DATUM(n->key));
+	GBT_VARKEY *orge = (GBT_VARKEY *) DatumGetPointer(o->key);
+	GBT_VARKEY *newe = (GBT_VARKEY *) DatumGetPointer(n->key);
 	GBT_VARKEY_R ok,
 				nk;
 	GBT_VARKEY *tmp = NULL;
@@ -436,13 +440,7 @@ gbt_var_penalty(float *res, const GISTENTRY *o, const GISTENTRY *n, const gbtree
 	if (tmp && tmp != newe)
 		pfree(tmp);
 
-	if (newe != newt)
-		pfree(newe);
-
-	if (orge != orgt)
-		pfree(orge);
 	return res;
-
 }
 
 
@@ -466,12 +464,9 @@ gbt_var_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v, const gbtre
 	OffsetNumber i,
 				maxoff = entryvec->n - 1;
 	Vsrt	   *arr;
-	int			pfrcntr = 0,
-				svcntr = 0,
+	int			svcntr = 0,
 				nbytes;
-	char	   *tst,
-			   *cur;
-	char	  **pfr = NULL;
+	char	   *cur;
 	GBT_VARKEY **sv = NULL;
 
 	arr = (Vsrt *) palloc((maxoff + 1) * sizeof(Vsrt));
@@ -483,7 +478,6 @@ gbt_var_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v, const gbtre
 	v->spl_nleft = 0;
 	v->spl_nright = 0;
 
-	pfr = palloc(sizeof(GBT_VARKEY *) * (maxoff + 1));
 	sv = palloc(sizeof(bytea *) * (maxoff + 1));
 
 	/* Sort entries */
@@ -492,13 +486,7 @@ gbt_var_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v, const gbtre
 	{
 		GBT_VARKEY_R ro;
 
-		tst = (char *) DatumGetPointer((entryvec->vector[i].key));
-		cur = (char *) DatumGetPointer(PG_DETOAST_DATUM((entryvec->vector[i].key)));
-		if (tst != cur)
-		{
-			pfr[pfrcntr] = cur;
-			pfrcntr++;
-		}
+		cur = (char *) DatumGetPointer(entryvec->vector[i].key);
 		ro = gbt_var_key_readable((GBT_VARKEY *) cur);
 		if (ro.lower == ro.upper)		/* leaf */
 		{
@@ -537,17 +525,10 @@ gbt_var_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v, const gbtre
 		}
 	}
 
-	/* Free detoasted keys */
-	for (i = 0; i < pfrcntr; i++)
-		pfree(pfr[i]);
-
 	/* Free strxfrm'ed leafs */
 	for (i = 0; i < svcntr; i++)
 		pfree(sv[i]);
 
-	if (pfr)
-		pfree(pfr);
-
 	if (sv)
 		pfree(sv);