1616import com .google .common .annotations .VisibleForTesting ;
1717import com .google .common .base .Joiner ;
1818import com .google .common .base .Splitter ;
19+ import com .google .common .base .Supplier ;
1920import com .google .common .collect .ImmutableList ;
2021import com .google .common .collect .ImmutableMap ;
2122import com .google .common .collect .ImmutableSet ;
2425import io .airlift .units .Duration ;
2526import io .trino .client .ClientSelectedRole ;
2627import io .trino .client .ClientSession ;
28+ import io .trino .client .JsonResponse ;
29+ import io .trino .client .ServerInfo ;
2730import io .trino .client .StatementClient ;
31+ import io .trino .client .TrinoJsonCodec ;
2832import jakarta .annotation .Nullable ;
2933import okhttp3 .Call ;
3034import okhttp3 .HttpUrl ;
7478import static com .google .common .base .Preconditions .checkArgument ;
7579import static com .google .common .base .Preconditions .checkState ;
7680import static com .google .common .base .Strings .nullToEmpty ;
81+ import static com .google .common .base .Suppliers .memoize ;
7782import static com .google .common .base .Throwables .getCausalChain ;
7883import static com .google .common .collect .Maps .fromProperties ;
7984import static io .airlift .units .Duration .nanosSince ;
85+ import static io .trino .client .JsonResponse .execute ;
8086import static io .trino .client .StatementClientFactory .newStatementClient ;
87+ import static io .trino .client .TrinoJsonCodec .jsonCodec ;
8188import static io .trino .jdbc .ClientInfoProperty .APPLICATION_NAME ;
8289import static io .trino .jdbc .ClientInfoProperty .CLIENT_INFO ;
8390import static io .trino .jdbc .ClientInfoProperty .CLIENT_TAGS ;
8491import static io .trino .jdbc .ClientInfoProperty .TRACE_TOKEN ;
8592import static java .lang .String .format ;
8693import static java .net .HttpURLConnection .HTTP_BAD_METHOD ;
94+ import static java .net .HttpURLConnection .HTTP_FORBIDDEN ;
95+ import static java .net .HttpURLConnection .HTTP_NOT_FOUND ;
8796import static java .net .HttpURLConnection .HTTP_OK ;
8897import static java .net .HttpURLConnection .HTTP_UNAUTHORIZED ;
8998import 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
0 commit comments