]> granicus.if.org Git - postgresql/commitdiff
Make oidin/oidout produce and consume unsigned representation of Oid,
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 21 Nov 2000 03:23:21 +0000 (03:23 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 21 Nov 2000 03:23:21 +0000 (03:23 +0000)
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
src/include/catalog/catversion.h
src/include/catalog/pg_operator.h
src/include/catalog/pg_proc.h
src/include/utils/builtins.h
src/test/regress/expected/oid.out
src/test/regress/sql/oid.sql

index 6ae7d48d2c73b6fd4b82e1acbfd29dc754155b89..0e78e97dbcce19d4ef1011e4eb9c9082cdfd4583 100644 (file)
@@ -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)
 {
index 558feef575ba0f005f55ecdc182942b568be354d..270b52cac975a35449e05f2bbabe59e6012b4d2b 100644 (file)
@@ -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
index 219652fbea7b8ba96babf7d7ea485331439d0ad9..0265acb746b78316cdc4efcf13c184446bc33f34 100644 (file)
@@ -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 ));
index a45b6dcb90c06c5b2b73627b1d0f5a4b731c17cc..b2c2ab7a82db71f523655b29f519bebab6ab55dd 100644 (file)
@@ -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");
index f6a4055bb1d030a087eae5a9648475211b2a667d..42d2d81173d54489fae35c9ecd6b286ee57006cc 100644 (file)
@@ -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);
index 11a53a5d242eb241536c4c8b51494879ca544d39..f280dca81d9c203cc0fec93c3a96c3deeef075f8 100644 (file)
@@ -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;
index a33cfaca4faf150f37c1fc134910b085e77fdf77..17bfd01942d4d9f6f64178d0f623cbcc16009638 100644 (file)
@@ -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;