*** a/src/backend/utils/adt/xid.c --- b/src/backend/utils/adt/xid.c *************** *** 32,40 **** Datum xidin(PG_FUNCTION_ARGS) { ! char *str = PG_GETARG_CSTRING(0); ! PG_RETURN_TRANSACTIONID((TransactionId) strtoul(str, NULL, 0)); } Datum --- 32,83 ---- Datum xidin(PG_FUNCTION_ARGS) { ! unsigned long cvt; ! char *endptr; ! char *s = PG_GETARG_CSTRING(0); ! ! if (*s == '\0') ! ereport(ERROR, ! (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), ! errmsg("invalid input syntax for type xid: \"%s\"", ! s))); ! errno = 0; ! cvt = strtoul(s, &endptr, 0); ! ! /* ! * 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 != ERANGE && errno != EINVAL) ! ereport(ERROR, ! (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), ! errmsg("invalid input syntax for type xid: \"%s\"", ! s))); ! ! if (endptr == s) ! ereport(ERROR, ! (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), ! errmsg("invalid input syntax for type xid: \"%s\"", ! s))); ! ! if (errno == ERANGE) ! ereport(ERROR, ! (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), ! errmsg("value \"%s\" is out of range for type xid", s))); ! ! /* allow only whitespace after number */ ! while (*endptr && isspace((unsigned char) *endptr)) ! endptr++; ! if (*endptr) ! ereport(ERROR, ! (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), ! errmsg("invalid input syntax for type xid: \"%s\"", ! s))); ! ! ! PG_RETURN_TRANSACTIONID((TransactionId) cvt); } Datum