Skip to content

Commit 1194956

Browse files
Support all the array types
1 parent 0cbdd7c commit 1194956

File tree

5 files changed

+91
-28
lines changed

5 files changed

+91
-28
lines changed

src/main/java/com/google/cloud/spanner/jdbc/JdbcArray.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,11 @@ class JdbcArray implements Array {
6060
* the elements array is not compatible with the base type of the array.
6161
*/
6262
static JdbcArray createArray(String typeName, Object[] elements) throws SQLException {
63-
for (JdbcDataType type : JdbcDataType.values()) {
64-
if (type.getTypeName().equalsIgnoreCase(typeName)) {
65-
return new JdbcArray(type, elements);
63+
if(typeName != null) {
64+
for (JdbcDataType type : JdbcDataType.values()) {
65+
if (type.getTypeName().equalsIgnoreCase(typeName) || type.getAliases().contains(typeName.toLowerCase())) {
66+
return new JdbcArray(type, elements);
67+
}
6668
}
6769
}
6870
throw JdbcSqlExceptionFactory.of(
@@ -91,7 +93,11 @@ private JdbcArray(JdbcDataType type, Object[] elements) throws SQLException {
9193
java.lang.reflect.Array.newInstance(
9294
elements.getClass().getComponentType(), elements.length);
9395
} else {
94-
this.data = java.lang.reflect.Array.newInstance(type.getJavaClass(), elements.length);
96+
Class<?> clazz = type.getJavaClass();
97+
if(elements.length > 0 && type.getSupportedJavaClasses().contains(elements[0].getClass())) {
98+
clazz = elements[0].getClass();
99+
}
100+
this.data = java.lang.reflect.Array.newInstance(clazz, elements.length);
95101
}
96102
try {
97103
System.arraycopy(elements, 0, this.data, 0, elements.length);

src/main/java/com/google/cloud/spanner/jdbc/JdbcDataType.java

Lines changed: 56 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,43 @@
2424
import java.sql.Date;
2525
import java.sql.Timestamp;
2626
import java.sql.Types;
27+
import java.time.LocalDate;
28+
import java.util.ArrayList;
2729
import java.util.Arrays;
2830
import java.util.Collections;
2931
import java.util.HashSet;
3032
import java.util.List;
3133
import java.util.Set;
3234
import java.util.UUID;
35+
import java.util.stream.Collectors;
3336

3437
/** Enum for mapping Cloud Spanner data types to Java classes and JDBC SQL {@link Types}. */
3538
enum JdbcDataType {
39+
INTEGER {
40+
public int getSqlType() {
41+
return Types.INTEGER;
42+
}
43+
44+
@Override
45+
public Class<Integer> getJavaClass() {
46+
return Integer.class;
47+
}
48+
49+
@Override
50+
public Code getCode() {
51+
return Code.INT64;
52+
}
53+
54+
@Override
55+
public List<Integer> getArrayElements(ResultSet rs, int columnIndex) {
56+
return rs.getLongList(columnIndex).stream().map(Long::intValue).collect(Collectors.toList());
57+
}
58+
59+
@Override
60+
public Type getSpannerType() {
61+
return Type.int64();
62+
}
63+
},
3664
BOOL {
3765
@Override
3866
public int getSqlType() {
@@ -58,6 +86,11 @@ public List<Boolean> getArrayElements(ResultSet rs, int columnIndex) {
5886
public Type getSpannerType() {
5987
return Type.bool();
6088
}
89+
90+
@Override
91+
public List<String> getAliases() {
92+
return Collections.singletonList("boolean");
93+
}
6194
},
6295
BYTES {
6396
@Override
@@ -86,6 +119,8 @@ public Type getSpannerType() {
86119
}
87120
},
88121
DATE {
122+
private final Set<Class<?>> classes = new HashSet<>(Arrays.asList(Date.class, LocalDate.class));
123+
89124
@Override
90125
public int getSqlType() {
91126
return Types.DATE;
@@ -96,6 +131,11 @@ public Class<Date> getJavaClass() {
96131
return Date.class;
97132
}
98133

134+
@Override
135+
public Set<? extends Class<?>> getSupportedJavaClasses() {
136+
return classes;
137+
}
138+
99139
@Override
100140
public Code getCode() {
101141
return Code.DATE;
@@ -218,6 +258,11 @@ public List<Long> getArrayElements(ResultSet rs, int columnIndex) {
218258
public Type getSpannerType() {
219259
return Type.int64();
220260
}
261+
262+
@Override
263+
public List<String> getAliases() {
264+
return Collections.singletonList("bigint");
265+
}
221266
},
222267
NUMERIC {
223268
@Override
@@ -244,6 +289,11 @@ public List<BigDecimal> getArrayElements(ResultSet rs, int columnIndex) {
244289
public Type getSpannerType() {
245290
return Type.numeric();
246291
}
292+
293+
@Override
294+
public List<String> getAliases() {
295+
return Collections.singletonList("decimal");
296+
}
247297
},
248298
PG_NUMERIC {
249299
@Override
@@ -296,31 +346,10 @@ public List<String> getArrayElements(ResultSet rs, int columnIndex) {
296346
public Type getSpannerType() {
297347
return Type.string();
298348
}
299-
},
300-
TEXT {
301-
@Override
302-
public int getSqlType() {
303-
return Types.NVARCHAR;
304-
}
305-
306-
@Override
307-
public Class<String> getJavaClass() {
308-
return String.class;
309-
}
310349

311350
@Override
312-
public Code getCode() {
313-
return Code.STRING;
314-
}
315-
316-
@Override
317-
public List<String> getArrayElements(ResultSet rs, int columnIndex) {
318-
return rs.getStringList(columnIndex);
319-
}
320-
321-
@Override
322-
public Type getSpannerType() {
323-
return Type.string();
351+
public List<String> getAliases() {
352+
return Arrays.asList("text");
324353
}
325354
},
326355
JSON {
@@ -524,6 +553,10 @@ public Type getSpannerType() {
524553

525554
public abstract Type getSpannerType();
526555

556+
public List<String> getAliases() {
557+
return new ArrayList<>();
558+
}
559+
527560
// TODO: Implement and use this method for all types.
528561
public int getPrecision() {
529562
throw new UnsupportedOperationException();

src/main/java/com/google/cloud/spanner/jdbc/JdbcParameterStore.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,8 @@ private Builder setArrayValue(ValueBinder<Builder> binder, int type, Object valu
914914
}
915915
} else if (Date[].class.isAssignableFrom(value.getClass())) {
916916
return binder.toDateArray(JdbcTypeConverter.toGoogleDates((Date[]) value));
917+
} else if (LocalDate[].class.isAssignableFrom(value.getClass())) {
918+
return binder.toDateArray(JdbcTypeConverter.toGoogleDates((LocalDate[]) value));
917919
} else if (Timestamp[].class.isAssignableFrom(value.getClass())) {
918920
return binder.toTimestampArray(JdbcTypeConverter.toGoogleTimestamps((Timestamp[]) value));
919921
} else if (UUID[].class.isAssignableFrom(value.getClass())) {

src/main/java/com/google/cloud/spanner/jdbc/JdbcTypeConverter.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,10 @@ static Date toGoogleDate(java.sql.Time date) {
425425
return Date.fromYearMonthDay(1970, 1, 1);
426426
}
427427

428+
static Date toGoogleDate(LocalDate date) {
429+
return Date.fromYearMonthDay(date.getYear(), date.getMonthValue(), date.getDayOfMonth());
430+
}
431+
428432
@SuppressWarnings("deprecation")
429433
static Date toGoogleDate(java.sql.Timestamp date) {
430434
return date == null
@@ -440,6 +444,14 @@ static List<Date> toGoogleDates(java.sql.Date[] dates) {
440444
return res;
441445
}
442446

447+
static List<Date> toGoogleDates(LocalDate[] dates) {
448+
List<com.google.cloud.Date> res = new ArrayList<>(dates.length);
449+
for (LocalDate date : dates) {
450+
res.add(toGoogleDate(date));
451+
}
452+
return res;
453+
}
454+
443455
static java.sql.Date toSqlDate(Date date) {
444456
return toSqlDate(date, Calendar.getInstance());
445457
}

src/main/resources/com/google/cloud/spanner/jdbc/postgresql/DatabaseMetaData_GetColumns.sql

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,17 @@ SELECT TABLE_CATALOG AS "TABLE_CAT", TABLE_SCHEMA AS "TABLE_SCHEM", TABLE_NAME A
2929
WHEN DATA_TYPE = 'timestamp with time zone' THEN 93
3030
END AS "DATA_TYPE",
3131
CASE
32-
WHEN spanner_type LIKE 'character varying[]' then '_varchar'
32+
WHEN DATA_TYPE LIKE 'ARRAY' THEN
33+
CASE
34+
WHEN spanner_type LIKE '%[]' THEN
35+
CONCAT('_',
36+
REPLACE(
37+
REPLACE(
38+
REPLACE(spanner_type, '[]', ''),
39+
'character varying', 'varchar'),
40+
'boolean', 'bool'))
41+
ELSE spanner_type
42+
END
3343
ELSE DATA_TYPE
3444
END AS "TYPE_NAME",
3545
CASE

0 commit comments

Comments
 (0)