16
16
import com .facebook .presto .common .block .Block ;
17
17
import com .facebook .presto .common .type .AbstractLongType ;
18
18
import com .facebook .presto .common .type .StandardTypes ;
19
+ import com .facebook .presto .spi .PrestoException ;
19
20
import com .facebook .presto .spi .function .BlockIndex ;
20
21
import com .facebook .presto .spi .function .BlockPosition ;
21
22
import com .facebook .presto .spi .function .IsNull ;
42
43
import static com .facebook .presto .common .function .OperatorType .NEGATION ;
43
44
import static com .facebook .presto .common .function .OperatorType .NOT_EQUAL ;
44
45
import static com .facebook .presto .common .function .OperatorType .SUBTRACT ;
46
+ import static com .facebook .presto .spi .StandardErrorCode .DIVISION_BY_ZERO ;
47
+ import static com .facebook .presto .spi .StandardErrorCode .NUMERIC_VALUE_OUT_OF_RANGE ;
45
48
import static com .facebook .presto .type .IntervalDayTimeType .INTERVAL_DAY_TIME ;
46
49
import static io .airlift .slice .Slices .utf8Slice ;
50
+ import static java .lang .String .format ;
47
51
48
52
public final class IntervalDayTimeOperators
49
53
{
@@ -55,56 +59,103 @@ private IntervalDayTimeOperators()
55
59
@ SqlType (StandardTypes .INTERVAL_DAY_TO_SECOND )
56
60
public static long add (@ SqlType (StandardTypes .INTERVAL_DAY_TO_SECOND ) long left , @ SqlType (StandardTypes .INTERVAL_DAY_TO_SECOND ) long right )
57
61
{
58
- return left + right ;
62
+ try {
63
+ return Math .addExact (left , right );
64
+ }
65
+ catch (ArithmeticException e ) {
66
+ throw new PrestoException (NUMERIC_VALUE_OUT_OF_RANGE , format ("interval_day_to_second addition overflow: %s ms + %s ms" , left , right ), e );
67
+ }
59
68
}
60
69
61
70
@ ScalarOperator (SUBTRACT )
62
71
@ SqlType (StandardTypes .INTERVAL_DAY_TO_SECOND )
63
72
public static long subtract (@ SqlType (StandardTypes .INTERVAL_DAY_TO_SECOND ) long left , @ SqlType (StandardTypes .INTERVAL_DAY_TO_SECOND ) long right )
64
73
{
65
- return left - right ;
74
+ try {
75
+ return Math .subtractExact (left , right );
76
+ }
77
+ catch (ArithmeticException e ) {
78
+ throw new PrestoException (NUMERIC_VALUE_OUT_OF_RANGE , format ("interval_day_to_second subtraction overflow: %s ms - %s ms" , left , right ), e );
79
+ }
66
80
}
67
81
68
82
@ ScalarOperator (MULTIPLY )
69
83
@ SqlType (StandardTypes .INTERVAL_DAY_TO_SECOND )
70
84
public static long multiplyByBigint (@ SqlType (StandardTypes .INTERVAL_DAY_TO_SECOND ) long left , @ SqlType (StandardTypes .BIGINT ) long right )
71
85
{
72
- return left * right ;
86
+ try {
87
+ return Math .multiplyExact (left , right );
88
+ }
89
+ catch (ArithmeticException e ) {
90
+ throw new PrestoException (NUMERIC_VALUE_OUT_OF_RANGE , format ("interval_day_to_second multiply overflow: %s ms * %s" , left , right ), e );
91
+ }
73
92
}
74
93
75
94
@ ScalarOperator (MULTIPLY )
76
95
@ SqlType (StandardTypes .INTERVAL_DAY_TO_SECOND )
77
96
public static long multiplyByDouble (@ SqlType (StandardTypes .INTERVAL_DAY_TO_SECOND ) long left , @ SqlType (StandardTypes .DOUBLE ) double right )
78
97
{
79
- return (long ) (left * right );
98
+ try {
99
+ return Math .addExact (
100
+ (long ) (left * (right - (long ) right )),
101
+ Math .multiplyExact (left , (long ) right ));
102
+ }
103
+ catch (ArithmeticException e ) {
104
+ throw new PrestoException (NUMERIC_VALUE_OUT_OF_RANGE , format ("interval_day_to_second multiply overflow: %s ms * %s" , left , right ), e );
105
+ }
80
106
}
81
107
82
108
@ ScalarOperator (MULTIPLY )
83
109
@ SqlType (StandardTypes .INTERVAL_DAY_TO_SECOND )
84
110
public static long bigintMultiply (@ SqlType (StandardTypes .BIGINT ) long left , @ SqlType (StandardTypes .INTERVAL_DAY_TO_SECOND ) long right )
85
111
{
86
- return left * right ;
112
+ try {
113
+ return Math .multiplyExact (left , right );
114
+ }
115
+ catch (ArithmeticException e ) {
116
+ throw new PrestoException (NUMERIC_VALUE_OUT_OF_RANGE , format ("interval_day_to_second multiply overflow: %s * %s ms" , left , right ), e );
117
+ }
87
118
}
88
119
89
120
@ ScalarOperator (MULTIPLY )
90
121
@ SqlType (StandardTypes .INTERVAL_DAY_TO_SECOND )
91
122
public static long doubleMultiply (@ SqlType (StandardTypes .DOUBLE ) double left , @ SqlType (StandardTypes .INTERVAL_DAY_TO_SECOND ) long right )
92
123
{
93
- return (long ) (left * right );
124
+ try {
125
+ return Math .addExact (
126
+ Math .multiplyExact ((long ) left , right ),
127
+ (long ) ((left - (long ) left ) * right ));
128
+ }
129
+ catch (ArithmeticException e ) {
130
+ throw new PrestoException (NUMERIC_VALUE_OUT_OF_RANGE , format ("interval_day_to_second multiply overflow: %s * %s ms" , left , right ), e );
131
+ }
94
132
}
95
133
96
134
@ ScalarOperator (DIVIDE )
97
135
@ SqlType (StandardTypes .INTERVAL_DAY_TO_SECOND )
98
136
public static long divideByDouble (@ SqlType (StandardTypes .INTERVAL_DAY_TO_SECOND ) long left , @ SqlType (StandardTypes .DOUBLE ) double right )
99
137
{
100
- return (long ) (left / right );
138
+ if (right == 0 ) {
139
+ throw new PrestoException (DIVISION_BY_ZERO , format ("interval_day_to_second division by zero: %s ms / %s" , left , right ));
140
+ }
141
+
142
+ try {
143
+ return multiplyByDouble (left , 1.0 / right );
144
+ } catch (PrestoException e ) {
145
+ throw new PrestoException (NUMERIC_VALUE_OUT_OF_RANGE , format ("interval_day_to_second division overflow: %s ms / %s" , left , right ));
146
+ }
101
147
}
102
148
103
149
@ ScalarOperator (NEGATION )
104
150
@ SqlType (StandardTypes .INTERVAL_DAY_TO_SECOND )
105
151
public static long negate (@ SqlType (StandardTypes .INTERVAL_DAY_TO_SECOND ) long value )
106
152
{
107
- return -value ;
153
+ try {
154
+ return Math .negateExact (value );
155
+ }
156
+ catch (ArithmeticException e ) {
157
+ throw new PrestoException (NUMERIC_VALUE_OUT_OF_RANGE , "interval_day_to_second negation overflow: " + value , e );
158
+ }
108
159
}
109
160
110
161
@ ScalarOperator (EQUAL )
0 commit comments