aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2000-12-22 21:36:09 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2000-12-22 21:36:09 +0000
commit0db1a951d5bb7617bbf2bd0b30a9f0971c2ce11d (patch)
tree0a93b01eb10a5b8ea09cf6b1f7633b47844c8e34 /src
parent369aace5f3dc46409f6777c0fed9ef113db43d4a (diff)
downloadpostgresql-0db1a951d5bb7617bbf2bd0b30a9f0971c2ce11d.tar.gz
postgresql-0db1a951d5bb7617bbf2bd0b30a9f0971c2ce11d.zip
Repair not-too-well-thought-out code to do rangechecking of OIDs on
64-bit machines. Also, make oidvectorin use the same code as oidin.
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/oid.c140
-rw-r--r--src/include/postgres_ext.h12
2 files changed, 98 insertions, 54 deletions
diff --git a/src/backend/utils/adt/oid.c b/src/backend/utils/adt/oid.c
index daf66621fa8..6becfd0dbc7 100644
--- a/src/backend/utils/adt/oid.c
+++ b/src/backend/utils/adt/oid.c
@@ -1,14 +1,14 @@
/*-------------------------------------------------------------------------
*
* oid.c
- * Functions for the built-in type Oid.
+ * Functions for the built-in type Oid ... also oidvector.
*
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/oid.c,v 1.41 2000/12/03 20:45:36 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/oid.c,v 1.42 2000/12/22 21:36:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,6 +16,7 @@
#include <ctype.h>
#include <errno.h>
+#include <limits.h>
#include "utils/builtins.h"
@@ -23,6 +24,85 @@
* USER I/O ROUTINES *
*****************************************************************************/
+static Oid
+oidin_subr(const char *funcname, const char *s, char **endloc)
+{
+ 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. Note that for historical reasons we accept
+ * an empty string as meaning 0.
+ */
+ if (errno && errno != EINVAL)
+ elog(ERROR, "%s: error reading \"%s\": %m",
+ funcname, s);
+ if (endptr == s && *endptr)
+ elog(ERROR, "%s: error in \"%s\": can't parse \"%s\"",
+ funcname, s, endptr);
+
+ if (endloc)
+ {
+ /* caller wants to deal with rest of string */
+ *endloc = endptr;
+ }
+ else
+ {
+ /* allow only whitespace after number */
+ while (*endptr && isspace((unsigned char) *endptr))
+ endptr++;
+ if (*endptr)
+ elog(ERROR, "%s: error in \"%s\": can't parse \"%s\"",
+ funcname, s, endptr);
+ }
+
+ result = (Oid) cvt;
+
+ /*
+ * Cope with possibility that unsigned long is wider than Oid.
+ *
+ * To ensure consistent results on 32-bit and 64-bit platforms,
+ * make sure the error message is the same as if strtoul() had
+ * returned ERANGE.
+ */
+#if OID_MAX < ULONG_MAX
+ if (cvt > (unsigned long) OID_MAX)
+ elog(ERROR, "%s: error reading \"%s\": %s",
+ funcname, s, strerror(ERANGE));
+#endif
+
+ return result;
+}
+
+Datum
+oidin(PG_FUNCTION_ARGS)
+{
+ char *s = PG_GETARG_CSTRING(0);
+ Oid result;
+
+ result = oidin_subr("oidin", s, NULL);
+ PG_RETURN_OID(result);
+}
+
+Datum
+oidout(PG_FUNCTION_ARGS)
+{
+ Oid o = PG_GETARG_OID(0);
+ char *result = (char *) palloc(12);
+
+ snprintf(result, 12, "%u", o);
+ PG_RETURN_CSTRING(result);
+}
+
+
/*
* oidvectorin - converts "num num ..." to internal form
*
@@ -38,14 +118,13 @@ oidvectorin(PG_FUNCTION_ARGS)
result = (Oid *) palloc(sizeof(Oid[INDEX_MAX_KEYS]));
- for (slot = 0; *oidString && slot < INDEX_MAX_KEYS; slot++)
+ for (slot = 0; slot < INDEX_MAX_KEYS; slot++)
{
- if (sscanf(oidString, "%u", &result[slot]) != 1)
- break;
while (*oidString && isspace((unsigned char) *oidString))
oidString++;
- while (*oidString && isdigit((unsigned char) *oidString))
- oidString++;
+ if (*oidString == '\0')
+ break;
+ result[slot] = oidin_subr("oidvectorin", oidString, &oidString);
}
while (*oidString && isspace((unsigned char) *oidString))
oidString++;
@@ -88,49 +167,6 @@ oidvectorout(PG_FUNCTION_ARGS)
PG_RETURN_CSTRING(result);
}
-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);
-
- return ObjectIdGetDatum(result);
-}
-
-Datum
-oidout(PG_FUNCTION_ARGS)
-{
- Oid o = PG_GETARG_OID(0);
- char *result = (char *) palloc(12);
-
- snprintf(result, 12, "%u", o);
- PG_RETURN_CSTRING(result);
-}
-
/*****************************************************************************
* PUBLIC ROUTINES *
*****************************************************************************/
@@ -294,8 +330,8 @@ text_oid(PG_FUNCTION_ARGS)
memcpy(str, VARDATA(string), len);
*(str + len) = '\0';
- result = DatumGetObjectId(DirectFunctionCall1(oidin,
- CStringGetDatum(str)));
+ result = oidin_subr("text_oid", str, NULL);
+
pfree(str);
PG_RETURN_OID(result);
diff --git a/src/include/postgres_ext.h b/src/include/postgres_ext.h
index 7e73539912a..18be70ea922 100644
--- a/src/include/postgres_ext.h
+++ b/src/include/postgres_ext.h
@@ -16,7 +16,7 @@
* use header files that are otherwise internal to Postgres to interface
* with the backend.
*
- * $Id: postgres_ext.h,v 1.4 1999/06/04 21:12:07 tgl Exp $
+ * $Id: postgres_ext.h,v 1.5 2000/12/22 21:36:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -24,9 +24,17 @@
#ifndef POSTGRES_EXT_H
#define POSTGRES_EXT_H
+/*
+ * Object ID is a fundamental type in Postgres.
+ */
typedef unsigned int Oid;
-/* NAMEDATALEN is the max length for system identifiers (e.g. table names,
+#define OID_MAX UINT_MAX
+/* you will need to include <limits.h> to use the above #define */
+
+
+/*
+ * NAMEDATALEN is the max length for system identifiers (e.g. table names,
* attribute names, function names, etc.)
*
* NOTE that databases with different NAMEDATALEN's cannot interoperate!