Result getResult(Session session) {

    boolean startTransaction = false;

    if (this.isExplain) {
      return Result.newSingleColumnStringResult("OPERATION", describe(session));
    }

    switch (type) {

        // cursor
      case StatementTypes.ALLOCATE_CURSOR:
      case StatementTypes.ALLOCATE_DESCRIPTOR:
        return Result.updateZeroResult;

        //
      case StatementTypes.COMMIT_WORK:
        {
          try {
            boolean chain = parameters != null;

            session.commit(chain);

            return Result.updateZeroResult;
          } catch (HsqlException e) {
            return Result.newErrorResult(e, sql);
          }
        }
      case StatementTypes.DEALLOCATE_DESCRIPTOR:
      case StatementTypes.DEALLOCATE_PREPARE:
        return Result.updateZeroResult;

      case StatementTypes.DISCONNECT:
        session.close();

        return Result.updateZeroResult;

        //
      case StatementTypes.DYNAMIC_CLOSE:
      case StatementTypes.DYNAMIC_DELETE_CURSOR:
      case StatementTypes.DYNAMIC_FETCH:
      case StatementTypes.DYNAMIC_OPEN:

        //
      case StatementTypes.FETCH:
      case StatementTypes.FREE_LOCATOR:
      case StatementTypes.GET_DESCRIPTOR:
      case StatementTypes.HOLD_LOCATOR:

        //
      case StatementTypes.OPEN:
      case StatementTypes.PREPARABLE_DYNAMIC_DELETE_CURSOR:
      case StatementTypes.PREPARABLE_DYNAMIC_UPDATE_CURSOR:
      case StatementTypes.PREPARE:
        return Result.updateZeroResult;

      case StatementTypes.TRANSACTION_LOCK_TABLE:
        {
          return Result.updateZeroResult;
        }
      case StatementTypes.RELEASE_SAVEPOINT:
        {
          String savepoint = (String) parameters[0];

          try {
            session.releaseSavepoint(savepoint);

            return Result.updateZeroResult;
          } catch (HsqlException e) {
            return Result.newErrorResult(e, sql);
          }
        }
      case StatementTypes.ROLLBACK_WORK:
        {
          boolean chain = ((Boolean) parameters[0]).booleanValue();

          session.rollback(chain);

          return Result.updateZeroResult;
        }
      case StatementTypes.ROLLBACK_SAVEPOINT:
        {
          String savepoint = (String) parameters[0];

          try {
            session.rollbackToSavepoint(savepoint);

            return Result.updateZeroResult;
          } catch (HsqlException e) {
            return Result.newErrorResult(e, sql);
          }
        }
      case StatementTypes.SAVEPOINT:
        {
          String savepoint = (String) parameters[0];

          session.savepoint(savepoint);

          return Result.updateZeroResult;
        }
      case StatementTypes.SET_CATALOG:
        {
          String name;

          try {
            name = (String) expressions[0].getValue(session);
            name = (String) Type.SQL_VARCHAR.trim(session, name, ' ', true, true);

            if (session.database.getCatalogName().name.equals(name)) {
              return Result.updateZeroResult;
            }

            return Result.newErrorResult(Error.error(ErrorCode.X_3D000), sql);
          } catch (HsqlException e) {
            return Result.newErrorResult(e, sql);
          }
        }
      case StatementTypes.SET_CONNECTION:
      case StatementTypes.SET_CONSTRAINT:
      case StatementTypes.SET_DESCRIPTOR:
        return Result.updateZeroResult;

      case StatementTypes.SET_TIME_ZONE:
        {
          Object value = null;

          if (expressions[0].getType() == OpTypes.VALUE
              && expressions[0].getConstantValueNoCheck(session) == null) {
            session.timeZoneSeconds = session.sessionTimeZoneSeconds;

            return Result.updateZeroResult;
          }

          try {
            value = expressions[0].getValue(session);
          } catch (HsqlException e) {
          }

          if (value instanceof Result) {
            Result result = (Result) value;

            if (result.isData()) {
              Object[] data = (Object[]) result.getNavigator().getNext();
              boolean single = !result.getNavigator().next();

              if (single && data != null && data[0] != null) {
                value = data[0];

                result.getNavigator().close();
              } else {
                result.getNavigator().close();

                return Result.newErrorResult(Error.error(ErrorCode.X_22009), sql);
              }
            } else {
              return Result.newErrorResult(Error.error(ErrorCode.X_22009), sql);
            }
          } else {
            if (value == null) {
              return Result.newErrorResult(Error.error(ErrorCode.X_22009), sql);
            }
          }

          long seconds = ((IntervalSecondData) value).getSeconds();

          if (-DTIType.timezoneSecondsLimit <= seconds && seconds <= DTIType.timezoneSecondsLimit) {
            session.timeZoneSeconds = (int) seconds;

            return Result.updateZeroResult;
          }

          return Result.newErrorResult(Error.error(ErrorCode.X_22009), sql);
        }
      case StatementTypes.SET_NAMES:
        return Result.updateZeroResult;

      case StatementTypes.SET_PATH:
        return Result.updateZeroResult;

      case StatementTypes.SET_ROLE:
        {
          String name;
          Grantee role = null;

          try {
            name = (String) expressions[0].getValue(session);

            if (name != null) {
              name = (String) Type.SQL_VARCHAR.trim(session, name, ' ', true, true);
              role = session.database.granteeManager.getRole(name);
            }
          } catch (HsqlException e) {
            return Result.newErrorResult(Error.error(ErrorCode.X_0P000), sql);
          }

          if (session.isInMidTransaction()) {
            return Result.newErrorResult(Error.error(ErrorCode.X_25001), sql);
          }

          if (role == null) {
            session.setRole(null);
          }

          if (session.getGrantee().hasRole(role)) {
            session.setRole(role);

            return Result.updateZeroResult;
          } else {
            return Result.newErrorResult(Error.error(ErrorCode.X_0P000), sql);
          }
        }
      case StatementTypes.SET_SCHEMA:
        {
          String name;
          HsqlName schema;

          try {
            if (expressions == null) {
              name = ((HsqlName) parameters[0]).name;
            } else {
              name = (String) expressions[0].getValue(session);
            }

            name = (String) Type.SQL_VARCHAR.trim(session, name, ' ', true, true);
            schema = session.database.schemaManager.getSchemaHsqlName(name);

            session.setSchema(schema.name);

            return Result.updateZeroResult;
          } catch (HsqlException e) {
            return Result.newErrorResult(e, sql);
          }
        }
      case StatementTypes.SET_SESSION_AUTHORIZATION:
        {
          if (session.isInMidTransaction()) {
            return Result.newErrorResult(Error.error(ErrorCode.X_25001), sql);
          }

          try {
            String user;
            String password = null;

            user = (String) expressions[0].getValue(session);
            user = (String) Type.SQL_VARCHAR.trim(session, user, ' ', true, true);

            if (expressions[1] != null) {
              password = (String) expressions[1].getValue(session);
            }

            User userObject;

            if (password == null) {
              userObject = session.database.userManager.get(user);
            } else {
              userObject = session.database.getUserManager().getUser(user, password);
            }

            if (userObject == null) {
              throw Error.error(ErrorCode.X_28501);
            }

            sql = userObject.getConnectUserSQL();

            if (userObject == session.getGrantee()) {
              return Result.updateZeroResult;
            }

            if (session.getGrantee().canChangeAuthorisation()) {
              session.setUser((User) userObject);
              session.setRole(null);
              session.resetSchema();

              return Result.updateZeroResult;
            }

            /** @todo may need different error code */
            throw Error.error(ErrorCode.X_28000);
          } catch (HsqlException e) {
            return Result.newErrorResult(e, sql);
          }
        }
      case StatementTypes.SET_SESSION_CHARACTERISTICS:
        {
          try {
            if (parameters[0] != null) {
              boolean readonly = ((Boolean) parameters[0]).booleanValue();

              session.setReadOnlyDefault(readonly);
            }

            if (parameters[1] != null) {
              int level = ((Integer) parameters[1]).intValue();

              session.setIsolationDefault(level);
            }

            return Result.updateZeroResult;
          } catch (HsqlException e) {
            return Result.newErrorResult(e, sql);
          }
        }
      case StatementTypes.SET_COLLATION:
        return Result.updateZeroResult;

      case StatementTypes.SET_TRANSFORM_GROUP:
        return Result.updateZeroResult;

      case StatementTypes.START_TRANSACTION:
        startTransaction = true;

        // fall through
      case StatementTypes.SET_TRANSACTION:
        {
          try {
            if (parameters[0] != null) {
              boolean readonly = ((Boolean) parameters[0]).booleanValue();

              session.setReadOnly(readonly);
            }

            if (parameters[1] != null) {
              int level = ((Integer) parameters[1]).intValue();

              session.setIsolation(level);
            }

            if (startTransaction) {
              session.startTransaction();
            }

            return Result.updateZeroResult;
          } catch (HsqlException e) {
            return Result.newErrorResult(e, sql);
          }
        }

        //
      case StatementTypes.SET_SESSION_AUTOCOMMIT:
        {
          boolean mode = ((Boolean) parameters[0]).booleanValue();

          try {
            session.setAutoCommit(mode);

            return Result.updateZeroResult;
          } catch (HsqlException e) {
            return Result.newErrorResult(e, sql);
          }
        }
      case StatementTypes.DECLARE_VARIABLE:
        {
          ColumnSchema variable = (ColumnSchema) parameters[0];

          try {
            session.sessionContext.addSessionVariable(variable);

            return Result.updateZeroResult;
          } catch (HsqlException e) {
            return Result.newErrorResult(e, sql);
          }
        }
      case StatementTypes.SET_SESSION_RESULT_MAX_ROWS:
        {
          int size = ((Integer) parameters[0]).intValue();

          session.setSQLMaxRows(size);

          return Result.updateZeroResult;
        }
      case StatementTypes.SET_SESSION_RESULT_MEMORY_ROWS:
        {
          int size = ((Integer) parameters[0]).intValue();

          session.setResultMemoryRowCount(size);

          return Result.updateZeroResult;
        }
      default:
        throw Error.runtimeError(ErrorCode.U_S0500, "CompiledStateemntCommand");
    }
  }
  /**
   * Determines if the authorizations are adequate to execute the compiled object. Completion
   * requires the list of all database objects in a compiled statement.
   */
  void checkAccessRights(Session session) {

    if (targetTable != null && !targetTable.isTemp()) {
      Grantee owner = targetTable.getOwner();

      if (owner != null && owner.isSystem()) {
        if (!session.getUser().isSystem()) {
          throw Error.error(ErrorCode.X_42501, targetTable.getName().name);
        }
      }

      if (!session.isProcessingScript) {
        targetTable.checkDataReadOnly();
      }

      session.checkReadWrite();
    }

    if (session.isAdmin()) {
      return;
    }

    for (int i = 0; i < sequences.length; i++) {
      session.getGrantee().checkAccess(sequences[i]);
    }

    for (int i = 0; i < routines.length; i++) {
      if (routines[i].isLibraryRoutine()) {
        continue;
      }

      session.getGrantee().checkAccess(routines[i]);
    }

    for (int i = 0; i < rangeVariables.length; i++) {
      RangeVariable range = rangeVariables[i];

      if (range.rangeTable.getSchemaName() == SqlInvariants.SYSTEM_SCHEMA_HSQLNAME) {
        continue;
      }

      session.getGrantee().checkSelect(range.rangeTable, range.usedColumns);
    }

    switch (type) {
      case StatementTypes.CALL:
        {
          break;
        }
      case StatementTypes.INSERT:
        {
          session.getGrantee().checkInsert(targetTable, insertCheckColumns);

          break;
        }
      case StatementTypes.SELECT_CURSOR:
        break;

      case StatementTypes.DELETE_WHERE:
        {
          session.getGrantee().checkDelete(targetTable);

          break;
        }
      case StatementTypes.UPDATE_WHERE:
        {
          session.getGrantee().checkUpdate(targetTable, updateCheckColumns);

          break;
        }
      case StatementTypes.MERGE:
        {
          session.getGrantee().checkInsert(targetTable, insertCheckColumns);
          session.getGrantee().checkUpdate(targetTable, updateCheckColumns);

          break;
        }
    }
  }