Skip to content

Commit c5baf6b

Browse files
committed
[yugabyte#5408] [YSQL] Error suppression support for upcoming jsonpath .datetime() method
Summary: Original Postgres commit was 5bc450629b31a0b6986e668056d5bd36792412d2 Commit message was: Add support of error suppression in some date and time manipulation functions as it's required for jsonpath .datetime() method support. This commit doesn't use PG_TRY()/PG_CATCH() in order to implement that. Instead, it provides internal versions of date and time functions used, which support error suppression. Discussion: https://postgr.es/m/CAPpHfdsZgYEra_PeCLGNoXOWYx6iU-S3wF8aX0ObQUcZU%2B4XTw%40mail.gmail.com Author: Alexander Korotkov, Nikita Glukhov Reviewed-by: Anastasia Lubennikova, Peter Eisentraut Test Plan: Build yugabyte db and run tests via Jenkins Reviewers: mihnea, jason Reviewed By: jason Subscribers: yql Differential Revision: https://phabricator.dev.yugabyte.com/D9545
1 parent cb6fbe8 commit c5baf6b

File tree

7 files changed

+479
-220
lines changed

7 files changed

+479
-220
lines changed

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

Lines changed: 71 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -558,13 +558,15 @@ date_mii(PG_FUNCTION_ARGS)
558558
PG_RETURN_DATEADT(result);
559559
}
560560

561+
561562
/*
562-
* Internal routines for promoting date to timestamp and timestamp with
563-
* time zone
563+
* Promote date to timestamp.
564+
*
565+
* If 'have_error' is NULL, then errors are thrown, else '*have_error' is set
566+
* and zero is returned.
564567
*/
565-
566-
static Timestamp
567-
date2timestamp(DateADT dateVal)
568+
Timestamp
569+
date2timestamp_opt_error(DateADT dateVal, bool *have_error)
568570
{
569571
Timestamp result;
570572

@@ -580,9 +582,19 @@ date2timestamp(DateADT dateVal)
580582
* boundary need be checked for overflow.
581583
*/
582584
if (dateVal >= (TIMESTAMP_END_JULIAN - POSTGRES_EPOCH_JDATE))
583-
ereport(ERROR,
584-
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
585-
errmsg("date out of range for timestamp")));
585+
{
586+
if (have_error)
587+
{
588+
*have_error = true;
589+
return (Timestamp) 0;
590+
}
591+
else
592+
{
593+
ereport(ERROR,
594+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
595+
errmsg("date out of range for timestamp")));
596+
}
597+
}
586598

587599
/* date is days since 2000, timestamp is microseconds since same... */
588600
result = dateVal * USECS_PER_DAY;
@@ -591,8 +603,23 @@ date2timestamp(DateADT dateVal)
591603
return result;
592604
}
593605

606+
/*
607+
* Single-argument version of date2timestamp_opt_error().
608+
*/
594609
static TimestampTz
595-
date2timestamptz(DateADT dateVal)
610+
date2timestamp(DateADT dateVal)
611+
{
612+
return date2timestamp_opt_error(dateVal, NULL);
613+
}
614+
615+
/*
616+
* Promote date to timestamp with time zone.
617+
*
618+
* If 'have_error' is NULL, then errors are thrown, else '*have_error' is set
619+
* and zero is returned.
620+
*/
621+
TimestampTz
622+
date2timestamptz_opt_error(DateADT dateVal, bool *have_error)
596623
{
597624
TimestampTz result;
598625
struct pg_tm tt,
@@ -611,9 +638,19 @@ date2timestamptz(DateADT dateVal)
611638
* boundary need be checked for overflow.
612639
*/
613640
if (dateVal >= (TIMESTAMP_END_JULIAN - POSTGRES_EPOCH_JDATE))
614-
ereport(ERROR,
615-
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
616-
errmsg("date out of range for timestamp")));
641+
{
642+
if (have_error)
643+
{
644+
*have_error = true;
645+
return (TimestampTz) 0;
646+
}
647+
else
648+
{
649+
ereport(ERROR,
650+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
651+
errmsg("date out of range for timestamp")));
652+
}
653+
}
617654

618655
j2date(dateVal + POSTGRES_EPOCH_JDATE,
619656
&(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
@@ -629,14 +666,33 @@ date2timestamptz(DateADT dateVal)
629666
* of time zone, check for allowed timestamp range after adding tz.
630667
*/
631668
if (!IS_VALID_TIMESTAMP(result))
632-
ereport(ERROR,
633-
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
634-
errmsg("date out of range for timestamp")));
669+
{
670+
if (have_error)
671+
{
672+
*have_error = true;
673+
return (TimestampTz) 0;
674+
}
675+
else
676+
{
677+
ereport(ERROR,
678+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
679+
errmsg("date out of range for timestamp")));
680+
}
681+
}
635682
}
636683

637684
return result;
638685
}
639686

687+
/*
688+
* Single-argument version of date2timestamptz_opt_error().
689+
*/
690+
static TimestampTz
691+
date2timestamptz(DateADT dateVal)
692+
{
693+
return date2timestamptz_opt_error(dateVal, NULL);
694+
}
695+
640696
/*
641697
* date2timestamp_no_overflow
642698
*

0 commit comments

Comments
 (0)