abstractdog commented on code in PR #5613:
URL: https://github.com/apache/hive/pull/5613#discussion_r1925128843


##########
ql/src/java/org/apache/hadoop/hive/ql/DriverContext.java:
##########
@@ -247,4 +275,107 @@ public String getQueryErrorMessage() {
   public void setQueryErrorMessage(String queryErrorMessage) {
     this.queryErrorMessage = queryErrorMessage;
   }
+
+  public long getQueryStartTime() {
+    return getQueryInfo() != null ? getQueryInfo().getBeginTime() : 
getQueryDisplay().getQueryStartTime();
+  }
+
+  /**
+   * Resolves the query type from the SemanticAnalyzer and the query AST, 
which might look magic.
+   * Magic is needed because a query can fail due to semantic exceptions, and 
at that time, from syntax point of view,
+   * it's already clear what's the query type, even if the SemanticAnalyzer 
bailed out, typical problems:
+   * 1. general semantic exception
+   * 2. transaction manager validation (throwin exception)
+   * What a user expects here is something like "QUERY", "DDL", "DML", so this 
magic will do its best to tell.
+   * any kind of "analyze": STATS
+   * DML operations (INSERT, UPDATE, DELETE, MERGE): DML
+   * MAPRED: QUERY, DML (depending on QueryProperties achieved in compile time)
+   * FETCH: QUERY: a simple fetch task is a QUERY
+   * UNKNOWN: if we can't determine the type of the query:
+   * e.g. when ParseException happens, we won't do further magic,
+   * even if it's obvious by reading the sql statement that user wanted to run 
e.g. a select query
+   * @param sem the semantic analyzer which already analyzed the query
+   * @param tree the root ASTNode of the query
+   */
+  public void setQueryType(BaseSemanticAnalyzer sem, ASTNode tree) {
+    List<Task<? extends Serializable>> rootTasks = sem.getAllRootTasks();
+    QueryProperties props = sem.getQueryProperties();
+    queryType = isAnalyze(props) ? "STATS" : (isDML(props) ? "DML" : null);
+    // common confusion whether CTAS is DML or DDL, let's pick DDL here
+    if (props != null && props.isCTAS()) {
+      queryType = "DDL";
+    }
+    if (queryType != null) {
+      return; //already figured out
+    }
+    queryType = rootTasks.stream().findFirst().map(t -> {
+      String type = t.getType().toString();
+      // a MAPRED stage could mean an INSERT query also
+      if (props != null && type.equalsIgnoreCase("MAPRED")) {
+        return props.isInsert ? "DML" : "QUERY";
+      }
+      return type;
+    }).orElseGet(() -> {
+      // in case of a semantic exception (e.g. a table not found or something 
else)
+      // the root AST Node can still imply if this is a query, try to fall 
back to that
+      // instead of "UNKNOWN"
+      if (tree.getText().equalsIgnoreCase("TOK_QUERY")){
+        return "QUERY";
+      }
+      // if there is a fetch task, this is a query
+      if (sem.getFetchTask() != null) {
+        return "QUERY";
+      }
+      // from this point, best efforts come
+      // whether it's a DDL?
+      if (DDLSemanticAnalyzerFactory.handles(tree)) {
+        return "DDL";
+      }
+      // whether it's DML? UPDATE/DELETE/MERGE queries are handled with an 
instance of RewriteSemanticAnalyzer
+      if (RewriteSemanticAnalyzer.class.isAssignableFrom(sem.getClass())) {
+        return "DML";
+      }
+      return "UNKNOWN";
+    });
+
+    // in case of DDL queries, the DDL type can be figured out from the tree 
root token, e.g.:
+    // CREATETABLE, ALTERTABLE_ADDPARTS, SHOWDATABASES, SHOWTABLES, etc.
+    this.ddlType = "DDL".equalsIgnoreCase(queryType) ? 
tree.getText().substring("TOK_".length()) : "";
+  }
+
+  /**
+   * The return value of either isAnalyzeCommand() or isAnalyzeRewrite() is 
always true for analyze commands:
+   * isAnalyzeCommand=true for "compute statistics",
+   * isAnalyzeRewrite=true for "compute statistics for columns".
+   * @return
+   */
+  private boolean isAnalyze(QueryProperties queryProperties) {
+    return queryProperties != null && (queryProperties.isAnalyzeCommand() || 
queryProperties.isAnalyzeRewrite());
+  }
+
+  /**
+   * DML (Data Manipulation Language) operations are operations that modify 
data,
+   * queryProperties.isInsert seems to reflect this very well: true for INSERT 
[OVERWRITE], UPDATE, DELETE, MERGE
+   * @return
+   */
+  private boolean isDML(QueryProperties queryProperties) {
+    return queryProperties != null && queryProperties.isInsert;
+  }
+
+  public boolean isQueryHistoryExplainEnabled() {
+    return 
conf.getBoolVar(HiveConf.ConfVars.HIVE_QUERY_HISTORY_SERVICE_ENABLED) &&

Review Comment:
   moved the convenience method to the HiveConf (which already has similar ones 
like isWebUiQueryInfoCacheEnabled)



-- 
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: gitbox-unsubscr...@hive.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscr...@hive.apache.org
For additional commands, e-mail: gitbox-h...@hive.apache.org

Reply via email to