diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
new file mode 100644
index e08bf60..e417c5b
*** a/doc/src/sgml/func.sgml
--- b/doc/src/sgml/func.sgml
***************
*** 782,787 ****
--- 782,800 ----
        <row>
         <entry>
          <indexterm>
+          <primary>numeric_trim</primary>
+         </indexterm>
+         <literal><function>numeric_trim(<type>numeric</type>)</function></literal>
+        </entry>
+        <entry><type>numeric</type></entry>
+        <entry>remove trailing decimal zeroes after the decimal point</entry>
+        <entry><literal>numeric_trim(8.4100)</literal></entry>
+        <entry><literal>8.41</literal></entry>
+       </row>
+ 
+       <row>
+        <entry>
+         <indexterm>
           <primary>pi</primary>
          </indexterm>
          <literal><function>pi()</function></literal>
diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c
new file mode 100644
index fa93a8c..2f62dc2
*** a/src/backend/utils/adt/numeric.c
--- b/src/backend/utils/adt/numeric.c
*************** numeric_power(PG_FUNCTION_ARGS)
*** 2825,2830 ****
--- 2825,2907 ----
  	PG_RETURN_NUMERIC(res);
  }
  
+ /*
+  * numeric_trim() -
+  *
+  *	Remove trailing decimal zeroes after the decimal point
+  */
+ Datum
+ numeric_trim(PG_FUNCTION_ARGS)
+ {
+ 	Numeric		num = PG_GETARG_NUMERIC(0);
+ 	NumericVar	arg;
+ 	Numeric		res;
+ 	int dscale;
+ 	int ndigits;
+ 
+ 	if (NUMERIC_IS_NAN(num))
+ 		PG_RETURN_NUMERIC(make_result(&const_nan));
+ 
+ 	init_var_from_num(num, &arg);
+ 
+ 	ndigits = arg.ndigits;
+ 
+ 	/* for simplicity in the loop below, do full NBASE digits at a time */
+ 	dscale = ((arg.dscale + DEC_DIGITS - 1) / DEC_DIGITS) * DEC_DIGITS;
+ 
+ 	/* trim unstored significant trailing zeroes right away */
+ 	if (dscale > (ndigits - arg.weight - 1) * DEC_DIGITS)
+ 		dscale = (ndigits - arg.weight - 1) * DEC_DIGITS;
+ 
+ 	while (dscale > 0 && ndigits > 0)
+ 	{
+ 		NumericDigit dig = arg.digits[ndigits - 1];
+ 
+ #if DEC_DIGITS == 4
+ 		if ((dig % 10) != 0)
+ 			break;
+ 		if (--dscale == 0)
+ 			break;
+ 		if ((dig % 100) != 0)
+ 			break;
+ 		if (--dscale == 0)
+ 			break;
+ 		if ((dig % 1000) != 0)
+ 			break;
+ 		if (--dscale == 0)
+ 			break;
+ #elif DEC_DIGITS == 2
+ 		if ((dig % 10) != 0)
+ 			break;
+ 		if (--dscale == 0)
+ 			break;
+ #elif DEC_DIGITS == 1
+ 		/* nothing to do */
+ #else
+ #error unsupported NBASE
+ #endif
+ 		if (dig != 0)
+ 			break;
+ 		--dscale;
+ 		--ndigits;
+ 	}
+ 	arg.dscale = dscale;
+ 	arg.ndigits = ndigits;
+ 
+ 	/* If it's zero, normalize the sign and weight */
+ 	if (ndigits == 0)
+ 	{
+ 		arg.sign = NUMERIC_POS;
+ 		arg.weight = 0;
+ 		arg.dscale = 0;
+ 	}
+ 
+ 	res = make_result(&arg);
+ 	free_var(&arg);
+ 
+ 	PG_RETURN_NUMERIC(res);
+ }
+ 
  
  /* ----------------------------------------------------------------------
   *
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
new file mode 100644
index d8640db..c8240cd
*** a/src/include/catalog/pg_proc.h
--- b/src/include/catalog/pg_proc.h
*************** DESCR("exponentiation");
*** 2361,2366 ****
--- 2361,2368 ----
  DATA(insert OID = 2169 ( power					PGNSP PGUID 12 1 0 0 0 f f f f t f i s 2 0 1700 "1700 1700" _null_ _null_ _null_ _null_ _null_	numeric_power _null_ _null_ _null_ ));
  DESCR("exponentiation");
  DATA(insert OID = 1739 ( numeric_power			PGNSP PGUID 12 1 0 0 0 f f f f t f i s 2 0 1700 "1700 1700" _null_ _null_ _null_ _null_ _null_	numeric_power _null_ _null_ _null_ ));
+ DATA(insert OID = 8888 ( numeric_trim			PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 1700 "1700" _null_ _null_ _null_ _null_ _null_	numeric_trim _null_ _null_ _null_ ));
+ DESCR("remove trailing decimal zeroes after the decimal point");
  DATA(insert OID = 1740 ( numeric				PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 1700 "23" _null_ _null_ _null_ _null_ _null_ int4_numeric _null_ _null_ _null_ ));
  DESCR("convert int4 to numeric");
  DATA(insert OID = 1741 ( log					PGNSP PGUID 14 1 0 0 0 f f f f t f i s 1 0 1700 "1700" _null_ _null_ _null_ _null_ _null_ "select pg_catalog.log(10, $1)" _null_ _null_ _null_ ));
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
new file mode 100644
index e610bf3..ac0cb8b
*** a/src/include/utils/builtins.h
--- b/src/include/utils/builtins.h
*************** extern Datum numeric_exp(PG_FUNCTION_ARG
*** 1022,1027 ****
--- 1022,1028 ----
  extern Datum numeric_ln(PG_FUNCTION_ARGS);
  extern Datum numeric_log(PG_FUNCTION_ARGS);
  extern Datum numeric_power(PG_FUNCTION_ARGS);
+ extern Datum numeric_trim(PG_FUNCTION_ARGS);
  extern Datum int4_numeric(PG_FUNCTION_ARGS);
  extern Datum numeric_int4(PG_FUNCTION_ARGS);
  extern Datum int8_numeric(PG_FUNCTION_ARGS);
diff --git a/src/test/regress/expected/numeric.out b/src/test/regress/expected/numeric.out
new file mode 100644
index caac424..e99cee0
*** a/src/test/regress/expected/numeric.out
--- b/src/test/regress/expected/numeric.out
*************** select log(3.1954752e47, 9.4792021e-73);
*** 1852,1854 ****
--- 1852,2013 ----
   -1.51613372350688302142917386143459361608600157692779164475351842333265418126982165
  (1 row)
  
+ --
+ -- Tests for numeric_trim()
+ --
+ select numeric_trim('NaN');
+  numeric_trim 
+ --------------
+           NaN
+ (1 row)
+ 
+ select numeric_trim('0');
+  numeric_trim 
+ --------------
+             0
+ (1 row)
+ 
+ select numeric_trim('0.0');
+  numeric_trim 
+ --------------
+             0
+ (1 row)
+ 
+ select numeric_trim('0.0000000000000000000000');
+  numeric_trim 
+ --------------
+             0
+ (1 row)
+ 
+ select numeric_trim('1.0');
+  numeric_trim 
+ --------------
+             1
+ (1 row)
+ 
+ select numeric_trim('1.00');
+  numeric_trim 
+ --------------
+             1
+ (1 row)
+ 
+ select numeric_trim('1.00000');
+  numeric_trim 
+ --------------
+             1
+ (1 row)
+ 
+ select numeric_trim('1.1');
+  numeric_trim 
+ --------------
+           1.1
+ (1 row)
+ 
+ select numeric_trim('1.11');
+  numeric_trim 
+ --------------
+          1.11
+ (1 row)
+ 
+ select numeric_trim('1.111');
+  numeric_trim 
+ --------------
+         1.111
+ (1 row)
+ 
+ select numeric_trim('1.1111');
+  numeric_trim 
+ --------------
+        1.1111
+ (1 row)
+ 
+ select numeric_trim('1.11111');
+  numeric_trim 
+ --------------
+       1.11111
+ (1 row)
+ 
+ select numeric_trim('1.010');
+  numeric_trim 
+ --------------
+          1.01
+ (1 row)
+ 
+ select numeric_trim('1.0010');
+  numeric_trim 
+ --------------
+         1.001
+ (1 row)
+ 
+ select numeric_trim('1.00010');
+  numeric_trim 
+ --------------
+        1.0001
+ (1 row)
+ 
+ select numeric_trim('1.000010');
+  numeric_trim 
+ --------------
+       1.00001
+ (1 row)
+ 
+ select numeric_trim('1.00001000000');
+  numeric_trim 
+ --------------
+       1.00001
+ (1 row)
+ 
+ select numeric_trim('1.001000000');
+  numeric_trim 
+ --------------
+         1.001
+ (1 row)
+ 
+ select numeric_trim('5124124800.10');
+  numeric_trim 
+ --------------
+  5124124800.1
+ (1 row)
+ 
+ select numeric_trim('5124124800.010');
+  numeric_trim  
+ ---------------
+  5124124800.01
+ (1 row)
+ 
+ select numeric_trim('5124124800.0010');
+   numeric_trim  
+ ----------------
+  5124124800.001
+ (1 row)
+ 
+ select numeric_trim('5124124800.00010');
+   numeric_trim   
+ -----------------
+  5124124800.0001
+ (1 row)
+ 
+ select numeric_trim('5124124800.000010');
+    numeric_trim   
+ ------------------
+  5124124800.00001
+ (1 row)
+ 
+ select numeric_trim('5124124800.0000010');
+    numeric_trim    
+ -------------------
+  5124124800.000001
+ (1 row)
+ 
+ select numeric_trim('5124124800.00000100000000000');
+    numeric_trim    
+ -------------------
+  5124124800.000001
+ (1 row)
+ 
+ select numeric_trim('5124124800.00100000000000');
+   numeric_trim  
+ ----------------
+  5124124800.001
+ (1 row)
+ 
diff --git a/src/test/regress/sql/numeric.sql b/src/test/regress/sql/numeric.sql
new file mode 100644
index 0a4d1cb..c545666
*** a/src/test/regress/sql/numeric.sql
--- b/src/test/regress/sql/numeric.sql
*************** select log(1.23e-89, 6.4689e45);
*** 983,985 ****
--- 983,1017 ----
  select log(0.99923, 4.58934e34);
  select log(1.000016, 8.452010e18);
  select log(3.1954752e47, 9.4792021e-73);
+ 
+ 
+ --
+ -- Tests for numeric_trim()
+ --
+ 
+ select numeric_trim('NaN');
+ select numeric_trim('0');
+ select numeric_trim('0.0');
+ select numeric_trim('0.0000000000000000000000');
+ select numeric_trim('1.0');
+ select numeric_trim('1.00');
+ select numeric_trim('1.00000');
+ select numeric_trim('1.1');
+ select numeric_trim('1.11');
+ select numeric_trim('1.111');
+ select numeric_trim('1.1111');
+ select numeric_trim('1.11111');
+ select numeric_trim('1.010');
+ select numeric_trim('1.0010');
+ select numeric_trim('1.00010');
+ select numeric_trim('1.000010');
+ select numeric_trim('1.00001000000');
+ select numeric_trim('1.001000000');
+ select numeric_trim('5124124800.10');
+ select numeric_trim('5124124800.010');
+ select numeric_trim('5124124800.0010');
+ select numeric_trim('5124124800.00010');
+ select numeric_trim('5124124800.000010');
+ select numeric_trim('5124124800.0000010');
+ select numeric_trim('5124124800.00000100000000000');
+ select numeric_trim('5124124800.00100000000000');
