Commit 93fcbd14 authored by Tom Lane's avatar Tom Lane

Make oidin/oidout produce and consume unsigned representation of Oid,

rather than just being aliases for int4in/int4out.  Give type Oid a
full set of comparison operators that do proper unsigned comparison,
instead of reusing the int4 comparators.  Since pg_dump is now doing
unsigned comparisons of OIDs, it is now *necessary* that we play by
the rules here.  In fact, given that btoidcmp() has been doing unsigned
comparison for quite some time, it seems likely that we have index-
corruption problems in 7.0 and before once the Oid counter goes past
2G.  Fixing these operators is a necessary step before we can think
about 8-byte Oid, too.
parent 01f2547c
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/oid.c,v 1.38 2000/08/01 18:29:35 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/oid.c,v 1.39 2000/11/21 03:23:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -43,7 +43,7 @@ oidvectorin(PG_FUNCTION_ARGS)
break;
while (*oidString && isspace((int) *oidString))
oidString++;
while (*oidString && !isspace((int) *oidString))
while (*oidString && isdigit((int) *oidString))
oidString++;
}
while (*oidString && isspace((int) *oidString))
......@@ -79,7 +79,7 @@ oidvectorout(PG_FUNCTION_ARGS)
{
if (num != 0)
*rp++ = ' ';
pg_ltoa((int32) oidArray[num], rp);
sprintf(rp, "%u", oidArray[num]);
while (*++rp != '\0')
;
}
......@@ -91,18 +91,43 @@ Datum
oidin(PG_FUNCTION_ARGS)
{
char *s = PG_GETARG_CSTRING(0);
unsigned long cvt;
char *endptr;
Oid result;
errno = 0;
cvt = strtoul(s, &endptr, 10);
/*
* strtoul() normally only sets ERANGE. On some systems it also
* may set EINVAL, which simply means it couldn't parse the
* input string. This is handled by the second "if" consistent
* across platforms.
*/
if (errno && errno != EINVAL)
elog(ERROR, "oidin: error reading \"%s\": %m", s);
if (endptr && *endptr)
elog(ERROR, "oidin: error in \"%s\": can't parse \"%s\"", s, endptr);
/*
* Cope with possibility that unsigned long is wider than Oid.
*/
result = (Oid) cvt;
if ((unsigned long) result != cvt)
elog(ERROR, "oidin: error reading \"%s\": value too large", s);
/* XXX should use an unsigned-int conversion here */
return DirectFunctionCall1(int4in, CStringGetDatum(s));
return ObjectIdGetDatum(result);
}
Datum
oidout(PG_FUNCTION_ARGS)
{
Oid o = PG_GETARG_OID(0);
char *result = (char *) palloc(12);
/* XXX should use an unsigned-int conversion here */
return DirectFunctionCall1(int4out, ObjectIdGetDatum(o));
snprintf(result, 12, "%u", o);
PG_RETURN_CSTRING(result);
}
/*****************************************************************************
......@@ -127,6 +152,42 @@ oidne(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(arg1 != arg2);
}
Datum
oidlt(PG_FUNCTION_ARGS)
{
Oid arg1 = PG_GETARG_OID(0);
Oid arg2 = PG_GETARG_OID(1);
PG_RETURN_BOOL(arg1 < arg2);
}
Datum
oidle(PG_FUNCTION_ARGS)
{
Oid arg1 = PG_GETARG_OID(0);
Oid arg2 = PG_GETARG_OID(1);
PG_RETURN_BOOL(arg1 <= arg2);
}
Datum
oidge(PG_FUNCTION_ARGS)
{
Oid arg1 = PG_GETARG_OID(0);
Oid arg2 = PG_GETARG_OID(1);
PG_RETURN_BOOL(arg1 >= arg2);
}
Datum
oidgt(PG_FUNCTION_ARGS)
{
Oid arg1 = PG_GETARG_OID(0);
Oid arg2 = PG_GETARG_OID(1);
PG_RETURN_BOOL(arg1 > arg2);
}
Datum
oidvectoreq(PG_FUNCTION_ARGS)
{
......@@ -197,26 +258,6 @@ oidvectorgt(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(false);
}
Datum
oideqint4(PG_FUNCTION_ARGS)
{
Oid arg1 = PG_GETARG_OID(0);
int32 arg2 = PG_GETARG_INT32(1);
/* oid is unsigned, but int4 is signed */
PG_RETURN_BOOL(arg2 >= 0 && arg1 == arg2);
}
Datum
int4eqoid(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
Oid arg2 = PG_GETARG_OID(1);
/* oid is unsigned, but int4 is signed */
PG_RETURN_BOOL(arg1 >= 0 && arg1 == arg2);
}
Datum
oid_text(PG_FUNCTION_ARGS)
{
......
......@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: catversion.h,v 1.62 2000/11/20 20:36:50 tgl Exp $
* $Id: catversion.h,v 1.63 2000/11/21 03:23:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 200011201
#define CATALOG_VERSION_NO 200011211
#endif
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_operator.h,v 1.83 2000/10/24 20:15:45 petere Exp $
* $Id: pg_operator.h,v 1.84 2000/11/21 03:23:19 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
......@@ -280,10 +280,10 @@ DATA(insert OID = 606 ( "<#>" PGUID 0 b t f 702 702 704 0 0 0 0 mktinte
DATA(insert OID = 607 ( "=" PGUID 0 b t t 26 26 16 607 608 609 609 oideq eqsel eqjoinsel ));
#define MIN_OIDCMP 607 /* used by cache code */
DATA(insert OID = 608 ( "<>" PGUID 0 b t f 26 26 16 608 607 0 0 oidne neqsel neqjoinsel ));
DATA(insert OID = 609 ( "<" PGUID 0 b t f 26 26 16 610 612 0 0 int4lt scalarltsel scalarltjoinsel ));
DATA(insert OID = 610 ( ">" PGUID 0 b t f 26 26 16 609 611 0 0 int4gt scalargtsel scalargtjoinsel ));
DATA(insert OID = 611 ( "<=" PGUID 0 b t f 26 26 16 612 610 0 0 int4le scalarltsel scalarltjoinsel ));
DATA(insert OID = 612 ( ">=" PGUID 0 b t f 26 26 16 611 609 0 0 int4ge scalargtsel scalargtjoinsel ));
DATA(insert OID = 609 ( "<" PGUID 0 b t f 26 26 16 610 612 0 0 oidlt scalarltsel scalarltjoinsel ));
DATA(insert OID = 610 ( ">" PGUID 0 b t f 26 26 16 609 611 0 0 oidgt scalargtsel scalargtjoinsel ));
DATA(insert OID = 611 ( "<=" PGUID 0 b t f 26 26 16 612 610 0 0 oidle scalarltsel scalarltjoinsel ));
DATA(insert OID = 612 ( ">=" PGUID 0 b t f 26 26 16 611 609 0 0 oidge scalargtsel scalargtjoinsel ));
#define MAX_OIDCMP 612 /* used by cache code */
DATA(insert OID = 644 ( "<>" PGUID 0 b t f 30 30 16 644 649 0 0 oidvectorne neqsel neqjoinsel ));
......@@ -516,9 +516,9 @@ DATA(insert OID = 1133 ( ">" PGUID 0 b t f 701 700 16 1122 1134 0 0 float84
DATA(insert OID = 1134 ( "<=" PGUID 0 b t f 701 700 16 1125 1133 0 0 float84le scalarltsel scalarltjoinsel ));
DATA(insert OID = 1135 ( ">=" PGUID 0 b t f 701 700 16 1124 1132 0 0 float84ge scalargtsel scalargtjoinsel ));
/* int4 and oid equality */
DATA(insert OID = 1136 ( "=" PGUID 0 b t t 23 26 16 1137 0 0 0 int4eqoid eqsel eqjoinsel ));
DATA(insert OID = 1137 ( "=" PGUID 0 b t t 26 23 16 1136 0 0 0 oideqint4 eqsel eqjoinsel ));
/* int4 vs oid equality --- use oid (unsigned) comparison */
DATA(insert OID = 1136 ( "=" PGUID 0 b t t 23 26 16 1137 1656 0 0 oideq eqsel eqjoinsel ));
DATA(insert OID = 1137 ( "=" PGUID 0 b t t 26 23 16 1136 1661 0 0 oideq eqsel eqjoinsel ));
DATA(insert OID = 1158 ( "!" PGUID 0 r t f 21 0 23 0 0 0 0 int2fac - - ));
DATA(insert OID = 1175 ( "!!" PGUID 0 l t f 0 21 23 0 0 0 0 int2fac - - ));
......@@ -704,6 +704,18 @@ DATA(insert OID = 1631 ( "~~*" PGUID 0 b t f 1043 25 16 0 1632 0 0 texticli
#define OID_VARCHAR_ICLIKE_OP 1631
DATA(insert OID = 1632 ( "!~~*" PGUID 0 b t f 1043 25 16 0 1631 0 0 texticnlike icnlikesel icnlikejoinsel ));
/* int4 vs oid comparisons --- use oid (unsigned) comparison */
DATA(insert OID = 1656 ( "<>" PGUID 0 b t f 23 26 16 1661 1136 0 0 oidne neqsel neqjoinsel ));
DATA(insert OID = 1657 ( "<" PGUID 0 b t f 23 26 16 1663 1660 0 0 oidlt scalarltsel scalarltjoinsel ));
DATA(insert OID = 1658 ( ">" PGUID 0 b t f 23 26 16 1662 1659 0 0 oidgt scalargtsel scalargtjoinsel ));
DATA(insert OID = 1659 ( "<=" PGUID 0 b t f 23 26 16 1665 1658 0 0 oidle scalarltsel scalarltjoinsel ));
DATA(insert OID = 1660 ( ">=" PGUID 0 b t f 23 26 16 1664 1657 0 0 oidge scalargtsel scalargtjoinsel ));
DATA(insert OID = 1661 ( "<>" PGUID 0 b t f 26 23 16 1656 1137 0 0 oidne neqsel neqjoinsel ));
DATA(insert OID = 1662 ( "<" PGUID 0 b t f 26 23 16 1658 1665 0 0 oidlt scalarltsel scalarltjoinsel ));
DATA(insert OID = 1663 ( ">" PGUID 0 b t f 26 23 16 1657 1664 0 0 oidgt scalargtsel scalargtjoinsel ));
DATA(insert OID = 1664 ( "<=" PGUID 0 b t f 26 23 16 1660 1663 0 0 oidle scalarltsel scalarltjoinsel ));
DATA(insert OID = 1665 ( ">=" PGUID 0 b t f 26 23 16 1659 1662 0 0 oidge scalargtsel scalargtjoinsel ));
/* NUMERIC type - OID's 1700-1799 */
DATA(insert OID = 1751 ( "-" PGUID 0 l t f 0 1700 1700 0 0 0 0 numeric_uminus - - ));
DATA(insert OID = 1752 ( "=" PGUID 0 b t f 1700 1700 16 1752 1753 1754 1754 numeric_eq eqsel eqjoinsel ));
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_proc.h,v 1.174 2000/11/11 19:55:33 thomas Exp $
* $Id: pg_proc.h,v 1.175 2000/11/21 03:23:19 tgl Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
......@@ -936,10 +936,10 @@ DATA(insert OID = 713 ( oidrand PGUID 12 f t f t 2 f 16 "26 23" 100 0 0 100
DESCR("random");
DATA(insert OID = 715 ( oidsrand PGUID 12 f t f t 1 f 16 "23" 100 0 0 100 oidsrand - ));
DESCR("seed random number generator");
DATA(insert OID = 716 ( oideqint4 PGUID 12 f t t t 2 f 16 "26 23" 100 0 0 100 oideqint4 - ));
DESCR("equal");
DATA(insert OID = 717 ( int4eqoid PGUID 12 f t t t 2 f 16 "23 26" 100 0 0 100 int4eqoid - ));
DESCR("equal");
DATA(insert OID = 716 ( oidlt PGUID 12 f t t t 2 f 16 "26 26" 100 0 0 100 oidlt - ));
DESCR("less-than");
DATA(insert OID = 717 ( oidle PGUID 12 f t t t 2 f 16 "26 26" 100 0 0 100 oidle - ));
DESCR("less-than-or-equal");
DATA(insert OID = 720 ( octet_length PGUID 12 f t t t 1 f 23 "17" 100 0 0 100 byteaoctetlen - ));
DESCR("octet length");
......@@ -2128,6 +2128,11 @@ DESCR("convert encoding name to encoding id");
DATA(insert OID = 1597 ( pg_encoding_to_char PGUID 12 f t f t 1 f 19 "23" 100 0 0 100 PG_encoding_to_char - ));
DESCR("convert encoding id to encoding name");
DATA(insert OID = 1638 ( oidgt PGUID 12 f t t t 2 f 16 "26 26" 100 0 0 100 oidgt - ));
DESCR("greater-than");
DATA(insert OID = 1639 ( oidge PGUID 12 f t t t 2 f 16 "26 26" 100 0 0 100 oidge - ));
DESCR("greater-than-or-equal");
/* System-view support functions */
DATA(insert OID = 1640 ( pg_get_ruledef PGUID 12 f t f t 1 f 25 "19" 100 0 0 100 pg_get_ruledef - ));
DESCR("source text of a rule");
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: builtins.h,v 1.141 2000/11/10 20:13:26 tgl Exp $
* $Id: builtins.h,v 1.142 2000/11/21 03:23:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -283,22 +283,24 @@ extern Datum int4notin(PG_FUNCTION_ARGS);
extern Datum oidnotin(PG_FUNCTION_ARGS);
/* oid.c */
extern Datum oidvectorin(PG_FUNCTION_ARGS);
extern Datum oidvectorout(PG_FUNCTION_ARGS);
extern Datum oidin(PG_FUNCTION_ARGS);
extern Datum oidout(PG_FUNCTION_ARGS);
extern Datum oideq(PG_FUNCTION_ARGS);
extern Datum oidne(PG_FUNCTION_ARGS);
extern Datum oidlt(PG_FUNCTION_ARGS);
extern Datum oidle(PG_FUNCTION_ARGS);
extern Datum oidge(PG_FUNCTION_ARGS);
extern Datum oidgt(PG_FUNCTION_ARGS);
extern Datum oid_text(PG_FUNCTION_ARGS);
extern Datum text_oid(PG_FUNCTION_ARGS);
extern Datum oidvectorin(PG_FUNCTION_ARGS);
extern Datum oidvectorout(PG_FUNCTION_ARGS);
extern Datum oidvectoreq(PG_FUNCTION_ARGS);
extern Datum oidvectorne(PG_FUNCTION_ARGS);
extern Datum oidvectorlt(PG_FUNCTION_ARGS);
extern Datum oidvectorle(PG_FUNCTION_ARGS);
extern Datum oidvectorge(PG_FUNCTION_ARGS);
extern Datum oidvectorgt(PG_FUNCTION_ARGS);
extern Datum oideqint4(PG_FUNCTION_ARGS);
extern Datum int4eqoid(PG_FUNCTION_ARGS);
extern Datum oid_text(PG_FUNCTION_ARGS);
extern Datum text_oid(PG_FUNCTION_ARGS);
/* regexp.c */
extern Datum nameregexeq(PG_FUNCTION_ARGS);
......
......@@ -6,63 +6,70 @@ INSERT INTO OID_TBL(f1) VALUES ('1234');
INSERT INTO OID_TBL(f1) VALUES ('1235');
INSERT INTO OID_TBL(f1) VALUES ('987');
INSERT INTO OID_TBL(f1) VALUES ('-1040');
INSERT INTO OID_TBL(f1) VALUES ('99999999');
INSERT INTO OID_TBL(f1) VALUES ('');
-- bad inputs
INSERT INTO OID_TBL(f1) VALUES ('asdfasd');
ERROR: pg_atoi: error in "asdfasd": can't parse "asdfasd"
SELECT '' AS five, OID_TBL.*;
five | f1
------+-------
ERROR: oidin: error in "asdfasd": can't parse "asdfasd"
INSERT INTO OID_TBL(f1) VALUES ('99asdfasd');
ERROR: oidin: error in "99asdfasd": can't parse "asdfasd"
SELECT '' AS six, OID_TBL.*;
six | f1
-----+------------
| 1234
| 1235
| 987
| -1040
| 4294966256
| 99999999
| 0
(5 rows)
(6 rows)
SELECT '' AS one, o.* FROM OID_TBL o WHERE o.f1 = oid '1234';
SELECT '' AS one, o.* FROM OID_TBL o WHERE o.f1 = 1234;
one | f1
-----+------
| 1234
(1 row)
SELECT '' AS four, o.* FROM OID_TBL o WHERE o.f1 <> '1234';
four | f1
------+-------
SELECT '' AS five, o.* FROM OID_TBL o WHERE o.f1 <> '1234';
five | f1
------+------------
| 1235
| 987
| -1040
| 4294966256
| 99999999
| 0
(4 rows)
(5 rows)
SELECT '' AS four, o.* FROM OID_TBL o WHERE o.f1 <= '1234';
four | f1
------+-------
SELECT '' AS three, o.* FROM OID_TBL o WHERE o.f1 <= '1234';
three | f1
-------+------
| 1234
| 987
| -1040
| 0
(4 rows)
(3 rows)
SELECT '' AS three, o.* FROM OID_TBL o WHERE o.f1 < '1234';
three | f1
-------+-------
SELECT '' AS two, o.* FROM OID_TBL o WHERE o.f1 < '1234';
two | f1
-----+-----
| 987
| -1040
| 0
(3 rows)
(2 rows)
SELECT '' AS two, o.* FROM OID_TBL o WHERE o.f1 >= '1234';
two | f1
-----+------
SELECT '' AS four, o.* FROM OID_TBL o WHERE o.f1 >= '1234';
four | f1
------+------------
| 1234
| 1235
(2 rows)
| 4294966256
| 99999999
(4 rows)
SELECT '' AS one, o.* FROM OID_TBL o WHERE o.f1 > '1234';
one | f1
-----+------
SELECT '' AS three, o.* FROM OID_TBL o WHERE o.f1 > '1234';
three | f1
-------+------------
| 1235
(1 row)
| 4294966256
| 99999999
(3 rows)
DROP TABLE OID_TBL;
......@@ -12,24 +12,28 @@ INSERT INTO OID_TBL(f1) VALUES ('987');
INSERT INTO OID_TBL(f1) VALUES ('-1040');
INSERT INTO OID_TBL(f1) VALUES ('99999999');
INSERT INTO OID_TBL(f1) VALUES ('');
-- bad inputs
INSERT INTO OID_TBL(f1) VALUES ('asdfasd');
INSERT INTO OID_TBL(f1) VALUES ('99asdfasd');
SELECT '' AS five, OID_TBL.*;
SELECT '' AS six, OID_TBL.*;
SELECT '' AS one, o.* FROM OID_TBL o WHERE o.f1 = oid '1234';
SELECT '' AS one, o.* FROM OID_TBL o WHERE o.f1 = 1234;
SELECT '' AS four, o.* FROM OID_TBL o WHERE o.f1 <> '1234';
SELECT '' AS five, o.* FROM OID_TBL o WHERE o.f1 <> '1234';
SELECT '' AS four, o.* FROM OID_TBL o WHERE o.f1 <= '1234';
SELECT '' AS three, o.* FROM OID_TBL o WHERE o.f1 <= '1234';
SELECT '' AS three, o.* FROM OID_TBL o WHERE o.f1 < '1234';
SELECT '' AS two, o.* FROM OID_TBL o WHERE o.f1 < '1234';
SELECT '' AS two, o.* FROM OID_TBL o WHERE o.f1 >= '1234';
SELECT '' AS four, o.* FROM OID_TBL o WHERE o.f1 >= '1234';
SELECT '' AS one, o.* FROM OID_TBL o WHERE o.f1 > '1234';
SELECT '' AS three, o.* FROM OID_TBL o WHERE o.f1 > '1234';
DROP TABLE OID_TBL;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment