diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index fbef91b35d8006b8d28739c65811b0ea5f9faa49..601b503ec114a50eae39d23ad5103c2e07156f97 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.107 2000/02/20 21:32:05 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.108 2000/02/21 18:47:00 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1501,14 +1501,12 @@ _copyValue(Value *from)
 	newnode->type = from->type;
 	switch (from->type)
 	{
-		case T_String:
-			newnode->val.str = pstrdup(from->val.str);
-			break;
 		case T_Integer:
 			newnode->val.ival = from->val.ival;
 			break;
 		case T_Float:
-			newnode->val.dval = from->val.dval;
+		case T_String:
+			newnode->val.str = pstrdup(from->val.str);
 			break;
 		default:
 			break;
@@ -1722,8 +1720,8 @@ copyObject(void *from)
 			 * VALUE NODES
 			 */
 		case T_Integer:
-		case T_String:
 		case T_Float:
+		case T_String:
 			retval = _copyValue(from);
 			break;
 		case T_List:
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index b4f5fc6285c2ba77e296d151014bd358350f1c6c..6cb9eada0f8a6c937c0578d04da98b66821923de 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.62 2000/02/20 21:32:05 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.63 2000/02/21 18:47:00 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -737,12 +737,11 @@ _equalValue(Value *a, Value *b)
 
 	switch (a->type)
 	{
-		case T_String:
-			return strcmp(a->val.str, b->val.str);
 		case T_Integer:
 			return a->val.ival == b->val.ival;
 		case T_Float:
-			return a->val.dval == b->val.dval;
+		case T_String:
+			return strcmp(a->val.str, b->val.str) == 0;
 		default:
 			break;
 	}
@@ -870,8 +869,8 @@ equal(void *a, void *b)
 			retval = _equalEState(a, b);
 			break;
 		case T_Integer:
-		case T_String:
 		case T_Float:
+		case T_String:
 			retval = _equalValue(a, b);
 			break;
 		case T_List:
diff --git a/src/backend/nodes/freefuncs.c b/src/backend/nodes/freefuncs.c
index daca4a6d96a18230f27010f93b76434ed531edc2..14a5ed12d9e90d9ed4c06597b0c28918216b454f 100644
--- a/src/backend/nodes/freefuncs.c
+++ b/src/backend/nodes/freefuncs.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/nodes/Attic/freefuncs.c,v 1.37 2000/02/20 21:32:05 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/nodes/Attic/freefuncs.c,v 1.38 2000/02/21 18:47:00 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1130,7 +1130,8 @@ _freeValue(Value *node)
 {
 	switch (node->type)
 	{
-			case T_String:
+		case T_Float:
+		case T_String:
 			pfree(node->val.str);
 			break;
 		default:
@@ -1345,8 +1346,8 @@ freeObject(void *node)
 			 * VALUE NODES
 			 */
 		case T_Integer:
-		case T_String:
 		case T_Float:
+		case T_String:
 			_freeValue(node);
 			break;
 		case T_List:
diff --git a/src/backend/nodes/list.c b/src/backend/nodes/list.c
index 723930f36a8f0011b29d82a80863750f0cf64fe6..a47851f2420b8b066c5b23ea706658453b08dbb6 100644
--- a/src/backend/nodes/list.c
+++ b/src/backend/nodes/list.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.29 2000/02/06 03:27:32 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.30 2000/02/21 18:47:00 tgl Exp $
  *
  * NOTES
  *	  XXX a few of the following functions are duplicated to handle
@@ -73,19 +73,23 @@ makeInteger(long i)
 
 /*
  *	makeFloat
+ *
+ * Caller is responsible for passing a palloc'd string.
  */
 Value *
-makeFloat(double d)
+makeFloat(char *numericStr)
 {
 	Value	   *v = makeNode(Value);
 
 	v->type = T_Float;
-	v->val.dval = d;
+	v->val.str = numericStr;
 	return v;
 }
 
 /*
  *	makeString
+ *
+ * Caller is responsible for passing a palloc'd string.
  */
 Value *
 makeString(char *str)
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index db785afab9fa9ea4a91ef279d32eb18f3a29c815..eb2c1a7ffa8528b50243a5738aca739e90dc95aa 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- *	$Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.109 2000/02/20 21:32:05 tgl Exp $
+ *	$Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.110 2000/02/21 18:47:00 tgl Exp $
  *
  * NOTES
  *	  Every (plan) node in POSTGRES has an associated "out" routine which
@@ -1265,16 +1265,19 @@ _outValue(StringInfo str, Value *value)
 {
 	switch (value->type)
 	{
-		case T_String:
-			appendStringInfo(str, " \"");
-			_outToken(str, value->val.str);
-			appendStringInfo(str, "\" ");
-			break;
 		case T_Integer:
 			appendStringInfo(str, " %ld ", value->val.ival);
 			break;
 		case T_Float:
-			appendStringInfo(str, " %.17g ", value->val.dval);
+			/* We assume the value is a valid numeric literal
+			 * and so does not need quoting.
+			 */
+			appendStringInfo(str, " %s ", value->val.str);
+			break;
+		case T_String:
+			appendStringInfo(str, " \"");
+			_outToken(str, value->val.str);
+			appendStringInfo(str, "\" ");
 			break;
 		default:
 			elog(NOTICE, "_outValue: don't know how to print type %d ",
diff --git a/src/backend/nodes/read.c b/src/backend/nodes/read.c
index 75e10576d5b5fa30b3726d9a133b0656b2a6a852..9f68f4d0e90892e52f5062dbd1ab94b31170c051 100644
--- a/src/backend/nodes/read.c
+++ b/src/backend/nodes/read.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/nodes/read.c,v 1.20 2000/01/26 05:56:32 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/nodes/read.c,v 1.21 2000/02/21 18:47:00 tgl Exp $
  *
  * HISTORY
  *	  AUTHOR			DATE			MAJOR EVENT
@@ -18,6 +18,7 @@
  *-------------------------------------------------------------------------
  */
 #include <ctype.h>
+#include <errno.h>
 
 #include "postgres.h"
 
@@ -193,30 +194,32 @@ static NodeTag
 nodeTokenType(char *token, int length)
 {
 	NodeTag		retval;
+	char	   *numptr;
+	int			numlen;
+	char	   *endptr;
 
 	/*
-	 * Check if the token is a number (decimal or integer, positive or
-	 * negative)
+	 * Check if the token is a number
 	 */
-	if (isdigit(*token) ||
-		(length >= 2 && *token == '-' && isdigit(token[1])))
+	numptr = token;
+	numlen = length;
+	if (*numptr == '+' || *numptr == '-')
+		numptr++, numlen--;
+	if ((numlen > 0 && isdigit(*numptr)) ||
+		(numlen > 1 && *numptr == '.' && isdigit(numptr[1])))
 	{
 		/*
-		 * skip the optional '-' (i.e. negative number)
+		 * Yes.  Figure out whether it is integral or float;
+		 * this requires both a syntax check and a range check.
+		 * strtol() can do both for us.
+		 * We know the token will end at a character that strtol will
+		 * stop at, so we do not need to modify the string.
 		 */
-		if (*token == '-')
-			token++, length--;
-
-		/*
-		 * See if there is a decimal point
-		 */
-		while (length > 0 && *token != '.')
-			token++, length--;
-
-		/*
-		 * if there isn't, token's an int, otherwise it's a float.
-		 */
-		retval = (*token != '.') ? T_Integer : T_Float;
+		errno = 0;
+		(void) strtol(token, &endptr, 10);
+		if (endptr != token+length || errno == ERANGE)
+			return T_Float;
+		return T_Integer;
 	}
 	/*
 	 * these three cases do not need length checks, since lsptok()
@@ -317,17 +320,23 @@ nodeRead(bool read_car_only)
 				make_dotted_pair_cell = true;
 			}
 			break;
-		case T_Float:
-			/* we know that the token terminates on a char atof will stop at */
-			this_value = (Node *) makeFloat(atof(token));
-			make_dotted_pair_cell = true;
-			break;
 		case T_Integer:
-			/* we know that the token terminates on a char atoi will stop at */
-			this_value = (Node *) makeInteger(atoi(token));
+			/* we know that the token terminates on a char atol will stop at */
+			this_value = (Node *) makeInteger(atol(token));
 			make_dotted_pair_cell = true;
 			break;
+		case T_Float:
+			{
+				char   *fval = (char *) palloc(tok_len + 1);
+
+				memcpy(fval, token, tok_len);
+				fval[tok_len] = '\0';
+				this_value = (Node *) makeFloat(fval);
+				make_dotted_pair_cell = true;
+			}
+			break;
 		case T_String:
+			/* need to remove leading and trailing quotes, and backslashes */
 			this_value = (Node *) makeString(debackslash(token+1, tok_len-2));
 			make_dotted_pair_cell = true;
 			break;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index f43393eeff872ca2477bf96c42336f264cd5e7fa..b81b6d387aba6c8dd7d48e57843abdd364ede543 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.147 2000/02/20 02:14:58 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.148 2000/02/21 18:47:02 tgl Exp $
  *
  * HISTORY
  *	  AUTHOR			DATE			MAJOR EVENT
@@ -78,6 +78,7 @@ static Node *makeRowExpr(char *opr, List *largs, List *rargs);
 static void mapTargetColumns(List *source, List *target);
 static void param_type_init(Oid *typev, int nargs);
 static Node *doNegate(Node *n);
+static void doNegateFloat(Value *v);
 
 /* old versions of flex define this as a macro */
 #if defined(yywrap)
@@ -88,7 +89,6 @@ static Node *doNegate(Node *n);
 
 %union
 {
-	double				dval;
 	int					ival;
 	char				chr;
 	char				*str;
@@ -352,9 +352,8 @@ static Node *doNegate(Node *n);
 		UNLISTEN, UNTIL, VACUUM, VALID, VERBOSE, VERSION
 
 /* Special keywords, not in the query language - see the "lex" file */
-%token <str>	IDENT, SCONST, Op
+%token <str>	IDENT, FCONST, SCONST, Op
 %token <ival>	ICONST, PARAM
-%token <dval>	FCONST
 
 /* these are not real. they are here so that they get generated as #define's*/
 %token			OP
@@ -1567,7 +1566,7 @@ FloatOnly:  FCONST
 			| '-' FCONST
 				{
 					$$ = makeFloat($2);
-					$$->val.dval = - $$->val.dval;
+					doNegateFloat($$);
 				}
 		;
 
@@ -1722,16 +1721,11 @@ TriggerFuncArgs:  TriggerFuncArg
 
 TriggerFuncArg:  ICONST
 				{
-					char *s = (char *) palloc (256);
+					char *s = (char *) palloc(64);
 					sprintf (s, "%d", $1);
 					$$ = s;
 				}
-			| FCONST
-				{
-					char *s = (char *) palloc (256);
-					sprintf (s, "%g", $1);
-					$$ = s;
-				}
+			| FCONST						{  $$ = $1; }
 			| Sconst						{  $$ = $1; }
 			| IDENT							{  $$ = $1; }
 		;
@@ -5183,7 +5177,7 @@ AexprConst:  Iconst
 				{
 					A_Const *n = makeNode(A_Const);
 					n->val.type = T_Float;
-					n->val.val.dval = $1;
+					n->val.val.str = $1;
 					$$ = (Node *)n;
 				}
 		| Sconst
@@ -5621,7 +5615,8 @@ Oid param_type(int t)
  *	a few cycles throughout the parse and rewrite stages if we collapse
  *	the minus into the constant sooner rather than later...
  */
-static Node *doNegate(Node *n)
+static Node *
+doNegate(Node *n)
 {
 	if (IsA(n, A_Const))
 	{
@@ -5634,10 +5629,30 @@ static Node *doNegate(Node *n)
 		}
 		if (con->val.type == T_Float)
 		{
-			con->val.val.dval = -con->val.val.dval;
+			doNegateFloat(&con->val);
 			return n;
 		}
 	}
 
 	return makeA_Expr(OP, "-", NULL, n);
 }
+
+static void
+doNegateFloat(Value *v)
+{
+	char   *oldval = v->val.str;
+
+	Assert(IsA(v, Float));
+	if (*oldval == '+')
+		oldval++;
+	if (*oldval == '-')
+		v->val.str = oldval;	/* just strip the '-' */
+	else
+	{
+		char   *newval = (char *) palloc(strlen(oldval) + 2);
+
+		*newval = '-';
+		strcpy(newval+1, oldval);
+		v->val.str = newval;
+	}
+}
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 3fd3370672ff40db0af42520cb4f3360c516fb92..2efdd136005ce3a181bd6685f40ee7b49950eeda 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.69 2000/02/20 21:32:10 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.70 2000/02/21 18:47:02 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -726,23 +726,19 @@ parser_typecast_constant(Value *expr, TypeName *typename)
 
 	switch (nodeTag(expr))
 	{
-		case T_String:
-			const_string = DatumGetPointer(expr->val.str);
-			break;
 		case T_Integer:
 			string_palloced = true;
 			const_string = int4out(expr->val.ival);
 			break;
 		case T_Float:
-			string_palloced = true;
-			const_string = float8out(&expr->val.dval);
+		case T_String:
+			const_string = expr->val.str;
 			break;
 		case T_Null:
 			isNull = true;
 			break;
 		default:
-			elog(ERROR,
-				 "Cannot cast this expression to type '%s'",
+			elog(ERROR, "Cannot cast this expression to type '%s'",
 				 typename->name);
 	}
 
diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l
index fa3408c1f1df79e28ff1660cfde624e1d48af8eb..5b8dd16d81f93324a00d781095942471d62404dc 100644
--- a/src/backend/parser/scan.l
+++ b/src/backend/parser/scan.l
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/scan.l,v 1.64 2000/02/19 04:17:25 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/scan.l,v 1.65 2000/02/21 18:47:02 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -324,7 +324,7 @@ other			.
 				}
 
 {param}			{
-					yylval.ival = atoi((char*)&yytext[1]);
+					yylval.ival = atol((char*)&yytext[1]);
 					return PARAM;
 				}
 
@@ -332,46 +332,21 @@ other			.
 					char* endptr;
 
 					errno = 0;
-					yylval.ival = strtol((char *)yytext,&endptr,10);
+					yylval.ival = strtol((char *)yytext, &endptr, 10);
 					if (*endptr != '\0' || errno == ERANGE)
 					{
-						errno = 0;
-#if 0
-						yylval.dval = strtod(((char *)yytext),&endptr);
-						if (*endptr != '\0' || errno == ERANGE)
-							elog(ERROR,"Bad integer input '%s'",yytext);
-						CheckFloat8Val(yylval.dval);
-						elog(NOTICE,"Integer input '%s' is out of range; promoted to float", yytext);
-						return FCONST;
-#endif
+						/* integer too large, treat it as a float */
 						yylval.str = pstrdup((char*)yytext);
-						return SCONST;
+						return FCONST;
 					}
 					return ICONST;
 				}
 {decimal}		{
-					char* endptr;
-
-					if (strlen((char *)yytext) <= 17)
-					{
-						errno = 0;
-						yylval.dval = strtod((char *)yytext,&endptr);
-						if (*endptr != '\0' || errno == ERANGE)
-							elog(ERROR,"Bad float input '%s'",yytext);
-						CheckFloat8Val(yylval.dval);
-						return FCONST;
-					}
 					yylval.str = pstrdup((char*)yytext);
-					return SCONST;
+					return FCONST;
 				}
 {real}			{
-					char* endptr;
-
-					errno = 0;
-					yylval.dval = strtod((char *)yytext,&endptr);
-					if (*endptr != '\0' || errno == ERANGE)
-						elog(ERROR,"Bad float input '%s'",yytext);
-					CheckFloat8Val(yylval.dval);
+					yylval.str = pstrdup((char*)yytext);
 					return FCONST;
 				}
 
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index d6120affabefda8efdcedbb5747e3f0f1e360619..f5d613233101ab2ac8e7458264cb345960d9bd98 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.73 2000/02/17 05:00:38 inoue Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.74 2000/02/21 18:47:03 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -453,6 +453,7 @@ BufferAlloc(Relation reln,
 		 */
 		Assert(buf->refcount == 0);
 		buf->refcount = 1;
+		Assert(PrivateRefCount[BufferDescriptorGetBuffer(buf) - 1] == 0);
 		PrivateRefCount[BufferDescriptorGetBuffer(buf) - 1] = 1;
 
 		if (buf->flags & BM_DIRTY)
@@ -542,6 +543,7 @@ BufferAlloc(Relation reln,
 				inProgress = FALSE;
 				buf->flags &= ~BM_IO_IN_PROGRESS;
 				TerminateBufferIO(buf);
+				Assert(PrivateRefCount[BufferDescriptorGetBuffer(buf)-1] == 1);
 				PrivateRefCount[BufferDescriptorGetBuffer(buf) - 1] = 0;
 				buf->refcount--;
 				buf = (BufferDesc *) NULL;
@@ -568,6 +570,7 @@ BufferAlloc(Relation reln,
 				{
 					TerminateBufferIO(buf);
 					/* give up the buffer since we don't need it any more */
+					Assert(PrivateRefCount[BufferDescriptorGetBuffer(buf)-1] == 1);
 					PrivateRefCount[BufferDescriptorGetBuffer(buf) - 1] = 0;
 					Assert(buf->refcount > 0);
 					buf->refcount--;
@@ -1469,8 +1472,16 @@ ReleaseRelationBuffers(Relation rel)
 			if (!(buf->flags & BM_FREE))
 			{
 				/* Assert checks that buffer will actually get freed! */
-				Assert(PrivateRefCount[i - 1] == 1 &&
-					   buf->refcount == 1);
+				Assert(buf->refcount == 1);
+				if (PrivateRefCount[i - 1] <= 0)
+				{
+					fprintf(stderr, "Nonpositive PrivateRefCount on buffer for %s\n",
+							RelationGetRelationName(rel));
+					fflush(stderr);
+					* ((char *) 0) = 0;
+					abort();
+				}
+				Assert(PrivateRefCount[i - 1] == 1);
 				/* ReleaseBuffer expects we do not hold the lock at entry */
 				SpinRelease(BufMgrLock);
 				holding = false;
diff --git a/src/backend/utils/adt/network.c b/src/backend/utils/adt/network.c
index cb1b9b90bfea4ed3b7e02d2d602c067fdc5df0f2..44045c184b5c591a8d619233c711457fc78ca4c0 100644
--- a/src/backend/utils/adt/network.c
+++ b/src/backend/utils/adt/network.c
@@ -3,22 +3,23 @@
  *	is for IP V4 CIDR notation, but prepared for V6: just
  *	add the necessary bits where the comments indicate.
  *
- *	$Id: network.c,v 1.16 1999/09/23 17:42:23 momjian Exp $
+ *	$Header: /cvsroot/pgsql/src/backend/utils/adt/network.c,v 1.17 2000/02/21 18:47:07 tgl Exp $
+ *
  *	Jon Postel RIP 16 Oct 1998
  */
 
+#include "postgres.h"
+
 #include <sys/types.h>
 #include <sys/socket.h>
-
 #include <errno.h>
-
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
-#include "postgres.h"
 #include "utils/builtins.h"
 
-static int	v4bitncmp(unsigned int a1, unsigned int a2, int bits);
+
+static int	v4bitncmp(unsigned long a1, unsigned long a2, int bits);
 
 /*
  *	Access macros.	Add IPV6 support.
@@ -39,6 +40,7 @@ static int	v4bitncmp(unsigned int a1, unsigned int a2, int bits);
 #define ip_v4addr(inetptr) \
 	(((inet_struct *)VARDATA(inetptr))->addr.ipv4_addr)
 
+
 /* Common input routine */
 static inet *
 network_in(char *src, int type)
@@ -127,7 +129,8 @@ cidr_out(inet *src)
 }
 
 /*
- *	Boolean tests for magnitude.  Add V4/V6 testing!
+ *	Boolean tests for ordering operators --- must agree with sorting
+ *	operator network_cmp().
  */
 
 bool
@@ -135,19 +138,7 @@ network_lt(inet *a1, inet *a2)
 {
 	if (!PointerIsValid(a1) || !PointerIsValid(a2))
 		return FALSE;
-	if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
-	{
-		int			order = v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2));
-
-		return ((order < 0) || ((order == 0) && (ip_bits(a1) < ip_bits(a2))));
-	}
-	else
-	{
-		/* Go for an IPV6 address here, before faulting out: */
-		elog(ERROR, "cannot compare address families %d and %d",
-			 ip_family(a1), ip_family(a2));
-		return FALSE;
-	}
+	return (bool) (network_cmp(a1, a2) < 0);
 }
 
 bool
@@ -155,7 +146,7 @@ network_le(inet *a1, inet *a2)
 {
 	if (!PointerIsValid(a1) || !PointerIsValid(a2))
 		return FALSE;
-	return (network_lt(a1, a2) || network_eq(a1, a2));
+	return (bool) (network_cmp(a1, a2) <= 0);
 }
 
 bool
@@ -163,18 +154,7 @@ network_eq(inet *a1, inet *a2)
 {
 	if (!PointerIsValid(a1) || !PointerIsValid(a2))
 		return FALSE;
-	if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
-	{
-		return ((ip_bits(a1) == ip_bits(a2))
-		 && (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1)) == 0));
-	}
-	else
-	{
-		/* Go for an IPV6 address here, before faulting out: */
-		elog(ERROR, "cannot compare address families %d and %d",
-			 ip_family(a1), ip_family(a2));
-		return FALSE;
-	}
+	return (bool) (network_cmp(a1, a2) == 0);
 }
 
 bool
@@ -182,7 +162,7 @@ network_ge(inet *a1, inet *a2)
 {
 	if (!PointerIsValid(a1) || !PointerIsValid(a2))
 		return FALSE;
-	return (network_gt(a1, a2) || network_eq(a1, a2));
+	return (bool) (network_cmp(a1, a2) >= 0);
 }
 
 bool
@@ -190,29 +170,44 @@ network_gt(inet *a1, inet *a2)
 {
 	if (!PointerIsValid(a1) || !PointerIsValid(a2))
 		return FALSE;
+	return (bool) (network_cmp(a1, a2) > 0);
+}
+
+bool
+network_ne(inet *a1, inet *a2)
+{
+	if (!PointerIsValid(a1) || !PointerIsValid(a2))
+		return FALSE;
+	return (bool) (network_cmp(a1, a2) != 0);
+}
+
+/*
+ *	Comparison function for sorting.  Add V4/V6 testing!
+ */
+
+int4
+network_cmp(inet *a1, inet *a2)
+{
 	if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
 	{
-		int			order = v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2));
-
-		return ((order > 0) || ((order == 0) && (ip_bits(a1) > ip_bits(a2))));
+		int		order = v4bitncmp(ip_v4addr(a1), ip_v4addr(a2),
+								  (ip_bits(a1) < ip_bits(a2)) ?
+								  ip_bits(a1) : ip_bits(a2));
+
+		if (order)
+			return order;
+		/* They agree in the first N bits, so shorter one comes first */
+		return (int) ip_bits(a1) - (int) ip_bits(a2);
 	}
 	else
 	{
 		/* Go for an IPV6 address here, before faulting out: */
 		elog(ERROR, "cannot compare address families %d and %d",
 			 ip_family(a1), ip_family(a2));
-		return FALSE;
+		return 0;
 	}
 }
 
-bool
-network_ne(inet *a1, inet *a2)
-{
-	if (!PointerIsValid(a1) || !PointerIsValid(a2))
-		return FALSE;
-	return (!network_eq(a1, a2));
-}
-
 bool
 network_sub(inet *a1, inet *a2)
 {
@@ -293,28 +288,6 @@ network_supeq(inet *a1, inet *a2)
 	}
 }
 
-/*
- *	Comparison function for sorting.  Add V4/V6 testing!
- */
-
-int4
-network_cmp(inet *a1, inet *a2)
-{
-	if (ntohl(ip_v4addr(a1)) < ntohl(ip_v4addr(a2)))
-		return (-1);
-
-	if (ntohl(ip_v4addr(a1)) > ntohl(ip_v4addr(a2)))
-		return (1);
-
-	if (ip_bits(a1) < ip_bits(a2))
-		return (-1);
-
-	if (ip_bits(a1) > ip_bits(a2))
-		return (1);
-
-	return 0;
-}
-
 text *
 network_host(inet *ip)
 {
@@ -476,7 +449,7 @@ network_netmask(inet *ip)
  */
 
 static int
-v4bitncmp(unsigned int a1, unsigned int a2, int bits)
+v4bitncmp(unsigned long a1, unsigned long a2, int bits)
 {
 	unsigned long mask = 0;
 	int			i;
@@ -485,9 +458,11 @@ v4bitncmp(unsigned int a1, unsigned int a2, int bits)
 		mask = (mask >> 1) | 0x80000000;
 	a1 = ntohl(a1);
 	a2 = ntohl(a2);
-	if ((a1 & mask) < (a2 & mask))
+	a1 &= mask;
+	a2 &= mask;
+	if (a1 < a2)
 		return (-1);
-	else if ((a1 & mask) > (a2 & mask))
+	else if (a1 > a2)
 		return (1);
 	return (0);
 }
diff --git a/src/include/nodes/pg_list.h b/src/include/nodes/pg_list.h
index 94aa8d58c6b91882290c15366698695447a9dc3d..9f05bc7985ffd665a66f7e09ecaf6018d7e21027 100644
--- a/src/include/nodes/pg_list.h
+++ b/src/include/nodes/pg_list.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_list.h,v 1.15 2000/02/06 03:27:35 tgl Exp $
+ * $Id: pg_list.h,v 1.16 2000/02/21 18:47:12 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -23,6 +23,21 @@
 
 /*----------------------
  *		Value node
+ *
+ * The same Value struct is used for three node types: T_Integer,
+ * T_Float, and T_String.  Integral values are actually represented
+ * by a machine integer, but both floats and strings are represented
+ * as strings.  Using T_Float as the node type simply indicates that
+ * the contents of the string look like a valid numeric literal.
+ *
+ * (Before Postgres 7.0, we used a double to represent T_Float,
+ * but that creates loss-of-precision problems when the value is
+ * ultimately destined to be converted to NUMERIC.  Since Value nodes
+ * are only used in the parsing process, not for runtime data, it's
+ * better to use the more general representation.)
+ *
+ * Note that an integer-looking string will get lexed as T_Float if
+ * the value is too large to fit in a 'long'.
  *----------------------
  */
 typedef struct Value
@@ -30,14 +45,13 @@ typedef struct Value
 	NodeTag		type;			/* tag appropriately (eg. T_String) */
 	union ValUnion
 	{
+		long		ival;		/* machine integer */
 		char	   *str;		/* string */
-		long		ival;
-		double		dval;
 	}			val;
 } Value;
 
 #define intVal(v)		(((Value *)(v))->val.ival)
-#define floatVal(v)		(((Value *)(v))->val.dval)
+#define floatVal(v)		atof(((Value *)(v))->val.str)
 #define strVal(v)		(((Value *)(v))->val.str)
 
 
@@ -89,9 +103,9 @@ extern List *lconsi(int datum, List *list);
 extern bool member(void *datum, List *list);
 extern bool intMember(int datum, List *list);
 extern Value *makeInteger(long i);
-extern Value *makeFloat(double d);
+extern Value *makeFloat(char *numericStr);
 extern Value *makeString(char *str);
-extern List *makeList(void *elem,...);
+extern List *makeList(void *elem, ...);
 extern List *lappend(List *list, void *datum);
 extern List *lappendi(List *list, int datum);
 extern List *lremove(void *elem, List *list);