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/int8.h"
30
31
#include "utils/numeric.h"
31
32
#include "utils/pg_locale.h"
@@ -87,6 +88,82 @@ num_word(Cash value)
87
88
return buf ;
88
89
} /* num_word() */
89
90
91
+ static inline Cash
92
+ cash_pl_cash (Cash c1 , Cash c2 )
93
+ {
94
+ Cash res ;
95
+
96
+ if (unlikely (pg_add_s64_overflow (c1 , c2 , & res )))
97
+ ereport (ERROR ,
98
+ (errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
99
+ errmsg ("money out of range" )));
100
+
101
+ return res ;
102
+ }
103
+
104
+ static inline Cash
105
+ cash_mi_cash (Cash c1 , Cash c2 )
106
+ {
107
+ Cash res ;
108
+
109
+ if (unlikely (pg_sub_s64_overflow (c1 , c2 , & res )))
110
+ ereport (ERROR ,
111
+ (errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
112
+ errmsg ("money out of range" )));
113
+
114
+ return res ;
115
+ }
116
+
117
+ static inline Cash
118
+ cash_mul_float8 (Cash c , float8 f )
119
+ {
120
+ float8 res = rint (float8_mul ((float8 ) c , f ));
121
+
122
+ if (unlikely (isnan (res ) || !FLOAT8_FITS_IN_INT64 (res )))
123
+ ereport (ERROR ,
124
+ (errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
125
+ errmsg ("money out of range" )));
126
+
127
+ return (Cash ) res ;
128
+ }
129
+
130
+ static inline Cash
131
+ cash_div_float8 (Cash c , float8 f )
132
+ {
133
+ float8 res = rint (float8_div ((float8 ) c , f ));
134
+
135
+ if (unlikely (isnan (res ) || !FLOAT8_FITS_IN_INT64 (res )))
136
+ ereport (ERROR ,
137
+ (errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
138
+ errmsg ("money out of range" )));
139
+
140
+ return (Cash ) res ;
141
+ }
142
+
143
+ static inline Cash
144
+ cash_mul_int64 (Cash c , int64 i )
145
+ {
146
+ Cash res ;
147
+
148
+ if (unlikely (pg_mul_s64_overflow (c , i , & res )))
149
+ ereport (ERROR ,
150
+ (errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
151
+ errmsg ("money out of range" )));
152
+
153
+ return res ;
154
+ }
155
+
156
+ static inline Cash
157
+ cash_div_int64 (Cash c , int64 i )
158
+ {
159
+ if (unlikely (i == 0 ))
160
+ ereport (ERROR ,
161
+ (errcode (ERRCODE_DIVISION_BY_ZERO ),
162
+ errmsg ("division by zero" )));
163
+
164
+ return c / i ;
165
+ }
166
+
90
167
/* cash_in()
91
168
* Convert a string to a cash data type.
92
169
* 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