Copilot commented on code in PR #6412:
URL: https://github.com/apache/hive/pull/6412#discussion_r3434529718


##########
service/src/java/org/apache/hive/service/cli/operation/SQLOperation.java:
##########
@@ -179,6 +179,11 @@ private void prepare(QueryState queryState) throws 
HiveSQLException {
           try {
             final String queryId = queryState.getQueryId();

Review Comment:
   The scheduled timeout task unconditionally sets the operation exception and 
calls cancel(TIMEDOUT). If the operation reaches a terminal state 
(FINISHED/ERROR/CANCELED) before the delay elapses but is not yet closed, this 
timer can still fire later and incorrectly flip the operation to TIMEDOUT (and 
overwrite the exception). Consider checking the current operation state inside 
the scheduled task and returning early when already terminal.



##########
jdbc/src/java/org/apache/hive/jdbc/HiveStatement.java:
##########
@@ -398,20 +398,93 @@ private TGetOperationStatusResp waitForResultSetStatus() 
throws SQLException {
     return statusResp;
   }
 
+  /**
+   * Returns the timeout message for a {@code TIMEDOUT_STATE} response.
+   * Uses the server error message when the SQL state is {@code HYT00} 
("timeout expired"),
+   * which indicates that the server set a precise message. Otherwise falls 
back to a
+   * locally derived message from {@link #setQueryTimeout(int)} or the 
URL-seeded
+   * {@code hive.query.timeout.seconds} value on the connection.
+   */
+  private String sqlTimeoutMessageForTimedOutState(String serverMessage, 
String sqlState) {
+    if ("HYT00".equals(sqlState) && StringUtils.isNotBlank(serverMessage)) {
+      return serverMessage;
+    }
+    long effectiveSec = resolveEffectiveTimeoutSecondsForMessage();
+    if (effectiveSec > 0) {
+      return "Query timed out after " + effectiveSec + " seconds";
+    }
+    return "Query timed out";
+  }
+
+  private long resolveEffectiveTimeoutSecondsForMessage() {
+    if (queryTimeout > 0) {
+      return queryTimeout;
+    }
+    long tracked = connection.getSessionQueryTimeoutSeconds();
+    if (tracked > 0) {
+      return tracked;
+    }
+    return 0L;

Review Comment:
   resolveEffectiveTimeoutSecondsForMessage() falls back to 
HiveConnection#getSessionQueryTimeoutSeconds(), but that value is currently 
only seeded from the JDBC URL and is never updated when executing a 
session-level `SET hive.query.timeout.seconds=...`. This means the described 
fallback behavior for SET-driven timeouts won’t work if the server doesn’t 
supply a reliable timeout message (e.g., when connecting to an older HS2).



##########
jdbc/src/java/org/apache/hive/jdbc/HiveStatement.java:
##########
@@ -398,20 +398,93 @@ private TGetOperationStatusResp waitForResultSetStatus() 
throws SQLException {
     return statusResp;
   }
 
+  /**
+   * Returns the timeout message for a {@code TIMEDOUT_STATE} response.
+   * Uses the server error message when the SQL state is {@code HYT00} 
("timeout expired"),
+   * which indicates that the server set a precise message. Otherwise falls 
back to a
+   * locally derived message from {@link #setQueryTimeout(int)} or the 
URL-seeded
+   * {@code hive.query.timeout.seconds} value on the connection.
+   */
+  private String sqlTimeoutMessageForTimedOutState(String serverMessage, 
String sqlState) {
+    if ("HYT00".equals(sqlState) && StringUtils.isNotBlank(serverMessage)) {
+      return serverMessage;
+    }
+    long effectiveSec = resolveEffectiveTimeoutSecondsForMessage();
+    if (effectiveSec > 0) {
+      return "Query timed out after " + effectiveSec + " seconds";
+    }
+    return "Query timed out";
+  }

Review Comment:
   The PR description says the client should ignore clearly-wrong server 
timeout text (e.g. containing "after 0 seconds") and fall back to a locally 
derived timeout. The current logic returns any non-blank HYT00 serverMessage 
unchanged, which can preserve the original incorrect "after 0 seconds" behavior 
when talking to older servers or other timeout paths.



##########
jdbc/src/java/org/apache/hive/jdbc/HiveConnection.java:
##########
@@ -190,6 +201,48 @@ public class HiveConnection implements java.sql.Connection 
{
 
   public TCLIService.Iface getClient() { return client; }
 
+  /**
+   * Updates the tracked {@code hive.query.timeout.seconds} value (in seconds) 
on this connection.
+   * Called at connect time from the JDBC URL hive-conf map, and may be called 
again later if needed.
+   */
+  void setSessionQueryTimeoutSeconds(long seconds) {
+    sessionQueryTimeoutSeconds.set(seconds);
+  }
+
+  /**
+   * If the JDBC URL supplied {@code hive.query.timeout.seconds} (via the 
{@code ?hive_conf_list}
+   * segment), parses and stores the value so that {@link 
#getSessionQueryTimeoutSeconds()} can
+   * return it for timeout error messages. This runs once at connect time and 
does not affect the
+   * server-side configuration, which is applied separately in {@link 
#openSession()}.
+   */
+  private void applySessionQueryTimeoutFromJdbcUrl() {
+    Map<String, String> hiveConfs = connParams.getHiveConfs();
+    if (hiveConfs == null || hiveConfs.isEmpty()) {
+      return;
+    }
+    String raw = hiveConfs.get(ConfVars.HIVE_QUERY_TIMEOUT_SECONDS.varname);
+    if (StringUtils.isBlank(raw)) {
+      return;
+    }
+    try {
+      HiveConf conf = new HiveConf();
+      conf.set(ConfVars.HIVE_QUERY_TIMEOUT_SECONDS.varname, raw.trim());
+      long sec = HiveConf.getTimeVar(conf, 
ConfVars.HIVE_QUERY_TIMEOUT_SECONDS, TimeUnit.SECONDS);
+      if (sec > 0) {
+        setSessionQueryTimeoutSeconds(sec);
+      }
+    } catch (Exception e) {
+      LOG.debug("Could not parse {} from JDBC URL: {}", 
ConfVars.HIVE_QUERY_TIMEOUT_SECONDS.varname, raw, e);
+    }

Review Comment:
   applySessionQueryTimeoutFromJdbcUrl() creates a new HiveConf and uses 
getTimeVar just to parse a single time value. Constructing HiveConf can be 
relatively expensive at connect time (it may load configuration resources). 
Since this is just parsing a duration string, HiveConf.toTime(...) can do the 
conversion without building a full HiveConf instance.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to