Skip to content

Commit 23ce386

Browse files
authored
chore: add method for getting the backend type name (#2763)
* chore: add method for getting the backend type name JDBC must be able to return the type name of a query parameter. Currently, that is done with a custom implementation in the JDBC driver. This adds a method to the Spanner client for the same, so the feature is in a more logical place. * chore: add ignored change to clirr
1 parent 247946e commit 23ce386

File tree

5 files changed

+395
-17
lines changed

5 files changed

+395
-17
lines changed

google-cloud-spanner/clirr-ignored-differences.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,4 +455,10 @@
455455
<className>com/google/cloud/spanner/spi/v1/SpannerRpc</className>
456456
<method>java.util.Set getExecuteQueryRetryableCodes()</method>
457457
</difference>
458+
<!-- Added getDefaultSchema() to Dialect enum. -->
459+
<difference>
460+
<differenceType>7013</differenceType>
461+
<className>com/google/cloud/spanner/Dialect</className>
462+
<method>java.lang.String getDefaultSchema()</method>
463+
</difference>
458464
</differences>

google-cloud-spanner/src/main/java/com/google/cloud/spanner/Dialect.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ public String createDatabaseStatementFor(String databaseName) {
3333
public DatabaseDialect toProto() {
3434
return DatabaseDialect.GOOGLE_STANDARD_SQL;
3535
}
36+
37+
@Override
38+
public String getDefaultSchema() {
39+
return "";
40+
}
3641
},
3742
POSTGRESQL {
3843
@Override
@@ -44,6 +49,11 @@ public String createDatabaseStatementFor(String databaseName) {
4449
public DatabaseDialect toProto() {
4550
return DatabaseDialect.POSTGRESQL;
4651
}
52+
53+
@Override
54+
public String getDefaultSchema() {
55+
return "public";
56+
}
4757
};
4858

4959
private static final Map<DatabaseDialect, Dialect> protoToDialect =
@@ -56,6 +66,8 @@ public DatabaseDialect toProto() {
5666

5767
public abstract DatabaseDialect toProto();
5868

69+
public abstract String getDefaultSchema();
70+
5971
public static Dialect fromProto(DatabaseDialect databaseDialect) {
6072
final Dialect dialect = protoToDialect.get(databaseDialect);
6173
if (dialect == null) {

google-cloud-spanner/src/main/java/com/google/cloud/spanner/Type.java

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -234,20 +234,20 @@ private Type(
234234

235235
/** Enumerates the categories of types. */
236236
public enum Code {
237-
UNRECOGNIZED(TypeCode.UNRECOGNIZED),
238-
BOOL(TypeCode.BOOL),
239-
INT64(TypeCode.INT64),
240-
NUMERIC(TypeCode.NUMERIC),
241-
PG_NUMERIC(TypeCode.NUMERIC, TypeAnnotationCode.PG_NUMERIC),
242-
FLOAT64(TypeCode.FLOAT64),
243-
STRING(TypeCode.STRING),
244-
JSON(TypeCode.JSON),
245-
PG_JSONB(TypeCode.JSON, TypeAnnotationCode.PG_JSONB),
246-
BYTES(TypeCode.BYTES),
247-
TIMESTAMP(TypeCode.TIMESTAMP),
248-
DATE(TypeCode.DATE),
249-
ARRAY(TypeCode.ARRAY),
250-
STRUCT(TypeCode.STRUCT);
237+
UNRECOGNIZED(TypeCode.UNRECOGNIZED, "unknown"),
238+
BOOL(TypeCode.BOOL, "boolean"),
239+
INT64(TypeCode.INT64, "bigint"),
240+
NUMERIC(TypeCode.NUMERIC, "unknown"),
241+
PG_NUMERIC(TypeCode.NUMERIC, "numeric", TypeAnnotationCode.PG_NUMERIC),
242+
FLOAT64(TypeCode.FLOAT64, "double precision"),
243+
STRING(TypeCode.STRING, "character varying"),
244+
JSON(TypeCode.JSON, "unknown"),
245+
PG_JSONB(TypeCode.JSON, "jsonb", TypeAnnotationCode.PG_JSONB),
246+
BYTES(TypeCode.BYTES, "bytea"),
247+
TIMESTAMP(TypeCode.TIMESTAMP, "timestamp with time zone"),
248+
DATE(TypeCode.DATE, "date"),
249+
ARRAY(TypeCode.ARRAY, "array"),
250+
STRUCT(TypeCode.STRUCT, "struct");
251251

252252
private static final Map<Entry<TypeCode, TypeAnnotationCode>, Code> protoToCode;
253253

@@ -260,15 +260,17 @@ public enum Code {
260260
protoToCode = builder.build();
261261
}
262262

263+
private final String postgreSQLName;
263264
private final TypeCode typeCode;
264265
private final TypeAnnotationCode typeAnnotationCode;
265266

266-
Code(TypeCode typeCode) {
267-
this(typeCode, TYPE_ANNOTATION_CODE_UNSPECIFIED);
267+
Code(TypeCode typeCode, String postgreSQLName) {
268+
this(typeCode, postgreSQLName, TYPE_ANNOTATION_CODE_UNSPECIFIED);
268269
}
269270

270-
Code(TypeCode typeCode, TypeAnnotationCode typeAnnotationCode) {
271+
Code(TypeCode typeCode, String postgreSQLName, TypeAnnotationCode typeAnnotationCode) {
271272
this.typeCode = typeCode;
273+
this.postgreSQLName = postgreSQLName;
272274
this.typeAnnotationCode = typeAnnotationCode;
273275
}
274276

@@ -293,6 +295,14 @@ public String toString() {
293295
return typeCode.toString() + "<" + typeAnnotationCode.toString() + ">";
294296
}
295297
}
298+
299+
private String getGoogleSQLName() {
300+
return name();
301+
}
302+
303+
private String getPostgreSQLName() {
304+
return postgreSQLName;
305+
}
296306
}
297307

298308
/** Describes an individual field in a {@code STRUCT type}. */
@@ -439,6 +449,31 @@ public String toString() {
439449
return b.toString();
440450
}
441451

452+
/** Returns the type name as used by the database in the given dialect. */
453+
public String getSpannerTypeName(Dialect dialect) {
454+
switch (dialect) {
455+
case POSTGRESQL:
456+
return getTypeNamePostgreSQL();
457+
case GOOGLE_STANDARD_SQL:
458+
default:
459+
return getTypeNameGoogleSQL();
460+
}
461+
}
462+
463+
private String getTypeNameGoogleSQL() {
464+
if (code == Code.ARRAY) {
465+
return code.getGoogleSQLName() + "<" + arrayElementType.getTypeNameGoogleSQL() + ">";
466+
}
467+
return code.getGoogleSQLName();
468+
}
469+
470+
private String getTypeNamePostgreSQL() {
471+
if (code == Code.ARRAY) {
472+
return arrayElementType.getTypeNamePostgreSQL() + "[]";
473+
}
474+
return code.getPostgreSQLName();
475+
}
476+
442477
@Override
443478
public boolean equals(Object o) {
444479
if (this == o) {

google-cloud-spanner/src/test/java/com/google/cloud/spanner/TypeTest.java

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,69 @@ public void testUnrecognizedArrayWithAnnotation() {
517517
assertNotEquals(unrecognizedArray, Type.array(Type.int64()));
518518
}
519519

520+
@Test
521+
public void testGoogleSQLTypeNames() {
522+
assertEquals("INT64", Type.int64().getSpannerTypeName(Dialect.GOOGLE_STANDARD_SQL));
523+
assertEquals("BOOL", Type.bool().getSpannerTypeName(Dialect.GOOGLE_STANDARD_SQL));
524+
assertEquals("FLOAT64", Type.float64().getSpannerTypeName(Dialect.GOOGLE_STANDARD_SQL));
525+
assertEquals("STRING", Type.string().getSpannerTypeName(Dialect.GOOGLE_STANDARD_SQL));
526+
assertEquals("BYTES", Type.bytes().getSpannerTypeName(Dialect.GOOGLE_STANDARD_SQL));
527+
assertEquals("DATE", Type.date().getSpannerTypeName(Dialect.GOOGLE_STANDARD_SQL));
528+
assertEquals("TIMESTAMP", Type.timestamp().getSpannerTypeName(Dialect.GOOGLE_STANDARD_SQL));
529+
assertEquals("JSON", Type.json().getSpannerTypeName(Dialect.GOOGLE_STANDARD_SQL));
530+
assertEquals("NUMERIC", Type.numeric().getSpannerTypeName(Dialect.GOOGLE_STANDARD_SQL));
531+
532+
assertEquals(
533+
"ARRAY<INT64>", Type.array(Type.int64()).getSpannerTypeName(Dialect.GOOGLE_STANDARD_SQL));
534+
assertEquals(
535+
"ARRAY<BOOL>", Type.array(Type.bool()).getSpannerTypeName(Dialect.GOOGLE_STANDARD_SQL));
536+
assertEquals(
537+
"ARRAY<FLOAT64>",
538+
Type.array(Type.float64()).getSpannerTypeName(Dialect.GOOGLE_STANDARD_SQL));
539+
assertEquals(
540+
"ARRAY<STRING>", Type.array(Type.string()).getSpannerTypeName(Dialect.GOOGLE_STANDARD_SQL));
541+
assertEquals(
542+
"ARRAY<BYTES>", Type.array(Type.bytes()).getSpannerTypeName(Dialect.GOOGLE_STANDARD_SQL));
543+
assertEquals(
544+
"ARRAY<DATE>", Type.array(Type.date()).getSpannerTypeName(Dialect.GOOGLE_STANDARD_SQL));
545+
assertEquals(
546+
"ARRAY<TIMESTAMP>",
547+
Type.array(Type.timestamp()).getSpannerTypeName(Dialect.GOOGLE_STANDARD_SQL));
548+
assertEquals(
549+
"ARRAY<JSON>", Type.array(Type.json()).getSpannerTypeName(Dialect.GOOGLE_STANDARD_SQL));
550+
assertEquals(
551+
"ARRAY<NUMERIC>",
552+
Type.array(Type.numeric()).getSpannerTypeName(Dialect.GOOGLE_STANDARD_SQL));
553+
}
554+
555+
@Test
556+
public void testPostgreSQLTypeNames() {
557+
assertEquals("bigint", Type.int64().getSpannerTypeName(Dialect.POSTGRESQL));
558+
assertEquals("boolean", Type.bool().getSpannerTypeName(Dialect.POSTGRESQL));
559+
assertEquals("double precision", Type.float64().getSpannerTypeName(Dialect.POSTGRESQL));
560+
assertEquals("character varying", Type.string().getSpannerTypeName(Dialect.POSTGRESQL));
561+
assertEquals("bytea", Type.bytes().getSpannerTypeName(Dialect.POSTGRESQL));
562+
assertEquals("date", Type.date().getSpannerTypeName(Dialect.POSTGRESQL));
563+
assertEquals(
564+
"timestamp with time zone", Type.timestamp().getSpannerTypeName(Dialect.POSTGRESQL));
565+
assertEquals("jsonb", Type.pgJsonb().getSpannerTypeName(Dialect.POSTGRESQL));
566+
assertEquals("numeric", Type.pgNumeric().getSpannerTypeName(Dialect.POSTGRESQL));
567+
568+
assertEquals("bigint[]", Type.array(Type.int64()).getSpannerTypeName(Dialect.POSTGRESQL));
569+
assertEquals("boolean[]", Type.array(Type.bool()).getSpannerTypeName(Dialect.POSTGRESQL));
570+
assertEquals(
571+
"double precision[]", Type.array(Type.float64()).getSpannerTypeName(Dialect.POSTGRESQL));
572+
assertEquals(
573+
"character varying[]", Type.array(Type.string()).getSpannerTypeName(Dialect.POSTGRESQL));
574+
assertEquals("bytea[]", Type.array(Type.bytes()).getSpannerTypeName(Dialect.POSTGRESQL));
575+
assertEquals("date[]", Type.array(Type.date()).getSpannerTypeName(Dialect.POSTGRESQL));
576+
assertEquals(
577+
"timestamp with time zone[]",
578+
Type.array(Type.timestamp()).getSpannerTypeName(Dialect.POSTGRESQL));
579+
assertEquals("jsonb[]", Type.array(Type.pgJsonb()).getSpannerTypeName(Dialect.POSTGRESQL));
580+
assertEquals("numeric[]", Type.array(Type.pgNumeric()).getSpannerTypeName(Dialect.POSTGRESQL));
581+
}
582+
520583
private static void assertProtoEquals(com.google.spanner.v1.Type proto, String expected) {
521584
MatcherAssert.assertThat(
522585
proto, SpannerMatchers.matchesProto(com.google.spanner.v1.Type.class, expected));

0 commit comments

Comments
 (0)