Beispiel #1
0
  protected Object getNativeDateTimeValue(
      int columnIndex,
      byte[] bits,
      int offset,
      int length,
      Calendar targetCalendar,
      int jdbcType,
      int mysqlType,
      TimeZone tz,
      boolean rollForward,
      MySQLConnection conn,
      ResultSetImpl rs)
      throws SQLException {

    int year = 0;
    int month = 0;
    int day = 0;

    int hour = 0;
    int minute = 0;
    int seconds = 0;

    int nanos = 0;

    if (bits == null) {

      return null;
    }

    Calendar sessionCalendar =
        conn.getUseJDBCCompliantTimezoneShift()
            ? conn.getUtcCalendar()
            : rs.getCalendarInstanceForSessionOrNew();

    boolean populatedFromDateTimeValue = false;

    switch (mysqlType) {
      case MysqlDefs.FIELD_TYPE_DATETIME:
      case MysqlDefs.FIELD_TYPE_TIMESTAMP:
        populatedFromDateTimeValue = true;

        if (length != 0) {
          year = (bits[offset + 0] & 0xff) | ((bits[offset + 1] & 0xff) << 8);
          month = bits[offset + 2];
          day = bits[offset + 3];

          if (length > 4) {
            hour = bits[offset + 4];
            minute = bits[offset + 5];
            seconds = bits[offset + 6];
          }

          if (length > 7) {
            // MySQL uses microseconds
            nanos =
                ((bits[offset + 7] & 0xff)
                        | ((bits[offset + 8] & 0xff) << 8)
                        | ((bits[offset + 9] & 0xff) << 16)
                        | ((bits[offset + 10] & 0xff) << 24))
                    * 1000;
          }
        }

        break;
      case MysqlDefs.FIELD_TYPE_DATE:
        populatedFromDateTimeValue = true;

        if (bits.length != 0) {
          year = (bits[offset + 0] & 0xff) | ((bits[offset + 1] & 0xff) << 8);
          month = bits[offset + 2];
          day = bits[offset + 3];
        }

        break;
      case MysqlDefs.FIELD_TYPE_TIME:
        populatedFromDateTimeValue = true;

        if (bits.length != 0) {
          // bits[0] // skip tm->neg
          // binaryData.readLong(); // skip daysPart
          hour = bits[offset + 5];
          minute = bits[offset + 6];
          seconds = bits[offset + 7];
        }

        year = 1970;
        month = 1;
        day = 1;

        break;
      default:
        populatedFromDateTimeValue = false;
    }

    switch (jdbcType) {
      case Types.TIME:
        if (populatedFromDateTimeValue) {
          if (!rs.useLegacyDatetimeCode) {
            return TimeUtil.fastTimeCreate(
                hour, minute, seconds, targetCalendar, this.exceptionInterceptor);
          }

          Time time =
              TimeUtil.fastTimeCreate(
                  rs.getCalendarInstanceForSessionOrNew(),
                  hour,
                  minute,
                  seconds,
                  this.exceptionInterceptor);

          Time adjustedTime =
              TimeUtil.changeTimezone(
                  conn,
                  sessionCalendar,
                  targetCalendar,
                  time,
                  conn.getServerTimezoneTZ(),
                  tz,
                  rollForward);

          return adjustedTime;
        }

        return rs.getNativeTimeViaParseConversion(columnIndex + 1, targetCalendar, tz, rollForward);

      case Types.DATE:
        if (populatedFromDateTimeValue) {
          if ((year == 0) && (month == 0) && (day == 0)) {
            if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL.equals(
                conn.getZeroDateTimeBehavior())) {

              return null;
            } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION.equals(
                conn.getZeroDateTimeBehavior())) {
              throw new SQLException(
                  "Value '0000-00-00' can not be represented as java.sql.Date",
                  SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
            }

            year = 1;
            month = 1;
            day = 1;
          }

          if (!rs.useLegacyDatetimeCode) {
            return TimeUtil.fastDateCreate(year, month, day, targetCalendar);
          }

          return rs.fastDateCreate(rs.getCalendarInstanceForSessionOrNew(), year, month, day);
        }

        return rs.getNativeDateViaParseConversion(columnIndex + 1);
      case Types.TIMESTAMP:
        if (populatedFromDateTimeValue) {
          if ((year == 0) && (month == 0) && (day == 0)) {
            if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL.equals(
                conn.getZeroDateTimeBehavior())) {

              return null;
            } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION.equals(
                conn.getZeroDateTimeBehavior())) {
              throw new SQLException(
                  "Value '0000-00-00' can not be represented as java.sql.Timestamp",
                  SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
            }

            year = 1;
            month = 1;
            day = 1;
          }

          if (!rs.useLegacyDatetimeCode) {
            return TimeUtil.fastTimestampCreate(tz, year, month, day, hour, minute, seconds, nanos);
          }

          Timestamp ts =
              rs.fastTimestampCreate(
                  rs.getCalendarInstanceForSessionOrNew(),
                  year,
                  month,
                  day,
                  hour,
                  minute,
                  seconds,
                  nanos);

          Timestamp adjustedTs =
              TimeUtil.changeTimezone(
                  conn,
                  sessionCalendar,
                  targetCalendar,
                  ts,
                  conn.getServerTimezoneTZ(),
                  tz,
                  rollForward);

          return adjustedTs;
        }

        return rs.getNativeTimestampViaParseConversion(
            columnIndex + 1, targetCalendar, tz, rollForward);

      default:
        throw new SQLException(
            "Internal error - conversion method doesn't support this type",
            SQLError.SQL_STATE_GENERAL_ERROR);
    }
  }
Beispiel #2
0
  protected Timestamp getNativeTimestamp(
      byte[] bits,
      int offset,
      int length,
      Calendar targetCalendar,
      TimeZone tz,
      boolean rollForward,
      MySQLConnection conn,
      ResultSetImpl rs)
      throws SQLException {
    int year = 0;
    int month = 0;
    int day = 0;

    int hour = 0;
    int minute = 0;
    int seconds = 0;

    int nanos = 0;

    if (length != 0) {
      year = (bits[offset + 0] & 0xff) | ((bits[offset + 1] & 0xff) << 8);
      month = bits[offset + 2];
      day = bits[offset + 3];

      if (length > 4) {
        hour = bits[offset + 4];
        minute = bits[offset + 5];
        seconds = bits[offset + 6];
      }

      if (length > 7) {
        // MySQL uses microseconds
        nanos =
            ((bits[offset + 7] & 0xff)
                    | ((bits[offset + 8] & 0xff) << 8)
                    | ((bits[offset + 9] & 0xff) << 16)
                    | ((bits[offset + 10] & 0xff) << 24))
                * 1000;
      }
    }

    if (length == 0 || ((year == 0) && (month == 0) && (day == 0))) {
      if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL.equals(
          conn.getZeroDateTimeBehavior())) {

        return null;
      } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION.equals(
          conn.getZeroDateTimeBehavior())) {
        throw SQLError.createSQLException(
            "Value '0000-00-00' can not be represented as java.sql.Timestamp",
            SQLError.SQL_STATE_ILLEGAL_ARGUMENT,
            this.exceptionInterceptor);
      }

      year = 1;
      month = 1;
      day = 1;
    }

    if (!rs.useLegacyDatetimeCode) {
      return TimeUtil.fastTimestampCreate(tz, year, month, day, hour, minute, seconds, nanos);
    }

    Calendar sessionCalendar =
        conn.getUseJDBCCompliantTimezoneShift()
            ? conn.getUtcCalendar()
            : rs.getCalendarInstanceForSessionOrNew();

    synchronized (sessionCalendar) {
      Timestamp ts =
          rs.fastTimestampCreate(sessionCalendar, year, month, day, hour, minute, seconds, nanos);

      Timestamp adjustedTs =
          TimeUtil.changeTimezone(
              conn,
              sessionCalendar,
              targetCalendar,
              ts,
              conn.getServerTimezoneTZ(),
              tz,
              rollForward);

      return adjustedTs;
    }
  }
Beispiel #3
0
  protected Timestamp getTimestampFast(
      int columnIndex,
      byte[] timestampAsBytes,
      int offset,
      int length,
      Calendar targetCalendar,
      TimeZone tz,
      boolean rollForward,
      MySQLConnection conn,
      ResultSetImpl rs)
      throws SQLException {

    try {
      Calendar sessionCalendar =
          conn.getUseJDBCCompliantTimezoneShift()
              ? conn.getUtcCalendar()
              : rs.getCalendarInstanceForSessionOrNew();

      synchronized (sessionCalendar) {
        boolean allZeroTimestamp = true;

        boolean onlyTimePresent = false;

        for (int i = 0; i < length; i++) {
          if (timestampAsBytes[offset + i] == ':') {
            onlyTimePresent = true;
            break;
          }
        }

        for (int i = 0; i < length; i++) {
          byte b = timestampAsBytes[offset + i];

          if (b == ' ' || b == '-' || b == '/') {
            onlyTimePresent = false;
          }

          if (b != '0' && b != ' ' && b != ':' && b != '-' && b != '/' && b != '.') {
            allZeroTimestamp = false;

            break;
          }
        }

        if (!onlyTimePresent && allZeroTimestamp) {

          if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL.equals(
              conn.getZeroDateTimeBehavior())) {

            return null;
          } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION.equals(
              conn.getZeroDateTimeBehavior())) {
            throw SQLError.createSQLException(
                "Value '"
                    + StringUtils.toString(timestampAsBytes)
                    + "' can not be represented as java.sql.Timestamp",
                SQLError.SQL_STATE_ILLEGAL_ARGUMENT,
                this.exceptionInterceptor);
          }

          if (!rs.useLegacyDatetimeCode) {
            return TimeUtil.fastTimestampCreate(tz, 1, 1, 1, 0, 0, 0, 0);
          }
          // We're left with the case of 'round' to a date Java _can_
          // represent, which is '0001-01-01'.
          return rs.fastTimestampCreate(null, 1, 1, 1, 0, 0, 0, 0);

        } else if (this.metadata[columnIndex].getMysqlType() == MysqlDefs.FIELD_TYPE_YEAR) {

          if (!rs.useLegacyDatetimeCode) {
            return TimeUtil.fastTimestampCreate(
                tz, StringUtils.getInt(timestampAsBytes, offset, 4), 1, 1, 0, 0, 0, 0);
          }

          return TimeUtil.changeTimezone(
              conn,
              sessionCalendar,
              targetCalendar,
              rs.fastTimestampCreate(
                  sessionCalendar,
                  StringUtils.getInt(timestampAsBytes, offset, 4),
                  1,
                  1,
                  0,
                  0,
                  0,
                  0),
              conn.getServerTimezoneTZ(),
              tz,
              rollForward);
        } else {
          if (timestampAsBytes[offset + length - 1] == '.') {
            length--;
          }

          // Convert from TIMESTAMP or DATE

          int year = 0;
          int month = 0;
          int day = 0;
          int hour = 0;
          int minutes = 0;
          int seconds = 0;
          int nanos = 0;

          switch (length) {
            case 29:
            case 26:
            case 25:
            case 24:
            case 23:
            case 22:
            case 21:
            case 20:
            case 19:
              {
                year = StringUtils.getInt(timestampAsBytes, offset + 0, offset + 4);
                month = StringUtils.getInt(timestampAsBytes, offset + 5, offset + 7);
                day = StringUtils.getInt(timestampAsBytes, offset + 8, offset + 10);
                hour = StringUtils.getInt(timestampAsBytes, offset + 11, offset + 13);
                minutes = StringUtils.getInt(timestampAsBytes, offset + 14, offset + 16);
                seconds = StringUtils.getInt(timestampAsBytes, offset + 17, offset + 19);

                nanos = 0;

                if (length > 19) {
                  int decimalIndex = -1;

                  for (int i = 0; i < length; i++) {
                    if (timestampAsBytes[offset + i] == '.') {
                      decimalIndex = i;
                    }
                  }

                  if (decimalIndex != -1) {
                    if ((decimalIndex + 2) <= length) {
                      nanos =
                          StringUtils.getInt(
                              timestampAsBytes, offset + decimalIndex + 1, offset + length);

                      int numDigits = (length) - (decimalIndex + 1);

                      if (numDigits < 9) {
                        int factor = (int) (Math.pow(10, 9 - numDigits));
                        nanos = nanos * factor;
                      }
                    } else {
                      throw new IllegalArgumentException(); // re-thrown
                      // further
                      // down
                      // with
                      // a
                      // much better error message
                    }
                  }
                }

                break;
              }

            case 14:
              {
                year = StringUtils.getInt(timestampAsBytes, offset + 0, offset + 4);
                month = StringUtils.getInt(timestampAsBytes, offset + 4, offset + 6);
                day = StringUtils.getInt(timestampAsBytes, offset + 6, offset + 8);
                hour = StringUtils.getInt(timestampAsBytes, offset + 8, offset + 10);
                minutes = StringUtils.getInt(timestampAsBytes, offset + 10, offset + 12);
                seconds = StringUtils.getInt(timestampAsBytes, offset + 12, offset + 14);

                break;
              }

            case 12:
              {
                year = StringUtils.getInt(timestampAsBytes, offset + 0, offset + 2);

                if (year <= 69) {
                  year = (year + 100);
                }

                year += 1900;

                month = StringUtils.getInt(timestampAsBytes, offset + 2, offset + 4);
                day = StringUtils.getInt(timestampAsBytes, offset + 4, offset + 6);
                hour = StringUtils.getInt(timestampAsBytes, offset + 6, offset + 8);
                minutes = StringUtils.getInt(timestampAsBytes, offset + 8, offset + 10);
                seconds = StringUtils.getInt(timestampAsBytes, offset + 10, offset + 12);

                break;
              }

            case 10:
              {
                boolean hasDash = false;

                for (int i = 0; i < length; i++) {
                  if (timestampAsBytes[offset + i] == '-') {
                    hasDash = true;
                    break;
                  }
                }

                if ((this.metadata[columnIndex].getMysqlType() == MysqlDefs.FIELD_TYPE_DATE)
                    || hasDash) {
                  year = StringUtils.getInt(timestampAsBytes, offset + 0, offset + 4);
                  month = StringUtils.getInt(timestampAsBytes, offset + 5, offset + 7);
                  day = StringUtils.getInt(timestampAsBytes, offset + 8, offset + 10);
                  hour = 0;
                  minutes = 0;
                } else {
                  year = StringUtils.getInt(timestampAsBytes, offset + 0, offset + 2);

                  if (year <= 69) {
                    year = (year + 100);
                  }

                  month = StringUtils.getInt(timestampAsBytes, offset + 2, offset + 4);
                  day = StringUtils.getInt(timestampAsBytes, offset + 4, offset + 6);
                  hour = StringUtils.getInt(timestampAsBytes, offset + 6, offset + 8);
                  minutes = StringUtils.getInt(timestampAsBytes, offset + 8, offset + 10);

                  year += 1900; // two-digit year
                }

                break;
              }

            case 8:
              {
                boolean hasColon = false;

                for (int i = 0; i < length; i++) {
                  if (timestampAsBytes[offset + i] == ':') {
                    hasColon = true;
                    break;
                  }
                }

                if (hasColon) {
                  hour = StringUtils.getInt(timestampAsBytes, offset + 0, offset + 2);
                  minutes = StringUtils.getInt(timestampAsBytes, offset + 3, offset + 5);
                  seconds = StringUtils.getInt(timestampAsBytes, offset + 6, offset + 8);

                  year = 1970;
                  month = 1;
                  day = 1;

                  break;
                }

                year = StringUtils.getInt(timestampAsBytes, offset + 0, offset + 4);
                month = StringUtils.getInt(timestampAsBytes, offset + 4, offset + 6);
                day = StringUtils.getInt(timestampAsBytes, offset + 6, offset + 8);

                year -= 1900;
                month--;

                break;
              }

            case 6:
              {
                year = StringUtils.getInt(timestampAsBytes, offset + 0, offset + 2);

                if (year <= 69) {
                  year = (year + 100);
                }

                year += 1900;

                month = StringUtils.getInt(timestampAsBytes, offset + 2, offset + 4);
                day = StringUtils.getInt(timestampAsBytes, offset + 4, offset + 6);

                break;
              }

            case 4:
              {
                year = StringUtils.getInt(timestampAsBytes, offset + 0, offset + 2);

                if (year <= 69) {
                  year = (year + 100);
                }

                month = StringUtils.getInt(timestampAsBytes, offset + 2, offset + 4);

                day = 1;

                break;
              }

            case 2:
              {
                year = StringUtils.getInt(timestampAsBytes, offset + 0, offset + 2);

                if (year <= 69) {
                  year = (year + 100);
                }

                year += 1900;
                month = 1;
                day = 1;

                break;
              }

            default:
              throw new java.sql.SQLException(
                  "Bad format for Timestamp '"
                      + StringUtils.toString(timestampAsBytes)
                      + "' in column "
                      + (columnIndex + 1)
                      + ".",
                  SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
          }

          if (!rs.useLegacyDatetimeCode) {
            return TimeUtil.fastTimestampCreate(
                tz, year, month, day, hour, minutes, seconds, nanos);
          }

          return TimeUtil.changeTimezone(
              conn,
              sessionCalendar,
              targetCalendar,
              rs.fastTimestampCreate(
                  sessionCalendar, year, month, day, hour, minutes, seconds, nanos),
              conn.getServerTimezoneTZ(),
              tz,
              rollForward);
        }
      }
    } catch (RuntimeException e) {
      SQLException sqlEx =
          SQLError.createSQLException(
              "Cannot convert value '"
                  + getString(columnIndex, "ISO8859_1", conn)
                  + "' from column "
                  + (columnIndex + 1)
                  + " to TIMESTAMP.",
              SQLError.SQL_STATE_ILLEGAL_ARGUMENT,
              this.exceptionInterceptor);
      sqlEx.initCause(e);

      throw sqlEx;
    }
  }