19
19
import com .google .cloud .spanner .Type ;
20
20
import com .google .cloud .spanner .Type .Code ;
21
21
import com .google .common .base .Preconditions ;
22
+ import java .math .BigDecimal ;
23
+ import java .math .BigInteger ;
22
24
import java .sql .Date ;
23
25
import java .sql .SQLException ;
24
26
import java .sql .SQLFeatureNotSupportedException ;
@@ -44,6 +46,7 @@ static int extractColumnType(Type type) {
44
46
if (type .equals (Type .date ())) return Types .DATE ;
45
47
if (type .equals (Type .float64 ())) return Types .DOUBLE ;
46
48
if (type .equals (Type .int64 ())) return Types .BIGINT ;
49
+ if (type .equals (Type .numeric ())) return Types .NUMERIC ;
47
50
if (type .equals (Type .string ())) return Types .NVARCHAR ;
48
51
if (type .equals (Type .timestamp ())) return Types .TIMESTAMP ;
49
52
if (type .getCode () == Code .ARRAY ) return Types .ARRAY ;
@@ -60,6 +63,8 @@ static String getSpannerTypeName(int sqlType) {
60
63
|| sqlType == Types .INTEGER
61
64
|| sqlType == Types .SMALLINT
62
65
|| sqlType == Types .TINYINT ) return Type .int64 ().getCode ().name ();
66
+ if (sqlType == Types .NUMERIC || sqlType == Types .DECIMAL )
67
+ return Type .numeric ().getCode ().name ();
63
68
if (sqlType == Types .NVARCHAR ) return Type .string ().getCode ().name ();
64
69
if (sqlType == Types .TIMESTAMP ) return Type .timestamp ().getCode ().name ();
65
70
if (sqlType == Types .ARRAY ) return Code .ARRAY .name ();
@@ -77,6 +82,7 @@ static String getClassName(int sqlType) {
77
82
|| sqlType == Types .INTEGER
78
83
|| sqlType == Types .SMALLINT
79
84
|| sqlType == Types .TINYINT ) return Long .class .getName ();
85
+ if (sqlType == Types .NUMERIC || sqlType == Types .DECIMAL ) return BigDecimal .class .getName ();
80
86
if (sqlType == Types .NVARCHAR ) return String .class .getName ();
81
87
if (sqlType == Types .TIMESTAMP ) return Timestamp .class .getName ();
82
88
if (sqlType == Types .ARRAY ) return Object .class .getName ();
@@ -96,6 +102,7 @@ static String getClassName(Type type) {
96
102
if (type == Type .date ()) return Date .class .getName ();
97
103
if (type == Type .float64 ()) return Double .class .getName ();
98
104
if (type == Type .int64 ()) return Long .class .getName ();
105
+ if (type == Type .numeric ()) return BigDecimal .class .getName ();
99
106
if (type == Type .string ()) return String .class .getName ();
100
107
if (type == Type .timestamp ()) return Timestamp .class .getName ();
101
108
if (type .getCode () == Code .ARRAY ) {
@@ -104,6 +111,7 @@ static String getClassName(Type type) {
104
111
if (type .getArrayElementType () == Type .date ()) return Date [].class .getName ();
105
112
if (type .getArrayElementType () == Type .float64 ()) return Double [].class .getName ();
106
113
if (type .getArrayElementType () == Type .int64 ()) return Long [].class .getName ();
114
+ if (type .getArrayElementType () == Type .numeric ()) return BigDecimal [].class .getName ();
107
115
if (type .getArrayElementType () == Type .string ()) return String [].class .getName ();
108
116
if (type .getArrayElementType () == Type .timestamp ()) return Timestamp [].class .getName ();
109
117
}
@@ -122,6 +130,16 @@ static byte checkedCastToByte(long val) throws SQLException {
122
130
return (byte ) val ;
123
131
}
124
132
133
+ /** Cast value and throw {@link SQLException} if out-of-range. */
134
+ static byte checkedCastToByte (BigDecimal val ) throws SQLException {
135
+ try {
136
+ return val .byteValueExact ();
137
+ } catch (ArithmeticException e ) {
138
+ throw JdbcSqlExceptionFactory .of (
139
+ String .format (OUT_OF_RANGE_MSG , "byte" , val ), com .google .rpc .Code .OUT_OF_RANGE );
140
+ }
141
+ }
142
+
125
143
/** Cast value and throw {@link SQLException} if out-of-range. */
126
144
static short checkedCastToShort (long val ) throws SQLException {
127
145
if (val > Short .MAX_VALUE || val < Short .MIN_VALUE ) {
@@ -131,6 +149,16 @@ static short checkedCastToShort(long val) throws SQLException {
131
149
return (short ) val ;
132
150
}
133
151
152
+ /** Cast value and throw {@link SQLException} if out-of-range. */
153
+ static short checkedCastToShort (BigDecimal val ) throws SQLException {
154
+ try {
155
+ return val .shortValueExact ();
156
+ } catch (ArithmeticException e ) {
157
+ throw JdbcSqlExceptionFactory .of (
158
+ String .format (OUT_OF_RANGE_MSG , "short" , val ), com .google .rpc .Code .OUT_OF_RANGE );
159
+ }
160
+ }
161
+
134
162
/** Cast value and throw {@link SQLException} if out-of-range. */
135
163
static int checkedCastToInt (long val ) throws SQLException {
136
164
if (val > Integer .MAX_VALUE || val < Integer .MIN_VALUE ) {
@@ -140,6 +168,16 @@ static int checkedCastToInt(long val) throws SQLException {
140
168
return (int ) val ;
141
169
}
142
170
171
+ /** Cast value and throw {@link SQLException} if out-of-range. */
172
+ static int checkedCastToInt (BigDecimal val ) throws SQLException {
173
+ try {
174
+ return val .intValueExact ();
175
+ } catch (ArithmeticException e ) {
176
+ throw JdbcSqlExceptionFactory .of (
177
+ String .format (OUT_OF_RANGE_MSG , "int" , val ), com .google .rpc .Code .OUT_OF_RANGE );
178
+ }
179
+ }
180
+
143
181
/** Cast value and throw {@link SQLException} if out-of-range. */
144
182
static float checkedCastToFloat (double val ) throws SQLException {
145
183
if (val > Float .MAX_VALUE || val < -Float .MAX_VALUE ) {
@@ -163,6 +201,26 @@ static long parseLong(String val) throws SQLException {
163
201
}
164
202
}
165
203
204
+ /** Cast value and throw {@link SQLException} if out-of-range. */
205
+ static BigInteger checkedCastToBigInteger (BigDecimal val ) throws SQLException {
206
+ try {
207
+ return val .toBigIntegerExact ();
208
+ } catch (ArithmeticException e ) {
209
+ throw JdbcSqlExceptionFactory .of (
210
+ String .format (OUT_OF_RANGE_MSG , "BigInteger" , val ), com .google .rpc .Code .OUT_OF_RANGE );
211
+ }
212
+ }
213
+
214
+ /** Cast value and throw {@link SQLException} if out-of-range. */
215
+ static long checkedCastToLong (BigDecimal val ) throws SQLException {
216
+ try {
217
+ return val .longValueExact ();
218
+ } catch (ArithmeticException e ) {
219
+ throw JdbcSqlExceptionFactory .of (
220
+ String .format (OUT_OF_RANGE_MSG , "long" , val ), com .google .rpc .Code .OUT_OF_RANGE );
221
+ }
222
+ }
223
+
166
224
/**
167
225
* Parses the given string value as a double. Throws {@link SQLException} if the string is not a
168
226
* valid double value.
0 commit comments