Skip to content

Commit 52ad1e6

Browse files
committed
Refactor jsonpath's compareDatetime()
This commit refactors come ridiculous coding in compareDatetime(). Also, it provides correct cross-datatype comparison even when one of values overflows during cast. That eliminates dilemma on whether we should suppress overflow errors during cast. Reported-by: Tom Lane Discussion: https://postgr.es/m/32308.1569455803%40sss.pgh.pa.us Discussion: https://postgr.es/m/a5629d0c-8162-7559-16aa-0c8390d6ba5f%40postgrespro.ru Author: Nikita Glukhov, Alexander Korotkov
1 parent a6888fd commit 52ad1e6

File tree

7 files changed

+237
-144
lines changed

7 files changed

+237
-144
lines changed

src/backend/utils/adt/date.c

+24-16
Original file line numberDiff line numberDiff line change
@@ -554,11 +554,12 @@ date_mii(PG_FUNCTION_ARGS)
554554
/*
555555
* Promote date to timestamp.
556556
*
557-
* If 'have_error' is NULL, then errors are thrown, else '*have_error' is set
558-
* and zero is returned.
557+
* On overflow error is thrown if 'overflow' is NULL. Otherwise, '*overflow'
558+
* is set to -1 (+1) when result value exceed lower (upper) boundary and zero
559+
* returned.
559560
*/
560561
Timestamp
561-
date2timestamp_opt_error(DateADT dateVal, bool *have_error)
562+
date2timestamp_opt_overflow(DateADT dateVal, int *overflow)
562563
{
563564
Timestamp result;
564565

@@ -575,9 +576,9 @@ date2timestamp_opt_error(DateADT dateVal, bool *have_error)
575576
*/
576577
if (dateVal >= (TIMESTAMP_END_JULIAN - POSTGRES_EPOCH_JDATE))
577578
{
578-
if (have_error)
579+
if (overflow)
579580
{
580-
*have_error = true;
581+
*overflow = 1;
581582
return (Timestamp) 0;
582583
}
583584
else
@@ -596,22 +597,23 @@ date2timestamp_opt_error(DateADT dateVal, bool *have_error)
596597
}
597598

598599
/*
599-
* Single-argument version of date2timestamp_opt_error().
600+
* Single-argument version of date2timestamp_opt_overflow().
600601
*/
601602
static TimestampTz
602603
date2timestamp(DateADT dateVal)
603604
{
604-
return date2timestamp_opt_error(dateVal, NULL);
605+
return date2timestamp_opt_overflow(dateVal, NULL);
605606
}
606607

607608
/*
608609
* Promote date to timestamp with time zone.
609610
*
610-
* If 'have_error' is NULL, then errors are thrown, else '*have_error' is set
611-
* and zero is returned.
611+
* On overflow error is thrown if 'overflow' is NULL. Otherwise, '*overflow'
612+
* is set to -1 (+1) when result value exceed lower (upper) boundary and zero
613+
* returned.
612614
*/
613615
TimestampTz
614-
date2timestamptz_opt_error(DateADT dateVal, bool *have_error)
616+
date2timestamptz_opt_overflow(DateADT dateVal, int *overflow)
615617
{
616618
TimestampTz result;
617619
struct pg_tm tt,
@@ -631,9 +633,9 @@ date2timestamptz_opt_error(DateADT dateVal, bool *have_error)
631633
*/
632634
if (dateVal >= (TIMESTAMP_END_JULIAN - POSTGRES_EPOCH_JDATE))
633635
{
634-
if (have_error)
636+
if (overflow)
635637
{
636-
*have_error = true;
638+
*overflow = 1;
637639
return (TimestampTz) 0;
638640
}
639641
else
@@ -659,9 +661,15 @@ date2timestamptz_opt_error(DateADT dateVal, bool *have_error)
659661
*/
660662
if (!IS_VALID_TIMESTAMP(result))
661663
{
662-
if (have_error)
664+
if (overflow)
663665
{
664-
*have_error = true;
666+
if (result < MIN_TIMESTAMP)
667+
*overflow = -1;
668+
else
669+
{
670+
Assert(result >= END_TIMESTAMP);
671+
*overflow = 1;
672+
}
665673
return (TimestampTz) 0;
666674
}
667675
else
@@ -677,12 +685,12 @@ date2timestamptz_opt_error(DateADT dateVal, bool *have_error)
677685
}
678686

679687
/*
680-
* Single-argument version of date2timestamptz_opt_error().
688+
* Single-argument version of date2timestamptz_opt_overflow().
681689
*/
682690
static TimestampTz
683691
date2timestamptz(DateADT dateVal)
684692
{
685-
return date2timestamptz_opt_error(dateVal, NULL);
693+
return date2timestamptz_opt_overflow(dateVal, NULL);
686694
}
687695

688696
/*

0 commit comments

Comments
 (0)