From 93fcbd140a8d9044b8fb238e2a6e2266c4851f0d Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 21 Nov 2000 03:23:21 +0000 Subject: [PATCH] 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. --- src/backend/utils/adt/oid.c | 95 ++++++++++++++++++++++--------- src/include/catalog/catversion.h | 4 +- src/include/catalog/pg_operator.h | 28 ++++++--- src/include/catalog/pg_proc.h | 15 +++-- src/include/utils/builtins.h | 16 +++--- src/test/regress/expected/oid.out | 95 +++++++++++++++++-------------- src/test/regress/sql/oid.sql | 18 +++--- 7 files changed, 171 insertions(+), 100 deletions(-) diff --git a/src/backend/utils/adt/oid.c b/src/backend/utils/adt/oid.c index 6ae7d48d2c..0e78e97dbc 100644 --- a/src/backend/utils/adt/oid.c +++ b/src/backend/utils/adt/oid.c @@ -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; - /* XXX should use an unsigned-int conversion here */ - return DirectFunctionCall1(int4in, CStringGetDatum(s)); + 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); + + 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) { diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 558feef575..270b52cac9 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -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 diff --git a/src/include/catalog/pg_operator.h b/src/include/catalog/pg_operator.h index 219652fbea..0265acb746 100644 --- a/src/include/catalog/pg_operator.h +++ b/src/include/catalog/pg_operator.h @@ -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 )); diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index a45b6dcb90..b2c2ab7a82 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -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"); diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index f6a4055bb1..42d2d81173 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -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); diff --git a/src/test/regress/expected/oid.out b/src/test/regress/expected/oid.out index 11a53a5d24..f280dca81d 100644 --- a/src/test/regress/expected/oid.out +++ b/src/test/regress/expected/oid.out @@ -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 -------+------- - | 1234 - | 1235 - | 987 - | -1040 - | 0 -(5 rows) +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 + | 4294966256 + | 99999999 + | 0 +(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 -------+------- - | 1235 - | 987 - | -1040 - | 0 -(4 rows) - -SELECT '' AS four, o.* FROM OID_TBL o WHERE o.f1 <= '1234'; - four | f1 -------+------- - | 1234 - | 987 - | -1040 - | 0 -(4 rows) +SELECT '' AS five, o.* FROM OID_TBL o WHERE o.f1 <> '1234'; + five | f1 +------+------------ + | 1235 + | 987 + | 4294966256 + | 99999999 + | 0 +(5 rows) -SELECT '' AS three, o.* FROM OID_TBL o WHERE o.f1 < '1234'; - three | f1 --------+------- - | 987 - | -1040 - | 0 +SELECT '' AS three, o.* FROM OID_TBL o WHERE o.f1 <= '1234'; + three | f1 +-------+------ + | 1234 + | 987 + | 0 (3 rows) -SELECT '' AS two, o.* FROM OID_TBL o WHERE o.f1 >= '1234'; - two | f1 ------+------ - | 1234 - | 1235 +SELECT '' AS two, o.* FROM OID_TBL o WHERE o.f1 < '1234'; + two | f1 +-----+----- + | 987 + | 0 (2 rows) -SELECT '' AS one, o.* FROM OID_TBL o WHERE o.f1 > '1234'; - one | f1 ------+------ - | 1235 -(1 row) +SELECT '' AS four, o.* FROM OID_TBL o WHERE o.f1 >= '1234'; + four | f1 +------+------------ + | 1234 + | 1235 + | 4294966256 + | 99999999 +(4 rows) + +SELECT '' AS three, o.* FROM OID_TBL o WHERE o.f1 > '1234'; + three | f1 +-------+------------ + | 1235 + | 4294966256 + | 99999999 +(3 rows) DROP TABLE OID_TBL; diff --git a/src/test/regress/sql/oid.sql b/src/test/regress/sql/oid.sql index a33cfaca4f..17bfd01942 100644 --- a/src/test/regress/sql/oid.sql +++ b/src/test/regress/sql/oid.sql @@ -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; -- 2.40.0