Result getResult(Session session) {

    switch (type) {
      case StatementTypes.SIGNAL:
      case StatementTypes.RESIGNAL:

        // todo
      case StatementTypes.ITERATE:
      case StatementTypes.LEAVE:
      case StatementTypes.RETURN:
      case StatementTypes.CONDITION:
        return this.getResultValue(session);

      case StatementTypes.ASSIGNMENT:
        {
          Object[] variables =
              variable.getType() == SchemaObject.PARAMETER
                  ? session.sessionContext.routineArguments
                  : session.sessionContext.routineVariables;

          try {
            Object o = expression.getValue(session, variable.getDataType());

            variables[variableIndex] = o;

            return Result.updateZeroResult;
          } catch (HsqlException e) {
            return Result.newErrorResult(e);
          }
        }
      default:
        throw Error.runtimeError(ErrorCode.U_S0500, "");
    }
  }
  public String getNameString() {

    switch (typeCode) {
      case Types.TINYINT:
        return Tokens.T_TINYINT;

      case Types.SQL_SMALLINT:
        return Tokens.T_SMALLINT;

      case Types.SQL_INTEGER:
        return Tokens.T_INTEGER;

      case Types.SQL_BIGINT:
        return Tokens.T_BIGINT;

      case Types.SQL_REAL:
        return Tokens.T_REAL;

      case Types.SQL_FLOAT:
        return Tokens.T_FLOAT;

      case Types.SQL_DOUBLE:
        return Tokens.T_DOUBLE;

      case Types.SQL_NUMERIC:
        return Tokens.T_NUMERIC;

      case Types.SQL_DECIMAL:
        return Tokens.T_DECIMAL;

      default:
        throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
    }
  }
  public static NumberType getNumberType(int type, long precision, int scale) {

    switch (type) {
      case Types.SQL_INTEGER:
        return SQL_INTEGER;

      case Types.SQL_SMALLINT:
        return SQL_SMALLINT;

      case Types.SQL_BIGINT:
        return SQL_BIGINT;

      case Types.TINYINT:
        return TINYINT;

      case Types.SQL_REAL:
      case Types.SQL_DOUBLE:
        return SQL_DOUBLE;

      case Types.SQL_NUMERIC:
      case Types.SQL_DECIMAL:
        return new NumberType(type, precision, scale);

      default:
        throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
    }
  }
Exemple #4
0
  boolean hasColumnOnly(int colIndex) {

    switch (constType) {
      case CHECK:
        return rangeVariable.usedColumns[colIndex]
            && ArrayUtil.countTrueElements(rangeVariable.usedColumns) == 1;

      case PRIMARY_KEY:
      case UNIQUE:
        return core.mainCols.length == 1 && core.mainCols[0] == colIndex;

      case MAIN:
        return core.mainCols.length == 1
            && core.mainCols[0] == colIndex
            && core.mainTable == core.refTable;

      case FOREIGN_KEY:
        return core.refCols.length == 1
            && core.refCols[0] == colIndex
            && core.mainTable == core.refTable;

      default:
        throw Error.runtimeError(ErrorCode.U_S0500, "Constraint");
    }
  }
  public boolean isNegative(Object a) throws HsqlException {

    if (a == null) {
      return false;
    }

    switch (typeCode) {
      case Types.SQL_REAL:
      case Types.SQL_FLOAT:
      case Types.SQL_DOUBLE:
        {
          double ad = ((Number) a).doubleValue();

          return ad < 0;
        }
      case Types.SQL_NUMERIC:
      case Types.SQL_DECIMAL:
        return ((BigDecimal) a).signum() < 0;

      case Types.TINYINT:
      case Types.SQL_SMALLINT:
      case Types.SQL_INTEGER:
        return ((Number) a).intValue() < 0;

      case Types.SQL_BIGINT:
        return ((Number) a).longValue() < 0;

      default:
        throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
    }
  }
  static int getExpressionType(int tokenT) {

    int type = expressionTypeMap.get(tokenT, -1);

    if (type == -1) {
      throw Error.runtimeError(ErrorCode.U_S0500, "Parser");
    }

    return type;
  }
  public void resetAccessorKeys(Index[] keys) {

    if (indexList.length == 0 || indexList[0] == null || accessorList[0] == null) {
      indexList = keys;
      accessorList = new CachedObject[indexList.length];

      return;
    }

    throw Error.runtimeError(ErrorCode.U_S0500, "RowStoreAVLDisk");
  }
  public Object add(Object a, Object b, Type otherType) throws HsqlException {

    if (a == null || b == null) {
      return null;
    }

    switch (typeCode) {
      case Types.SQL_REAL:
      case Types.SQL_FLOAT:
      case Types.SQL_DOUBLE:
        {
          double ad = ((Number) a).doubleValue();
          double bd = ((Number) b).doubleValue();

          return ValuePool.getDouble(Double.doubleToLongBits(ad + bd));

          //                return new Double(ad + bd);
        }
      case Types.SQL_NUMERIC:
      case Types.SQL_DECIMAL:
        {
          a = convertToDefaultType(null, a);
          b = convertToDefaultType(null, b);

          BigDecimal abd = (BigDecimal) a;
          BigDecimal bbd = (BigDecimal) b;

          return abd.add(bbd);
        }
      case Types.TINYINT:
      case Types.SQL_SMALLINT:
      case Types.SQL_INTEGER:
        {
          int ai = ((Number) a).intValue();
          int bi = ((Number) b).intValue();

          return ValuePool.getInt(ai + bi);
        }
      case Types.SQL_BIGINT:
        {
          long longa = ((Number) a).longValue();
          long longb = ((Number) b).longValue();

          return ValuePool.getLong(longa + longb);
        }
      default:
        throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
    }
  }
  public String convertToString(Object a) {

    if (a == null) {
      return null;
    }

    switch (this.typeCode) {
      case Types.TINYINT:
      case Types.SQL_SMALLINT:
      case Types.SQL_INTEGER:
      case Types.SQL_BIGINT:
        return a.toString();

      case Types.SQL_REAL:
      case Types.SQL_DOUBLE:
        double value = ((Double) a).doubleValue();

        // todo - java 5 format change
        if (value == Double.NEGATIVE_INFINITY) {
          return "-1E0/0";
        }

        if (value == Double.POSITIVE_INFINITY) {
          return "1E0/0";
        }

        if (Double.isNaN(value)) {
          return "0E0/0E0";
        }

        String s = Double.toString(value);

        // ensure the engine treats the value as a DOUBLE, not DECIMAL
        if (s.indexOf('E') < 0) {
          s = s.concat("E0");
        }

        return s;

      case Types.SQL_NUMERIC:
      case Types.SQL_DECIMAL:
        return JavaSystem.toString((BigDecimal) a);

      default:
        throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
    }
  }
  StatementSession(int type, HsqlName[] readNames, HsqlName[] writeNames) {

    super(type);

    this.isTransactionStatement = true;
    this.readTableNames = readNames;
    writeTableNames = writeNames;

    switch (type) {
      case StatementTypes.TRANSACTION_LOCK_TABLE:
        group = StatementTypes.X_HSQLDB_TRANSACTION;
        break;

      default:
        throw Error.runtimeError(ErrorCode.U_S0500, "StatementCommand");
    }
  }
Exemple #11
0
  boolean hasColumn(int colIndex) {

    switch (constType) {
      case CHECK:
        return rangeVariable.usedColumns[colIndex];

      case PRIMARY_KEY:
      case UNIQUE:
      case MAIN:
        return ArrayUtil.find(core.mainCols, colIndex) != -1;

      case FOREIGN_KEY:
        return ArrayUtil.find(core.refCols, colIndex) != -1;

      default:
        throw Error.runtimeError(ErrorCode.U_S0500, "Constraint");
    }
  }
  private static BigDecimal convertToDecimal(Object a) {

    if (a instanceof BigDecimal) {
      return (BigDecimal) a;
    } else if (a instanceof Integer || a instanceof Long) {
      return BigDecimal.valueOf(((Number) a).longValue());
    } else if (a instanceof Double) {
      double value = ((Number) a).doubleValue();

      if (Double.isInfinite(value) || Double.isNaN(value)) {
        return null;
      }

      return new BigDecimal(value);
    } else {
      throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
    }
  }
  public int displaySize() {

    switch (typeCode) {
      case Types.SQL_DECIMAL:
      case Types.SQL_NUMERIC:
        if (scale == 0) {
          if (precision == 0) {
            return 646456995; // precision + "-.".length()}
          }

          return (int) precision + 1;
        }

        if (precision == scale) {
          return (int) precision + 3;
        }

        return (int) precision + 2;

      case Types.SQL_FLOAT:
      case Types.SQL_REAL:
      case Types.SQL_DOUBLE:
        return 23; // String.valueOf(-Double.MAX_VALUE).length();

      case Types.SQL_BIGINT:
        return 20; // decimal precision + "-".length();

      case Types.SQL_INTEGER:
        return 11; // decimal precision + "-".length();

      case Types.SQL_SMALLINT:
        return 6; // decimal precision + "-".length();

      case Types.TINYINT:
        return 4; // decimal precision + "-".length();

      default:
        throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
    }
  }
  /** Returns decimal precision for NUMERIC/DECIMAL. Returns binary precision for other parts. */
  public int getPrecision() {

    switch (typeCode) {
      case Types.TINYINT:
      case Types.SQL_SMALLINT:
      case Types.SQL_INTEGER:
      case Types.SQL_BIGINT:
        return typeWidth;

      case Types.SQL_REAL:
      case Types.SQL_FLOAT:
      case Types.SQL_DOUBLE:
        return 64;

      case Types.SQL_NUMERIC:
      case Types.SQL_DECIMAL:
        return (int) precision;

      default:
        throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
    }
  }
  public String getJDBCClassName() {

    switch (typeCode) {
      case Types.TINYINT:
      case Types.SQL_SMALLINT:
      case Types.SQL_INTEGER:
      case Types.SQL_BIGINT:
        return "java.lang.Integer";

      case Types.SQL_REAL:
      case Types.SQL_FLOAT:
      case Types.SQL_DOUBLE:
        return "java.lang.Double";

      case Types.SQL_NUMERIC:
      case Types.SQL_DECIMAL:
        return "java.math.BigDecimal";

      default:
        throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
    }
  }
  /** @todo - review usage to see if range enforcement / java type conversion is necessary */
  public Object convertToTypeLimits(Object a) throws HsqlException {

    if (a == null) {
      return null;
    }

    switch (typeCode) {
      case Types.TINYINT:
      case Types.SQL_SMALLINT:
      case Types.SQL_INTEGER:
      case Types.SQL_BIGINT:
        return a;

      case Types.SQL_REAL:
      case Types.SQL_FLOAT:
      case Types.SQL_DOUBLE:
        return a;

      case Types.SQL_NUMERIC:
      case Types.SQL_DECIMAL:
        BigDecimal dec = (BigDecimal) a;

        if (scale != dec.scale()) {
          dec = dec.setScale(scale, BigDecimal.ROUND_HALF_DOWN);
        }

        int valuePrecision = JavaSystem.precision(dec);

        if (valuePrecision > precision) {
          throw Error.error(ErrorCode.X_22003);
        }

        return dec;

      default:
        throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
    }
  }
  StatementSession(int type, Expression[] args) {

    super(type);

    this.expressions = args;
    isTransactionStatement = false;

    switch (type) {
      case StatementTypes.SET_PATH:
      case StatementTypes.SET_TIME_ZONE:
      case StatementTypes.SET_NAMES:
      case StatementTypes.SET_ROLE:
      case StatementTypes.SET_SCHEMA:
      case StatementTypes.SET_CATALOG:
      case StatementTypes.SET_SESSION_AUTHORIZATION:
      case StatementTypes.SET_COLLATION:
        group = StatementTypes.X_SQL_SESSION;
        break;

      default:
        throw Error.runtimeError(ErrorCode.U_S0500, "StateemntCommand");
    }
  }
Exemple #18
0
  boolean hasColumnPlus(int colIndex) {

    switch (constType) {
      case CHECK:
        return rangeVariable.usedColumns[colIndex]
            && ArrayUtil.countTrueElements(rangeVariable.usedColumns) > 1;

      case PRIMARY_KEY:
      case UNIQUE:
        return core.mainCols.length != 1 && ArrayUtil.find(core.mainCols, colIndex) != -1;

      case MAIN:
        return ArrayUtil.find(core.mainCols, colIndex) != -1
            && (core.mainCols.length != 1 || core.mainTable != core.refTable);

      case FOREIGN_KEY:
        return ArrayUtil.find(core.refCols, colIndex) != -1
            && (core.mainCols.length != 1 || core.mainTable == core.refTable);

      default:
        throw Error.runtimeError(ErrorCode.U_S0500, "Constraint");
    }
  }
  public int compareToZero(Object a) throws HsqlException {

    if (a == null) {
      return 0;
    }

    switch (typeCode) {
      case Types.SQL_REAL:
      case Types.SQL_FLOAT:
      case Types.SQL_DOUBLE:
        {
          double ad = ((Number) a).doubleValue();

          return ad == 0 ? 0 : ad < 0 ? -1 : 1;
        }
      case Types.SQL_NUMERIC:
      case Types.SQL_DECIMAL:
        return ((BigDecimal) a).signum();

      case Types.TINYINT:
      case Types.SQL_SMALLINT:
      case Types.SQL_INTEGER:
        {
          int ai = ((Number) a).intValue();

          return ai == 0 ? 0 : ai < 0 ? -1 : 1;
        }
      case Types.SQL_BIGINT:
        {
          long al = ((Number) a).longValue();

          return al == 0 ? 0 : al < 0 ? -1 : 1;
        }
      default:
        throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
    }
  }
  public NumberType(int type, long precision, int scale) {

    super(Types.SQL_NUMERIC, type, precision, scale);

    switch (type) {
      case Types.TINYINT:
        typeWidth = TINYINT_WIDTH;
        break;

      case Types.SQL_SMALLINT:
        typeWidth = SMALLINT_WIDTH;
        break;

      case Types.SQL_INTEGER:
        typeWidth = INTEGER_WIDTH;
        break;

      case Types.SQL_BIGINT:
        typeWidth = BIGINT_WIDTH;
        break;

      case Types.SQL_REAL:
      case Types.SQL_FLOAT:
      case Types.SQL_DOUBLE:
        typeWidth = DOUBLE_WIDTH;
        break;

      case Types.SQL_NUMERIC:
      case Types.SQL_DECIMAL:
        typeWidth = DECIMAL_WIDTH;
        break;

      default:
        throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
    }
  }
  Expression readDateTimeIntervalLiteral() {

    int pos = getPosition();

    switch (token.tokenType) {
      case Tokens.DATE:
        {
          read();

          if (token.tokenType != Tokens.X_VALUE || token.dataType.typeCode != Types.SQL_CHAR) {
            break;
          }

          String s = token.tokenString;

          read();

          Object date = scanner.newDate(s);

          return new ExpressionValue(date, Type.SQL_DATE);
        }
      case Tokens.TIME:
        {
          read();

          if (token.tokenType != Tokens.X_VALUE || token.dataType.typeCode != Types.SQL_CHAR) {
            break;
          }

          String s = token.tokenString;

          read();

          TimeData value = scanner.newTime(s);
          Type dataType = scanner.dateTimeType;

          return new ExpressionValue(value, dataType);
        }
      case Tokens.TIMESTAMP:
        {
          read();

          if (token.tokenType != Tokens.X_VALUE || token.dataType.typeCode != Types.SQL_CHAR) {
            break;
          }

          String s = token.tokenString;

          read();

          Object date = scanner.newTimestamp(s);
          Type dataType = scanner.dateTimeType;

          return new ExpressionValue(date, dataType);
        }
      case Tokens.INTERVAL:
        {
          boolean minus = false;

          read();

          if (token.tokenType == Tokens.MINUS) {
            read();

            minus = true;
          } else if (token.tokenType == Tokens.PLUS) {
            read();
          }

          if (token.tokenType != Tokens.X_VALUE || token.dataType.typeCode != Types.SQL_CHAR) {
            break;
          }

          String s = token.tokenString;

          read();

          IntervalType dataType = readIntervalType();
          Object interval = scanner.newInterval(s, dataType);

          dataType = (IntervalType) scanner.dateTimeType;

          if (minus) {
            interval = dataType.negate(interval);
          }

          return new ExpressionValue(interval, dataType);
        }
      default:
        throw Error.runtimeError(ErrorCode.U_S0500, "Parser");
    }

    rewind(pos);

    return null;
  }
  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");
    }
  }
  public Object negate(Object a) throws HsqlException {

    if (a == null) {
      return null;
    }

    switch (typeCode) {
      case Types.SQL_REAL:
      case Types.SQL_FLOAT:
      case Types.SQL_DOUBLE:
        {
          double ad = -((Number) a).doubleValue();

          return ValuePool.getDouble(Double.doubleToLongBits(ad));
        }
      case Types.SQL_NUMERIC:
      case Types.SQL_DECIMAL:
        return ((BigDecimal) a).negate();

      case Types.TINYINT:
        {
          int value = ((Number) a).intValue();

          if (value == Byte.MIN_VALUE) {
            throw Error.error(ErrorCode.X_22003);
          }

          return ValuePool.getInt(-value);
        }
      case Types.SQL_SMALLINT:
        {
          int value = ((Number) a).intValue();

          if (value == Short.MIN_VALUE) {
            throw Error.error(ErrorCode.X_22003);
          }

          return ValuePool.getInt(-value);
        }
      case Types.SQL_INTEGER:
        {
          int value = ((Number) a).intValue();

          if (value == Integer.MIN_VALUE) {
            throw Error.error(ErrorCode.X_22003);
          }

          return ValuePool.getInt(-value);
        }
      case Types.SQL_BIGINT:
        {
          long value = ((Number) a).longValue();

          if (value == Long.MIN_VALUE) {
            throw Error.error(ErrorCode.X_22003);
          }

          return ValuePool.getLong(-value);
        }
      default:
        throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
    }
  }
  void write(RowOutputInterface out) throws IOException {

    out.writeInt(type);
    out.writeInt(columnCount);

    switch (type) {
      case UPDATE_RESULT_METADATA:
      case SIMPLE_RESULT_METADATA:
        {
          for (int i = 0; i < columnCount; i++) {
            out.writeType(columnTypes[i].typeCode);
          }

          return;
        }
      case GENERATED_INDEX_METADATA:
        {
          for (int i = 0; i < columnCount; i++) {
            out.writeInt(colIndexes[i]);
          }

          return;
        }
      case GENERATED_NAME_METADATA:
        {
          for (int i = 0; i < columnCount; i++) {
            out.writeString(columnLabels[i]);
          }

          return;
        }
      case PARAM_METADATA:
        for (int i = 0; i < columnCount; i++) {
          writeDataType(out, columnTypes[i]);
          out.writeString(columnLabels[i]);
          out.writeByte(encodeParamColumnAttrs(i));
        }

        return;

      case RESULT_METADATA:
        {
          out.writeInt(extendedColumnCount);

          for (int i = 0; i < extendedColumnCount; i++) {
            if (columnTypes[i] == null) {
              ColumnBase column = columns[i];

              columnTypes[i] = column.getDataType();
            }

            writeDataType(out, columnTypes[i]);
          }

          for (int i = 0; i < columnCount; i++) {
            ColumnBase column = columns[i];

            out.writeString(columnLabels[i]);
            out.writeString(column.getCatalogNameString());
            out.writeString(column.getSchemaNameString());
            out.writeString(column.getTableNameString());
            out.writeString(column.getNameString());
            out.writeByte(encodeTableColumnAttrs(column));
          }

          if (columnCount != extendedColumnCount) {
            for (int i = 0; i < colIndexes.length; i++) {
              out.writeInt(colIndexes[i]);
            }
          }

          return;
        }
      default:
        {
          throw Error.runtimeError(ErrorCode.U_S0500, "ResultMetaData");
        }
    }
  }
  public int compare(Object a, Object b) {

    if (a == b) {
      return 0;
    }

    if (a == null) {
      return -1;
    }

    if (b == null) {
      return 1;
    }

    switch (typeCode) {
      case Types.TINYINT:
      case Types.SQL_SMALLINT:
      case Types.SQL_INTEGER:
        {
          if (b instanceof Integer) {
            int ai = ((Number) a).intValue();
            int bi = ((Number) b).intValue();

            return (ai > bi) ? 1 : (bi > ai ? -1 : 0);
          } else if (b instanceof Double) {
            double ai = ((Number) a).doubleValue();
            double bi = ((Number) b).doubleValue();

            return (ai > bi) ? 1 : (bi > ai ? -1 : 0);
          } else if (b instanceof BigDecimal) {
            BigDecimal ad = convertToDecimal(a);
            int i = ad.compareTo((BigDecimal) b);

            return (i == 0) ? 0 : (i < 0 ? -1 : 1);
          }
        }

        // fall through
      case Types.SQL_BIGINT:
        {
          if (b instanceof Long) {
            long longa = ((Number) a).longValue();
            long longb = ((Number) b).longValue();

            return (longa > longb) ? 1 : (longb > longa ? -1 : 0);
          } else if (b instanceof Double) {
            BigDecimal ad = BigDecimal.valueOf(((Number) a).longValue());
            BigDecimal bd = new BigDecimal(((Double) b).doubleValue());
            int i = ad.compareTo(bd);

            return (i == 0) ? 0 : (i < 0 ? -1 : 1);
          } else if (b instanceof BigDecimal) {
            BigDecimal ad = BigDecimal.valueOf(((Number) a).longValue());
            int i = ad.compareTo((BigDecimal) b);

            return (i == 0) ? 0 : (i < 0 ? -1 : 1);
          }
        }

        // fall through
      case Types.SQL_REAL:
      case Types.SQL_FLOAT:
      case Types.SQL_DOUBLE:
        {

          // todo big-decimal etc
          double ad = ((Number) a).doubleValue();
          double bd = ((Number) b).doubleValue();

          return (ad > bd) ? 1 : (bd > ad ? -1 : 0);
        }
      case Types.SQL_NUMERIC:
      case Types.SQL_DECIMAL:
        {
          BigDecimal bd = convertToDecimal(b);
          int i = ((BigDecimal) a).compareTo(bd);

          return (i == 0) ? 0 : (i < 0 ? -1 : 1);
        }
      default:
        throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
    }
  }
  /**
   * Returns a SQL type "wide" enough to represent the result of the expression.<br>
   * A type is "wider" than the other if it can represent all its numeric values.<br>
   * Arithmetic operation terms are promoted to a type that can represent the resulting values and
   * avoid incorrect results.
   *
   * <p>FLOAT/REAL/DOUBLE used in an operation results in the same type, regardless of the type of
   * the other operand. When the result or the expression is converted to the type of the target
   * column for storage, an exception is thrown if the resulting value cannot be stored in the
   * column
   *
   * <p>Types narrower than INTEGER (int) are promoted to INTEGER. The order of promotion is as
   * follows
   *
   * <p>INTEGER, BIGINT, NUMERIC/DECIMAL
   *
   * <p>TINYINT and SMALLINT in any combination return INTEGER<br>
   * TINYINT/SMALLINT/INTEGER and INTEGER return BIGINT<br>
   * TINYINT/SMALLINT/INTEGER and BIGINT return NUMERIC/DECIMAL<br>
   * BIGINT and BIGINT return NUMERIC/DECIMAL<br>
   * REAL/FLOAT/DOUBLE and any type return REAL/FLOAT/DOUBLE<br>
   * NUMERIC/DECIMAL any type other than REAL/FLOAT/DOUBLE returns NUMERIC/DECIMAL<br>
   * In the case of NUMERIC/DECIMAL returned, the result precision is always large enough to express
   * any value result, while the scale depends on the operation:<br>
   * For ADD/SUBTRACT/DIVIDE, the scale is the larger of the two<br>
   * For MULTIPLY, the scale is the sum of the two scales<br>
   */
  public Type getCombinedType(Type other, int operation) throws HsqlException {

    if (other.typeCode == Types.SQL_ALL_TYPES) {
      other = this;
    }

    switch (operation) {
      case OpTypes.ADD:
        break;

      case OpTypes.MULTIPLY:
        if (other.isIntervalType()) {
          return other.getCombinedType(this, OpTypes.MULTIPLY);
        }
        break;

      case OpTypes.DIVIDE:
      case OpTypes.SUBTRACT:
      default:

        // all derivatives of equality ops or comparison ops
        return getAggregateType(other);
    }

    // resolution for ADD and MULTIPLY only
    if (!other.isNumberType()) {
      throw Error.error(ErrorCode.X_42562);
    }

    if (typeWidth == DOUBLE_WIDTH || ((NumberType) other).typeWidth == DOUBLE_WIDTH) {
      return Type.SQL_DOUBLE;
    }

    int sum = typeWidth + ((NumberType) other).typeWidth;

    if (sum <= INTEGER_WIDTH) {
      return Type.SQL_INTEGER;
    }

    if (sum <= BIGINT_WIDTH) {
      return Type.SQL_BIGINT;
    }

    int newScale;
    long newDigits;

    switch (operation) {

        //            case OpCodes.DIVIDE :
        //            case OpCodes.SUBTRACT :
      case OpTypes.ADD:
        newScale = scale > other.scale ? scale : other.scale;
        newDigits =
            precision - scale > other.precision - other.scale
                ? precision - scale
                : other.precision - other.scale;

        newDigits++;
        break;

      case OpTypes.MULTIPLY:
        newDigits = precision - scale + other.precision - other.scale;
        newScale = scale + other.scale;
        break;

      default:
        throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
    }

    return getNumberType(Types.SQL_DECIMAL, newScale + newDigits, newScale);
  }
  public Object divide(Object a, Object b) throws HsqlException {

    if (a == null || b == null) {
      return null;
    }

    switch (typeCode) {
      case Types.SQL_REAL:
      case Types.SQL_FLOAT:
      case Types.SQL_DOUBLE:
        {
          double ad = ((Number) a).doubleValue();
          double bd = ((Number) b).doubleValue();

          if (bd == 0) {
            throw Error.error(ErrorCode.X_22012);
          }

          return ValuePool.getDouble(Double.doubleToLongBits(ad / bd));
        }
      case Types.SQL_NUMERIC:
      case Types.SQL_DECIMAL:
        {
          a = convertToDefaultType(null, a);
          b = convertToDefaultType(null, b);

          BigDecimal abd = (BigDecimal) a;
          BigDecimal bbd = (BigDecimal) b;
          int scale = abd.scale() > bbd.scale() ? abd.scale() : bbd.scale();

          if (bbd.signum() == 0) {
            throw Error.error(ErrorCode.X_22012);
          }

          return abd.divide(bbd, scale, BigDecimal.ROUND_DOWN);
        }
      case Types.TINYINT:
      case Types.SQL_SMALLINT:
      case Types.SQL_INTEGER:
        {
          int ai = ((Number) a).intValue();
          int bi = ((Number) b).intValue();

          if (bi == 0) {
            throw Error.error(ErrorCode.X_22012);
          }

          return ValuePool.getInt(ai / bi);
        }
      case Types.SQL_BIGINT:
        {
          long al = ((Number) a).longValue();
          long bl = ((Number) b).longValue();

          if (bl == 0) {
            throw Error.error(ErrorCode.X_22012);
          }

          return ValuePool.getLong(al / bl);
        }
      default:
        throw Error.runtimeError(ErrorCode.U_S0500, "NumberType");
    }
  }
  StatementSession(int type, Object[] args) {

    super(type);

    this.parameters = args;
    isTransactionStatement = false;
    isLogged = false;

    switch (type) {

        // logged by statement
      case StatementTypes.SET_SCHEMA:
        group = StatementTypes.X_SQL_SESSION;
        isLogged = true;
        break;

      case StatementTypes.DECLARE_VARIABLE:
        group = StatementTypes.X_HSQLDB_SESSION;
        isLogged = true;
        break;

        // cursor
      case StatementTypes.ALLOCATE_CURSOR:
        group = StatementTypes.X_SQL_DATA;
        break;

      case StatementTypes.ALLOCATE_DESCRIPTOR:
      case StatementTypes.DEALLOCATE_DESCRIPTOR:
      case StatementTypes.DEALLOCATE_PREPARE:
        group = StatementTypes.X_DYNAMIC;
        break;

        //
      case StatementTypes.DYNAMIC_DELETE_CURSOR:
        group = StatementTypes.X_SQL_DATA_CHANGE;
        break;

      case StatementTypes.DYNAMIC_CLOSE:
      case StatementTypes.DYNAMIC_FETCH:
      case StatementTypes.DYNAMIC_OPEN:
        group = StatementTypes.X_SQL_DATA;
        break;

        //
      case StatementTypes.OPEN:
      case StatementTypes.FETCH:
      case StatementTypes.FREE_LOCATOR:
      case StatementTypes.GET_DESCRIPTOR:
      case StatementTypes.HOLD_LOCATOR:
        group = StatementTypes.X_SQL_DATA;
        break;

        //
      case StatementTypes.PREPARABLE_DYNAMIC_DELETE_CURSOR:
      case StatementTypes.PREPARABLE_DYNAMIC_UPDATE_CURSOR:
      case StatementTypes.PREPARE:
        group = StatementTypes.X_DYNAMIC;
        break;

        // logged by session
      case StatementTypes.DISCONNECT:
        group = StatementTypes.X_SQL_CONNECTION;
        break;

        //
      case StatementTypes.SET_CONNECTION:
      case StatementTypes.SET_CONSTRAINT:
      case StatementTypes.SET_DESCRIPTOR:
      case StatementTypes.SET_SESSION_CHARACTERISTICS:
      case StatementTypes.SET_TRANSFORM_GROUP:
      case StatementTypes.SET_SESSION_RESULT_MAX_ROWS:
      case StatementTypes.SET_SESSION_RESULT_MEMORY_ROWS:
      case StatementTypes.SET_SESSION_AUTOCOMMIT:
        group = StatementTypes.X_HSQLDB_SESSION;
        break;

        // logged by session if necessary
      case StatementTypes.COMMIT_WORK:
      case StatementTypes.RELEASE_SAVEPOINT:
      case StatementTypes.ROLLBACK_SAVEPOINT:
      case StatementTypes.ROLLBACK_WORK:
      case StatementTypes.SAVEPOINT:
      case StatementTypes.SET_TRANSACTION:
      case StatementTypes.START_TRANSACTION:
        group = StatementTypes.X_SQL_TRANSACTION;
        break;

      default:
        throw Error.runtimeError(ErrorCode.U_S0500, "StatementCommand");
    }
  }
  ResultMetaData(RowInputBinary in) throws IOException {

    type = in.readInt();
    columnCount = in.readInt();

    switch (type) {
      case UPDATE_RESULT_METADATA:
      case SIMPLE_RESULT_METADATA:
        {
          columnTypes = new Type[columnCount];

          for (int i = 0; i < columnCount; i++) {
            int type = in.readType();

            columnTypes[i] = Type.getDefaultType(type);
          }

          return;
        }
      case GENERATED_INDEX_METADATA:
        {
          colIndexes = new int[columnCount];

          for (int i = 0; i < columnCount; i++) {
            colIndexes[i] = in.readInt();
          }

          return;
        }
      case GENERATED_NAME_METADATA:
        {
          columnLabels = new String[columnCount];

          for (int i = 0; i < columnCount; i++) {
            columnLabels[i] = in.readString();
          }

          return;
        }
      case PARAM_METADATA:
        {
          columnTypes = new Type[columnCount];
          columnLabels = new String[columnCount];
          paramModes = new byte[columnCount];
          paramNullable = new byte[columnCount];

          for (int i = 0; i < columnCount; i++) {
            columnTypes[i] = readDataType(in);
            columnLabels[i] = in.readString();

            decodeParamColumnAttrs(in.readByte(), i);
          }

          return;
        }
      case RESULT_METADATA:
        {
          extendedColumnCount = in.readInt();
          columnTypes = new Type[extendedColumnCount];
          columnLabels = new String[columnCount];
          columns = new ColumnBase[columnCount];

          if (columnCount != extendedColumnCount) {
            colIndexes = new int[columnCount];
          }

          for (int i = 0; i < extendedColumnCount; i++) {
            Type type = readDataType(in);

            columnTypes[i] = type;
          }

          for (int i = 0; i < columnCount; i++) {
            columnLabels[i] = in.readString();

            String catalog = in.readString();
            String schema = in.readString();
            String table = in.readString();
            String name = in.readString();
            ColumnBase column = new ColumnBase(catalog, schema, table, name);

            column.setType(columnTypes[i]);
            decodeTableColumnAttrs(in.readByte(), column);

            columns[i] = column;
          }

          if (columnCount != extendedColumnCount) {
            for (int i = 0; i < columnCount; i++) {
              colIndexes[i] = in.readInt();
            }
          }

          return;
        }
      default:
        {
          throw Error.runtimeError(ErrorCode.U_S0500, "ResultMetaData");
        }
    }
  }
  public void resolve() throws HsqlException {

    boolean resolved = false;

    switch (type) {
      case StatementTypes.SIGNAL:
      case StatementTypes.RESIGNAL:
        break;

      case StatementTypes.RETURN:
        if (root.isProcedure()) {

          // todo better message
          throw Error.error(ErrorCode.X_2F501);
        }

        resolved = true;
        break;

      case StatementTypes.ITERATE:
        {
          StatementCompound statement = parent;

          while (statement != null) {
            if (statement.isLoop) {
              if (label == null) {
                resolved = true;

                break;
              }

              if (statement.label != null && label.name.equals(statement.label.name)) {
                resolved = true;

                break;
              }
            }

            statement = statement.parent;
          }

          break;
        }
      case StatementTypes.LEAVE:
        resolved = true;
        break;

      case StatementTypes.ASSIGNMENT:
        resolved = true;
        break;

      case StatementTypes.CONDITION:
        resolved = true;
        break;

      default:
        throw Error.runtimeError(ErrorCode.U_S0500, "");
    }

    if (!resolved) {

      // todo better message
      throw Error.error(ErrorCode.X_2F501);
    }
  }