private ResultSet executeQuerySQL(String sql, long timeoutInMS) throws TException, SQLException {
    isCancelled = false;
    TSExecuteStatementReq execReq = new TSExecuteStatementReq(sessionId, sql, stmtId);
    int rows = fetchSize;
    if (maxRows != 0 && fetchSize > maxRows) {
      rows = maxRows;
    }
    execReq.setFetchSize(rows);
    execReq.setTimeout(timeoutInMS);
    execReq.setJdbcQuery(true);
    TSExecuteStatementResp execResp =
        callWithRetryAndReconnect(
            () -> client.executeQueryStatementV2(execReq), TSExecuteStatementResp::getStatus);
    queryId = execResp.getQueryId();
    try {
      RpcUtils.verifySuccess(execResp.getStatus());
    } catch (StatementExecutionException e) {
      throw new IoTDBSQLException(e.getMessage(), execResp.getStatus());
    }

    if (!execResp.isSetQueryResult()) {
      throw new SQLException("execResp.queryResult should never be null.");
    } else {
      this.resultSet =
          new IoTDBJDBCResultSet(
              this,
              execResp.getColumns(),
              execResp.getDataTypeList(),
              execResp.columnNameIndexMap,
              execResp.isIgnoreTimeStamp(),
              client,
              sql,
              queryId,
              sessionId,
              execResp.getQueryResult(),
              execResp.tracingInfo,
              execReq.timeout,
              execResp.moreData,
              zoneId,
              charset,
              execResp.isSetTableModel() && execResp.isTableModel(),
              execResp.getColumnIndex2TsBlockColumnIndexList());
    }
    return resultSet;
  }
There are two kinds of sql here: (1) query sql (2) update sql.

<p>(1) return IoTDBJDBCResultSet or IoTDBNonAlignJDBCResultSet (2) simply get executed
iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBStatement.java