1
1
/*-------------------------------------------------------------------------
2
2
*
3
3
* oid.c
4
- * Functions for the built-in type Oid.
4
+ * Functions for the built-in type Oid ... also oidvector .
5
5
*
6
6
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
7
7
* Portions Copyright (c) 1994, Regents of the University of California
8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
15
15
#include "postgres.h"
16
16
17
17
#include <ctype.h>
18
18
#include <errno.h>
19
+ #include <limits.h>
19
20
20
21
#include "utils/builtins.h"
21
22
22
23
/*****************************************************************************
23
24
* USER I/O ROUTINES *
24
25
*****************************************************************************/
25
26
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 ((unsigned char ) * 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
+
26
106
/*
27
107
* oidvectorin - converts "num num ..." to internal form
28
108
*
@@ -38,14 +118,13 @@ oidvectorin(PG_FUNCTION_ARGS)
38
118
39
119
result = (Oid * ) palloc (sizeof (Oid [INDEX_MAX_KEYS ]));
40
120
41
- for (slot = 0 ; * oidString && slot < INDEX_MAX_KEYS ; slot ++ )
121
+ for (slot = 0 ; slot < INDEX_MAX_KEYS ; slot ++ )
42
122
{
43
- if (sscanf (oidString , "%u" , & result [slot ]) != 1 )
44
- break ;
45
123
while (* oidString && isspace ((unsigned char ) * oidString ))
46
124
oidString ++ ;
47
- while (* oidString && isdigit ((unsigned char ) * oidString ))
48
- oidString ++ ;
125
+ if (* oidString == '\0' )
126
+ break ;
127
+ result [slot ] = oidin_subr ("oidvectorin" , oidString , & oidString );
49
128
}
50
129
while (* oidString && isspace ((unsigned char ) * oidString ))
51
130
oidString ++ ;
@@ -88,49 +167,6 @@ oidvectorout(PG_FUNCTION_ARGS)
88
167
PG_RETURN_CSTRING (result );
89
168
}
90
169
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
-
134
170
/*****************************************************************************
135
171
* PUBLIC ROUTINES *
136
172
*****************************************************************************/
@@ -294,8 +330,8 @@ text_oid(PG_FUNCTION_ARGS)
294
330
memcpy (str , VARDATA (string ), len );
295
331
* (str + len ) = '\0' ;
296
332
297
- result = DatumGetObjectId ( DirectFunctionCall1 ( oidin ,
298
- CStringGetDatum ( str )));
333
+ result = oidin_subr ( "text_oid" , str , NULL );
334
+
299
335
pfree (str );
300
336
301
337
PG_RETURN_OID (result );
0 commit comments