diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/parsers/BooleanParser.java b/src/main/java/com/google/cloud/spanner/pgadapter/parsers/BooleanParser.java index 3b0d21876b..0871737df2 100644 --- a/src/main/java/com/google/cloud/spanner/pgadapter/parsers/BooleanParser.java +++ b/src/main/java/com/google/cloud/spanner/pgadapter/parsers/BooleanParser.java @@ -63,18 +63,22 @@ public class BooleanParser extends Parser { } BooleanParser(byte[] item, FormatCode formatCode) { - if (item != null) { - switch (formatCode) { - case TEXT: - String stringValue = new String(item, UTF8).toLowerCase(Locale.ENGLISH); - this.item = toBoolean(stringValue); - break; - case BINARY: - this.item = toBoolean(item); - break; - default: - throw new IllegalArgumentException("Unsupported format: " + formatCode); - } + this.item = toBoolean(item, formatCode); + } + + /** Converts the given data to a boolean value based on the format code. */ + public static Boolean toBoolean(byte[] item, FormatCode formatCode) { + if (item == null) { + return null; + } + switch (formatCode) { + case TEXT: + String stringValue = new String(item, UTF8).toLowerCase(Locale.ENGLISH); + return toBoolean(stringValue); + case BINARY: + return toBoolean(item); + default: + throw new IllegalArgumentException("Unsupported format: " + formatCode); } } @@ -140,6 +144,14 @@ public static byte[] convertToPG(ResultSet resultSet, int position, DataFormat f } } + public static void bind( + ImmutableMap.Builder parametersBuilder, + String name, + byte[] item, + FormatCode formatCode) { + parametersBuilder.put(name, Value.bool(toBoolean(item, formatCode))); + } + @Override public void bind(ImmutableMap.Builder parametersBuilder, String name) { parametersBuilder.put(name, Value.bool(this.item)); diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/parsers/Parser.java b/src/main/java/com/google/cloud/spanner/pgadapter/parsers/Parser.java index 6a86cf3fd0..8cbd7b97b7 100644 --- a/src/main/java/com/google/cloud/spanner/pgadapter/parsers/Parser.java +++ b/src/main/java/com/google/cloud/spanner/pgadapter/parsers/Parser.java @@ -259,6 +259,25 @@ protected static Parser create(Object result, Code typeCode, SessionState ses } } + /** Binds a parameter value to a statement builder without necessarily instantiating a parser. */ + public static void bind( + ImmutableMap.Builder parametersBuilder, + String name, + byte[] item, + int oidType, + FormatCode formatCode, + SessionState sessionState) { + switch (oidType) { + case Oid.BOOL: + case Oid.BIT: + BooleanParser.bind(parametersBuilder, name, item, formatCode); + break; + default: + // Fallback to instance creation until all types are optimized with static bind methods. + create(sessionState, item, oidType, formatCode).bind(parametersBuilder, name); + } + } + /** * Translates the given Cloud Spanner {@link Type} to a PostgreSQL OID constant. * diff --git a/src/main/java/com/google/cloud/spanner/pgadapter/statements/IntermediatePortalStatement.java b/src/main/java/com/google/cloud/spanner/pgadapter/statements/IntermediatePortalStatement.java index 30704ee14a..8a17c03a3e 100644 --- a/src/main/java/com/google/cloud/spanner/pgadapter/statements/IntermediatePortalStatement.java +++ b/src/main/java/com/google/cloud/spanner/pgadapter/statements/IntermediatePortalStatement.java @@ -117,16 +117,16 @@ public Statement bind(Statement statement) { for (int index = 0; index < this.parameters.length; index++) { short formatCode = getParameterFormatCode(index); int type = preparedStatement.getParameterDataType(index); - Parser parser = - Parser.create( - connectionHandler - .getExtendedQueryProtocolHandler() - .getBackendConnection() - .getSessionState(), - this.parameters[index], - type, - FormatCode.of(formatCode)); - parser.bind(parametersBuilder, "p" + (index + 1)); + Parser.bind( + parametersBuilder, + "p" + (index + 1), + this.parameters[index], + type, + FormatCode.of(formatCode), + connectionHandler + .getExtendedQueryProtocolHandler() + .getBackendConnection() + .getSessionState()); } return Statement.of(statement.getSql(), parametersBuilder.build()); }