Skip to content

Commit

Permalink
fix: catch unknown types in RowDescription (#343)
Browse files Browse the repository at this point in the history
* fix: catch unknown types in RowDescription

Catch any errors when converting from a Spanner type to an OID to
prevent unknown types from making PGAdapter return an incomplete
response. An unknown type would now cause the RowDescriptionResponse to
fail halfway, which meant that half a message would be written to the
output buffer. This could then make a client hang, as it was waiting for
more data for the specific message.

* test: add a test to verify that the exception is caught

* test: add more tests
  • Loading branch information
olavloite authored Sep 6, 2022
1 parent 808217e commit 6562014
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,12 @@ protected String getPayloadString() {
}

int getOidType(int column_index) {
Type type = this.resultSet.getColumnType(column_index);
return Parser.toOid(type);
try {
Type type = this.resultSet.getColumnType(column_index);
return Parser.toOid(type);
} catch (Exception ignored) {
return Oid.UNSPECIFIED;
}
}

int getOidTypeSize(int oid_type) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@
package com.google.cloud.spanner.pgadapter.wireoutput;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import com.google.cloud.spanner.ErrorCode;
import com.google.cloud.spanner.ResultSet;
import com.google.cloud.spanner.SpannerExceptionFactory;
import com.google.cloud.spanner.Type;
import com.google.cloud.spanner.Type.StructField;
import com.google.cloud.spanner.pgadapter.ConnectionHandler.QueryMode;
Expand Down Expand Up @@ -107,6 +110,13 @@ public void OidTest() throws Exception {
// Types.TIMESTAMP
assertEquals(Oid.TIMESTAMPTZ, response.getOidType(7));
assertEquals(12, response.getOidTypeSize(Oid.TIMESTAMPTZ));

assertEquals(4, response.getOidTypeSize(Oid.INT4));
assertEquals(2, response.getOidTypeSize(Oid.INT2));
assertEquals(4, response.getOidTypeSize(Oid.FLOAT4));
assertEquals(1, response.getOidTypeSize(Oid.CHAR));
assertEquals(-1, response.getOidTypeSize(Oid.TEXT));
assertEquals(8, response.getOidTypeSize(Oid.TIME));
}

@Test
Expand Down Expand Up @@ -340,4 +350,21 @@ public void SendPayloadStatementTest() throws Exception {
assertEquals(i, outputReader.readShort());
}
}

@Test
public void testUnknownTypeReturnsUnspecified() throws Exception {
ResultSet resultSet = mock(ResultSet.class);
when(resultSet.getColumnType(0))
.thenThrow(SpannerExceptionFactory.newSpannerException(ErrorCode.INTERNAL, "unknown type"));

RowDescriptionResponse response =
new RowDescriptionResponse(
mock(DataOutputStream.class),
mock(IntermediateStatement.class),
resultSet,
mock(OptionsMetadata.class),
QueryMode.SIMPLE);

assertEquals(Oid.UNSPECIFIED, response.getOidType(0));
}
}

0 comments on commit 6562014

Please sign in to comment.