Skip to content

Commit cea84a4

Browse files
committed
Retrieve database product version from v1/info
1 parent f522a29 commit cea84a4

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

client/trino-jdbc/src/main/java/io/trino/jdbc/TrinoConnection.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import com.google.common.annotations.VisibleForTesting;
1717
import com.google.common.base.Joiner;
1818
import com.google.common.base.Splitter;
19+
import com.google.common.base.Supplier;
1920
import com.google.common.collect.ImmutableList;
2021
import com.google.common.collect.ImmutableMap;
2122
import com.google.common.collect.ImmutableSet;
@@ -24,7 +25,10 @@
2425
import io.airlift.units.Duration;
2526
import io.trino.client.ClientSelectedRole;
2627
import io.trino.client.ClientSession;
28+
import io.trino.client.JsonResponse;
29+
import io.trino.client.ServerInfo;
2730
import io.trino.client.StatementClient;
31+
import io.trino.client.TrinoJsonCodec;
2832
import jakarta.annotation.Nullable;
2933
import okhttp3.Call;
3034
import okhttp3.HttpUrl;
@@ -74,16 +78,21 @@
7478
import static com.google.common.base.Preconditions.checkArgument;
7579
import static com.google.common.base.Preconditions.checkState;
7680
import static com.google.common.base.Strings.nullToEmpty;
81+
import static com.google.common.base.Suppliers.memoize;
7782
import static com.google.common.base.Throwables.getCausalChain;
7883
import static com.google.common.collect.Maps.fromProperties;
7984
import static io.airlift.units.Duration.nanosSince;
85+
import static io.trino.client.JsonResponse.execute;
8086
import static io.trino.client.StatementClientFactory.newStatementClient;
87+
import static io.trino.client.TrinoJsonCodec.jsonCodec;
8188
import static io.trino.jdbc.ClientInfoProperty.APPLICATION_NAME;
8289
import static io.trino.jdbc.ClientInfoProperty.CLIENT_INFO;
8390
import static io.trino.jdbc.ClientInfoProperty.CLIENT_TAGS;
8491
import static io.trino.jdbc.ClientInfoProperty.TRACE_TOKEN;
8592
import static java.lang.String.format;
8693
import static java.net.HttpURLConnection.HTTP_BAD_METHOD;
94+
import static java.net.HttpURLConnection.HTTP_FORBIDDEN;
95+
import static java.net.HttpURLConnection.HTTP_NOT_FOUND;
8796
import static java.net.HttpURLConnection.HTTP_OK;
8897
import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED;
8998
import static java.nio.charset.StandardCharsets.US_ASCII;
@@ -98,6 +107,7 @@ public class TrinoConnection
98107
{
99108
private static final Logger logger = Logger.getLogger(TrinoConnection.class.getPackage().getName());
100109

110+
private static final TrinoJsonCodec<ServerInfo> SERVER_INFO_CODEC = jsonCodec(ServerInfo.class);
101111
private static final int CONNECTION_TIMEOUT_SECONDS = 30; // Not configurable
102112

103113
private final AtomicBoolean closed = new AtomicBoolean();
@@ -136,6 +146,7 @@ public class TrinoConnection
136146
private boolean useExplicitPrepare = true;
137147
private boolean assumeNullCatalogMeansCurrentCatalog;
138148
private final boolean validateConnection;
149+
private final Supplier<Optional<String>> versionSupplier;
139150

140151
TrinoConnection(TrinoDriverUri uri, Call.Factory httpCallFactory, Call.Factory segmentHttpCallFactory)
141152
throws SQLException
@@ -186,6 +197,35 @@ public class TrinoConnection
186197
throw new SQLException("Unable to connect to Trino server", "08001", e);
187198
}
188199
}
200+
this.versionSupplier = memoize(this::fetchVersionFromServerInfo);
201+
}
202+
203+
private Optional<String> fetchVersionFromServerInfo()
204+
{
205+
HttpUrl url = HttpUrl.get(httpUri)
206+
.newBuilder()
207+
.encodedPath("/v1/info")
208+
.build();
209+
210+
Request request = new Request.Builder()
211+
.url(url)
212+
.get()
213+
.build();
214+
215+
Duration timeoutDuration = new Duration(CONNECTION_TIMEOUT_SECONDS, TimeUnit.SECONDS);
216+
long start = System.nanoTime();
217+
while (timeoutDuration.compareTo(nanosSince(start)) > 0) {
218+
JsonResponse<ServerInfo> serverInfo = execute(SERVER_INFO_CODEC, httpCallFactory, request);
219+
switch (serverInfo.getStatusCode()) {
220+
case HTTP_OK:
221+
return Optional.ofNullable(serverInfo.getValue().getNodeVersion().getVersion());
222+
case HTTP_NOT_FOUND:
223+
case HTTP_FORBIDDEN:
224+
return Optional.empty();
225+
}
226+
}
227+
228+
return Optional.empty();
189229
}
190230

191231
private boolean isConnectionValid(int timeout)
@@ -237,6 +277,11 @@ private boolean isConnectionValid(int timeout)
237277
throw new IOException(format("Connection validation timed out after %ss", timeout), lastException);
238278
}
239279

280+
public Optional<String> getServerVersion()
281+
{
282+
return versionSupplier.get();
283+
}
284+
240285
@Override
241286
public Statement createStatement()
242287
throws SQLException

client/trino-jdbc/src/main/java/io/trino/jdbc/TrinoDatabaseMetaData.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import java.util.ArrayList;
3232
import java.util.Comparator;
3333
import java.util.List;
34+
import java.util.Optional;
3435
import java.util.stream.Stream;
3536

3637
import static com.google.common.base.Preconditions.checkArgument;
@@ -140,6 +141,11 @@ public String getDatabaseProductName()
140141
public String getDatabaseProductVersion()
141142
throws SQLException
142143
{
144+
Optional<String> serverVersion = connection.getServerVersion();
145+
if (serverVersion.isPresent()) {
146+
return serverVersion.orElseThrow();
147+
}
148+
143149
try (ResultSet rs = select("SELECT version()")) {
144150
rs.next();
145151
return rs.getString(1);

0 commit comments

Comments
 (0)