aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/nodes/copyfuncs.c10
-rw-r--r--src/backend/nodes/equalfuncs.c9
-rw-r--r--src/backend/nodes/freefuncs.c7
-rw-r--r--src/backend/nodes/list.c10
-rw-r--r--src/backend/nodes/outfuncs.c17
-rw-r--r--src/backend/nodes/read.c61
-rw-r--r--src/backend/parser/gram.y45
-rw-r--r--src/backend/parser/parse_expr.c12
-rw-r--r--src/backend/parser/scan.l39
-rw-r--r--src/backend/storage/buffer/bufmgr.c17
-rw-r--r--src/backend/utils/adt/network.c115
-rw-r--r--src/include/nodes/pg_list.h26
12 files changed, 184 insertions, 184 deletions
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index fbef91b35d8..601b503ec11 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 b4f5fc6285c..6cb9eada0f8 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 daca4a6d96a..14a5ed12d9e 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 723930f36a8..a47851f2420 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 db785afab9f..eb2c1a7ffa8 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 75e10576d5b..9f68f4d0e90 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 f43393eeff8..b81b6d387ab 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 3fd3370672f..2efdd136005 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 fa3408c1f1d..5b8dd16d81f 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 d6120affabe..f5d61323310 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 cb1b9b90bfe..44045c184b5 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,30 +170,45 @@ 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)
{
if (!PointerIsValid(a1) || !PointerIsValid(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 94aa8d58c6b..9f05bc7985f 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);