Skip to content

Commit

Permalink
feat: add support for describe statement (#125)
Browse files Browse the repository at this point in the history
* feat: add support for describe statement

Adds support for DescribeStatement by transforming sql statements into a
select statement that queries the (types of) the parameters in the
original query. This can be used to temporarily support prepared
statements until a DescribeStatement endpoint is available in the
backend.

* test: add metadata results

* test: fix pgx tests

* perf: first describe portal

* feat: execute actual select first

* deps: use client lib SNAPSHOT

* fix: remove local absolute path

* fix: test failures

* fix: JDBC metadata test

* fix: address review comments

* fix: remove parameterized offset clause

Spangres does not (yet) support offset clauses that are not an integer literal.

* fix: ignore test for unsupported backend feature
  • Loading branch information
olavloite authored May 30, 2022
1 parent c15de51 commit 52452d7
Show file tree
Hide file tree
Showing 27 changed files with 12,110 additions and 10,339 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import org.postgresql.core.Oid;
import org.postgresql.util.PGbytea;

/**
* Parser is the parsing superclass, used to take wire format data types and convert them
Expand Down Expand Up @@ -52,13 +53,9 @@ public static FormatCode of(short code) {
protected T item;

/**
* Untyped parameters are allowed in PostgreSQL, and some drivers use this deliberately to work
* around side effects regarding dates and timestamps with and without timezones. See for example
* https://github.com/pgjdbc/pgjdbc/blob/3af3b32cc5b77db3e7af1cbc217d6288fd0cf9b9/pgjdbc/src/main/java/org/postgresql/jdbc/PgPreparedStatement.java#L1322
* TODO: Remove when we have full support for DescribeStatement.
*
* <p>TODO: This method currently only checks whether the value could be a timestamp with
* timezone. Date and timestamp without timezone are also known to be sent with type code {@link
* Oid#UNSPECIFIED} by the JDBC driver, and must be implemented once Spanner supports these types.
* <p>Guess the type of a parameter with unspecified type.
*
* @param item The value to guess the type for
* @param formatCode The encoding that is used for the value
Expand All @@ -69,6 +66,17 @@ private static int guessType(byte[] item, FormatCode formatCode) {
// TODO: Put 'guessType' behind a command line flag so it is only enabled when wanted.
if (formatCode == FormatCode.TEXT && item != null) {
String value = new String(item, StandardCharsets.UTF_8);
if (value.equals("t") || value.equals("f")) {
return Oid.BOOL;
}
if (value.length() >= 2 && value.charAt(0) == '\\' && value.charAt(1) == 'x') {
try {
PGbytea.toBytes(item);
return Oid.BYTEA;
} catch (Exception e) {
// ignore and fall through
}
}
if (TimestampParser.isTimestamp(value)) {
return Oid.TIMESTAMPTZ;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,13 @@
class UnspecifiedParser extends Parser<Value> {

UnspecifiedParser(byte[] item, FormatCode formatCode) {
this.item = item == null ? null : Value.string(new String(item, UTF8));
this.item =
item == null
? null
: Value.untyped(
com.google.protobuf.Value.newBuilder()
.setStringValue(new String(item, StandardCharsets.UTF_8))
.build());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ public class IntermediatePortalStatement extends IntermediatePreparedStatement {
public IntermediatePortalStatement(
ConnectionHandler connectionHandler,
OptionsMetadata options,
String name,
ParsedStatement parsedStatement) {
super(connectionHandler, options, parsedStatement);
super(connectionHandler, options, name, parsedStatement);
this.statement = Statement.of(parsedStatement.getSqlWithoutComments());
this.parameterFormatCodes = new ArrayList<>();
this.resultFormatCodes = new ArrayList<>();
Expand Down
Loading

0 comments on commit 52452d7

Please sign in to comment.