@ -74,7 +74,8 @@ typedef struct
static TimeOffset time2t ( const int hour , const int min , const int sec , const fsec_t fsec ) ;
static TimeOffset time2t ( const int hour , const int min , const int sec , const fsec_t fsec ) ;
static Timestamp dt2local ( Timestamp dt , int timezone ) ;
static Timestamp dt2local ( Timestamp dt , int timezone ) ;
static void AdjustIntervalForTypmod ( Interval * interval , int32 typmod ) ;
static bool AdjustIntervalForTypmod ( Interval * interval , int32 typmod ,
Node * escontext ) ;
static TimestampTz timestamp2timestamptz ( Timestamp timestamp ) ;
static TimestampTz timestamp2timestamptz ( Timestamp timestamp ) ;
static Timestamp timestamptz2timestamp ( TimestampTz timestamp ) ;
static Timestamp timestamptz2timestamp ( TimestampTz timestamp ) ;
@ -145,11 +146,11 @@ Datum
timestamp_in ( PG_FUNCTION_ARGS )
timestamp_in ( PG_FUNCTION_ARGS )
{
{
char * str = PG_GETARG_CSTRING ( 0 ) ;
char * str = PG_GETARG_CSTRING ( 0 ) ;
# ifdef NOT_USED
# ifdef NOT_USED
Oid typelem = PG_GETARG_OID ( 1 ) ;
Oid typelem = PG_GETARG_OID ( 1 ) ;
# endif
# endif
int32 typmod = PG_GETARG_INT32 ( 2 ) ;
int32 typmod = PG_GETARG_INT32 ( 2 ) ;
Node * escontext = fcinfo - > context ;
Timestamp result ;
Timestamp result ;
fsec_t fsec ;
fsec_t fsec ;
struct pg_tm tt ,
struct pg_tm tt ,
@ -169,13 +170,16 @@ timestamp_in(PG_FUNCTION_ARGS)
dterr = DecodeDateTime ( field , ftype , nf ,
dterr = DecodeDateTime ( field , ftype , nf ,
& dtype , tm , & fsec , & tz , & extra ) ;
& dtype , tm , & fsec , & tz , & extra ) ;
if ( dterr ! = 0 )
if ( dterr ! = 0 )
DateTimeParseError ( dterr , & extra , str , " timestamp " ) ;
{
DateTimeParseError ( dterr , & extra , str , " timestamp " , escontext ) ;
PG_RETURN_NULL ( ) ;
}
switch ( dtype )
switch ( dtype )
{
{
case DTK_DATE :
case DTK_DATE :
if ( tm2timestamp ( tm , fsec , NULL , & result ) ! = 0 )
if ( tm2timestamp ( tm , fsec , NULL , & result ) ! = 0 )
ereport ( ERROR ,
ereturn ( escontext , ( Datum ) 0 ,
( errcode ( ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ) ,
( errcode ( ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ) ,
errmsg ( " timestamp out of range: \" %s \" " , str ) ) ) ;
errmsg ( " timestamp out of range: \" %s \" " , str ) ) ) ;
break ;
break ;
@ -198,7 +202,7 @@ timestamp_in(PG_FUNCTION_ARGS)
TIMESTAMP_NOEND ( result ) ;
TIMESTAMP_NOEND ( result ) ;
}
}
AdjustTimestampForTypmod ( & result , typmod ) ;
AdjustTimestampForTypmod ( & result , typmod , escontext ) ;
PG_RETURN_TIMESTAMP ( result ) ;
PG_RETURN_TIMESTAMP ( result ) ;
}
}
@ -257,7 +261,7 @@ timestamp_recv(PG_FUNCTION_ARGS)
( errcode ( ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ) ,
( errcode ( ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ) ,
errmsg ( " timestamp out of range " ) ) ) ;
errmsg ( " timestamp out of range " ) ) ) ;
AdjustTimestampForTypmod ( & timestamp , typmod ) ;
AdjustTimestampForTypmod ( & timestamp , typmod , NULL ) ;
PG_RETURN_TIMESTAMP ( timestamp ) ;
PG_RETURN_TIMESTAMP ( timestamp ) ;
}
}
@ -328,17 +332,20 @@ timestamp_scale(PG_FUNCTION_ARGS)
result = timestamp ;
result = timestamp ;
AdjustTimestampForTypmod ( & result , typmod ) ;
AdjustTimestampForTypmod ( & result , typmod , NULL ) ;
PG_RETURN_TIMESTAMP ( result ) ;
PG_RETURN_TIMESTAMP ( result ) ;
}
}
/*
/*
* AdjustTimestampForTypmodError - - - round off a timestamp to suit given typmod
* AdjustTimestampForTypmod - - - round off a timestamp to suit given typmod
* Works for either timestamp or timestamptz .
* Works for either timestamp or timestamptz .
*
* Returns true on success , false on failure ( if escontext points to an
* ErrorSaveContext ; otherwise errors are thrown ) .
*/
*/
bool
bool
AdjustTimestampForTypmodError ( Timestamp * time , int32 typmod , bool * error )
AdjustTimestampForTypmod ( Timestamp * time , int32 typmod , Node * escontext )
{
{
static const int64 TimestampScales [ MAX_TIMESTAMP_PRECISION + 1 ] = {
static const int64 TimestampScales [ MAX_TIMESTAMP_PRECISION + 1 ] = {
INT64CONST ( 1000000 ) ,
INT64CONST ( 1000000 ) ,
@ -364,18 +371,10 @@ AdjustTimestampForTypmodError(Timestamp *time, int32 typmod, bool *error)
& & ( typmod ! = - 1 ) & & ( typmod ! = MAX_TIMESTAMP_PRECISION ) )
& & ( typmod ! = - 1 ) & & ( typmod ! = MAX_TIMESTAMP_PRECISION ) )
{
{
if ( typmod < 0 | | typmod > MAX_TIMESTAMP_PRECISION )
if ( typmod < 0 | | typmod > MAX_TIMESTAMP_PRECISION )
{
ereturn ( escontext , false ,
if ( error )
{
* error = true ;
return false ;
}
ereport ( ERROR ,
( errcode ( ERRCODE_INVALID_PARAMETER_VALUE ) ,
( errcode ( ERRCODE_INVALID_PARAMETER_VALUE ) ,
errmsg ( " timestamp(%d) precision must be between %d and %d " ,
errmsg ( " timestamp(%d) precision must be between %d and %d " ,
typmod , 0 , MAX_TIMESTAMP_PRECISION ) ) ) ;
typmod , 0 , MAX_TIMESTAMP_PRECISION ) ) ) ;
}
if ( * time > = INT64CONST ( 0 ) )
if ( * time > = INT64CONST ( 0 ) )
{
{
@ -392,12 +391,6 @@ AdjustTimestampForTypmodError(Timestamp *time, int32 typmod, bool *error)
return true ;
return true ;
}
}
void
AdjustTimestampForTypmod ( Timestamp * time , int32 typmod )
{
( void ) AdjustTimestampForTypmodError ( time , typmod , NULL ) ;
}
/* timestamptz_in()
/* timestamptz_in()
* Convert a string to internal form .
* Convert a string to internal form .
*/
*/
@ -405,11 +398,11 @@ Datum
timestamptz_in ( PG_FUNCTION_ARGS )
timestamptz_in ( PG_FUNCTION_ARGS )
{
{
char * str = PG_GETARG_CSTRING ( 0 ) ;
char * str = PG_GETARG_CSTRING ( 0 ) ;
# ifdef NOT_USED
# ifdef NOT_USED
Oid typelem = PG_GETARG_OID ( 1 ) ;
Oid typelem = PG_GETARG_OID ( 1 ) ;
# endif
# endif
int32 typmod = PG_GETARG_INT32 ( 2 ) ;
int32 typmod = PG_GETARG_INT32 ( 2 ) ;
Node * escontext = fcinfo - > context ;
TimestampTz result ;
TimestampTz result ;
fsec_t fsec ;
fsec_t fsec ;
struct pg_tm tt ,
struct pg_tm tt ,
@ -429,13 +422,17 @@ timestamptz_in(PG_FUNCTION_ARGS)
dterr = DecodeDateTime ( field , ftype , nf ,
dterr = DecodeDateTime ( field , ftype , nf ,
& dtype , tm , & fsec , & tz , & extra ) ;
& dtype , tm , & fsec , & tz , & extra ) ;
if ( dterr ! = 0 )
if ( dterr ! = 0 )
DateTimeParseError ( dterr , & extra , str , " timestamp with time zone " ) ;
{
DateTimeParseError ( dterr , & extra , str , " timestamp with time zone " ,
escontext ) ;
PG_RETURN_NULL ( ) ;
}
switch ( dtype )
switch ( dtype )
{
{
case DTK_DATE :
case DTK_DATE :
if ( tm2timestamp ( tm , fsec , & tz , & result ) ! = 0 )
if ( tm2timestamp ( tm , fsec , & tz , & result ) ! = 0 )
ereport ( ERROR ,
ereturn ( escontext , ( Datum ) 0 ,
( errcode ( ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ) ,
( errcode ( ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ) ,
errmsg ( " timestamp out of range: \" %s \" " , str ) ) ) ;
errmsg ( " timestamp out of range: \" %s \" " , str ) ) ) ;
break ;
break ;
@ -458,7 +455,7 @@ timestamptz_in(PG_FUNCTION_ARGS)
TIMESTAMP_NOEND ( result ) ;
TIMESTAMP_NOEND ( result ) ;
}
}
AdjustTimestampForTypmod ( & result , typmod ) ;
AdjustTimestampForTypmod ( & result , typmod , escontext ) ;
PG_RETURN_TIMESTAMPTZ ( result ) ;
PG_RETURN_TIMESTAMPTZ ( result ) ;
}
}
@ -525,7 +522,7 @@ parse_sane_timezone(struct pg_tm *tm, text *zone)
false ) ;
false ) ;
dterr = DecodeTimezoneAbbrev ( 0 , lowzone , & type , & val , & tzp , & extra ) ;
dterr = DecodeTimezoneAbbrev ( 0 , lowzone , & type , & val , & tzp , & extra ) ;
if ( dterr )
if ( dterr )
DateTimeParseError ( dterr , & extra , NULL , NULL ) ;
DateTimeParseError ( dterr , & extra , NULL , NULL , NULL ) ;
if ( type = = TZ | | type = = DTZ )
if ( type = = TZ | | type = = DTZ )
{
{
@ -824,7 +821,7 @@ timestamptz_recv(PG_FUNCTION_ARGS)
( errcode ( ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ) ,
( errcode ( ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ) ,
errmsg ( " timestamp out of range " ) ) ) ;
errmsg ( " timestamp out of range " ) ) ) ;
AdjustTimestampForTypmod ( & timestamp , typmod ) ;
AdjustTimestampForTypmod ( & timestamp , typmod , NULL ) ;
PG_RETURN_TIMESTAMPTZ ( timestamp ) ;
PG_RETURN_TIMESTAMPTZ ( timestamp ) ;
}
}
@ -873,7 +870,7 @@ timestamptz_scale(PG_FUNCTION_ARGS)
result = timestamp ;
result = timestamp ;
AdjustTimestampForTypmod ( & result , typmod ) ;
AdjustTimestampForTypmod ( & result , typmod , NULL ) ;
PG_RETURN_TIMESTAMPTZ ( result ) ;
PG_RETURN_TIMESTAMPTZ ( result ) ;
}
}
@ -889,11 +886,11 @@ Datum
interval_in ( PG_FUNCTION_ARGS )
interval_in ( PG_FUNCTION_ARGS )
{
{
char * str = PG_GETARG_CSTRING ( 0 ) ;
char * str = PG_GETARG_CSTRING ( 0 ) ;
# ifdef NOT_USED
# ifdef NOT_USED
Oid typelem = PG_GETARG_OID ( 1 ) ;
Oid typelem = PG_GETARG_OID ( 1 ) ;
# endif
# endif
int32 typmod = PG_GETARG_INT32 ( 2 ) ;
int32 typmod = PG_GETARG_INT32 ( 2 ) ;
Node * escontext = fcinfo - > context ;
Interval * result ;
Interval * result ;
struct pg_itm_in tt ,
struct pg_itm_in tt ,
* itm_in = & tt ;
* itm_in = & tt ;
@ -931,7 +928,8 @@ interval_in(PG_FUNCTION_ARGS)
{
{
if ( dterr = = DTERR_FIELD_OVERFLOW )
if ( dterr = = DTERR_FIELD_OVERFLOW )
dterr = DTERR_INTERVAL_OVERFLOW ;
dterr = DTERR_INTERVAL_OVERFLOW ;
DateTimeParseError ( dterr , & extra , str , " interval " ) ;
DateTimeParseError ( dterr , & extra , str , " interval " , escontext ) ;
PG_RETURN_NULL ( ) ;
}
}
result = ( Interval * ) palloc ( sizeof ( Interval ) ) ;
result = ( Interval * ) palloc ( sizeof ( Interval ) ) ;
@ -940,7 +938,7 @@ interval_in(PG_FUNCTION_ARGS)
{
{
case DTK_DELTA :
case DTK_DELTA :
if ( itmin2interval ( itm_in , result ) ! = 0 )
if ( itmin2interval ( itm_in , result ) ! = 0 )
ereport ( ERROR ,
ereturn ( escontext , ( Datum ) 0 ,
( errcode ( ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ) ,
( errcode ( ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ) ,
errmsg ( " interval out of range " ) ) ) ;
errmsg ( " interval out of range " ) ) ) ;
break ;
break ;
@ -950,7 +948,7 @@ interval_in(PG_FUNCTION_ARGS)
dtype , str ) ;
dtype , str ) ;
}
}
AdjustIntervalForTypmod ( result , typmod ) ;
AdjustIntervalForTypmod ( result , typmod , escontext ) ;
PG_RETURN_INTERVAL_P ( result ) ;
PG_RETURN_INTERVAL_P ( result ) ;
}
}
@ -994,7 +992,7 @@ interval_recv(PG_FUNCTION_ARGS)
interval - > day = pq_getmsgint ( buf , sizeof ( interval - > day ) ) ;
interval - > day = pq_getmsgint ( buf , sizeof ( interval - > day ) ) ;
interval - > month = pq_getmsgint ( buf , sizeof ( interval - > month ) ) ;
interval - > month = pq_getmsgint ( buf , sizeof ( interval - > month ) ) ;
AdjustIntervalForTypmod ( interval , typmod ) ;
AdjustIntervalForTypmod ( interval , typmod , NULL ) ;
PG_RETURN_INTERVAL_P ( interval ) ;
PG_RETURN_INTERVAL_P ( interval ) ;
}
}
@ -1318,7 +1316,7 @@ interval_scale(PG_FUNCTION_ARGS)
result = palloc ( sizeof ( Interval ) ) ;
result = palloc ( sizeof ( Interval ) ) ;
* result = * interval ;
* result = * interval ;
AdjustIntervalForTypmod ( result , typmod ) ;
AdjustIntervalForTypmod ( result , typmod , NULL ) ;
PG_RETURN_INTERVAL_P ( result ) ;
PG_RETURN_INTERVAL_P ( result ) ;
}
}
@ -1326,9 +1324,13 @@ interval_scale(PG_FUNCTION_ARGS)
/*
/*
* Adjust interval for specified precision , in both YEAR to SECOND
* Adjust interval for specified precision , in both YEAR to SECOND
* range and sub - second precision .
* range and sub - second precision .
*
* Returns true on success , false on failure ( if escontext points to an
* ErrorSaveContext ; otherwise errors are thrown ) .
*/
*/
static void
static bool
AdjustIntervalForTypmod ( Interval * interval , int32 typmod )
AdjustIntervalForTypmod ( Interval * interval , int32 typmod ,
Node * escontext )
{
{
static const int64 IntervalScales [ MAX_INTERVAL_PRECISION + 1 ] = {
static const int64 IntervalScales [ MAX_INTERVAL_PRECISION + 1 ] = {
INT64CONST ( 1000000 ) ,
INT64CONST ( 1000000 ) ,
@ -1468,7 +1470,7 @@ AdjustIntervalForTypmod(Interval *interval, int32 typmod)
if ( precision ! = INTERVAL_FULL_PRECISION )
if ( precision ! = INTERVAL_FULL_PRECISION )
{
{
if ( precision < 0 | | precision > MAX_INTERVAL_PRECISION )
if ( precision < 0 | | precision > MAX_INTERVAL_PRECISION )
ereport ( ERROR ,
ereturn ( escontext , false ,
( errcode ( ERRCODE_INVALID_PARAMETER_VALUE ) ,
( errcode ( ERRCODE_INVALID_PARAMETER_VALUE ) ,
errmsg ( " interval(%d) precision must be between %d and %d " ,
errmsg ( " interval(%d) precision must be between %d and %d " ,
precision , 0 , MAX_INTERVAL_PRECISION ) ) ) ;
precision , 0 , MAX_INTERVAL_PRECISION ) ) ) ;
@ -1489,6 +1491,8 @@ AdjustIntervalForTypmod(Interval *interval, int32 typmod)
}
}
}
}
}
}
return true ;
}
}
/*
/*
@ -1609,7 +1613,7 @@ current_timestamp(PG_FUNCTION_ARGS)
ts = GetCurrentTransactionStartTimestamp ( ) ;
ts = GetCurrentTransactionStartTimestamp ( ) ;
if ( typmod > = 0 )
if ( typmod > = 0 )
AdjustTimestampForTypmod ( & ts , typmod ) ;
AdjustTimestampForTypmod ( & ts , typmod , NULL ) ;
return TimestampTzGetDatum ( ts ) ;
return TimestampTzGetDatum ( ts ) ;
}
}
@ -1630,7 +1634,7 @@ sql_localtimestamp(PG_FUNCTION_ARGS)
ts = timestamptz2timestamp ( GetCurrentTransactionStartTimestamp ( ) ) ;
ts = timestamptz2timestamp ( GetCurrentTransactionStartTimestamp ( ) ) ;
if ( typmod > = 0 )
if ( typmod > = 0 )
AdjustTimestampForTypmod ( & ts , typmod ) ;
AdjustTimestampForTypmod ( & ts , typmod , NULL ) ;
return TimestampGetDatum ( ts ) ;
return TimestampGetDatum ( ts ) ;
}
}
@ -4324,7 +4328,7 @@ timestamptz_trunc_zone(PG_FUNCTION_ARGS)
dterr = DecodeTimezoneAbbrev ( 0 , lowzone , & type , & val , & tzp , & extra ) ;
dterr = DecodeTimezoneAbbrev ( 0 , lowzone , & type , & val , & tzp , & extra ) ;
if ( dterr )
if ( dterr )
DateTimeParseError ( dterr , & extra , NULL , NULL ) ;
DateTimeParseError ( dterr , & extra , NULL , NULL , NULL ) ;
if ( type = = TZ | | type = = DTZ )
if ( type = = TZ | | type = = DTZ )
{
{
@ -5452,7 +5456,7 @@ timestamp_zone(PG_FUNCTION_ARGS)
dterr = DecodeTimezoneAbbrev ( 0 , lowzone , & type , & val , & tzp , & extra ) ;
dterr = DecodeTimezoneAbbrev ( 0 , lowzone , & type , & val , & tzp , & extra ) ;
if ( dterr )
if ( dterr )
DateTimeParseError ( dterr , & extra , NULL , NULL ) ;
DateTimeParseError ( dterr , & extra , NULL , NULL , NULL ) ;
if ( type = = TZ | | type = = DTZ )
if ( type = = TZ | | type = = DTZ )
{
{
@ -5708,7 +5712,7 @@ timestamptz_zone(PG_FUNCTION_ARGS)
dterr = DecodeTimezoneAbbrev ( 0 , lowzone , & type , & val , & tzp , & extra ) ;
dterr = DecodeTimezoneAbbrev ( 0 , lowzone , & type , & val , & tzp , & extra ) ;
if ( dterr )
if ( dterr )
DateTimeParseError ( dterr , & extra , NULL , NULL ) ;
DateTimeParseError ( dterr , & extra , NULL , NULL , NULL ) ;
if ( type = = TZ | | type = = DTZ )
if ( type = = TZ | | type = = DTZ )
{
{