From 7964273efd81290c6a128a8f025c838dd2e131bd Mon Sep 17 00:00:00 2001 From: Sakthivel Subramanian Date: Tue, 7 Oct 2025 00:09:58 +0530 Subject: [PATCH 1/2] chore: Support text/varchar type in JDBC --- .../google/cloud/spanner/jdbc/JdbcArray.java | 8 ++-- .../cloud/spanner/jdbc/JdbcDataType.java | 37 +++++++++++++++++++ .../DatabaseMetaData_GetColumns.sql | 10 ++++- 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/google/cloud/spanner/jdbc/JdbcArray.java b/src/main/java/com/google/cloud/spanner/jdbc/JdbcArray.java index 80bea84eb..1dd83f817 100644 --- a/src/main/java/com/google/cloud/spanner/jdbc/JdbcArray.java +++ b/src/main/java/com/google/cloud/spanner/jdbc/JdbcArray.java @@ -60,9 +60,11 @@ class JdbcArray implements Array { * the elements array is not compatible with the base type of the array. */ static JdbcArray createArray(String typeName, Object[] elements) throws SQLException { - for (JdbcDataType type : JdbcDataType.values()) { - if (type.getTypeName().equalsIgnoreCase(typeName)) { - return new JdbcArray(type, elements); + if (typeName != null) { + for (JdbcDataType type : JdbcDataType.values()) { + if (type.matches(typeName)) { + return new JdbcArray(type, elements); + } } } throw JdbcSqlExceptionFactory.of( diff --git a/src/main/java/com/google/cloud/spanner/jdbc/JdbcDataType.java b/src/main/java/com/google/cloud/spanner/jdbc/JdbcDataType.java index 6a77cecc2..1870589fd 100644 --- a/src/main/java/com/google/cloud/spanner/jdbc/JdbcDataType.java +++ b/src/main/java/com/google/cloud/spanner/jdbc/JdbcDataType.java @@ -16,6 +16,7 @@ package com.google.cloud.spanner.jdbc; +import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.ResultSet; import com.google.cloud.spanner.Struct; import com.google.cloud.spanner.Type; @@ -154,6 +155,7 @@ public Type getSpannerType() { }, FLOAT64 { private final Set> classes = new HashSet<>(Arrays.asList(Float.class, Double.class)); + private final Set aliases = new HashSet<>(Collections.singletonList("float8")); @Override public int getSqlType() { @@ -184,6 +186,11 @@ public List getArrayElements(ResultSet rs, int columnIndex) { public Type getSpannerType() { return Type.float64(); } + + @Override + public Set getAliases() { + return aliases; + } }, INT64 { private final Set> classes = @@ -220,6 +227,9 @@ public Type getSpannerType() { } }, NUMERIC { + + private final Set aliases = new HashSet<>(Collections.singletonList("decimal")); + @Override public int getSqlType() { return Types.NUMERIC; @@ -244,6 +254,11 @@ public List getArrayElements(ResultSet rs, int columnIndex) { public Type getSpannerType() { return Type.numeric(); } + + @Override + public Set getAliases() { + return aliases; + } }, PG_NUMERIC { @Override @@ -272,6 +287,8 @@ public Type getSpannerType() { } }, STRING { + private final Set aliases = new HashSet<>(Arrays.asList("varchar", "text")); + @Override public int getSqlType() { return Types.NVARCHAR; @@ -296,6 +313,11 @@ public List getArrayElements(ResultSet rs, int columnIndex) { public Type getSpannerType() { return Type.string(); } + + @Override + public Set getAliases() { + return aliases; + } }, JSON { @Override @@ -498,6 +520,21 @@ public Type getSpannerType() { public abstract Type getSpannerType(); + public Set getAliases() { + return Collections.emptySet(); + } + + /*** + * @param typeName type of the column + * @return true if type name matches current type name or matches with one of postgres aliases + * or if it matches equivalent postgres type. + */ + public boolean matches(String typeName) { + return getTypeName().equalsIgnoreCase(typeName) + || getAliases().contains(typeName.toLowerCase()) + || getSpannerType().getSpannerTypeName(Dialect.POSTGRESQL).equalsIgnoreCase(typeName); + } + // TODO: Implement and use this method for all types. public int getPrecision() { throw new UnsupportedOperationException(); diff --git a/src/main/resources/com/google/cloud/spanner/jdbc/postgresql/DatabaseMetaData_GetColumns.sql b/src/main/resources/com/google/cloud/spanner/jdbc/postgresql/DatabaseMetaData_GetColumns.sql index a8260ff13..b0ca39944 100644 --- a/src/main/resources/com/google/cloud/spanner/jdbc/postgresql/DatabaseMetaData_GetColumns.sql +++ b/src/main/resources/com/google/cloud/spanner/jdbc/postgresql/DatabaseMetaData_GetColumns.sql @@ -28,7 +28,15 @@ SELECT TABLE_CATALOG AS "TABLE_CAT", TABLE_SCHEMA AS "TABLE_SCHEM", TABLE_NAME A WHEN DATA_TYPE = 'jsonb' THEN -9 WHEN DATA_TYPE = 'timestamp with time zone' THEN 93 END AS "DATA_TYPE", - DATA_TYPE AS "TYPE_NAME", + CASE + WHEN DATA_TYPE LIKE 'ARRAY' THEN + CASE + WHEN spanner_type LIKE '%[]' THEN + CONCAT('_', REPLACE(spanner_type, '[]', '')) + ELSE spanner_type + END + ELSE DATA_TYPE + END AS "TYPE_NAME", CASE WHEN DATA_TYPE LIKE 'ARRAY' THEN 0 WHEN DATA_TYPE = 'boolean' THEN NULL From 6de8f82bfe459e36af52cd8dc7c9c451da07f621 Mon Sep 17 00:00:00 2001 From: Sakthivel Subramanian Date: Wed, 22 Oct 2025 19:00:42 +0530 Subject: [PATCH 2/2] Addressed comments --- .../com/google/cloud/spanner/jdbc/JdbcDataType.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/google/cloud/spanner/jdbc/JdbcDataType.java b/src/main/java/com/google/cloud/spanner/jdbc/JdbcDataType.java index 1870589fd..c80db5302 100644 --- a/src/main/java/com/google/cloud/spanner/jdbc/JdbcDataType.java +++ b/src/main/java/com/google/cloud/spanner/jdbc/JdbcDataType.java @@ -188,7 +188,7 @@ public Type getSpannerType() { } @Override - public Set getAliases() { + public Set getPostgreSQLAliases() { return aliases; } }, @@ -256,7 +256,7 @@ public Type getSpannerType() { } @Override - public Set getAliases() { + public Set getPostgreSQLAliases() { return aliases; } }, @@ -315,7 +315,7 @@ public Type getSpannerType() { } @Override - public Set getAliases() { + public Set getPostgreSQLAliases() { return aliases; } }, @@ -520,7 +520,7 @@ public Type getSpannerType() { public abstract Type getSpannerType(); - public Set getAliases() { + public Set getPostgreSQLAliases() { return Collections.emptySet(); } @@ -529,9 +529,9 @@ public Set getAliases() { * @return true if type name matches current type name or matches with one of postgres aliases * or if it matches equivalent postgres type. */ - public boolean matches(String typeName) { + boolean matches(String typeName) { return getTypeName().equalsIgnoreCase(typeName) - || getAliases().contains(typeName.toLowerCase()) + || getPostgreSQLAliases().contains(typeName.toLowerCase()) || getSpannerType().getSpannerTypeName(Dialect.POSTGRESQL).equalsIgnoreCase(typeName); }