Search in sources :

Example 16 with LongPtr

use of com.actiontech.dble.plan.common.ptr.LongPtr in project dble by actiontech.

the class MyTime method dateAddInterval.

public static boolean dateAddInterval(MySQLTime ltime, MySqlIntervalUnit intType, Interval interval) {
    long period, sign;
    ltime.setNeg(false);
    sign = (interval.isNeg() ? -1 : 1);
    if (intType == MySqlIntervalUnit.SECOND || intType == MySqlIntervalUnit.SECOND_MICROSECOND || intType == MySqlIntervalUnit.MICROSECOND || intType == MySqlIntervalUnit.MINUTE || intType == MySqlIntervalUnit.HOUR || intType == MySqlIntervalUnit.MINUTE_MICROSECOND || intType == MySqlIntervalUnit.MINUTE_SECOND || intType == MySqlIntervalUnit.HOUR_MICROSECOND || intType == MySqlIntervalUnit.HOUR_SECOND || intType == MySqlIntervalUnit.HOUR_MINUTE || intType == MySqlIntervalUnit.DAY_MICROSECOND || intType == MySqlIntervalUnit.DAY_SECOND || intType == MySqlIntervalUnit.DAY_MINUTE || intType == MySqlIntervalUnit.DAY_HOUR) {
        long microseconds, extraSec;
        // Return
        ltime.setTimeType(MySQLTimestampType.MYSQL_TIMESTAMP_DATETIME);
        // full
        // date
        microseconds = ltime.getSecondPart() + sign * interval.getSecondPart();
        extraSec = microseconds / 1000000L;
        microseconds = microseconds % 1000000L;
        long sec = ((ltime.getDay() - 1) * 3600 * 24L + ltime.getHour() * 3600 + ltime.getMinute() * 60 + ltime.getSecond() + sign * (interval.getDay() * 3600 * 24L + interval.getHour() * 3600 + interval.getMinute() * (60) + interval.getSecond())) + extraSec;
        if (microseconds < 0) {
            microseconds += (1000000L);
            sec--;
        }
        long days = sec / (3600 * (24));
        sec -= days * 3600 * (24);
        if (sec < 0) {
            days--;
            sec += 3600 * 24;
        }
        ltime.setSecondPart(microseconds);
        ltime.setSecond((sec % 60));
        ltime.setMinute((sec / 60 % 60));
        ltime.setHour((sec / 3600));
        long daynr = calcDaynr(ltime.getYear(), ltime.getMonth(), 1) + days;
        /* Day number from year 0 to 9999-12-31 */
        if (daynr > MAX_DAY_NUMBER)
            return true;
        LongPtr ptrYear = new LongPtr(ltime.getYear());
        LongPtr ptrMonth = new LongPtr(ltime.getMonth());
        LongPtr ptrDay = new LongPtr(ltime.getDay());
        getDateFromDaynr(daynr, ptrYear, ptrMonth, ptrDay);
        ltime.setYear(ptrYear.get());
        ltime.setMonth(ptrMonth.get());
        ltime.setDay(ptrDay.get());
    } else if (intType == MySqlIntervalUnit.DAY || intType == MySqlIntervalUnit.WEEK) {
        period = (calcDaynr(ltime.getYear(), ltime.getMonth(), ltime.getDay()) + sign * interval.getDay());
        /* Daynumber from year 0 to 9999-12-31 */
        if (period > MAX_DAY_NUMBER)
            return true;
        LongPtr ptrYear = new LongPtr(ltime.getYear());
        LongPtr ptrMonth = new LongPtr(ltime.getMonth());
        LongPtr ptrDay = new LongPtr(ltime.getDay());
        getDateFromDaynr(period, ptrYear, ptrMonth, ptrDay);
        ltime.setYear(ptrYear.get());
        ltime.setMonth(ptrMonth.get());
        ltime.setDay(ptrDay.get());
    } else if (intType == MySqlIntervalUnit.YEAR) {
        ltime.setYear(ltime.getYear() + sign * interval.getYear());
        if (ltime.getYear() >= 10000)
            return true;
        if (ltime.getMonth() == 2 && ltime.getDay() == 29 && calcDaysInYear(ltime.getYear()) != 366)
            // Was leap-year
            ltime.setDay(28);
    } else if (intType == MySqlIntervalUnit.YEAR_MONTH || intType == MySqlIntervalUnit.QUARTER || intType == MySqlIntervalUnit.MONTH) {
        period = (ltime.getYear() * 12 + sign * interval.getYear() * 12 + ltime.getMonth() - 1 + sign * interval.getMonth());
        if (period >= 120000L)
            return true;
        ltime.setYear((period / 12));
        ltime.setMonth((period % 12L) + 1);
        /* Adjust day if the new month doesn't have enough days */
        if (ltime.getDay() > DAYS_IN_MONTH[(int) ltime.getMonth() - 1]) {
            ltime.setDay(DAYS_IN_MONTH[(int) ltime.getMonth() - 1]);
            if (ltime.getMonth() == 2 && calcDaysInYear(ltime.getYear()) == 366)
                // Leap-year
                ltime.setDay(ltime.getDay() + 1);
        }
    } else {
        return true;
    }
    // Ok
    return false;
}
Also used : LongPtr(com.actiontech.dble.plan.common.ptr.LongPtr)

Example 17 with LongPtr

use of com.actiontech.dble.plan.common.ptr.LongPtr in project dble by actiontech.

the class MyTime method myDecimalToTimeWithWarn.

public static boolean myDecimalToTimeWithWarn(BigDecimal decimal, MySQLTime ltime) {
    LongPtr warnings = new LongPtr(0);
    String sbd = decimal.toString();
    String[] sbds = sbd.split("\\.");
    long intPart = Long.parseLong(sbds[0]);
    long secondPart = 0;
    if (sbds.length == 2)
        secondPart = Long.parseLong(sbds[1]);
    if (numberToTime(intPart, ltime, warnings)) {
        ltime.setZeroTime(MySQLTimestampType.MYSQL_TIMESTAMP_ERROR);
        return true;
    }
    ltime.setSecondPart(secondPart);
    return false;
}
Also used : LongPtr(com.actiontech.dble.plan.common.ptr.LongPtr)

Example 18 with LongPtr

use of com.actiontech.dble.plan.common.ptr.LongPtr in project dble by actiontech.

the class MyTime method extractDateTime.

/**
 * Extract datetime value to MYSQL_TIME struct from string value according
 * to format string.
 *
 * @param format              date/time format specification
 * @param valStr              String to decode
 * @param lTime               Store result here
 * @param cachedTimestampType It uses to get an appropriate warning in the case when the
 *                            value is truncated.
 * @return 1 error
 * @note Possibility to parse strings matching to patterns equivalent to
 * compound specifiers is mainly intended for use from inside of this
 * function in order to understand %T and %r conversion specifiers, so
 * number of conversion specifiers that can be used in such
 * sub-patterns is limited. Also most of checks are skipped in this
 * case.
 * @note If one adds new format specifiers to this function he should also
 * consider adding them to Item_func_str_to_date::fix_from_format().
 */
public static boolean extractDateTime(DateTimeFormat format, String valStr, MySQLTime lTime, MySQLTimestampType cachedTimestampType, String dateTimeType) {
    int weekday = 0, yearday = 0, daypart = 0;
    int weekNumber = -1;
    BoolPtr error = new BoolPtr(false);
    int strictWeekNumberYear = -1;
    int fracPart;
    boolean usaTime = false;
    boolean sundayFirstNFirstWeekNonIso = false;
    boolean strictWeekNumber = false;
    boolean strictWeekNumberYearType = false;
    int val = 0;
    int valEnd = valStr.length();
    char[] valcs = valStr.toCharArray();
    int ptr = 0;
    int end = format.getFormat().length();
    char[] ptrcs = format.getFormat().toCharArray();
    for (; ptr != end && val != valEnd; ptr++) {
        if (ptrcs[ptr] == '%' && ptr + 1 != end) {
            int valLen;
            int tmp;
            error.set(false);
            valLen = valEnd - val;
            switch(ptrcs[++ptr]) {
                /* Year */
                case 'Y':
                    tmp = val + Math.min(4, valLen);
                    lTime.setYear(MySQLcom.myStrtoll10(valcs, val, tmp, error).intValue());
                    if (tmp - val <= 2)
                        lTime.setYear(MyTime.year2000Handling(lTime.getYear()));
                    val = tmp;
                    break;
                case 'y':
                    tmp = val + Math.min(2, valLen);
                    lTime.setYear(MySQLcom.myStrtoll10(valcs, val, tmp, error).intValue());
                    val = tmp;
                    lTime.setYear(MyTime.year2000Handling(lTime.getYear()));
                    break;
                /* Month */
                case 'm':
                case 'c':
                    tmp = val + Math.min(2, valLen);
                    lTime.setMonth(MySQLcom.myStrtoll10(valcs, val, tmp, error).intValue());
                    val = tmp;
                    break;
                case 'M':
                    lTime.setMonth(MySQLcom.checkWord(MONTH_NAMES, valcs, val, valEnd));
                    if (lTime.getMonth() <= 0) {
                        // logger.warn
                        return true;
                    }
                    break;
                case 'b':
                    lTime.setMonth(MySQLcom.checkWord(AB_MONTH_NAMES, valcs, val, valEnd));
                    if (lTime.getMonth() <= 0) {
                        // logger.warn
                        return true;
                    }
                    break;
                /* Day */
                case 'd':
                case 'e':
                    tmp = val + Math.min(2, valLen);
                    lTime.setDay(MySQLcom.myStrtoll10(valcs, val, tmp, error).intValue());
                    val = tmp;
                    break;
                case 'D':
                    tmp = val + Math.min(2, valLen);
                    lTime.setDay(MySQLcom.myStrtoll10(valcs, val, tmp, error).intValue());
                    /* Skip 'st, 'nd, 'th .. */
                    val = tmp + Math.min((int) (valEnd - tmp), 2);
                    break;
                /* Hour */
                case 'h':
                case 'I':
                case 'l':
                    usaTime = true;
                /* fall through */
                case 'k':
                case 'H':
                    tmp = val + Math.min(2, valLen);
                    lTime.setHour(MySQLcom.myStrtoll10(valcs, val, tmp, error).intValue());
                    val = tmp;
                    break;
                /* Minute */
                case 'i':
                    tmp = val + Math.min(2, valLen);
                    lTime.setMinute(MySQLcom.myStrtoll10(valcs, val, tmp, error).intValue());
                    val = tmp;
                    break;
                /* Second */
                case 's':
                case 'S':
                    tmp = val + Math.min(2, valLen);
                    lTime.setSecond(MySQLcom.myStrtoll10(valcs, val, tmp, error).intValue());
                    val = tmp;
                    break;
                /* Second part */
                case 'f':
                    tmp = valEnd;
                    if (tmp - val > 6)
                        tmp = val + 6;
                    lTime.setSecondPart(MySQLcom.myStrtoll10(valcs, val, tmp, error).intValue());
                    fracPart = 6 - (int) (tmp - val);
                    if (fracPart > 0)
                        lTime.setSecondPart(lTime.getSecondPart() * MySQLcom.LOG_10_INT[fracPart]);
                    val = tmp;
                    break;
                /* AM / PM */
                case 'p':
                    if (valLen < 2 || !usaTime) {
                        // logger.warn
                        return true;
                    }
                    if (new String(valcs, val, 2).compareTo("PM") == 0)
                        daypart = 12;
                    else if (new String(valcs, val, 2).compareTo("AM") == 0) {
                        {
                            // logger.warn
                            return true;
                        }
                    }
                    val += 2;
                    break;
                /* Exotic things */
                case 'W':
                    if ((weekday = MySQLcom.checkWord(DAY_NAMES, valcs, val, valEnd)) <= 0) {
                        {
                            // logger.warn
                            return true;
                        }
                    }
                    break;
                case 'a':
                    if ((weekday = MySQLcom.checkWord(AB_DAY_NAMES, valcs, val, valEnd)) <= 0) {
                        {
                            // logger.warn
                            return true;
                        }
                    }
                    break;
                case 'w':
                    tmp = val + 1;
                    if ((weekday = MySQLcom.myStrtoll10(valcs, val, tmp, error).intValue()) < 0 || weekday >= 7) {
                        {
                            // logger.warn
                            return true;
                        }
                    }
                    /* We should use the same 1 - 7 scale for %w as for %W */
                    if (weekday == 0)
                        weekday = 7;
                    val = tmp;
                    break;
                case 'j':
                    tmp = val + Math.min(valLen, 3);
                    yearday = MySQLcom.myStrtoll10(valcs, val, tmp, error).intValue();
                    val = tmp;
                    break;
                /* Week numbers */
                case 'V':
                case 'U':
                case 'v':
                case 'u':
                    sundayFirstNFirstWeekNonIso = (ptrcs[ptr] == 'U' || ptrcs[ptr] == 'V');
                    strictWeekNumber = (ptrcs[ptr] == 'V' || ptrcs[ptr] == 'v');
                    tmp = val + Math.min(valLen, 2);
                    if ((weekNumber = MySQLcom.myStrtoll10(valcs, val, tmp, error).intValue()) < 0 || (strictWeekNumber && weekNumber == 0) || weekNumber > 53) {
                        {
                            // logger.warn
                            return true;
                        }
                    }
                    val = tmp;
                    break;
                /* Year used with 'strict' %V and %v week numbers */
                case 'X':
                case 'x':
                    strictWeekNumberYearType = (ptrcs[ptr] == 'X');
                    tmp = val + Math.min(4, valLen);
                    strictWeekNumberYear = MySQLcom.myStrtoll10(valcs, val, tmp, error).intValue();
                    val = tmp;
                    break;
                /* Time in AM/PM notation */
                case 'r':
                    /*
     * We can't just set error here, as we don't want to
     * generate two warnings in case of errors
     */
                    if (extractDateTime(TIME_AMPM_FORMAT, new String(valcs, val, valEnd - val), lTime, cachedTimestampType, "time"))
                        return true;
                    break;
                /* Time in 24-hour notation */
                case 'T':
                    if (extractDateTime(TIME_24_HRS_FORMAT, new String(valcs, val, valEnd - val), lTime, cachedTimestampType, "time"))
                        return true;
                    break;
                /* Conversion specifiers that match classes of characters */
                case '.':
                    while (val < valEnd && Ctype.isPunct(valcs[val])) val++;
                    break;
                case '@':
                    while (val < valEnd && Ctype.myIsAlpha(valcs[val])) val++;
                    break;
                case '#':
                    while (val < valEnd && Ctype.isDigit(valcs[val])) val++;
                    break;
                default:
                    {
                        // logger.warn
                        return true;
                    }
            }
            if (error.get()) {
                // logger.warn
                return true;
            }
        } else if (!Ctype.spaceChar(ptrcs[ptr])) {
            if (valcs[val] != ptrcs[ptr]) {
                // logger.warn
                return true;
            }
            val++;
        }
    }
    if (usaTime) {
        if (lTime.getHour() > 12 || lTime.getHour() < 1) {
            // logger.warn
            return true;
        }
        lTime.setHour(lTime.getHour() % 12 + daypart);
    }
    if (yearday > 0) {
        long days;
        days = calcDaynr(lTime.getYear(), 1L, 1L) + yearday - 1;
        if (days <= 0 || days > MAX_DAY_NUMBER) {
            // logger.warn
            return true;
        }
        LongPtr yPtr = new LongPtr(lTime.getYear());
        LongPtr mPtr = new LongPtr(lTime.getMonth());
        LongPtr dPtr = new LongPtr(lTime.getDay());
        getDateFromDaynr(days, yPtr, mPtr, dPtr);
        lTime.setYear(yPtr.get());
        lTime.setMonth(mPtr.get());
        lTime.setDay(dPtr.get());
    }
    if (weekNumber >= 0 && weekday != 0) {
        int days;
        long weekdayB;
        /*
     * %V,%v require %X,%x resprectively, %U,%u should be used with %Y
     * and not %X or %x
     */
        if ((strictWeekNumber && (strictWeekNumberYear < 0 || strictWeekNumberYearType != sundayFirstNFirstWeekNonIso)) || (!strictWeekNumber && strictWeekNumberYear >= 0)) {
            // logger.warn
            return true;
        }
        /* Number of days since year 0 till 1st Jan of this year */
        days = (int) calcDaynr((strictWeekNumber ? strictWeekNumberYear : lTime.getYear()), 1, 1);
        /* Which day of week is 1st Jan of this year */
        weekdayB = calcWeekday(days, sundayFirstNFirstWeekNonIso);
        /*
     * Below we are going to sum: 1) number of days since year 0 till
     * 1st day of 1st week of this year 2) number of days between 1st
     * week and our week 3) and position of our day in the week
     */
        if (sundayFirstNFirstWeekNonIso) {
            days += ((weekdayB == 0) ? 0 : 7) - weekdayB + (weekNumber - 1) * 7 + weekday % 7;
        } else {
            days += ((weekdayB <= 3) ? 0 : 7) - weekdayB + (weekNumber - 1) * 7 + (weekday - 1);
        }
        if (days <= 0 || days > MAX_DAY_NUMBER) {
            // logger.warn
            return true;
        }
        LongPtr yPtr = new LongPtr(lTime.getYear());
        LongPtr mPtr = new LongPtr(lTime.getMonth());
        LongPtr dPtr = new LongPtr(lTime.getDay());
        getDateFromDaynr(days, yPtr, mPtr, dPtr);
        lTime.setYear(yPtr.get());
        lTime.setMonth(mPtr.get());
        lTime.setDay(dPtr.get());
    }
    if (lTime.getMonth() > 12 || lTime.getDay() > 31 || lTime.getHour() > 23 || lTime.getMinute() > 59 || lTime.getSecond() > 59) {
        // logger.warn
        return true;
    }
    if (val != valEnd) {
        do {
            if (!Ctype.spaceChar(valcs[val])) {
                // 
                break;
            }
        } while (++val != valEnd);
    }
    return false;
}
Also used : LongPtr(com.actiontech.dble.plan.common.ptr.LongPtr) BoolPtr(com.actiontech.dble.plan.common.ptr.BoolPtr)

Example 19 with LongPtr

use of com.actiontech.dble.plan.common.ptr.LongPtr in project dble by actiontech.

the class MyTime method myDoubleToTimeWithWarn.

public static boolean myDoubleToTimeWithWarn(double db, MySQLTime ltime) {
    LongPtr warnings = new LongPtr(0);
    String sbd = String.valueOf(db);
    String[] sbds = sbd.split("\\.");
    long intPart = Long.parseLong(sbds[0]);
    long secondPart = 0;
    if (sbds.length == 2)
        secondPart = Long.parseLong(sbds[1]);
    if (numberToTime(intPart, ltime, warnings)) {
        ltime.setZeroTime(MySQLTimestampType.MYSQL_TIMESTAMP_ERROR);
        return true;
    }
    ltime.setSecondPart(secondPart);
    return false;
}
Also used : LongPtr(com.actiontech.dble.plan.common.ptr.LongPtr)

Example 20 with LongPtr

use of com.actiontech.dble.plan.common.ptr.LongPtr in project dble by actiontech.

the class MyTime method strToDatetime.

/*
     * Convert a timestamp string to a MYSQL_TIME value.
     *
     * SYNOPSIS strToDatetime() str String to parse length Length of string
     * l_time Date is stored here flags Bitmap of following items
     * TIME_FUZZY_DATE Set if we should allow partial dates TIME_DATETIME_ONLY
     * Set if we only allow full datetimes. TIME_NO_ZERO_IN_DATE Don't allow
     * partial dates TIME_NO_ZERO_DATE Don't allow 0000-00-00 date
     * TIME_INVALID_DATES Allow 2000-02-31 status Conversion status
     *
     *
     * DESCRIPTION At least the following formats are recogniced (based on
     * number of digits) YYMMDD, YYYYMMDD, YYMMDDHHMMSS, YYYYMMDDHHMMSS
     * YY-MM-DD, YYYY-MM-DD, YY-MM-DD HH.MM.SS YYYYMMDDTHHMMSS where T is a the
     * character T (ISO8601) Also dates where all parts are zero are allowed
     *
     * The second part may have an optional .###### fraction part.
     *
     * NOTES This function should work with a format position vector as long as
     * the following things holds: - All date are kept together and all time
     * parts are kept together - Date and time parts must be separated by blank
     * - Second fractions must come after second part and be separated by a '.'.
     * (The second fractions are optional) - AM/PM must come after second
     * fractions (or after seconds if no fractions) - Year must always been
     * specified. - If time is before date, then we will use datetime format
     * only if the argument consist of two parts, separated by space. Otherwise
     * we will assume the argument is a date. - The hour part must be specified
     * in hour-minute-second order.
     *
     * status.warnings is set to: 0 Value OK MYSQL_TIME_WARN_TRUNCATED If value
     * was cut during conversion MYSQL_TIME_WARN_OUT_OF_RANGE
     * checkDate(date,flags) considers date invalid
     *
     * l_time.time_type is set as follows: MYSQL_TIMESTAMP_NONE String wasn't a
     * timestamp, like [DD [HH:[MM:[SS]]]].fraction. l_time is not changed.
     * MYSQL_TIMESTAMP_DATE DATE string (YY MM and DD parts ok)
     * MYSQL_TIMESTAMP_DATETIME Full timestamp MYSQL_TIMESTAMP_ERROR Timestamp
     * with wrong values. All elements in l_time is set to 0 RETURN VALUES 0 -
     * Ok 1 - Error
     */
public static boolean strToDatetime(String strori, int length, MySQLTime lTime, long flags, MySQLTimeStatus status) {
    /* Skip space at start */
    String str = strori.trim();
    long fieldLength, yearLength = 0;
    long[] date = new long[MAX_DATE_PARTS];
    long addHours = 0;
    final char[] chars = str.toCharArray();
    int lastFieldPos = 0;
    int[] formatPosition;
    boolean foundDelimiter = false, foundSpace = false;
    int fracPos, fracLen;
    myTimeStatusInit(status);
    if (str.isEmpty() || !Ctype.isDigit(str.charAt(0))) {
        status.setWarnings(MYSQL_TIME_WARN_TRUNCATED);
        lTime.setTimeType(MySQLTimestampType.MYSQL_TIMESTAMP_NONE);
        return true;
    }
    boolean isInternalFormat = false;
    /*
         * This has to be changed if want to activate different timestamp
     * formats
     */
    formatPosition = INTERNAL_FORMAT_POSITIONS;
    /*
     * Calculate number of digits in first part. If length= 8 or >= 14 then
     * year is of format YYYY. (YYYY-MM-DD, YYYYMMDD, YYYYYMMDDHHMMSS)
     */
    int pos;
    int end = str.length();
    for (pos = 0; pos != end && (Ctype.isDigit(chars[pos]) || chars[pos] == 'T'); pos++) {
    // do nothing
    }
    long digits = (long) pos;
    long startLoop = 0;
    /* Start of scan loop */
    int[] dateLen = new int[MAX_DATE_PARTS];
    dateLen[formatPosition[0]] = 0;
    /* Length of year field */
    if (pos == end || chars[pos] == '.') {
        /* Found date in internal format (only numbers like YYYYMMDD) */
        yearLength = (digits == 4 || digits == 8 || digits >= 14) ? 4 : 2;
        fieldLength = yearLength;
        isInternalFormat = true;
        formatPosition = INTERNAL_FORMAT_POSITIONS;
    } else {
        if (formatPosition[0] >= 3) /* If year is after HHMMDD */
        {
            /*
     * If year is not in first part then we have to determinate if
     * we got a date field or a datetime field. We do this by
     * checking if there is two numbers separated by space in the
     * input.
     */
            while (pos < end && !Ctype.spaceChar(chars[pos])) pos++;
            while (pos < end && !Ctype.isDigit(chars[pos])) pos++;
            if (pos == end) {
                if ((flags & TIME_DATETIME_ONLY) != 0) {
                    status.setWarnings(MYSQL_TIME_WARN_TRUNCATED);
                    lTime.setTimeType(MySQLTimestampType.MYSQL_TIMESTAMP_NONE);
                    return true;
                /* Can't be a full datetime */
                }
                /* Date field. Set hour, minutes and seconds to 0 */
                date[0] = date[1] = date[2] = date[3] = date[4] = 0;
                startLoop = 5;
            /* Start with first date part */
            }
        }
        fieldLength = formatPosition[0] == 0 ? 4 : 2;
    }
    /*
     * Only allow space in the first "part" of the datetime field and: -
     * after days, part seconds - before and after AM/PM (handled by code
     * later)
     *
     * 2003-03-03 20:00:20 AM 20:00:20.000000 AM 03-03-2000
     */
    long i = Math.max((long) formatPosition[0], (long) formatPosition[1]);
    if (i < (long) formatPosition[2])
        i = (long) formatPosition[2];
    long allowSpace = ((1 << i) | (1 << formatPosition[6]));
    allowSpace &= (1 | 2 | 4 | 8 | 64);
    long notZeroDate = 0;
    int strindex = 0;
    for (i = startLoop; i < MAX_DATE_PARTS - 1 && strindex != end && Ctype.isDigit(chars[strindex]); i++) {
        final int start = strindex;
        int tmpValue = chars[strindex++] - '0';
        /*
     * Internal format means no delimiters; every field has a fixed
     * width. Otherwise, we scan until we find a delimiter and discard
     * leading zeroes -- except for the microsecond part, where leading
     * zeroes are significant, and where we never process more than six
     * digits.
     */
        boolean scanUntilDelim = !isInternalFormat && ((i != formatPosition[6]));
        while (strindex != end && Ctype.isDigit(chars[strindex]) && (scanUntilDelim || (--fieldLength != 0))) {
            tmpValue = tmpValue * 10 + (chars[strindex] - '0');
            strindex++;
        }
        dateLen[(int) i] = (strindex - start);
        if (tmpValue > 999999) /* Impossible date part */
        {
            status.setWarnings(MYSQL_TIME_WARN_TRUNCATED);
            lTime.setTimeType(MySQLTimestampType.MYSQL_TIMESTAMP_NONE);
            return true;
        }
        date[(int) i] = tmpValue;
        notZeroDate |= tmpValue;
        /* Length of next field */
        fieldLength = formatPosition[(int) i + 1] == 0 ? 4 : 2;
        if ((lastFieldPos = strindex) == end) {
            i++;
            /* Register last found part */
            break;
        }
        /* Allow a 'T' after day to allow CCYYMMDDT type of fields */
        if (i == formatPosition[2] && chars[strindex] == 'T') {
            strindex++;
            /* ISO8601: CCYYMMDDThhmmss */
            continue;
        }
        if (i == formatPosition[5]) /* Seconds */
        {
            if (chars[strindex] == '.') /* Followed by part seconds */
            {
                strindex++;
                /*
     * Shift last_field_pos, so '2001-01-01 00:00:00.' is
     * treated as a valid value
     */
                lastFieldPos = strindex;
                fieldLength = 6;
            /* 6 digits */
            }
            continue;
        }
        while (strindex != end && (Ctype.isPunct(chars[strindex]) || Ctype.spaceChar(chars[strindex]))) {
            if (Ctype.spaceChar(chars[strindex])) {
                if ((allowSpace & (1 << i)) == 0) {
                    status.setWarnings(MYSQL_TIME_WARN_TRUNCATED);
                    lTime.setTimeType(MySQLTimestampType.MYSQL_TIMESTAMP_NONE);
                    return true;
                }
                foundSpace = true;
            }
            strindex++;
            foundDelimiter = true;
        /* Should be a 'normal' date */
        }
        /* Check if next position is AM/PM */
        if (i == formatPosition[6]) /* Seconds, time for AM/PM */
        {
            i++;
            /* Skip AM/PM part */
            if (formatPosition[7] != 255) /* If using AM/PM */
            {
                if (strindex + 2 <= end && (chars[strindex + 1] == 'M' || chars[strindex + 1] == 'm')) {
                    if (chars[strindex] == 'p' || chars[strindex] == 'P')
                        addHours = 12;
                    else if (chars[strindex] != 'a' || chars[strindex] != 'A')
                        continue;
                    /* Not AM/PM */
                    strindex += 2;
                    /* Skip space after AM/PM */
                    while (strindex != end && Ctype.spaceChar(chars[strindex])) strindex++;
                }
            }
        }
        lastFieldPos = strindex;
    }
    if (foundDelimiter && !foundSpace && (flags & TIME_DATETIME_ONLY) != 0) {
        status.setWarnings(MYSQL_TIME_WARN_TRUNCATED);
        lTime.setTimeType(MySQLTimestampType.MYSQL_TIMESTAMP_NONE);
        return true;
    /* Can't be a datetime */
    }
    strindex = lastFieldPos;
    final long numberOfFields = i - startLoop;
    while (i < MAX_DATE_PARTS) {
        dateLen[(int) i] = 0;
        date[(int) i++] = 0;
    }
    if (!isInternalFormat) {
        yearLength = dateLen[formatPosition[0]];
        if (yearLength == 0) /* Year must be specified */
        {
            status.setWarnings(MYSQL_TIME_WARN_TRUNCATED);
            lTime.setTimeType(MySQLTimestampType.MYSQL_TIMESTAMP_NONE);
            return true;
        }
        lTime.setYear(date[formatPosition[0]]);
        lTime.setMonth(date[formatPosition[1]]);
        lTime.setDay(date[formatPosition[2]]);
        lTime.setHour(date[formatPosition[3]]);
        lTime.setMinute(date[formatPosition[4]]);
        lTime.setSecond(date[formatPosition[5]]);
        fracPos = formatPosition[6];
        fracLen = dateLen[fracPos];
        status.setFractionalDigits(fracLen);
        if (fracLen < 6)
            date[fracPos] *= MySQLcom.LOG_10_INT[DATETIME_MAX_DECIMALS - fracLen];
        lTime.setSecondPart(date[fracPos]);
        if (formatPosition[7] != 255) {
            if (lTime.getHour() > 12) {
                status.setWarnings(MYSQL_TIME_WARN_TRUNCATED);
                lTime.setZeroTime(MySQLTimestampType.MYSQL_TIMESTAMP_ERROR);
                return true;
            }
            lTime.setHour(lTime.getHour() % 12 + addHours);
        }
    } else {
        lTime.setYear(date[0]);
        lTime.setMonth(date[1]);
        lTime.setDay(date[2]);
        lTime.setHour(date[3]);
        lTime.setMinute(date[4]);
        lTime.setSecond(date[5]);
        if (dateLen[6] < 6)
            date[6] *= MySQLcom.LOG_10_INT[DATETIME_MAX_DECIMALS - dateLen[6]];
        lTime.setSecondPart(date[6]);
        status.setFractionalDigits(dateLen[6]);
    }
    lTime.setNeg(false);
    if (yearLength == 2 && notZeroDate != 0)
        lTime.setYear(lTime.getYear() + (lTime.getYear() < YY_PART_YEAR ? 2000 : 1900));
    /*
     * Set time_type before check_datetime_range(), as the latter relies on
     * initialized time_type value.
     */
    lTime.setTimeType((numberOfFields <= 3 ? MySQLTimestampType.MYSQL_TIMESTAMP_DATE : MySQLTimestampType.MYSQL_TIMESTAMP_DATETIME));
    if (numberOfFields < 3 || checkDatetimeRange(lTime)) {
        /*
     * Only give warning for a zero date if there is some garbage after
     */
        if (notZeroDate == 0) /* If zero date */
        {
            for (; strindex != end; strindex++) {
                if (!Ctype.spaceChar(chars[strindex])) {
                    notZeroDate = 1;
                    /* Give warning */
                    break;
                }
            }
        }
        status.setWarnings(status.getWarnings() | (notZeroDate != 0 ? MYSQL_TIME_WARN_TRUNCATED : MYSQL_TIME_WARN_ZERO_DATE));
        lTime.setZeroTime(MySQLTimestampType.MYSQL_TIMESTAMP_ERROR);
        return true;
    }
    LongPtr lptmp = new LongPtr(0);
    boolean bcheckdate = checkDate(lTime, notZeroDate != 0, flags, lptmp);
    status.setWarnings((int) lptmp.get());
    if (bcheckdate) {
        lTime.setZeroTime(MySQLTimestampType.MYSQL_TIMESTAMP_ERROR);
        return true;
    }
    /* Scan all digits left after microseconds */
    if (status.getFractionalDigits() == 6 && strindex != end) {
        if (Ctype.isDigit(chars[strindex])) {
            /*
     * We don't need the exact nanoseconds value. Knowing the first
     * digit is enough for rounding.
     */
            status.setNanoseconds(100 * (chars[strindex++] - '0'));
            for (; strindex != end && Ctype.isDigit(chars[strindex]); strindex++) {
            // block
            }
        }
    }
    for (; strindex != end; strindex++) {
        if (!Ctype.spaceChar(chars[strindex])) {
            status.setWarnings(MYSQL_TIME_WARN_TRUNCATED);
            break;
        }
    }
    return false;
}
Also used : LongPtr(com.actiontech.dble.plan.common.ptr.LongPtr)

Aggregations

LongPtr (com.actiontech.dble.plan.common.ptr.LongPtr)23 MySQLTime (com.actiontech.dble.plan.common.time.MySQLTime)6 BigDecimal (java.math.BigDecimal)3 FieldTypes (com.actiontech.dble.plan.common.item.FieldTypes)2 MyLocale (com.actiontech.dble.plan.common.locale.MyLocale)1 BoolPtr (com.actiontech.dble.plan.common.ptr.BoolPtr)1 DoublePtr (com.actiontech.dble.plan.common.ptr.DoublePtr)1 BigInteger (java.math.BigInteger)1