diff --git a/src/backend/utils/adt/varbit.c b/src/backend/utils/adt/varbit.c
index adb08369ed28ab6b52aa2cd5213bcd5b4d8de7ad..1227e5a5082b03ba89100b2f7218e9368ab6a1d4 100644
--- a/src/backend/utils/adt/varbit.c
+++ b/src/backend/utils/adt/varbit.c
@@ -18,6 +18,8 @@
 
 #include "access/htup.h"
 #include "libpq/pqformat.h"
+#include "nodes/nodeFuncs.h"
+#include "parser/parse_clause.h"
 #include "utils/array.h"
 #include "utils/varbit.h"
 
@@ -645,6 +647,39 @@ varbit_send(PG_FUNCTION_ARGS)
 	PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
 }
 
+/*
+ * varbit_transform()
+ * Flatten calls to our length coercion function that leave the new maximum
+ * length >= the previous maximum length.  We ignore the isExplicit argument,
+ * which only affects truncation.
+ */
+Datum
+varbit_transform(PG_FUNCTION_ARGS)
+{
+	FuncExpr   *expr = (FuncExpr *) PG_GETARG_POINTER(0);
+	Node	   *typmod;
+	Node	   *ret = NULL;
+
+	if (!IsA(expr, FuncExpr))
+		PG_RETURN_POINTER(ret);
+
+	Assert(list_length(expr->args) == 3);
+	typmod = lsecond(expr->args);
+
+	if (IsA(typmod, Const))
+	{
+		Node	   *source = linitial(expr->args);
+		int32		new_typmod = DatumGetInt32(((Const *) typmod)->constvalue);
+		int32		old_max = exprTypmod(source);
+		int32		new_max = new_typmod;
+
+		if (new_max <= 0 || (old_max >= 0 && old_max <= new_max))
+			ret = relabel_to_typmod(source, new_typmod);
+	}
+
+	PG_RETURN_POINTER(ret);
+}
+
 /*
  * varbit()
  * Converts a varbit() type to a specific internal length.
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index a748c5e623ec78a2e8bbbacd9e98786e28446dda..ae4e5f5ae6b5fce71dfa2cd5a8c772664f01ee54 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -53,6 +53,6 @@
  */
 
 /*							yyyymmddN */
-#define CATALOG_VERSION_NO	201202071
+#define CATALOG_VERSION_NO	201202072
 
 #endif
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 006ed171824bb788192fdb22b15edba1c2a09764..f8d01fbba49de0b31ad62997e7861ab3e87ba529 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -2009,7 +2009,9 @@ DESCR("convert bitstring to int4");
 
 DATA(insert OID = 1685 (  bit			   PGNSP PGUID 12 1 0 0 0 f f f t f i 3 0 1560 "1560 23 16" _null_ _null_ _null_ _null_ bit _null_ _null_ _null_ ));
 DESCR("adjust bit() to typmod length");
-DATA(insert OID = 1687 (  varbit		   PGNSP PGUID 12 1 0 0 0 f f f t f i 3 0 1562 "1562 23 16" _null_ _null_ _null_ _null_ varbit _null_ _null_ _null_ ));
+DATA(insert OID = 3158 ( varbit_transform  PGNSP PGUID 12 1 0 0 0 f f f t f i 1 0 2281 "2281" _null_ _null_ _null_ _null_ varbit_transform _null_ _null_ _null_ ));
+DESCR("transform a varbit length coercion");
+DATA(insert OID = 1687 (  varbit		   PGNSP PGUID 12 1 0 0 3158 f f f t f i 3 0 1562 "1562 23 16" _null_ _null_ _null_ _null_ varbit _null_ _null_ _null_ ));
 DESCR("adjust varbit() to typmod length");
 
 DATA(insert OID = 1698 (  position		   PGNSP PGUID 12 1 0 0 0 f f f t f i 2 0 23 "1560 1560" _null_ _null_ _null_ _null_ bitposition _null_ _null_ _null_ ));
diff --git a/src/include/utils/varbit.h b/src/include/utils/varbit.h
index f268ca5853defea4b680731085d944c9dabd150b..52dca8b5d293ab3d50c123e369ce9797cbd1840f 100644
--- a/src/include/utils/varbit.h
+++ b/src/include/utils/varbit.h
@@ -72,6 +72,7 @@ extern Datum varbit_send(PG_FUNCTION_ARGS);
 extern Datum varbittypmodin(PG_FUNCTION_ARGS);
 extern Datum varbittypmodout(PG_FUNCTION_ARGS);
 extern Datum bit(PG_FUNCTION_ARGS);
+extern Datum varbit_transform(PG_FUNCTION_ARGS);
 extern Datum varbit(PG_FUNCTION_ARGS);
 extern Datum biteq(PG_FUNCTION_ARGS);
 extern Datum bitne(PG_FUNCTION_ARGS);