/**
   * Executes a SELECT statement. It is assumed that the argument is of the correct type.
   *
   * @param cs a CompiledStatement of type CompiledStatement.SELECT
   * @throws HsqlException if a database access error occurs
   * @return the result of executing the statement
   */
  private Result executeSelectStatement(CompiledStatement cs) throws HsqlException {

    Select select = cs.select;
    Result result;

    if (select.sIntoTable != null) {

      // session level user rights
      session.checkDDLWrite();

      if (session.getDatabase().findUserTable(session, select.sIntoTable.name) != null
          || session.getDatabase().dInfo.getSystemTable(session, select.sIntoTable.name) != null) {
        throw Trace.error(Trace.TABLE_ALREADY_EXISTS, select.sIntoTable.name);
      }

      result = select.getResult(session.getMaxRows(), session);
      result =
          session.dbCommandInterpreter.processSelectInto(
              result, select.sIntoTable, select.intoType);

      session.getDatabase().setMetaDirty(false);
    } else {
      result = select.getResult(session.getMaxRows(), session);
    }

    return result;
  }
  /**
   * Executes an INSERT_SELECT statement. It is assumed that the argument is of the correct type.
   *
   * @param cs a CompiledStatement of type CompiledStatement.INSERT_SELECT
   * @throws HsqlException if a database access error occurs
   * @return the result of executing the statement
   */
  private Result executeInsertSelectStatement(CompiledStatement cs) throws HsqlException {

    Table t = cs.targetTable;
    Select s = cs.select;
    int[] ct = t.getColumnTypes(); // column types
    Result r = s.getResult(session.getMaxRows(), session);
    Record rc = r.rRoot;
    int[] cm = cs.columnMap; // column map
    boolean[] ccl = cs.checkColumns; // column check list
    int len = cm.length;
    Object[] row;
    int count;
    boolean success = false;

    session.beginNestedTransaction();

    try {
      while (rc != null) {
        row = t.getNewRowData(session, ccl);

        for (int i = 0; i < len; i++) {
          int j = cm[i];

          if (ct[j] != r.metaData.colType[i]) {
            row[j] = Column.convertObject(rc.data[i], ct[j]);
          } else {
            row[j] = rc.data[i];
          }
        }

        rc.data = row;
        rc = rc.next;
      }

      count = t.insert(session, r);
      success = true;
    } finally {
      session.endNestedTransaction(!success);
    }

    updateResult.iUpdateCount = count;

    return updateResult;
  }