@@ -229,8 +229,8 @@ typedef struct FixedDecimalAggState
229
229
230
230
static char * pg_int64tostr (char * str , int64 value );
231
231
static char * pg_int64tostr_zeropad (char * str , int64 value , int64 padding );
232
- static void apply_typmod (int64 value , int32 typmod , int precision , int scale );
233
- static int64 scanfixeddecimal (const char * str , int * precision , int * scale );
232
+ static bool apply_typmod (int64 value , int32 typmod , int precision , int scale , FunctionCallInfo * fcinfo );
233
+ static int64 scanfixeddecimal (const char * str , int * precision , int * scale , FunctionCallInfo * fcinfo );
234
234
static FixedDecimalAggState * makeFixedDecimalAggState (FunctionCallInfo fcinfo );
235
235
static void fixeddecimal_accum (FixedDecimalAggState * state , int64 newval );
236
236
static int64 int8fixeddecimal_internal (int64 arg , const char * typename );
@@ -445,7 +445,7 @@ fixeddecimal2str(int64 val, char *buffer,
445
445
* scanfixeddecimal --- try to parse a string into a fixeddecimal.
446
446
*/
447
447
static int64
448
- scanfixeddecimal (const char * str , int * precision , int * scale )
448
+ scanfixeddecimal (const char * str , int * precision , int * scale , FunctionCallInfo * fcinfo )
449
449
{
450
450
const char * ptr = str ;
451
451
int64 integralpart = 0 ;
@@ -454,6 +454,7 @@ scanfixeddecimal(const char *str, int *precision, int *scale)
454
454
int vprecision = 0 ;
455
455
int vscale = 0 ;
456
456
bool has_seen_sign = false;
457
+ Node * escontext = (* fcinfo )-> context ;
457
458
458
459
/*
459
460
* Do our own scan, rather than relying on sscanf which might be broken
@@ -500,7 +501,7 @@ scanfixeddecimal(const char *str, int *precision, int *scale)
500
501
*/
501
502
if ((* ptr >= 'a' && * ptr <= 'z' ) || (* ptr >= 'A' && * ptr <= 'Z' ))
502
503
{
503
- ereport ( ERROR ,
504
+ ereturn ( escontext , ( Datum ) 0 ,
504
505
(errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
505
506
errmsg ("invalid characters found: cannot cast value \"%s\" to money" ,
506
507
str )));
@@ -520,7 +521,7 @@ scanfixeddecimal(const char *str, int *precision, int *scale)
520
521
{
521
522
if (has_seen_sign )
522
523
{
523
- ereport ( ERROR ,
524
+ ereturn ( escontext , ( Datum ) 0 ,
524
525
(errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
525
526
errmsg ("invalid characters found: cannot cast value \"%s\" to money" ,
526
527
str )));
@@ -539,7 +540,7 @@ scanfixeddecimal(const char *str, int *precision, int *scale)
539
540
vprecision ++ ;
540
541
if ((tmp / 10 ) != integralpart ) /* underflow? */
541
542
{
542
- ereport ( ERROR ,
543
+ ereturn ( escontext , ( Datum ) 0 ,
543
544
(errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
544
545
errmsg ("value \"%s\" is out of range for type fixeddecimal" ,
545
546
str )));
@@ -559,7 +560,7 @@ scanfixeddecimal(const char *str, int *precision, int *scale)
559
560
{
560
561
if (has_seen_sign )
561
562
{
562
- ereport ( ERROR ,
563
+ ereturn ( escontext , ( Datum ) 0 ,
563
564
(errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
564
565
errmsg ("invalid characters found: cannot cast value \"%s\" to money" ,
565
566
str )));
@@ -583,7 +584,7 @@ scanfixeddecimal(const char *str, int *precision, int *scale)
583
584
vprecision ++ ;
584
585
if ((tmp / 10 ) != integralpart ) /* overflow? */
585
586
{
586
- ereport ( ERROR ,
587
+ ereturn ( escontext , ( Datum ) 0 ,
587
588
(errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
588
589
errmsg ("value \"%s\" is out of range for type fixeddecimal" ,
589
590
str )));
@@ -628,7 +629,7 @@ scanfixeddecimal(const char *str, int *precision, int *scale)
628
629
ptr ++ ;
629
630
630
631
if (* ptr != '\0' )
631
- ereport ( ERROR ,
632
+ ereturn ( escontext , ( Datum ) 0 ,
632
633
(errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
633
634
errmsg ("value \"%s\" is out of range for type fixeddecimal" , str )));
634
635
@@ -644,13 +645,13 @@ scanfixeddecimal(const char *str, int *precision, int *scale)
644
645
int64 multiplier = FIXEDDECIMAL_MULTIPLIER ;
645
646
646
647
if (__builtin_mul_overflow (integralpart , multiplier , & value ))
647
- ereport ( ERROR ,
648
+ ereturn ( escontext , ( Datum ) 0 ,
648
649
(errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
649
650
errmsg ("value \"%s\" is out of range for type fixeddecimal" ,
650
651
str )));
651
652
652
653
if (__builtin_sub_overflow (value , fractionalpart , & value ))
653
- ereport ( ERROR ,
654
+ ereturn ( escontext , ( Datum ) 0 ,
654
655
(errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
655
656
errmsg ("value \"%s\" is out of range for type fixeddecimal" ,
656
657
str )));
@@ -661,7 +662,7 @@ scanfixeddecimal(const char *str, int *precision, int *scale)
661
662
if (value != 0 && (!SAMESIGN (value , integralpart ) ||
662
663
!SAMESIGN (value - fractionalpart , value ) ||
663
664
!SAMESIGN (value - fractionalpart , value )))
664
- ereport ( ERROR ,
665
+ ereturn ( escontext , ( Datum ) 0 ,
665
666
(errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
666
667
errmsg ("value \"%s\" is out of range for type fixeddecimal" ,
667
668
str )));
@@ -676,13 +677,13 @@ scanfixeddecimal(const char *str, int *precision, int *scale)
676
677
677
678
#ifdef HAVE_BUILTIN_OVERFLOW
678
679
if (__builtin_mul_overflow (integralpart , FIXEDDECIMAL_MULTIPLIER , & value ))
679
- ereport ( ERROR ,
680
+ ereturn ( escontext , ( Datum ) 0 ,
680
681
(errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
681
682
errmsg ("value \"%s\" is out of range for type fixeddecimal" ,
682
683
str )));
683
684
684
685
if (__builtin_add_overflow (value , fractionalpart , & value ))
685
- ereport ( ERROR ,
686
+ ereturn ( escontext , ( Datum ) 0 ,
686
687
(errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
687
688
errmsg ("value \"%s\" is out of range for type fixeddecimal" ,
688
689
str )));
@@ -692,7 +693,7 @@ scanfixeddecimal(const char *str, int *precision, int *scale)
692
693
if (value != 0 && (!SAMESIGN (value , integralpart ) ||
693
694
!SAMESIGN (value - fractionalpart , value ) ||
694
695
!SAMESIGN (value + fractionalpart , value )))
695
- ereport ( ERROR ,
696
+ ereturn ( escontext , ( Datum ) 0 ,
696
697
(errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
697
698
errmsg ("value \"%s\" is out of range for type fixeddecimal" ,
698
699
str )));
@@ -713,23 +714,24 @@ fixeddecimalin(PG_FUNCTION_ARGS)
713
714
int32 typmod = PG_GETARG_INT32 (2 );
714
715
int precision ;
715
716
int scale ;
716
- int64 result = scanfixeddecimal (str , & precision , & scale );
717
+ int64 result = scanfixeddecimal (str , & precision , & scale , & fcinfo );
717
718
718
- apply_typmod (result , typmod , precision , scale );
719
+ apply_typmod (result , typmod , precision , scale , & fcinfo );
719
720
720
721
PG_RETURN_INT64 (result );
721
722
}
722
723
723
- static void
724
- apply_typmod (int64 value , int32 typmod , int precision , int scale )
724
+ static bool
725
+ apply_typmod (int64 value , int32 typmod , int precision , int scale , FunctionCallInfo * fcinfo )
725
726
{
726
727
int precisionlimit ;
727
728
int scalelimit ;
728
729
int maxdigits ;
730
+ Node * escontext = (* fcinfo )-> context ;
729
731
730
732
/* Do nothing if we have a default typmod (-1) */
731
733
if (typmod < (int32 ) (VARHDRSZ ))
732
- return ;
734
+ return true ;
733
735
734
736
typmod -= VARHDRSZ ;
735
737
precisionlimit = (typmod >> 16 ) & 0xffff ;
@@ -739,13 +741,13 @@ apply_typmod(int64 value, int32 typmod, int precision, int scale)
739
741
if (scale > scalelimit )
740
742
741
743
if (scale != FIXEDDECIMAL_SCALE )
742
- ereport ( ERROR ,
744
+ ereturn ( escontext , false ,
743
745
(errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
744
746
errmsg ("FIXEDDECIMAL scale must be %d" ,
745
747
FIXEDDECIMAL_SCALE )));
746
748
747
749
if (precision > maxdigits )
748
- ereport ( ERROR ,
750
+ ereturn ( escontext , false ,
749
751
(errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
750
752
errmsg ("FIXEDDECIMAL field overflow" ),
751
753
errdetail ("A field with precision %d, scale %d must round to an absolute value less than %s%d." ,
@@ -754,7 +756,7 @@ apply_typmod(int64 value, int32 typmod, int precision, int scale)
754
756
maxdigits ? "10^" : "" ,
755
757
maxdigits ? maxdigits : 1
756
758
)));
757
-
759
+ return true;
758
760
}
759
761
760
762
Datum
@@ -3136,7 +3138,7 @@ char_to_fixeddecimal(PG_FUNCTION_ARGS)
3136
3138
char * str = TextDatumGetCString (PG_GETARG_DATUM (0 ));
3137
3139
int precision ;
3138
3140
int scale ;
3139
- int64 result = scanfixeddecimal (str , & precision , & scale );
3141
+ int64 result = scanfixeddecimal (str , & precision , & scale , & fcinfo );
3140
3142
3141
3143
PG_RETURN_INT64 (result );
3142
3144
}
0 commit comments