26
26
#include "libpq/pqformat.h"
27
27
#include "utils/builtins.h"
28
28
#include "utils/cash.h"
29
+ #include "utils/float.h"
29
30
#include "utils/numeric.h"
30
31
#include "utils/pg_locale.h"
31
32
@@ -86,6 +87,82 @@ num_word(Cash value)
86
87
return buf ;
87
88
} /* num_word() */
88
89
90
+ static inline Cash
91
+ cash_pl_cash (Cash c1 , Cash c2 )
92
+ {
93
+ Cash res ;
94
+
95
+ if (unlikely (pg_add_s64_overflow (c1 , c2 , & res )))
96
+ ereport (ERROR ,
97
+ (errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
98
+ errmsg ("money out of range" )));
99
+
100
+ return res ;
101
+ }
102
+
103
+ static inline Cash
104
+ cash_mi_cash (Cash c1 , Cash c2 )
105
+ {
106
+ Cash res ;
107
+
108
+ if (unlikely (pg_sub_s64_overflow (c1 , c2 , & res )))
109
+ ereport (ERROR ,
110
+ (errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
111
+ errmsg ("money out of range" )));
112
+
113
+ return res ;
114
+ }
115
+
116
+ static inline Cash
117
+ cash_mul_float8 (Cash c , float8 f )
118
+ {
119
+ float8 res = rint (float8_mul ((float8 ) c , f ));
120
+
121
+ if (unlikely (isnan (res ) || !FLOAT8_FITS_IN_INT64 (res )))
122
+ ereport (ERROR ,
123
+ (errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
124
+ errmsg ("money out of range" )));
125
+
126
+ return (Cash ) res ;
127
+ }
128
+
129
+ static inline Cash
130
+ cash_div_float8 (Cash c , float8 f )
131
+ {
132
+ float8 res = rint (float8_div ((float8 ) c , f ));
133
+
134
+ if (unlikely (isnan (res ) || !FLOAT8_FITS_IN_INT64 (res )))
135
+ ereport (ERROR ,
136
+ (errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
137
+ errmsg ("money out of range" )));
138
+
139
+ return (Cash ) res ;
140
+ }
141
+
142
+ static inline Cash
143
+ cash_mul_int64 (Cash c , int64 i )
144
+ {
145
+ Cash res ;
146
+
147
+ if (unlikely (pg_mul_s64_overflow (c , i , & res )))
148
+ ereport (ERROR ,
149
+ (errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
150
+ errmsg ("money out of range" )));
151
+
152
+ return res ;
153
+ }
154
+
155
+ static inline Cash
156
+ cash_div_int64 (Cash c , int64 i )
157
+ {
158
+ if (unlikely (i == 0 ))
159
+ ereport (ERROR ,
160
+ (errcode (ERRCODE_DIVISION_BY_ZERO ),
161
+ errmsg ("division by zero" )));
162
+
163
+ return c / i ;
164
+ }
165
+
89
166
/* cash_in()
90
167
* Convert a string to a cash data type.
91
168
* Format is [$]###[,]###[.##]
@@ -612,11 +689,8 @@ cash_pl(PG_FUNCTION_ARGS)
612
689
{
613
690
Cash c1 = PG_GETARG_CASH (0 );
614
691
Cash c2 = PG_GETARG_CASH (1 );
615
- Cash result ;
616
-
617
- result = c1 + c2 ;
618
692
619
- PG_RETURN_CASH (result );
693
+ PG_RETURN_CASH (cash_pl_cash ( c1 , c2 ) );
620
694
}
621
695
622
696
@@ -628,11 +702,8 @@ cash_mi(PG_FUNCTION_ARGS)
628
702
{
629
703
Cash c1 = PG_GETARG_CASH (0 );
630
704
Cash c2 = PG_GETARG_CASH (1 );
631
- Cash result ;
632
-
633
- result = c1 - c2 ;
634
705
635
- PG_RETURN_CASH (result );
706
+ PG_RETURN_CASH (cash_mi_cash ( c1 , c2 ) );
636
707
}
637
708
638
709
@@ -664,10 +735,8 @@ cash_mul_flt8(PG_FUNCTION_ARGS)
664
735
{
665
736
Cash c = PG_GETARG_CASH (0 );
666
737
float8 f = PG_GETARG_FLOAT8 (1 );
667
- Cash result ;
668
738
669
- result = rint (c * f );
670
- PG_RETURN_CASH (result );
739
+ PG_RETURN_CASH (cash_mul_float8 (c , f ));
671
740
}
672
741
673
742
@@ -679,10 +748,8 @@ flt8_mul_cash(PG_FUNCTION_ARGS)
679
748
{
680
749
float8 f = PG_GETARG_FLOAT8 (0 );
681
750
Cash c = PG_GETARG_CASH (1 );
682
- Cash result ;
683
751
684
- result = rint (f * c );
685
- PG_RETURN_CASH (result );
752
+ PG_RETURN_CASH (cash_mul_float8 (c , f ));
686
753
}
687
754
688
755
@@ -694,15 +761,8 @@ cash_div_flt8(PG_FUNCTION_ARGS)
694
761
{
695
762
Cash c = PG_GETARG_CASH (0 );
696
763
float8 f = PG_GETARG_FLOAT8 (1 );
697
- Cash result ;
698
764
699
- if (f == 0.0 )
700
- ereport (ERROR ,
701
- (errcode (ERRCODE_DIVISION_BY_ZERO ),
702
- errmsg ("division by zero" )));
703
-
704
- result = rint (c / f );
705
- PG_RETURN_CASH (result );
765
+ PG_RETURN_CASH (cash_div_float8 (c , f ));
706
766
}
707
767
708
768
@@ -714,10 +774,8 @@ cash_mul_flt4(PG_FUNCTION_ARGS)
714
774
{
715
775
Cash c = PG_GETARG_CASH (0 );
716
776
float4 f = PG_GETARG_FLOAT4 (1 );
717
- Cash result ;
718
777
719
- result = rint (c * (float8 ) f );
720
- PG_RETURN_CASH (result );
778
+ PG_RETURN_CASH (cash_mul_float8 (c , (float8 ) f ));
721
779
}
722
780
723
781
@@ -729,10 +787,8 @@ flt4_mul_cash(PG_FUNCTION_ARGS)
729
787
{
730
788
float4 f = PG_GETARG_FLOAT4 (0 );
731
789
Cash c = PG_GETARG_CASH (1 );
732
- Cash result ;
733
790
734
- result = rint ((float8 ) f * c );
735
- PG_RETURN_CASH (result );
791
+ PG_RETURN_CASH (cash_mul_float8 (c , (float8 ) f ));
736
792
}
737
793
738
794
@@ -745,15 +801,8 @@ cash_div_flt4(PG_FUNCTION_ARGS)
745
801
{
746
802
Cash c = PG_GETARG_CASH (0 );
747
803
float4 f = PG_GETARG_FLOAT4 (1 );
748
- Cash result ;
749
-
750
- if (f == 0.0 )
751
- ereport (ERROR ,
752
- (errcode (ERRCODE_DIVISION_BY_ZERO ),
753
- errmsg ("division by zero" )));
754
804
755
- result = rint (c / (float8 ) f );
756
- PG_RETURN_CASH (result );
805
+ PG_RETURN_CASH (cash_div_float8 (c , (float8 ) f ));
757
806
}
758
807
759
808
@@ -765,10 +814,8 @@ cash_mul_int8(PG_FUNCTION_ARGS)
765
814
{
766
815
Cash c = PG_GETARG_CASH (0 );
767
816
int64 i = PG_GETARG_INT64 (1 );
768
- Cash result ;
769
817
770
- result = c * i ;
771
- PG_RETURN_CASH (result );
818
+ PG_RETURN_CASH (cash_mul_int64 (c , i ));
772
819
}
773
820
774
821
@@ -780,10 +827,8 @@ int8_mul_cash(PG_FUNCTION_ARGS)
780
827
{
781
828
int64 i = PG_GETARG_INT64 (0 );
782
829
Cash c = PG_GETARG_CASH (1 );
783
- Cash result ;
784
830
785
- result = i * c ;
786
- PG_RETURN_CASH (result );
831
+ PG_RETURN_CASH (cash_mul_int64 (c , i ));
787
832
}
788
833
789
834
/* cash_div_int8()
@@ -794,16 +839,8 @@ cash_div_int8(PG_FUNCTION_ARGS)
794
839
{
795
840
Cash c = PG_GETARG_CASH (0 );
796
841
int64 i = PG_GETARG_INT64 (1 );
797
- Cash result ;
798
-
799
- if (i == 0 )
800
- ereport (ERROR ,
801
- (errcode (ERRCODE_DIVISION_BY_ZERO ),
802
- errmsg ("division by zero" )));
803
842
804
- result = c / i ;
805
-
806
- PG_RETURN_CASH (result );
843
+ PG_RETURN_CASH (cash_div_int64 (c , i ));
807
844
}
808
845
809
846
@@ -815,10 +852,8 @@ cash_mul_int4(PG_FUNCTION_ARGS)
815
852
{
816
853
Cash c = PG_GETARG_CASH (0 );
817
854
int32 i = PG_GETARG_INT32 (1 );
818
- Cash result ;
819
855
820
- result = c * i ;
821
- PG_RETURN_CASH (result );
856
+ PG_RETURN_CASH (cash_mul_int64 (c , (int64 ) i ));
822
857
}
823
858
824
859
@@ -830,10 +865,8 @@ int4_mul_cash(PG_FUNCTION_ARGS)
830
865
{
831
866
int32 i = PG_GETARG_INT32 (0 );
832
867
Cash c = PG_GETARG_CASH (1 );
833
- Cash result ;
834
868
835
- result = i * c ;
836
- PG_RETURN_CASH (result );
869
+ PG_RETURN_CASH (cash_mul_int64 (c , (int64 ) i ));
837
870
}
838
871
839
872
@@ -846,16 +879,8 @@ cash_div_int4(PG_FUNCTION_ARGS)
846
879
{
847
880
Cash c = PG_GETARG_CASH (0 );
848
881
int32 i = PG_GETARG_INT32 (1 );
849
- Cash result ;
850
-
851
- if (i == 0 )
852
- ereport (ERROR ,
853
- (errcode (ERRCODE_DIVISION_BY_ZERO ),
854
- errmsg ("division by zero" )));
855
-
856
- result = c / i ;
857
882
858
- PG_RETURN_CASH (result );
883
+ PG_RETURN_CASH (cash_div_int64 ( c , ( int64 ) i ) );
859
884
}
860
885
861
886
@@ -867,10 +892,8 @@ cash_mul_int2(PG_FUNCTION_ARGS)
867
892
{
868
893
Cash c = PG_GETARG_CASH (0 );
869
894
int16 s = PG_GETARG_INT16 (1 );
870
- Cash result ;
871
895
872
- result = c * s ;
873
- PG_RETURN_CASH (result );
896
+ PG_RETURN_CASH (cash_mul_int64 (c , (int64 ) s ));
874
897
}
875
898
876
899
/* int2_mul_cash()
@@ -881,10 +904,8 @@ int2_mul_cash(PG_FUNCTION_ARGS)
881
904
{
882
905
int16 s = PG_GETARG_INT16 (0 );
883
906
Cash c = PG_GETARG_CASH (1 );
884
- Cash result ;
885
907
886
- result = s * c ;
887
- PG_RETURN_CASH (result );
908
+ PG_RETURN_CASH (cash_mul_int64 (c , (int64 ) s ));
888
909
}
889
910
890
911
/* cash_div_int2()
@@ -896,15 +917,8 @@ cash_div_int2(PG_FUNCTION_ARGS)
896
917
{
897
918
Cash c = PG_GETARG_CASH (0 );
898
919
int16 s = PG_GETARG_INT16 (1 );
899
- Cash result ;
900
920
901
- if (s == 0 )
902
- ereport (ERROR ,
903
- (errcode (ERRCODE_DIVISION_BY_ZERO ),
904
- errmsg ("division by zero" )));
905
-
906
- result = c / s ;
907
- PG_RETURN_CASH (result );
921
+ PG_RETURN_CASH (cash_div_int64 (c , (int64 ) s ));
908
922
}
909
923
910
924
/* cashlarger()
0 commit comments