From 4dc633c8bf0b899867b23437d64aa53d35941bfd Mon Sep 17 00:00:00 2001 From: lixiachen Date: Tue, 16 Sep 2025 11:00:36 -0400 Subject: [PATCH] misc: Support Proto/Enum types in testproxy Also add schemaBundleId to SchemalessProto/Enum types Change-Id: I8878817ea7f194ce9d51939c1aae314304281b52 --- .../google/cloud/bigtable/common/Type.java | 32 +++++++--- .../cloud/bigtable/common/TypeTest.java | 46 +++++++++------ .../AbstractProtoStructReaderTest.java | 51 ++++++++++------ .../data/v2/internal/ProtoStructTest.java | 19 ++++-- .../data/v2/internal/ResultSetImplTest.java | 6 +- .../data/v2/models/sql/SqlTypeTest.java | 58 +++++++++++++------ .../sql/ProtoRowsMergingStateMachineTest.java | 4 +- .../data/v2/stub/sql/SqlProtoFactory.java | 11 ++-- .../testproxy/ResultSetSerializer.java | 19 +++++- 9 files changed, 170 insertions(+), 76 deletions(-) diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/common/Type.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/common/Type.java index 29add532b239..35a11f8c5bc3 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/common/Type.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/common/Type.java @@ -505,16 +505,19 @@ public int hashCode() { abstract class SchemalessProto implements SqlType.Proto { public static SchemalessProto fromProto(com.google.bigtable.v2.Type.Proto proto) { - return create(proto.getMessageName()); + return create(proto.getMessageName(), proto.getSchemaBundleId()); } - public static SchemalessProto create(java.lang.String messageName) { - return new AutoValue_Type_SchemalessProto(messageName); + public static SchemalessProto create( + java.lang.String messageName, java.lang.String schemaBundleId) { + return new AutoValue_Type_SchemalessProto(messageName, schemaBundleId); } @Override public abstract java.lang.String getMessageName(); + public abstract java.lang.String schemaBundleId(); + @Override public Parser getParserForType() { throw new UnsupportedOperationException( @@ -529,7 +532,12 @@ public Code getCode() { @Override public java.lang.String toString() { - return getCode().name() + "{messageName=" + getMessageName() + "}"; + return getCode().name() + + "{messageName=" + + getMessageName() + + ", schemaBundleId=" + + schemaBundleId() + + "}"; } } @@ -544,15 +552,18 @@ public java.lang.String toString() { abstract class SchemalessEnum implements SqlType.Enum { public static SchemalessEnum fromProto(com.google.bigtable.v2.Type.Enum proto) { - return create(proto.getEnumName()); + return create(proto.getEnumName(), proto.getSchemaBundleId()); } - public static SchemalessEnum create(java.lang.String enumName) { - return new AutoValue_Type_SchemalessEnum(enumName); + public static SchemalessEnum create( + java.lang.String enumName, java.lang.String schemaBundleId) { + return new AutoValue_Type_SchemalessEnum(enumName, schemaBundleId); } public abstract java.lang.String getEnumName(); + public abstract java.lang.String schemaBundleId(); + @Override public Function getForNumber() { throw new UnsupportedOperationException( @@ -567,7 +578,12 @@ public Code getCode() { @Override public java.lang.String toString() { - return getCode().name() + "{enumName=" + getEnumName() + "}"; + return getCode().name() + + "{enumName=" + + getEnumName() + + ", schemaBundleId=" + + schemaBundleId() + + "}"; } } diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/common/TypeTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/common/TypeTest.java index 0e103cac4bd1..d5c51451ca71 100644 --- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/common/TypeTest.java +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/common/TypeTest.java @@ -57,9 +57,10 @@ public void simpleTypes_TypeToString() { assertThat(Type.Timestamp.create().toString()).isEqualTo("TIMESTAMP"); assertThat(Type.Date.create().toString()).isEqualTo("DATE"); assertThat(Type.SchemalessStruct.create().toString()).isEqualTo("STRUCT"); - assertThat(Type.SchemalessProto.create("MyMessage").toString()) - .isEqualTo("PROTO{messageName=MyMessage}"); - assertThat(Type.SchemalessEnum.create("MyEnum").toString()).isEqualTo("ENUM{enumName=MyEnum}"); + assertThat(Type.SchemalessProto.create("MyMessage", "my_bundle").toString()) + .isEqualTo("PROTO{messageName=MyMessage, schemaBundleId=my_bundle}"); + assertThat(Type.SchemalessEnum.create("MyEnum", "other_bundle").toString()) + .isEqualTo("ENUM{enumName=MyEnum, schemaBundleId=other_bundle}"); } @Test @@ -123,37 +124,48 @@ public void map_equals() { @Test public void proto_equals() { - assertThat(Type.SchemalessProto.create("MyMessage")) - .isEqualTo(Type.SchemalessProto.create("MyMessage")); + assertThat(Type.SchemalessProto.create("MyMessage", "my_bundle")) + .isEqualTo(Type.SchemalessProto.create("MyMessage", "my_bundle")); assertThat(Type.Proto.create(Singer.getDefaultInstance())) .isEqualTo(Type.Proto.create(Singer.getDefaultInstance())); - assertThat(Type.SchemalessProto.create("MyMessage")) - .isNotEqualTo(Type.SchemalessProto.create("AnotherMessage")); + assertThat(Type.SchemalessProto.create("MyMessage", "my_bundle")) + .isNotEqualTo(Type.SchemalessProto.create("AnotherMessage", "my_bundle")); + assertThat(Type.SchemalessProto.create("MyMessage", "my_bundle")) + .isNotEqualTo(Type.SchemalessProto.create("MyMessage", "another_bundle")); assertThat(Type.Proto.create(Singer.getDefaultInstance())) .isNotEqualTo(Type.Proto.create(Album.getDefaultInstance())); - assertThat(Type.SchemalessProto.create("com.google.cloud.bigtable.data.v2.test.Singer")) + assertThat( + Type.SchemalessProto.create( + "com.google.cloud.bigtable.data.v2.test.Singer", "my_bundle")) .isNotEqualTo(Type.Proto.create(Singer.getDefaultInstance())); assertThat(Type.Proto.create(Singer.getDefaultInstance())) - .isNotEqualTo(Type.SchemalessProto.create("com.google.cloud.bigtable.data.v2.test.Singer")); + .isNotEqualTo( + Type.SchemalessProto.create( + "com.google.cloud.bigtable.data.v2.test.Singer", "my_bundle")); } @Test public void enum_equals() { - assertThat(Type.SchemalessEnum.create("MyEnum")) - .isEqualTo(Type.SchemalessEnum.create("MyEnum")); + assertThat(Type.SchemalessEnum.create("MyEnum", "my_bundle")) + .isEqualTo(Type.SchemalessEnum.create("MyEnum", "my_bundle")); assertThat(Type.Enum.create(Genre::forNumber)).isEqualTo(Type.Enum.create(Genre::forNumber)); - assertThat(Type.SchemalessEnum.create("MyEnum")) - .isNotEqualTo(Type.SchemalessEnum.create("AnotherEnum")); + assertThat(Type.SchemalessEnum.create("MyEnum", "my_bundle")) + .isNotEqualTo(Type.SchemalessEnum.create("AnotherEnum", "my_bundle")); + assertThat(Type.SchemalessEnum.create("MyEnum", "my_bundle")) + .isNotEqualTo(Type.SchemalessEnum.create("MyEnum", "another_bundle")); assertThat(Type.Enum.create(Genre::forNumber)) .isNotEqualTo(Type.Enum.create(Format::forNumber)); - assertThat(Type.SchemalessEnum.create("com.google.cloud.bigtable.data.v2.test.Genre")) + assertThat( + Type.SchemalessEnum.create("com.google.cloud.bigtable.data.v2.test.Genre", "my_bundle")) .isNotEqualTo(Type.Enum.create(Genre::forNumber)); assertThat(Type.Enum.create(Genre::forNumber)) - .isNotEqualTo(Type.SchemalessEnum.create("com.google.cloud.bigtable.data.v2.test.Genre")); + .isNotEqualTo( + Type.SchemalessEnum.create( + "com.google.cloud.bigtable.data.v2.test.Genre", "my_bundle")); } @Test @@ -230,13 +242,13 @@ public void schemalessStruct_throwsExceptionOnSchemaAccess() { @Test public void schemalessProto_throwsExceptionOnGetParser() { - SchemalessProto proto = Type.SchemalessProto.create("MyMessage"); + SchemalessProto proto = Type.SchemalessProto.create("MyMessage", "my_bundle"); assertThrows(UnsupportedOperationException.class, proto::getParserForType); } @Test public void schemalessEnum_throwsExceptionOnGetForNumber() { - SchemalessEnum myEnum = Type.SchemalessEnum.create("MyEnum"); + SchemalessEnum myEnum = Type.SchemalessEnum.create("MyEnum", "my_bundle"); assertThrows(UnsupportedOperationException.class, myEnum::getForNumber); } diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/internal/AbstractProtoStructReaderTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/internal/AbstractProtoStructReaderTest.java index 0c623dc18f38..b34c0536bdc0 100644 --- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/internal/AbstractProtoStructReaderTest.java +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/internal/AbstractProtoStructReaderTest.java @@ -257,7 +257,8 @@ public void mapField_accessingProto() { "testField", mapType( bytesType(), - protoType("com.google.cloud.bigtable.data.v2.test.Singer"))))), + protoType( + "com.google.cloud.bigtable.data.v2.test.Singer", "my_bundle"))))), Collections.singletonList( mapValue(mapElement(bytesValue("key"), bytesValue(singer.toByteArray()))))); HashMap expectedMap = new HashMap<>(); @@ -280,7 +281,8 @@ public void mapField_accessingProto() { "testField", SqlType.mapOf( SqlType.bytes(), - SchemalessProto.create("com.google.cloud.bigtable.data.v2.test.Singer")))); + SchemalessProto.create( + "com.google.cloud.bigtable.data.v2.test.Singer", "my_bundle")))); assertThrows( UnsupportedOperationException.class, () -> @@ -288,7 +290,8 @@ public void mapField_accessingProto() { 0, SqlType.mapOf( SqlType.bytes(), - SchemalessProto.create("com.google.cloud.bigtable.data.v2.test.Singer")))); + SchemalessProto.create( + "com.google.cloud.bigtable.data.v2.test.Singer", "my_bundle")))); assertThrows( IllegalStateException.class, () -> @@ -319,7 +322,8 @@ public void mapField_accessingEnum() { "testField", mapType( bytesType(), - enumType("com.google.cloud.bigtable.data.v2.test.Genre"))))), + enumType( + "com.google.cloud.bigtable.data.v2.test.Genre", "my_bundle"))))), Collections.singletonList(mapValue(mapElement(bytesValue("key"), int64Value(0))))); HashMap expectedMap = new HashMap<>(); expectedMap.put(ByteString.copyFromUtf8("key"), Genre.POP); @@ -340,7 +344,8 @@ public void mapField_accessingEnum() { "testField", SqlType.mapOf( SqlType.bytes(), - SchemalessEnum.create("com.google.cloud.bigtable.data.v2.test.Genre")))); + SchemalessEnum.create( + "com.google.cloud.bigtable.data.v2.test.Genre", "my_bundle")))); assertThrows( UnsupportedOperationException.class, () -> @@ -348,7 +353,8 @@ public void mapField_accessingEnum() { 0, SqlType.mapOf( SqlType.bytes(), - SchemalessEnum.create("com.google.cloud.bigtable.data.v2.test.Genre")))); + SchemalessEnum.create( + "com.google.cloud.bigtable.data.v2.test.Genre", "my_bundle")))); assertThrows( UnsupportedOperationException.class, () -> @@ -356,7 +362,8 @@ public void mapField_accessingEnum() { "testField", SqlType.mapOf( SqlType.bytes(), - SchemalessEnum.create("com.google.cloud.bigtable.data.v2.test.Genre")))); + SchemalessEnum.create( + "com.google.cloud.bigtable.data.v2.test.Genre", "my_bundle")))); assertThrows( UnsupportedOperationException.class, () -> @@ -364,7 +371,8 @@ public void mapField_accessingEnum() { 0, SqlType.mapOf( SqlType.bytes(), - SchemalessEnum.create("com.google.cloud.bigtable.data.v2.test.Genre")))); + SchemalessEnum.create( + "com.google.cloud.bigtable.data.v2.test.Genre", "my_bundle")))); assertThrows( IllegalStateException.class, () -> structWithMap.getMap("testField", SqlType.mapOf(SqlType.bytes(), SqlType.bytes()))); @@ -481,8 +489,8 @@ public static List parameters() { structField("stringField", stringType()), structField("intField", int64Type()), structField("listField", arrayType(stringType())), - structField("protoField", protoType("MyMessage")), - structField("enumField", enumType("MyEnum"))))), + structField("protoField", protoType("MyMessage", "my_bundle")), + structField("enumField", enumType("MyEnum", "other_bundle"))))), Collections.singletonList( arrayValue( stringValue("test"), @@ -501,8 +509,8 @@ public static List parameters() { structField("stringField", stringType()), structField("intField", int64Type()), structField("listField", arrayType(stringType())), - structField("protoField", protoType("MyMessage")), - structField("enumField", enumType("MyEnum")))), + structField("protoField", protoType("MyMessage", "my_bundle")), + structField("enumField", enumType("MyEnum", "other_bundle")))), arrayValue( stringValue("test"), int64Value(100), @@ -686,7 +694,8 @@ public static List parameters() { { Collections.singletonList( columnMetadata( - "testField", protoType("com.google.cloud.bigtable.data.v2.test.Singer"))), + "testField", + protoType("com.google.cloud.bigtable.data.v2.test.Singer", "my_bundle"))), Collections.singletonList( bytesValue( Singer.newBuilder() @@ -707,7 +716,9 @@ public static List parameters() { Collections.singletonList( columnMetadata( "testField", - arrayType(protoType("com.google.cloud.bigtable.data.v2.test.Singer")))), + arrayType( + protoType( + "com.google.cloud.bigtable.data.v2.test.Singer", "my_bundle")))), Collections.singletonList( arrayValue( bytesValue( @@ -743,7 +754,8 @@ public static List parameters() { "testField", mapType( bytesType(), - protoType("com.google.cloud.bigtable.data.v2.test.Singer")))), + protoType( + "com.google.cloud.bigtable.data.v2.test.Singer", "my_bundle")))), Collections.singletonList( mapValue( mapElement( @@ -791,7 +803,8 @@ public static List parameters() { { Collections.singletonList( columnMetadata( - "testField", enumType("com.google.cloud.bigtable.data.v2.test.Genre"))), + "testField", + enumType("com.google.cloud.bigtable.data.v2.test.Genre", "my_bundle"))), Collections.singletonList(int64Value(1)), 0, "testField", @@ -806,7 +819,8 @@ public static List parameters() { Collections.singletonList( columnMetadata( "testField", - arrayType(enumType("com.google.cloud.bigtable.data.v2.test.Genre")))), + arrayType( + enumType("com.google.cloud.bigtable.data.v2.test.Genre", "my_bundle")))), Collections.singletonList(arrayValue(nullValue(), int64Value(2), int64Value(100))), 0, "testField", @@ -824,7 +838,8 @@ public static List parameters() { columnMetadata( "testField", mapType( - bytesType(), enumType("com.google.cloud.bigtable.data.v2.test.Genre")))), + bytesType(), + enumType("com.google.cloud.bigtable.data.v2.test.Genre", "my_bundle")))), Collections.singletonList( mapValue( mapElement(bytesValue("foo"), int64Value(1)), diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/internal/ProtoStructTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/internal/ProtoStructTest.java index 6ebe1d7319a4..cd8dfc734004 100644 --- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/internal/ProtoStructTest.java +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/internal/ProtoStructTest.java @@ -85,9 +85,12 @@ public class ProtoStructTest { structField("listField", arrayType(stringType())), structField("mapField", mapType(stringType(), stringType())), structField( - "protoField", protoType("com.google.cloud.bigtable.data.v2.test.Singer")), + "protoField", + protoType("com.google.cloud.bigtable.data.v2.test.Singer", "my_bundle")), structField( - "enumField", enumType("com.google.cloud.bigtable.data.v2.test.Genre")))), + "enumField", + enumType( + "com.google.cloud.bigtable.data.v2.test.Genre", "other_bundle")))), arrayValue( bytesValue("testBytes"), stringValue("testString"), @@ -184,9 +187,11 @@ public void getColumnType_byName() { assertThat(struct.getColumnType("mapField")) .isEqualTo(SqlType.mapOf(SqlType.string(), SqlType.string())); assertThat(struct.getColumnType("protoField")) - .isEqualTo(SchemalessProto.create("com.google.cloud.bigtable.data.v2.test.Singer")); + .isEqualTo( + SchemalessProto.create("com.google.cloud.bigtable.data.v2.test.Singer", "my_bundle")); assertThat(struct.getColumnType("enumField")) - .isEqualTo(SchemalessEnum.create("com.google.cloud.bigtable.data.v2.test.Genre")); + .isEqualTo( + SchemalessEnum.create("com.google.cloud.bigtable.data.v2.test.Genre", "other_bundle")); } @Test @@ -205,9 +210,11 @@ public void getColumnType_byIndex() { assertThat(struct.getColumnType(10)) .isEqualTo(SqlType.mapOf(SqlType.string(), SqlType.string())); assertThat(struct.getColumnType(11)) - .isEqualTo(SchemalessProto.create("com.google.cloud.bigtable.data.v2.test.Singer")); + .isEqualTo( + SchemalessProto.create("com.google.cloud.bigtable.data.v2.test.Singer", "my_bundle")); assertThat(struct.getColumnType(12)) - .isEqualTo(SchemalessEnum.create("com.google.cloud.bigtable.data.v2.test.Genre")); + .isEqualTo( + SchemalessEnum.create("com.google.cloud.bigtable.data.v2.test.Genre", "other_bundle")); } @Test diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/internal/ResultSetImplTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/internal/ResultSetImplTest.java index 1b95540499fe..97877231640a 100644 --- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/internal/ResultSetImplTest.java +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/internal/ResultSetImplTest.java @@ -103,8 +103,10 @@ public void testSingleRow() throws ExecutionException, InterruptedException { columnMetadata("struct", structType(structField("string", stringType()))), columnMetadata("list", arrayType(stringType())), columnMetadata("map", mapType(stringType(), stringType())), - columnMetadata("proto", protoType("com.google.cloud.bigtable.data.v2.test.Singer")), - columnMetadata("enum", enumType("com.google.cloud.bigtable.data.v2.test.Genre"))); + columnMetadata( + "proto", protoType("com.google.cloud.bigtable.data.v2.test.Singer", "my_bundle")), + columnMetadata( + "enum", enumType("com.google.cloud.bigtable.data.v2.test.Genre", "other_bundle"))); ResultSetMetadata metadata = ProtoResultSetMetadata.fromProto(protoMetadata); ResultSet resultSet = resultSetWithFakeStream( diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/models/sql/SqlTypeTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/models/sql/SqlTypeTest.java index e9f45f595603..e8e33387a603 100644 --- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/models/sql/SqlTypeTest.java +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/models/sql/SqlTypeTest.java @@ -76,8 +76,9 @@ public void setUp() { protoToJavaMapping.put(arrayType(stringType()), SqlType.arrayOf(SqlType.string())); protoToJavaMapping.put( mapType(bytesType(), stringType()), SqlType.mapOf(SqlType.bytes(), SqlType.string())); - protoToJavaMapping.put(protoType("foo"), SchemalessProto.create("foo")); - protoToJavaMapping.put(enumType("foo"), SchemalessEnum.create("foo")); + protoToJavaMapping.put( + protoType("foo", "my_bundle"), SchemalessProto.create("foo", "my_bundle")); + protoToJavaMapping.put(enumType("foo", "my_bundle"), SchemalessEnum.create("foo", "my_bundle")); } @Test @@ -173,16 +174,17 @@ public void typesMatch_checksProto() { SqlType.Proto singerProto = SqlType.protoOf(Singer.getDefaultInstance()); SqlType.Proto albumProto = SqlType.protoOf(Album.getDefaultInstance()); SqlType.Proto schemalessSinger = - SchemalessProto.create("com.google.cloud.bigtable.data.v2.test.Singer"); + SchemalessProto.create("com.google.cloud.bigtable.data.v2.test.Singer", "my_bundle"); SqlType.Proto schemalessAlbum = - SchemalessProto.create("com.google.cloud.bigtable.data.v2.test.Album"); + SchemalessProto.create("com.google.cloud.bigtable.data.v2.test.Album", "my_bundle"); // Both Schemaless types assertThat(SqlType.typesMatch(schemalessSinger, schemalessAlbum)).isFalse(); assertThat( SqlType.typesMatch( schemalessSinger, - SchemalessProto.create("com.google.cloud.bigtable.data.v2.test.Singer"))) + SchemalessProto.create( + "com.google.cloud.bigtable.data.v2.test.Singer", "my_bundle"))) .isTrue(); // Both concrete types @@ -193,17 +195,28 @@ public void typesMatch_checksProto() { // Schemaless versus concrete types (unqualified proto message names must match) assertThat(SqlType.typesMatch(schemalessSinger, singerProto)).isTrue(); assertThat(SqlType.typesMatch(singerProto, schemalessSinger)).isTrue(); - assertThat(SqlType.typesMatch(singerProto, SchemalessProto.create("Singer"))).isTrue(); - assertThat(SqlType.typesMatch(singerProto, SchemalessProto.create("foo.bar.Singer"))).isTrue(); + assertThat(SqlType.typesMatch(singerProto, SchemalessProto.create("Singer", "my_bundle"))) + .isTrue(); + assertThat( + SqlType.typesMatch(singerProto, SchemalessProto.create("foo.bar.Singer", "my_bundle"))) + .isTrue(); + assertThat(SqlType.typesMatch(singerProto, SchemalessProto.create("Singer", "other_bundle"))) + .isTrue(); + assertThat( + SqlType.typesMatch( + singerProto, SchemalessProto.create("foo.bar.Singer", "other_bundle"))) + .isTrue(); assertThat(SqlType.typesMatch(schemalessSinger, albumProto)).isFalse(); assertThat(SqlType.typesMatch(albumProto, schemalessSinger)).isFalse(); - assertThat(SqlType.typesMatch(singerProto, SchemalessProto.create("Album"))).isFalse(); + assertThat(SqlType.typesMatch(singerProto, SchemalessProto.create("Album", "my_bundle"))) + .isFalse(); assertThat( SqlType.typesMatch( singerProto, - SchemalessProto.create("com.google.cloud.bigtable.data.v2.test.Album"))) + SchemalessProto.create( + "com.google.cloud.bigtable.data.v2.test.Album", "my_bundle"))) .isFalse(); - assertThat(SqlType.typesMatch(singerProto, SchemalessProto.create(""))).isFalse(); + assertThat(SqlType.typesMatch(singerProto, SchemalessProto.create("", "my_bundle"))).isFalse(); } @Test @@ -211,16 +224,16 @@ public void typesMatch_checksEnum() { SqlType.Enum genreEnum = SqlType.enumOf(Genre::forNumber); SqlType.Enum formatEnum = SqlType.enumOf(Format::forNumber); SqlType.Enum schemalessGenre = - SchemalessEnum.create("com.google.cloud.bigtable.data.v2.test.Genre"); + SchemalessEnum.create("com.google.cloud.bigtable.data.v2.test.Genre", "my_bundle"); SqlType.Enum schemalessFormat = - SchemalessEnum.create("com.google.cloud.bigtable.data.v2.test.Format"); + SchemalessEnum.create("com.google.cloud.bigtable.data.v2.test.Format", "my_bundle"); // Both Schemaless types assertThat(SqlType.typesMatch(schemalessGenre, schemalessFormat)).isFalse(); assertThat( SqlType.typesMatch( schemalessGenre, - SchemalessEnum.create("com.google.cloud.bigtable.data.v2.test.Genre"))) + SchemalessEnum.create("com.google.cloud.bigtable.data.v2.test.Genre", "my_bundle"))) .isTrue(); // Both concrete types @@ -230,16 +243,25 @@ public void typesMatch_checksEnum() { // Schemaless versus concrete types (unqualified enum message names must match) assertThat(SqlType.typesMatch(schemalessGenre, genreEnum)).isTrue(); assertThat(SqlType.typesMatch(genreEnum, schemalessGenre)).isTrue(); - assertThat(SqlType.typesMatch(genreEnum, SchemalessEnum.create("Genre"))).isTrue(); - assertThat(SqlType.typesMatch(genreEnum, SchemalessEnum.create("foo.bar.Genre"))).isTrue(); + assertThat(SqlType.typesMatch(genreEnum, SchemalessEnum.create("Genre", "my_bundle"))).isTrue(); + assertThat(SqlType.typesMatch(genreEnum, SchemalessEnum.create("foo.bar.Genre", "my_bundle"))) + .isTrue(); + assertThat(SqlType.typesMatch(genreEnum, SchemalessEnum.create("Genre", "other_bundle"))) + .isTrue(); + assertThat( + SqlType.typesMatch(genreEnum, SchemalessEnum.create("foo.bar.Genre", "other_bundle"))) + .isTrue(); assertThat(SqlType.typesMatch(schemalessGenre, formatEnum)).isFalse(); assertThat(SqlType.typesMatch(formatEnum, schemalessGenre)).isFalse(); - assertThat(SqlType.typesMatch(genreEnum, SchemalessEnum.create("Format"))).isFalse(); + assertThat(SqlType.typesMatch(genreEnum, SchemalessEnum.create("Format", "my_bundle"))) + .isFalse(); assertThat( SqlType.typesMatch( - genreEnum, SchemalessProto.create("com.google.cloud.bigtable.data.v2.test.Format"))) + genreEnum, + SchemalessProto.create( + "com.google.cloud.bigtable.data.v2.test.Format", "my_bundle"))) .isFalse(); - assertThat(SqlType.typesMatch(genreEnum, SchemalessEnum.create(""))).isFalse(); + assertThat(SqlType.typesMatch(genreEnum, SchemalessEnum.create("", "my_bundle"))).isFalse(); } @Test diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/sql/ProtoRowsMergingStateMachineTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/sql/ProtoRowsMergingStateMachineTest.java index 188ace72814a..e24445cf98eb 100644 --- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/sql/ProtoRowsMergingStateMachineTest.java +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/sql/ProtoRowsMergingStateMachineTest.java @@ -660,14 +660,14 @@ public void testValidateSupportsAllTypes() { IllegalStateException.class, () -> ProtoRowsMergingStateMachine.validateValueAndType( - Type.SchemalessProto.create("test"), stringValue("test"))); + Type.SchemalessProto.create("test", "my_bundle"), stringValue("test"))); break; case ENUM: assertThrows( IllegalStateException.class, () -> ProtoRowsMergingStateMachine.validateValueAndType( - Type.SchemalessEnum.create("test"), bytesValue("val"))); + Type.SchemalessEnum.create("test", "my_bundle"), bytesValue("val"))); break; default: assertWithMessage( diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/sql/SqlProtoFactory.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/sql/SqlProtoFactory.java index 51fef0884ae8..d1d1c684dfb6 100644 --- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/sql/SqlProtoFactory.java +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/sql/SqlProtoFactory.java @@ -224,14 +224,17 @@ public static Type mapType(Type keyType, Type valueType) { .build(); } - public static Type protoType(String messageName) { + public static Type protoType(String messageName, String schemaBundleId) { return Type.newBuilder() - .setProtoType(Type.Proto.newBuilder().setMessageName(messageName)) + .setProtoType( + Type.Proto.newBuilder().setMessageName(messageName).setSchemaBundleId(schemaBundleId)) .build(); } - public static Type enumType(String enumName) { - return Type.newBuilder().setEnumType(Type.Enum.newBuilder().setEnumName(enumName)).build(); + public static Type enumType(String enumName, String schemaBundleId) { + return Type.newBuilder() + .setEnumType(Type.Enum.newBuilder().setEnumName(enumName).setSchemaBundleId(schemaBundleId)) + .build(); } public static Value nullValue() { diff --git a/test-proxy/src/main/java/com/google/cloud/bigtable/testproxy/ResultSetSerializer.java b/test-proxy/src/main/java/com/google/cloud/bigtable/testproxy/ResultSetSerializer.java index 7400986b6e22..27b8217146c2 100644 --- a/test-proxy/src/main/java/com/google/cloud/bigtable/testproxy/ResultSetSerializer.java +++ b/test-proxy/src/main/java/com/google/cloud/bigtable/testproxy/ResultSetSerializer.java @@ -24,6 +24,7 @@ import com.google.bigtable.v2.Type.Float64; import com.google.bigtable.v2.Type.Int64; import com.google.bigtable.v2.Type.Map; +import com.google.bigtable.v2.Type.Proto; import com.google.bigtable.v2.Type.Struct; import com.google.bigtable.v2.Type.Timestamp; import com.google.bigtable.v2.Value; @@ -31,6 +32,8 @@ import com.google.cloud.bigtable.data.v2.models.sql.ColumnMetadata; import com.google.cloud.bigtable.data.v2.models.sql.ResultSet; import com.google.cloud.bigtable.data.v2.models.sql.SqlType; +import com.google.cloud.bigtable.common.Type.SchemalessProto; +import com.google.cloud.bigtable.common.Type.SchemalessEnum; import com.google.cloud.bigtable.data.v2.models.sql.StructReader; import com.google.protobuf.ByteString; import java.time.Instant; @@ -69,12 +72,14 @@ private static Value toProtoValue(Object value, SqlType type) { Value.Builder valueBuilder = Value.newBuilder(); switch (type.getCode()) { case BYTES: + case PROTO: valueBuilder.setBytesValue((ByteString) value); break; case STRING: valueBuilder.setStringValue((String) value); break; case INT64: + case ENUM: valueBuilder.setIntValue((Long) value); break; case FLOAT32: @@ -157,6 +162,7 @@ private static Object getColumn(StructReader struct, int fieldIndex, SqlType case BOOL: return struct.getBoolean(fieldIndex); case BYTES: + case PROTO: return struct.getBytes(fieldIndex); case DATE: return struct.getDate(fieldIndex); @@ -165,6 +171,7 @@ private static Object getColumn(StructReader struct, int fieldIndex, SqlType case FLOAT64: return struct.getDouble(fieldIndex); case INT64: + case ENUM: return struct.getLong(fieldIndex); case MAP: return struct.getMap(fieldIndex, (SqlType.Map) fieldType); @@ -225,7 +232,17 @@ private static Type toProtoType(SqlType type) { .setType(toProtoType(field.type())); } return Type.newBuilder().setStructType(structBuilder.build()).build(); - + case PROTO: + SchemalessProto protoType = (SchemalessProto) type; + return Type.newBuilder() + .setProtoType(Proto.newBuilder().setMessageName(protoType.getMessageName()) + .setSchemaBundleId(protoType.schemaBundleId()).build()).build(); + case ENUM: + SchemalessEnum enumType = (SchemalessEnum) type; + return Type.newBuilder() + .setEnumType( + com.google.bigtable.v2.Type.Enum.newBuilder().setEnumName(enumType.getEnumName()) + .setSchemaBundleId(enumType.schemaBundleId()).build()).build(); default: throw new IllegalStateException("Unexpected Type: " + type); }