@ -32,106 +32,13 @@
* USER I / O ROUTINES *
* USER I / O ROUTINES *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Parse a single OID and return its value .
*
* If endloc isn ' t NULL , store a pointer to the rest of the string there ,
* so that caller can parse the rest . Otherwise , it ' s an error if anything
* but whitespace follows .
*
* If escontext points to an ErrorSaveContext node , that is filled instead
* of throwing an error ; the caller must check SOFT_ERROR_OCCURRED ( )
* to detect errors .
*/
static Oid
oidin_subr ( const char * s , char * * endloc , Node * escontext )
{
unsigned long cvt ;
char * endptr ;
Oid result ;
if ( * s = = ' \0 ' )
ereturn ( escontext , InvalidOid ,
( errcode ( ERRCODE_INVALID_TEXT_REPRESENTATION ) ,
errmsg ( " invalid input syntax for type %s: \" %s \" " ,
" oid " , 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 ! = ERANGE & & errno ! = EINVAL )
ereturn ( escontext , InvalidOid ,
( errcode ( ERRCODE_INVALID_TEXT_REPRESENTATION ) ,
errmsg ( " invalid input syntax for type %s: \" %s \" " ,
" oid " , s ) ) ) ;
if ( endptr = = s & & * s ! = ' \0 ' )
ereturn ( escontext , InvalidOid ,
( errcode ( ERRCODE_INVALID_TEXT_REPRESENTATION ) ,
errmsg ( " invalid input syntax for type %s: \" %s \" " ,
" oid " , s ) ) ) ;
if ( errno = = ERANGE )
ereturn ( escontext , InvalidOid ,
( errcode ( ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ) ,
errmsg ( " value \" %s \" is out of range for type %s " ,
s , " oid " ) ) ) ;
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 )
ereturn ( escontext , InvalidOid ,
( errcode ( ERRCODE_INVALID_TEXT_REPRESENTATION ) ,
errmsg ( " invalid input syntax for type %s: \" %s \" " ,
" oid " , s ) ) ) ;
}
result = ( Oid ) cvt ;
/*
* Cope with possibility that unsigned long is wider than Oid , in which
* case strtoul will not raise an error for some values that are out of
* the range of Oid .
*
* For backwards compatibility , we want to accept inputs that are given
* with a minus sign , so allow the input value if it matches after either
* signed or unsigned extension to long .
*
* 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 ) result & &
cvt ! = ( unsigned long ) ( ( int ) result ) )
ereturn ( escontext , InvalidOid ,
( errcode ( ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ) ,
errmsg ( " value \" %s \" is out of range for type %s " ,
s , " oid " ) ) ) ;
# endif
return result ;
}
Datum
Datum
oidin ( PG_FUNCTION_ARGS )
oidin ( PG_FUNCTION_ARGS )
{
{
char * s = PG_GETARG_CSTRING ( 0 ) ;
char * s = PG_GETARG_CSTRING ( 0 ) ;
Oid result ;
Oid result ;
result = oid in_subr( s , NULL , fcinfo - > context ) ;
result = uint32in_subr ( s , NULL , " oid " , fcinfo - > context ) ;
PG_RETURN_OID ( result ) ;
PG_RETURN_OID ( result ) ;
}
}
@ -218,7 +125,8 @@ oidvectorin(PG_FUNCTION_ARGS)
oidString + + ;
oidString + + ;
if ( * oidString = = ' \0 ' )
if ( * oidString = = ' \0 ' )
break ;
break ;
result - > values [ n ] = oidin_subr ( oidString , & oidString , escontext ) ;
result - > values [ n ] = uint32in_subr ( oidString , & oidString ,
" oid " , escontext ) ;
if ( SOFT_ERROR_OCCURRED ( escontext ) )
if ( SOFT_ERROR_OCCURRED ( escontext ) )
PG_RETURN_NULL ( ) ;
PG_RETURN_NULL ( ) ;
}
}
@ -339,7 +247,8 @@ oidparse(Node *node)
* constants by the lexer . Accept these if they are valid OID
* constants by the lexer . Accept these if they are valid OID
* strings .
* strings .
*/
*/
return oidin_subr ( castNode ( Float , node ) - > fval , NULL , NULL ) ;
return uint32in_subr ( castNode ( Float , node ) - > fval , NULL ,
" oid " , NULL ) ;
default :
default :
elog ( ERROR , " unrecognized node type: %d " , ( int ) nodeTag ( node ) ) ;
elog ( ERROR , " unrecognized node type: %d " , ( int ) nodeTag ( node ) ) ;
}
}