diff -uNr b/src/backend/commands/tablecmds.c a/src/backend/commands/tablecmds.c
--- b/src/backend/commands/tablecmds.c	2013-08-31 17:11:00.529744869 +0800
+++ a/src/backend/commands/tablecmds.c	2013-09-16 16:33:49.527455560 +0800
@@ -367,7 +367,10 @@
 					  AlteredTableInfo *tab, Relation rel,
 					  bool recurse, bool recursing,
 					  AlterTableCmd *cmd, LOCKMODE lockmode);
-static bool ATColumnChangeRequiresRewrite(Node *expr, AttrNumber varattno);
+static void ATNumericColumnChangeRequiresCheck(AlteredTableInfo *tab);
+static bool ATColumnChangeRequiresRewrite(Node *expr, AttrNumber varattno,
+					int32 oldtypemod, int32 newtypemod,
+							AlteredTableInfo *tab);
 static void ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
 					  AlterTableCmd *cmd, LOCKMODE lockmode);
 static void ATExecAlterColumnGenericOptions(Relation rel, const char *colName,
@@ -7480,7 +7483,7 @@
 		newval->expr = (Expr *) transform;
 
 		tab->newvals = lappend(tab->newvals, newval);
-		if (ATColumnChangeRequiresRewrite(transform, attnum))
+		if (ATColumnChangeRequiresRewrite(transform, attnum, attTup->atttypmod, targettypmod, tab))
 			tab->rewrite = true;
 	}
 	else if (transform)
@@ -7520,6 +7523,102 @@
 }
 
 /*
+ * check the data when the scale of numeric increase
+ */
+
+static void
+ATNumericColumnChangeRequiresCheck(AlteredTableInfo *tab)
+{
+	Relation	oldrel;
+	TupleDesc	oldTupDesc;
+	int			i;
+	ListCell   *l;
+	EState	   *estate;
+	ExprContext *econtext;
+	bool	   *isnull;
+	TupleTableSlot *oldslot;
+	HeapScanDesc scan;
+	HeapTuple	tuple;
+	Snapshot	snapshot;
+	List	   *dropped_attrs = NIL;
+	ListCell   *lc;
+	Datum	   *values;
+
+	/*
+	 * Open the relation(s).  We have surely already locked the existing
+	 * table.
+	 */
+
+	oldrel = heap_open(tab->relid, NoLock);
+	oldTupDesc = tab->oldDesc;
+
+	for (i = 0; i < oldTupDesc->natts; i++)
+	{
+		if (oldTupDesc->attrs[i]->attisdropped)
+			dropped_attrs = lappend_int(dropped_attrs, i);
+	}
+	/*
+	 * Generate the constraint and default execution states
+	 */
+
+	estate = CreateExecutorState();	
+
+	foreach(l, tab->newvals)
+	{
+		NewColumnValue *ex = lfirst(l);
+
+		/* expr already planned */
+		ex->exprstate = ExecInitExpr((Expr *) ex->expr, NULL);
+	}
+
+	econtext = GetPerTupleExprContext(estate);
+	oldslot = MakeSingleTupleTableSlot(oldTupDesc);
+	
+	/* Preallocate values/isnull arrays */
+	i = oldTupDesc->natts;
+	values = (Datum *) palloc(i * sizeof(Datum));
+	isnull = (bool *) palloc(i * sizeof(bool));
+	memset(values, 0, i * sizeof(Datum));
+	memset(isnull, true, i * sizeof(bool));
+
+	/*
+	 * Scan through the rows, generating a new row if needed and then
+	 * checking all the constraints.
+	 */
+	snapshot = RegisterSnapshot(GetLatestSnapshot());
+	scan = heap_beginscan(oldrel, snapshot, 0, NULL);
+	while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
+	{
+		foreach(lc, dropped_attrs)
+			isnull[lfirst_int(lc)] = true;
+
+		heap_deform_tuple(tuple, oldTupDesc, values, isnull);
+		ExecStoreTuple(tuple, oldslot, InvalidBuffer, false);
+		econtext->ecxt_scantuple = oldslot;
+
+		foreach(l, tab->newvals)
+		{
+			
+			NewColumnValue *ex = lfirst(l);
+
+			ExecEvalExpr(ex->exprstate, econtext, 
+						&isnull[ex->attnum - 1], NULL);
+		}
+
+		CHECK_FOR_INTERRUPTS();
+	}
+	heap_endscan(scan);
+
+	UnregisterSnapshot(snapshot);
+
+	ExecDropSingleTupleTableSlot(oldslot);
+
+	FreeExecutorState(estate);
+
+	heap_close(oldrel, NoLock);
+}
+
+/*
  * When the data type of a column is changed, a rewrite might not be required
  * if the new type is sufficiently identical to the old one, and the USING
  * clause isn't trying to insert some other value.  It's safe to skip the
@@ -7530,7 +7629,9 @@
  * try to do that.
  */
 static bool
-ATColumnChangeRequiresRewrite(Node *expr, AttrNumber varattno)
+ATColumnChangeRequiresRewrite(Node *expr, AttrNumber varattno,
+					int32 oldtypemod, int32 newtypemod,
+							AlteredTableInfo *tab)
 {
 	Assert(expr != NULL);
 
@@ -7549,6 +7650,21 @@
 				return true;
 			expr = (Node *) d->arg;
 		}
+		else if (IsA(expr, FuncExpr))
+		{
+			int32	between = 0;
+
+			if(((FuncExpr *) expr)->funcresulttype == 1700 && ((FuncExpr *) expr)->funcid == 1703)
+				between = newtypemod - oldtypemod;
+
+			if(between > 0 && between < 1001)
+			{
+				ATNumericColumnChangeRequiresCheck(tab);
+				return false;
+			}
+			else
+				return true;
+		}
 		else
 			return true;
 	}
