diff --git a/src/main/java/com/google/cloud/spanner/jdbc/AbstractJdbcWrapper.java b/src/main/java/com/google/cloud/spanner/jdbc/AbstractJdbcWrapper.java index 022a9a5da..7c387d301 100644 --- a/src/main/java/com/google/cloud/spanner/jdbc/AbstractJdbcWrapper.java +++ b/src/main/java/com/google/cloud/spanner/jdbc/AbstractJdbcWrapper.java @@ -80,6 +80,13 @@ static String getSpannerTypeName(Type type, Dialect dialect) { return Preconditions.checkNotNull(type).getSpannerTypeName(dialect); } + static String getSpannerColumnTypeName(Type type, Dialect dialect) { + if (dialect == Dialect.POSTGRESQL && type.getCode() == Code.ARRAY) { + return "_" + getSpannerTypeName(type.getArrayElementType(), dialect); + } + return getSpannerTypeName(type, dialect); + } + /** * Extract Spanner type name from {@link java.sql.Types} code. * diff --git a/src/main/java/com/google/cloud/spanner/jdbc/JdbcResultSetMetaData.java b/src/main/java/com/google/cloud/spanner/jdbc/JdbcResultSetMetaData.java index f582ce45e..1502a9703 100644 --- a/src/main/java/com/google/cloud/spanner/jdbc/JdbcResultSetMetaData.java +++ b/src/main/java/com/google/cloud/spanner/jdbc/JdbcResultSetMetaData.java @@ -16,7 +16,9 @@ package com.google.cloud.spanner.jdbc; +import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.ResultSet; +import com.google.cloud.spanner.Type; import com.google.cloud.spanner.connection.ConnectionProperties; import com.google.common.base.Preconditions; import java.sql.Connection; @@ -192,7 +194,12 @@ public int getColumnType(int column) { @Override public String getColumnTypeName(int column) { - return spannerResultSet.getColumnType(column - 1).getCode().name(); + Type columnType = spannerResultSet.getColumnType(column - 1); + if (statement instanceof JdbcStatement) { + Dialect dialect = ((JdbcStatement) statement).getConnection().getDialect(); + return getSpannerColumnTypeName(columnType, dialect); + } + return columnType.getCode().name(); } @Override diff --git a/src/test/java/com/google/cloud/spanner/jdbc/AbstractJdbcWrapperTest.java b/src/test/java/com/google/cloud/spanner/jdbc/AbstractJdbcWrapperTest.java index 702477f45..f381d5658 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/AbstractJdbcWrapperTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/AbstractJdbcWrapperTest.java @@ -16,6 +16,7 @@ package com.google.cloud.spanner.jdbc; +import static com.google.cloud.spanner.jdbc.AbstractJdbcWrapper.getSpannerColumnTypeName; import static com.google.cloud.spanner.jdbc.AbstractJdbcWrapper.getSpannerTypeName; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; @@ -502,5 +503,23 @@ public void testPostgreSQLTypeNames() { getSpannerTypeName(Type.array(Type.timestamp()), Dialect.POSTGRESQL)); assertEquals("jsonb[]", getSpannerTypeName(Type.array(Type.pgJsonb()), Dialect.POSTGRESQL)); assertEquals("numeric[]", getSpannerTypeName(Type.array(Type.pgNumeric()), Dialect.POSTGRESQL)); + + assertEquals("_bigint", getSpannerColumnTypeName(Type.array(Type.int64()), Dialect.POSTGRESQL)); + assertEquals("_boolean", getSpannerColumnTypeName(Type.array(Type.bool()), Dialect.POSTGRESQL)); + assertEquals( + "_double precision", + getSpannerColumnTypeName(Type.array(Type.float64()), Dialect.POSTGRESQL)); + assertEquals( + "_character varying", + getSpannerColumnTypeName(Type.array(Type.string()), Dialect.POSTGRESQL)); + assertEquals("_bytea", getSpannerColumnTypeName(Type.array(Type.bytes()), Dialect.POSTGRESQL)); + assertEquals("_date", getSpannerColumnTypeName(Type.array(Type.date()), Dialect.POSTGRESQL)); + assertEquals( + "_timestamp with time zone", + getSpannerColumnTypeName(Type.array(Type.timestamp()), Dialect.POSTGRESQL)); + assertEquals( + "_jsonb", getSpannerColumnTypeName(Type.array(Type.pgJsonb()), Dialect.POSTGRESQL)); + assertEquals( + "_numeric", getSpannerColumnTypeName(Type.array(Type.pgNumeric()), Dialect.POSTGRESQL)); } } diff --git a/src/test/java/com/google/cloud/spanner/jdbc/JdbcResultSetMetaDataTest.java b/src/test/java/com/google/cloud/spanner/jdbc/JdbcResultSetMetaDataTest.java index 36996c801..18f5de94f 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/JdbcResultSetMetaDataTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/JdbcResultSetMetaDataTest.java @@ -23,6 +23,7 @@ import static org.mockito.Mockito.when; import com.google.cloud.ByteArray; +import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.ResultSet; import com.google.cloud.spanner.ResultSets; import com.google.cloud.spanner.Struct; @@ -540,6 +541,30 @@ public void getColumnTypeName() { } } + @Test + public void getColumnTypeNameForPostgreSQL() throws SQLException { + JdbcConnection connection = mock(JdbcConnection.class); + JdbcStatement statement = mock(JdbcStatement.class); + JdbcResultSet resultSet = getFooTestResultSet(statement); + when(connection.getSchema()).thenReturn(""); + when(connection.getCatalog()).thenReturn("test-database"); + when(statement.getConnection()).then(new Returns(connection)); + when(connection.getDialect()).thenReturn(Dialect.POSTGRESQL); + + JdbcResultSetMetaData sub = resultSet.getMetaData(); + + int index = 1; + for (TestColumn col : TEST_COLUMNS) { + if (col.type.getCode() == Type.Code.ARRAY + && col.type.getSpannerTypeName(Dialect.POSTGRESQL).contains("bool")) { + assertEquals("_boolean", sub.getColumnTypeName(index)); + } else if (col.type.getCode() == Type.Code.BOOL) { + assertEquals("boolean", sub.getColumnTypeName(index)); + } + index++; + } + } + @Test public void testIsReadOnly() { for (int i = 0; i < TEST_COLUMNS.size(); i++) {