public static Column[] getInputTableFields(Table table, String[] cols) {
   List<Column> schema = table.getSchema().getColumns();
   if (cols == null || cols.length == 0) {
     return null;
   }
   Column[] fields = new Column[cols.length];
   for (int i = 0; i < cols.length; i++) {
     for (Column field : schema) {
       if (schema.get(i).getName().equals(field.getName())) {
         fields[i] = schema.get(i);
       }
     }
   }
   return fields;
 }
  @Override
  public ResultSet executeQuery(String sql) throws SQLException {
    checkClosed();
    beforeExecute();

    long begin = System.currentTimeMillis();

    // Create a temp table for querying ResultSet and ensure its creation.
    // If the table can not be created (CANCELLED/FAIL), an exception will be caused.
    // Once the table has been created, it will last until the Statement is closed,
    // or another query is started.
    String tempTempTable = "jdbc_temp_tbl_" + UUID.randomUUID().toString().replaceAll("-", "_");

    try {
      executeInstance =
          runClientSQL(
              "create table "
                  + tempTempTable
                  + " lifecycle "
                  + connHanlde.lifecycle
                  + " as "
                  + sql);

      boolean complete = false;
      while (!complete) {
        try {
          Thread.sleep(POOLING_INTERVAL);
        } catch (InterruptedException e) {
          break;
        }

        Instance.TaskStatus.Status status;
        try {
          status = executeInstance.getTaskStatus().get("SQL").getStatus();
        } catch (NullPointerException e) {
          continue;
        }
        switch (status) {
          case SUCCESS:
            complete = true;
            break;
          case FAILED:
            String reason = executeInstance.getTaskResults().get("SQL");
            connHanlde.log.fine("create temp table failed: " + reason);
            throw new SQLException("create temp table failed: " + reason, "FAILED");
          case CANCELLED:
            connHanlde.log.info("create temp table cancelled");
            throw new SQLException("create temp table cancelled", "CANCELLED");
          case WAITING:
          case RUNNING:
          case SUSPENDED:
            break;
        }
      }
    } catch (OdpsException e) {
      connHanlde.log.fine("create temp table failed: " + e.getMessage());
      throw new SQLException(e);
    }

    // If we arrive here, the temp table must be effective
    tempTable = tempTempTable;
    long end = System.currentTimeMillis();
    connHanlde.log.fine("It took me " + (end - begin) + " ms to create " + tempTable);

    // Read schema
    begin = System.currentTimeMillis();
    List<String> columnNames = new ArrayList<String>();
    List<OdpsType> columnSqlTypes = new ArrayList<OdpsType>();
    try {
      Table table = connHanlde.getOdps().tables().get(tempTable);
      table.reload();
      for (Column col : table.getSchema().getColumns()) {
        columnNames.add(col.getName());
        columnSqlTypes.add(col.getType());
      }
    } catch (OdpsException e) {
      throw new SQLException(e);
    }
    OdpsResultSetMetaData meta = new OdpsResultSetMetaData(columnNames, columnSqlTypes);
    end = System.currentTimeMillis();
    connHanlde.log.fine("It took me " + (end - begin) + " ms to read the table schema");

    // Create a download session through tunnel
    DownloadSession session;
    try {
      TableTunnel tunnel = new TableTunnel(connHanlde.getOdps());
      String project_name = connHanlde.getOdps().getDefaultProject();
      session = tunnel.createDownloadSession(project_name, tempTable);
      connHanlde.log.info("create download session id=" + session.getId());
    } catch (TunnelException e) {
      throw new SQLException(e);
    }

    resultSet =
        isResultSetScrollable
            ? new OdpsScollResultSet(this, meta, session)
            : new OdpsForwardResultSet(this, meta, session);

    return resultSet;
  }