Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf2ba1e9

Browse files
committed
Avoid unexpected conversion overflow in planner for distant date values.
The "date" type supports a wider range of dates than int64 timestamps do.However, there is pre-int64-timestamp code in the planner that assumes thatall date values can be converted to timestamp with impunity. Fortunately,what we really need out of the conversion is always a double (float8)value; so even when the date is out of timestamp's range it's possible toproduce a sane answer. All we need is a code path that doesn't try toforce the result into int64. Per trouble report from David Rericha.Back-patch to all supported versions. Although this is surely a cornercase, there's not much point in advertising a date range wider thantimestamp's if we will choke on such values in unexpected places.
1 parent31d2efa commitf2ba1e9

File tree

3 files changed

+36
-2
lines changed

3 files changed

+36
-2
lines changed

‎src/backend/utils/adt/date.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,39 @@ date2timestamptz(DateADT dateVal)
459459
returnresult;
460460
}
461461

462+
/*
463+
* date2timestamp_no_overflow
464+
*
465+
* This is chartered to produce a double value that is numerically
466+
* equivalent to the corresponding Timestamp value, if the date is in the
467+
* valid range of Timestamps, but in any case not throw an overflow error.
468+
* We can do this since the numerical range of double is greater than
469+
* that of non-erroneous timestamps. The results are currently only
470+
* used for statistical estimation purposes.
471+
*/
472+
double
473+
date2timestamp_no_overflow(DateADTdateVal)
474+
{
475+
doubleresult;
476+
477+
if (DATE_IS_NOBEGIN(dateVal))
478+
result=-DBL_MAX;
479+
elseif (DATE_IS_NOEND(dateVal))
480+
result=DBL_MAX;
481+
else
482+
{
483+
#ifdefHAVE_INT64_TIMESTAMP
484+
/* date is days since 2000, timestamp is microseconds since same... */
485+
result=dateVal* (double)USECS_PER_DAY;
486+
#else
487+
/* date is days since 2000, timestamp is seconds since same... */
488+
result=dateVal* (double)SECS_PER_DAY;
489+
#endif
490+
}
491+
492+
returnresult;
493+
}
494+
462495

463496
/*
464497
* Crosstype comparison functions for dates

‎src/backend/utils/adt/selfuncs.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3866,8 +3866,7 @@ convert_timevalue_to_scalar(Datum value, Oid typid)
38663866
returnDatumGetTimestamp(DirectFunctionCall1(abstime_timestamp,
38673867
value));
38683868
caseDATEOID:
3869-
returnDatumGetTimestamp(DirectFunctionCall1(date_timestamp,
3870-
value));
3869+
returndate2timestamp_no_overflow(DatumGetDateADT(value));
38713870
caseINTERVALOID:
38723871
{
38733872
Interval*interval=DatumGetIntervalP(value);

‎src/include/utils/date.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ typedef struct
9191

9292

9393
/* date.c */
94+
externdoubledate2timestamp_no_overflow(DateADTdateVal);
95+
9496
externDatumdate_in(PG_FUNCTION_ARGS);
9597
externDatumdate_out(PG_FUNCTION_ARGS);
9698
externDatumdate_recv(PG_FUNCTION_ARGS);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp