11/*-------------------------------------------------------------------------
22 *
33 * oid.c
4- * Functions for the built-in type Oid.
4+ * Functions for the built-in type Oid ... also oidvector .
55 *
66 * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
77 * Portions Copyright (c) 1994, Regents of the University of California
88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/utils/adt/oid.c,v 1.41 2000/12/03 20:45:36 tgl Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/oid.c,v 1.42 2000/12/22 21:36:09 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
1515#include "postgres.h"
1616
1717#include <ctype.h>
1818#include <errno.h>
19+ #include <limits.h>
1920
2021#include "utils/builtins.h"
2122
2223/*****************************************************************************
2324 * USER I/O ROUTINES *
2425 *****************************************************************************/
2526
27+ static Oid
28+ oidin_subr (const char * funcname ,const char * s ,char * * endloc )
29+ {
30+ unsigned long cvt ;
31+ char * endptr ;
32+ Oid result ;
33+
34+ errno = 0 ;
35+
36+ cvt = strtoul (s ,& endptr ,10 );
37+
38+ /*
39+ * strtoul() normally only sets ERANGE. On some systems it also
40+ * may set EINVAL, which simply means it couldn't parse the
41+ * input string. This is handled by the second "if" consistent
42+ * across platforms. Note that for historical reasons we accept
43+ * an empty string as meaning 0.
44+ */
45+ if (errno && errno != EINVAL )
46+ elog (ERROR ,"%s: error reading \"%s\": %m" ,
47+ funcname ,s );
48+ if (endptr == s && * endptr )
49+ elog (ERROR ,"%s: error in \"%s\": can't parse \"%s\"" ,
50+ funcname ,s ,endptr );
51+
52+ if (endloc )
53+ {
54+ /* caller wants to deal with rest of string */
55+ * endloc = endptr ;
56+ }
57+ else
58+ {
59+ /* allow only whitespace after number */
60+ while (* endptr && isspace ((unsignedchar )* endptr ))
61+ endptr ++ ;
62+ if (* endptr )
63+ elog (ERROR ,"%s: error in \"%s\": can't parse \"%s\"" ,
64+ funcname ,s ,endptr );
65+ }
66+
67+ result = (Oid )cvt ;
68+
69+ /*
70+ * Cope with possibility that unsigned long is wider than Oid.
71+ *
72+ * To ensure consistent results on 32-bit and 64-bit platforms,
73+ * make sure the error message is the same as if strtoul() had
74+ * returned ERANGE.
75+ */
76+ #if OID_MAX < ULONG_MAX
77+ if (cvt > (unsigned long )OID_MAX )
78+ elog (ERROR ,"%s: error reading \"%s\": %s" ,
79+ funcname ,s ,strerror (ERANGE ));
80+ #endif
81+
82+ return result ;
83+ }
84+
85+ Datum
86+ oidin (PG_FUNCTION_ARGS )
87+ {
88+ char * s = PG_GETARG_CSTRING (0 );
89+ Oid result ;
90+
91+ result = oidin_subr ("oidin" ,s ,NULL );
92+ PG_RETURN_OID (result );
93+ }
94+
95+ Datum
96+ oidout (PG_FUNCTION_ARGS )
97+ {
98+ Oid o = PG_GETARG_OID (0 );
99+ char * result = (char * )palloc (12 );
100+
101+ snprintf (result ,12 ,"%u" ,o );
102+ PG_RETURN_CSTRING (result );
103+ }
104+
105+
26106/*
27107 *oidvectorin- converts "num num ..." to internal form
28108 *
@@ -38,14 +118,13 @@ oidvectorin(PG_FUNCTION_ARGS)
38118
39119result = (Oid * )palloc (sizeof (Oid [INDEX_MAX_KEYS ]));
40120
41- for (slot = 0 ;* oidString && slot < INDEX_MAX_KEYS ;slot ++ )
121+ for (slot = 0 ;slot < INDEX_MAX_KEYS ;slot ++ )
42122{
43- if (sscanf (oidString ,"%u" ,& result [slot ])!= 1 )
44- break ;
45123while (* oidString && isspace ((unsignedchar )* oidString ))
46124oidString ++ ;
47- while (* oidString && isdigit ((unsignedchar )* oidString ))
48- oidString ++ ;
125+ if (* oidString == '\0' )
126+ break ;
127+ result [slot ]= oidin_subr ("oidvectorin" ,oidString ,& oidString );
49128}
50129while (* oidString && isspace ((unsignedchar )* oidString ))
51130oidString ++ ;
@@ -88,49 +167,6 @@ oidvectorout(PG_FUNCTION_ARGS)
88167PG_RETURN_CSTRING (result );
89168}
90169
91- Datum
92- oidin (PG_FUNCTION_ARGS )
93- {
94- char * s = PG_GETARG_CSTRING (0 );
95- unsigned long cvt ;
96- char * endptr ;
97- Oid result ;
98-
99- errno = 0 ;
100-
101- cvt = strtoul (s ,& endptr ,10 );
102-
103- /*
104- * strtoul() normally only sets ERANGE. On some systems it also
105- * may set EINVAL, which simply means it couldn't parse the
106- * input string. This is handled by the second "if" consistent
107- * across platforms.
108- */
109- if (errno && errno != EINVAL )
110- elog (ERROR ,"oidin: error reading \"%s\": %m" ,s );
111- if (endptr && * endptr )
112- elog (ERROR ,"oidin: error in \"%s\": can't parse \"%s\"" ,s ,endptr );
113-
114- /*
115- * Cope with possibility that unsigned long is wider than Oid.
116- */
117- result = (Oid )cvt ;
118- if ((unsigned long )result != cvt )
119- elog (ERROR ,"oidin: error reading \"%s\": value too large" ,s );
120-
121- return ObjectIdGetDatum (result );
122- }
123-
124- Datum
125- oidout (PG_FUNCTION_ARGS )
126- {
127- Oid o = PG_GETARG_OID (0 );
128- char * result = (char * )palloc (12 );
129-
130- snprintf (result ,12 ,"%u" ,o );
131- PG_RETURN_CSTRING (result );
132- }
133-
134170/*****************************************************************************
135171 * PUBLIC ROUTINES *
136172 *****************************************************************************/
@@ -294,8 +330,8 @@ text_oid(PG_FUNCTION_ARGS)
294330memcpy (str ,VARDATA (string ),len );
295331* (str + len )= '\0' ;
296332
297- result = DatumGetObjectId ( DirectFunctionCall1 ( oidin ,
298- CStringGetDatum ( str )));
333+ result = oidin_subr ( "text_oid" , str , NULL );
334+
299335pfree (str );
300336
301337PG_RETURN_OID (result );