Skip to content

Commit 3129756

Browse files
authored
perf: get int8 values directly from the protobuf value (GoogleCloudPlatform#3097)
Get long values directly from the protobuf value instead of first parsing and copying into a different buffer by calling ResultSet#getLong(int).
1 parent 51b8353 commit 3129756

2 files changed

Lines changed: 48 additions & 12 deletions

File tree

src/main/java/com/google/cloud/spanner/pgadapter/parsers/LongParser.java

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,17 @@
1616

1717
import com.google.api.core.InternalApi;
1818
import com.google.cloud.spanner.ErrorCode;
19+
import com.google.cloud.spanner.ProtobufResultSet;
1920
import com.google.cloud.spanner.ResultSet;
2021
import com.google.cloud.spanner.SpannerExceptionFactory;
2122
import com.google.cloud.spanner.Statement;
2223
import com.google.cloud.spanner.pgadapter.ProxyServer.DataFormat;
2324
import com.google.cloud.spanner.pgadapter.error.PGExceptionFactory;
25+
import com.google.cloud.spanner.pgadapter.session.SessionState;
26+
import java.io.DataOutputStream;
27+
import java.io.IOException;
2428
import java.math.BigDecimal;
2529
import java.math.RoundingMode;
26-
import java.nio.charset.StandardCharsets;
2730
import javax.annotation.Nonnull;
2831
import org.postgresql.util.ByteConverter;
2932

@@ -95,18 +98,47 @@ static byte[] convertToPG(long value) {
9598
return result;
9699
}
97100

98-
public static byte[] convertToPG(ResultSet resultSet, int position, DataFormat format) {
101+
public static byte[] convertToPG(
102+
SessionState sessionState,
103+
DataOutputStream outputStream,
104+
ResultSet resultSet,
105+
int position,
106+
DataFormat format)
107+
throws IOException {
108+
writeToPG(sessionState, outputStream, resultSet, position, format);
109+
return null;
110+
}
111+
112+
static void writeToPG(
113+
SessionState sessionState,
114+
DataOutputStream outputStream,
115+
ResultSet resultSet,
116+
int position,
117+
DataFormat format)
118+
throws IOException {
99119
switch (format) {
100120
case SPANNER:
101121
case POSTGRESQL_TEXT:
102-
return Long.toString(resultSet.getLong(position)).getBytes(StandardCharsets.UTF_8);
122+
StringParser.writeToPG(sessionState, outputStream, getLongAsString(resultSet, position));
123+
break;
103124
case POSTGRESQL_BINARY:
104-
return convertToPG(resultSet.getLong(position));
125+
byte[] value = convertToPG(resultSet.getLong(position));
126+
outputStream.writeInt(value.length);
127+
outputStream.write(value);
128+
break;
105129
default:
106130
throw new IllegalArgumentException("unknown data format: " + format);
107131
}
108132
}
109133

134+
static String getLongAsString(ResultSet resultSet, int column) {
135+
if (resultSet instanceof ProtobufResultSet
136+
&& ((ProtobufResultSet) resultSet).canGetProtobufValue(column)) {
137+
return ((ProtobufResultSet) resultSet).getProtobufValue(column).getStringValue();
138+
}
139+
return Long.toString(resultSet.getLong(column));
140+
}
141+
110142
@Override
111143
public void bind(Statement.Builder statementBuilder, String name) {
112144
statementBuilder.bind(name).to(this.item);

src/main/java/com/google/cloud/spanner/pgadapter/utils/Converter.java

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ public int convertResultSetRowToDataRowResponse() throws IOException {
120120
: fixedFormat;
121121
byte[] column =
122122
Converter.convertToPG(outputStream, this.resultSet, column_index, format, sessionState);
123+
// TODO: Remove this if statement and write statements once all data types are written
124+
// directly to the output stream.
123125
if (column != null) {
124126
outputStream.writeInt(column.length);
125127
outputStream.write(column);
@@ -137,22 +139,24 @@ public void writeBuffer(DataOutputStream outputStream) throws IOException {
137139
* Return the data of the specified column of the {@link ResultSet} as a byte array. The column
138140
* may not contain a null value.
139141
*
142+
* @param outputStream The output stream to write value to if the converter supports that.
140143
* @param result The {@link ResultSet} to read the data from.
141144
* @param position The column index.
142145
* @param format The {@link DataFormat} format to use to encode the data.
143-
* @return a byte array containing the data in the specified format.
146+
* @param sessionState The {@link SessionState} that should be used to determine how to format the
147+
* data (e.g. timezone).
148+
* @return a byte array containing the data in the specified format or null if the data was
149+
* written directly to the output stream.
144150
*/
145-
public static byte[] convertToPG(
146-
ResultSet result, int position, DataFormat format, SessionState sessionState) {
147-
return convertToPG(null, result, position, format, sessionState);
148-
}
149-
151+
// TODO: Rename this method to writeToPG and change return type to void once all data types write
152+
// directly to the output stream.
150153
public static byte[] convertToPG(
151154
DataOutputStream outputStream,
152155
ResultSet result,
153156
int position,
154157
DataFormat format,
155-
SessionState sessionState) {
158+
SessionState sessionState)
159+
throws IOException {
156160
Preconditions.checkArgument(!result.isNull(position), "Column may not contain a null value");
157161
Type type = result.getColumnType(position);
158162
switch (type.getCode()) {
@@ -168,7 +172,7 @@ public static byte[] convertToPG(
168172
return DoubleParser.convertToPG(result, position, format);
169173
case INT64:
170174
case PG_OID:
171-
return LongParser.convertToPG(result, position, format);
175+
return LongParser.convertToPG(sessionState, outputStream, result, position, format);
172176
case PG_NUMERIC:
173177
return NumericParser.convertToPG(result, position, format);
174178
case STRING:

0 commit comments

Comments
 (0)