source: Ballon/out/artifacts/geisa_artifact/WEB-INF/lib/mysql-connector-java-5.1.21/src/com/mysql/jdbc/ResultSetRow.java

Last change on this file was 766, checked in by npipsl, 11 years ago
File size: 42.4 KB
Line 
1/*
2 Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
3 
4
5  The MySQL Connector/J is licensed under the terms of the GPLv2
6  <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most MySQL Connectors.
7  There are special exceptions to the terms and conditions of the GPLv2 as it is applied to
8  this software, see the FLOSS License Exception
9  <http://www.mysql.com/about/legal/licensing/foss-exception.html>.
10
11  This program is free software; you can redistribute it and/or modify it under the terms
12  of the GNU General Public License as published by the Free Software Foundation; version 2
13  of the License.
14
15  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
16  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17  See the GNU General Public License for more details.
18
19  You should have received a copy of the GNU General Public License along with this
20  program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth
21  Floor, Boston, MA 02110-1301  USA
22 
23 */
24package com.mysql.jdbc;
25
26import java.io.InputStream;
27import java.io.Reader;
28import java.sql.Date;
29import java.sql.SQLException;
30import java.sql.SQLWarning;
31import java.sql.Time;
32import java.sql.Timestamp;
33import java.sql.Types;
34import java.util.Calendar;
35import java.util.StringTokenizer;
36import java.util.TimeZone;
37
38/**
39 * Classes that implement this interface represent one row of data from the
40 * MySQL server that might be stored in different ways depending on whether the
41 * result set was streaming (so they wrap a reusable packet), or whether the
42 * result set was cached or via a server-side cursor (so they represent a
43 * byte[][]).
44 *
45 * Notice that <strong>no</strong> bounds checking is expected for implementors
46 * of this interface, it happens in ResultSetImpl.
47 *
48 * @version $Id: $
49 */
50public abstract class ResultSetRow {
51        protected ExceptionInterceptor exceptionInterceptor;
52       
53        protected ResultSetRow(ExceptionInterceptor exceptionInterceptor) {
54                this.exceptionInterceptor = exceptionInterceptor;
55        }
56       
57        /**
58         * The metadata of the fields of this result set.
59         */
60        protected Field[] metadata;
61
62        /**
63         * Called during navigation to next row to close all open
64         * streams.
65         */
66        public abstract void closeOpenStreams();
67
68        /**
69         * Returns data at the given index as an InputStream with no
70         * character conversion.
71         *
72         * @param columnIndex
73         *            of the column value (starting at 0) to return.
74         * @return the value at the given index as an InputStream or null
75         *         if null.
76         *         
77         * @throws SQLException if an error occurs while retrieving the value.
78         */
79        public abstract InputStream getBinaryInputStream(int columnIndex)
80                        throws SQLException;
81
82        /**
83         * Returns the value at the given column (index starts at 0) "raw" (i.e.
84         * as-returned by the server).
85         *
86         * @param index
87         *            of the column value (starting at 0) to return.
88         * @return the value for the given column (including NULL if it is)
89         * @throws SQLException
90         *             if an error occurs while retrieving the value.
91         */
92        public abstract byte[] getColumnValue(int index) throws SQLException;
93
94        protected final java.sql.Date getDateFast(int columnIndex,
95                        byte[] dateAsBytes, int offset, int length, MySQLConnection conn,
96                        ResultSetImpl rs, Calendar targetCalendar) throws SQLException {
97
98                int year = 0;
99                int month = 0;
100                int day = 0;
101
102                try {
103                        if (dateAsBytes == null) {
104                                return null;
105                        }
106
107                        boolean allZeroDate = true;
108
109                        boolean onlyTimePresent = false;
110
111                        for (int i = 0; i < length; i++) {
112                                if (dateAsBytes[offset + i] == ':') {
113                                        onlyTimePresent = true;
114                                        break;
115                                }
116                        }
117
118                        for (int i = 0; i < length; i++) {
119                                byte b = dateAsBytes[offset + i];
120
121                                if (b == ' ' || b == '-' || b == '/') {
122                                        onlyTimePresent = false;
123                                }
124
125                                if (b != '0' && b != ' ' && b != ':' && b != '-' && b != '/'
126                                                && b != '.') {
127                                        allZeroDate = false;
128
129                                        break;
130                                }
131                        }
132
133                        if (!onlyTimePresent && allZeroDate) {
134
135                                if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
136                                                .equals(conn.getZeroDateTimeBehavior())) {
137
138                                        return null;
139                                } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
140                                                .equals(conn.getZeroDateTimeBehavior())) {
141                                        throw SQLError.createSQLException("Value '"
142                                                        + StringUtils.toString(dateAsBytes)
143                                                        + "' can not be represented as java.sql.Date",
144                                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor);
145                                }
146
147                                // We're left with the case of 'round' to a date Java _can_
148                                // represent, which is '0001-01-01'.
149                                return rs.fastDateCreate(targetCalendar, 1, 1, 1);
150
151                        } else if (this.metadata[columnIndex].getMysqlType() == MysqlDefs.FIELD_TYPE_TIMESTAMP) {
152                                // Convert from TIMESTAMP
153                                switch (length) {
154                                case 29:
155                                case 21:
156                                case 19: { // java.sql.Timestamp format
157                                        year = StringUtils.getInt(dateAsBytes, offset + 0,
158                                                        offset + 4);
159                                        month = StringUtils.getInt(dateAsBytes, offset + 5,
160                                                        offset + 7);
161                                        day = StringUtils.getInt(dateAsBytes, offset + 8,
162                                                        offset + 10);
163
164                                        return rs.fastDateCreate(targetCalendar, year, month, day);
165                                }
166
167                                case 14:
168                                case 8: {
169                                        year = StringUtils.getInt(dateAsBytes, offset + 0,
170                                                        offset + 4);
171                                        month = StringUtils.getInt(dateAsBytes, offset + 4,
172                                                        offset + 6);
173                                        day = StringUtils.getInt(dateAsBytes, offset + 6,
174                                                        offset + 8);
175
176                                        return rs.fastDateCreate(targetCalendar, year, month, day);
177                                }
178
179                                case 12:
180                                case 10:
181                                case 6: {
182                                        year = StringUtils.getInt(dateAsBytes, offset + 0,
183                                                        offset + 2);
184
185                                        if (year <= 69) {
186                                                year = year + 100;
187                                        }
188
189                                        month = StringUtils.getInt(dateAsBytes, offset + 2,
190                                                        offset + 4);
191                                        day = StringUtils.getInt(dateAsBytes, offset + 4,
192                                                        offset + 6);
193
194                                        return rs.fastDateCreate(targetCalendar, year + 1900, month, day);
195                                }
196
197                                case 4: {
198                                        year = StringUtils.getInt(dateAsBytes, offset + 0,
199                                                        offset + 4);
200
201                                        if (year <= 69) {
202                                                year = year + 100;
203                                        }
204
205                                        month = StringUtils.getInt(dateAsBytes, offset + 2,
206                                                        offset + 4);
207
208                                        return rs.fastDateCreate(targetCalendar, year + 1900, month, 1);
209                                }
210
211                                case 2: {
212                                        year = StringUtils.getInt(dateAsBytes, offset + 0,
213                                                        offset + 2);
214
215                                        if (year <= 69) {
216                                                year = year + 100;
217                                        }
218
219                                        return rs.fastDateCreate(targetCalendar, year + 1900, 1, 1);
220                                }
221
222                                default:
223                                        throw SQLError
224                                                        .createSQLException(
225                                                                        Messages
226                                                                                        .getString(
227                                                                                                        "ResultSet.Bad_format_for_Date",
228                                                                                                        new Object[] {
229                                                                                                                        StringUtils.toString(
230                                                                                                                                        dateAsBytes),
231                                                                                                                        Integer.valueOf(columnIndex + 1) }),
232                                                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); //$NON-NLS-1$
233                                } /* endswitch */
234                        } else if (this.metadata[columnIndex].getMysqlType() == MysqlDefs.FIELD_TYPE_YEAR) {
235
236                                if (length == 2 || length == 1) {
237                                        year = StringUtils.getInt(dateAsBytes, offset, offset
238                                                        + length);
239
240                                        if (year <= 69) {
241                                                year = year + 100;
242                                        }
243
244                                        year += 1900;
245                                } else {
246                                        year = StringUtils.getInt(dateAsBytes, offset + 0,
247                                                        offset + 4);
248                                }
249
250                                return rs.fastDateCreate(targetCalendar, year, 1, 1);
251                        } else if (this.metadata[columnIndex].getMysqlType() == MysqlDefs.FIELD_TYPE_TIME) {
252                                return rs.fastDateCreate(targetCalendar, 1970, 1, 1); // Return EPOCH
253                        } else {
254                                if (length < 10) {
255                                        if (length == 8) {
256                                                return rs.fastDateCreate(targetCalendar, 1970, 1, 1); // Return
257                                                // EPOCH for
258                                                // TIME
259                                        }
260
261                                        throw SQLError
262                                                        .createSQLException(
263                                                                        Messages
264                                                                                        .getString(
265                                                                                                        "ResultSet.Bad_format_for_Date",
266                                                                                                        new Object[] {
267                                                                                                                        StringUtils.toString(
268                                                                                                                                        dateAsBytes),
269                                                                                                                        Integer.valueOf(columnIndex + 1) }),
270                                                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); //$NON-NLS-1$
271                                }
272
273                                if (length != 18) {
274                                        year = StringUtils.getInt(dateAsBytes, offset + 0,
275                                                        offset + 4);
276                                        month = StringUtils.getInt(dateAsBytes, offset + 5,
277                                                        offset + 7);
278                                        day = StringUtils.getInt(dateAsBytes, offset + 8,
279                                                        offset + 10);
280                                } else {
281                                        // JDK-1.3 timestamp format, not real easy to parse
282                                        // positionally :p
283                                        StringTokenizer st = new StringTokenizer(StringUtils.toString(
284                                                        dateAsBytes, offset, length, "ISO8859_1"), "- ");
285
286                                        year = Integer.parseInt(st.nextToken());
287                                        month = Integer.parseInt(st.nextToken());
288                                        day = Integer.parseInt(st.nextToken());
289                                }
290                        }
291
292                        return rs.fastDateCreate(targetCalendar, year, month, day);
293                } catch (SQLException sqlEx) {
294                        throw sqlEx; // don't re-wrap
295                } catch (Exception e) {
296                        SQLException sqlEx = SQLError.createSQLException(Messages.getString(
297                                        "ResultSet.Bad_format_for_Date", new Object[] {
298                                                        StringUtils.toString(dateAsBytes),
299                                                        Integer.valueOf(columnIndex + 1) }),
300                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor); //$NON-NLS-1$
301                        sqlEx.initCause(e);
302                       
303                        throw sqlEx;
304                }
305        }
306
307        public abstract java.sql.Date getDateFast(int columnIndex,
308                        MySQLConnection conn, ResultSetImpl rs, Calendar targetCalendar) throws SQLException;
309
310        /**
311         * Returns the value at the given column (index starts at 0) as an int. *
312         *
313         * @param index
314         *            of the column value (starting at 0) to return.
315         * @return the value for the given column (returns 0 if NULL, use isNull()
316         *         to determine if the value was actually NULL)
317         * @throws SQLException
318         *             if an error occurs while retrieving the value.
319         */
320        public abstract int getInt(int columnIndex) throws SQLException;
321
322        /**
323         * Returns the value at the given column (index starts at 0) as a long. *
324         *
325         * @param index
326         *            of the column value (starting at 0) to return.
327         * @return the value for the given column (returns 0 if NULL, use isNull()
328         *         to determine if the value was actually NULL)
329         * @throws SQLException
330         *             if an error occurs while retrieving the value.
331         */
332        public abstract long getLong(int columnIndex) throws SQLException;
333
334        /**
335         *
336         * @param columnIndex
337         * @param bits
338         * @param offset
339         * @param length
340         * @param conn
341         * @param rs
342         * @param cal
343         * @return
344         * @throws SQLException
345         */
346        protected java.sql.Date getNativeDate(int columnIndex, byte[] bits,
347                        int offset, int length, MySQLConnection conn, ResultSetImpl rs, Calendar cal)
348                        throws SQLException {
349
350                int year = 0;
351                int month = 0;
352                int day = 0;
353
354                if (length != 0) {
355                        year = (bits[offset + 0] & 0xff) | ((bits[offset + 1] & 0xff) << 8);
356
357                        month = bits[offset + 2];
358                        day = bits[offset + 3];
359                }
360
361                if (length == 0 || ((year == 0) && (month == 0) && (day == 0))) {
362                        if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
363                                        .equals(conn.getZeroDateTimeBehavior())) {
364                                return null;
365                        } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
366                                        .equals(conn.getZeroDateTimeBehavior())) {
367                                throw SQLError
368                                                .createSQLException(
369                                                                "Value '0000-00-00' can not be represented as java.sql.Date",
370                                                                SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor);
371                        }
372
373                        year = 1;
374                        month = 1;
375                        day = 1;
376                }
377
378                if (!rs.useLegacyDatetimeCode) {
379                        return TimeUtil.fastDateCreate(year, month, day, cal);
380                }
381               
382                return rs.fastDateCreate(cal == null ? rs.getCalendarInstanceForSessionOrNew() : cal, year,
383                                month, day);
384        }
385
386        public abstract Date getNativeDate(int columnIndex, MySQLConnection conn,
387                        ResultSetImpl rs, Calendar cal) throws SQLException;
388
389        protected Object getNativeDateTimeValue(int columnIndex, byte[] bits,
390                        int offset, int length, Calendar targetCalendar, int jdbcType,
391                        int mysqlType, TimeZone tz, boolean rollForward, MySQLConnection conn,
392                        ResultSetImpl rs) throws SQLException {
393
394                int year = 0;
395                int month = 0;
396                int day = 0;
397
398                int hour = 0;
399                int minute = 0;
400                int seconds = 0;
401
402                int nanos = 0;
403
404                if (bits == null) {
405
406                        return null;
407                }
408
409                Calendar sessionCalendar = conn.getUseJDBCCompliantTimezoneShift() ? conn
410                                .getUtcCalendar()
411                                : rs.getCalendarInstanceForSessionOrNew();
412
413                boolean populatedFromDateTimeValue = false;
414
415                switch (mysqlType) {
416                case MysqlDefs.FIELD_TYPE_DATETIME:
417                case MysqlDefs.FIELD_TYPE_TIMESTAMP:
418                        populatedFromDateTimeValue = true;
419
420                        if (length != 0) {
421                                year = (bits[offset + 0] & 0xff)
422                                                | ((bits[offset + 1] & 0xff) << 8);
423                                month = bits[offset + 2];
424                                day = bits[offset + 3];
425
426                                if (length > 4) {
427                                        hour = bits[offset + 4];
428                                        minute = bits[offset + 5];
429                                        seconds = bits[offset + 6];
430                                }
431
432                                if (length > 7) {
433                                        // MySQL uses microseconds
434                                        nanos = ((bits[offset + 7] & 0xff)
435                                                        | ((bits[offset + 8] & 0xff) << 8)
436                                                        | ((bits[offset + 9] & 0xff) << 16) | ((bits[offset + 10] & 0xff) << 24)) * 1000;
437                                }
438                        }
439
440                        break;
441                case MysqlDefs.FIELD_TYPE_DATE:
442                        populatedFromDateTimeValue = true;
443
444                        if (bits.length != 0) {
445                                year = (bits[offset + 0] & 0xff)
446                                                | ((bits[offset + 1] & 0xff) << 8);
447                                month = bits[offset + 2];
448                                day = bits[offset + 3];
449                        }
450
451                        break;
452                case MysqlDefs.FIELD_TYPE_TIME:
453                        populatedFromDateTimeValue = true;
454
455                        if (bits.length != 0) {
456                                // bits[0] // skip tm->neg
457                                // binaryData.readLong(); // skip daysPart
458                                hour = bits[offset + 5];
459                                minute = bits[offset + 6];
460                                seconds = bits[offset + 7];
461                        }
462
463                        year = 1970;
464                        month = 1;
465                        day = 1;
466
467                        break;
468                default:
469                        populatedFromDateTimeValue = false;
470                }
471
472                switch (jdbcType) {
473                case Types.TIME:
474                        if (populatedFromDateTimeValue) {
475                                if (!rs.useLegacyDatetimeCode) {
476                                        return TimeUtil.fastTimeCreate(hour, minute, seconds, targetCalendar, this.exceptionInterceptor);
477                                }
478                               
479                                Time time = TimeUtil.fastTimeCreate(rs
480                                                .getCalendarInstanceForSessionOrNew(), hour, minute,
481                                                seconds, this.exceptionInterceptor);
482
483                                Time adjustedTime = TimeUtil.changeTimezone(conn,
484                                                sessionCalendar, targetCalendar, time, conn
485                                                                .getServerTimezoneTZ(), tz, rollForward);
486
487                                return adjustedTime;
488                        }
489
490                        return rs.getNativeTimeViaParseConversion(columnIndex + 1,
491                                        targetCalendar, tz, rollForward);
492
493                case Types.DATE:
494                        if (populatedFromDateTimeValue) {
495                                if ((year == 0) && (month == 0) && (day == 0)) {
496                                        if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
497                                                        .equals(conn.getZeroDateTimeBehavior())) {
498
499                                                return null;
500                                        } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
501                                                        .equals(conn.getZeroDateTimeBehavior())) {
502                                                throw new SQLException(
503                                                                "Value '0000-00-00' can not be represented as java.sql.Date",
504                                                                SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
505                                        }
506
507                                        year = 1;
508                                        month = 1;
509                                        day = 1;
510                                }
511
512                                if (!rs.useLegacyDatetimeCode) {
513                                        return TimeUtil.fastDateCreate(year, month, day, targetCalendar);
514                                }
515                               
516                                return rs
517                                                .fastDateCreate(
518                                                                rs.getCalendarInstanceForSessionOrNew(), year,
519                                                                month, day);
520                        }
521
522                        return rs.getNativeDateViaParseConversion(columnIndex + 1);
523                case Types.TIMESTAMP:
524                        if (populatedFromDateTimeValue) {
525                                if ((year == 0) && (month == 0) && (day == 0)) {
526                                        if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
527                                                        .equals(conn.getZeroDateTimeBehavior())) {
528
529                                                return null;
530                                        } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
531                                                        .equals(conn.getZeroDateTimeBehavior())) {
532                                                throw new SQLException(
533                                                                "Value '0000-00-00' can not be represented as java.sql.Timestamp",
534                                                                SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
535                                        }
536
537                                        year = 1;
538                                        month = 1;
539                                        day = 1;
540                                }
541
542                                if (!rs.useLegacyDatetimeCode) {
543                                        return TimeUtil.fastTimestampCreate(tz, year, month, day, hour, minute, 
544                                                        seconds, nanos);
545                                }
546                               
547                                Timestamp ts = rs.fastTimestampCreate(rs
548                                                .getCalendarInstanceForSessionOrNew(), year, month,
549                                                day, hour, minute, seconds, nanos);
550
551                                Timestamp adjustedTs = TimeUtil.changeTimezone(conn,
552                                                sessionCalendar, targetCalendar, ts, conn
553                                                                .getServerTimezoneTZ(), tz, rollForward);
554
555                                return adjustedTs;
556                        }
557
558                        return rs.getNativeTimestampViaParseConversion(columnIndex + 1,
559                                        targetCalendar, tz, rollForward);
560
561                default:
562                        throw new SQLException(
563                                        "Internal error - conversion method doesn't support this type",
564                                        SQLError.SQL_STATE_GENERAL_ERROR);
565                }
566        }
567
568        public abstract Object getNativeDateTimeValue(int columnIndex,
569                        Calendar targetCalendar, int jdbcType, int mysqlType,
570                        TimeZone tz, boolean rollForward, MySQLConnection conn, ResultSetImpl rs)
571                        throws SQLException;
572
573        protected double getNativeDouble(byte[] bits, int offset) {
574                long valueAsLong = (bits[offset + 0] & 0xff)
575                                | ((long) (bits[offset + 1] & 0xff) << 8)
576                                | ((long) (bits[offset + 2] & 0xff) << 16)
577                                | ((long) (bits[offset + 3] & 0xff) << 24)
578                                | ((long) (bits[offset + 4] & 0xff) << 32)
579                                | ((long) (bits[offset + 5] & 0xff) << 40)
580                                | ((long) (bits[offset + 6] & 0xff) << 48)
581                                | ((long) (bits[offset + 7] & 0xff) << 56);
582
583                return Double.longBitsToDouble(valueAsLong);
584        }
585
586        public abstract double getNativeDouble(int columnIndex) throws SQLException;
587
588        protected float getNativeFloat(byte[] bits, int offset) {
589                int asInt = (bits[offset + 0] & 0xff)
590                                | ((bits[offset + 1] & 0xff) << 8)
591                                | ((bits[offset + 2] & 0xff) << 16)
592                                | ((bits[offset + 3] & 0xff) << 24);
593
594                return Float.intBitsToFloat(asInt);
595        }
596
597        public abstract float getNativeFloat(int columnIndex) throws SQLException;
598
599        protected int getNativeInt(byte[] bits, int offset) {
600
601                int valueAsInt = (bits[offset + 0] & 0xff)
602                                | ((bits[offset + 1] & 0xff) << 8)
603                                | ((bits[offset + 2] & 0xff) << 16)
604                                | ((bits[offset + 3] & 0xff) << 24);
605
606                return valueAsInt;
607        }
608
609        public abstract int getNativeInt(int columnIndex) throws SQLException;
610
611        protected long getNativeLong(byte[] bits, int offset) {
612                long valueAsLong = (bits[offset + 0] & 0xff)
613                                | ((long) (bits[offset + 1] & 0xff) << 8)
614                                | ((long) (bits[offset + 2] & 0xff) << 16)
615                                | ((long) (bits[offset + 3] & 0xff) << 24)
616                                | ((long) (bits[offset + 4] & 0xff) << 32)
617                                | ((long) (bits[offset + 5] & 0xff) << 40)
618                                | ((long) (bits[offset + 6] & 0xff) << 48)
619                                | ((long) (bits[offset + 7] & 0xff) << 56);
620
621                return valueAsLong;
622        }
623
624        public abstract long getNativeLong(int columnIndex) throws SQLException;
625
626        protected short getNativeShort(byte[] bits, int offset) {
627                short asShort = (short) ((bits[offset + 0] & 0xff) | ((bits[offset + 1] & 0xff) << 8));
628
629                return asShort;
630        }
631
632        public abstract short getNativeShort(int columnIndex) throws SQLException;
633
634        /**
635         *
636         * @param columnIndex
637         * @param bits
638         * @param offset
639         * @param length
640         * @param targetCalendar
641         * @param tz
642         * @param rollForward
643         * @param conn
644         * @param rs
645         * @return
646         * @throws SQLException
647         */
648        protected Time getNativeTime(int columnIndex, byte[] bits, int offset,
649                        int length, Calendar targetCalendar, TimeZone tz,
650                        boolean rollForward, MySQLConnection conn, ResultSetImpl rs)
651                        throws SQLException {
652
653                int hour = 0;
654                int minute = 0;
655                int seconds = 0;
656
657                if (length != 0) {
658                        // bits[0] // skip tm->neg
659                        // binaryData.readLong(); // skip daysPart
660                        hour = bits[offset + 5];
661                        minute = bits[offset + 6];
662                        seconds = bits[offset + 7];
663                }
664
665                if (!rs.useLegacyDatetimeCode) {
666                        return TimeUtil.fastTimeCreate(hour, minute, seconds, targetCalendar, this.exceptionInterceptor);
667                }
668               
669                Calendar sessionCalendar = rs.getCalendarInstanceForSessionOrNew();
670
671                synchronized (sessionCalendar) {
672                        Time time = TimeUtil.fastTimeCreate(sessionCalendar, hour, minute,
673                                        seconds, this.exceptionInterceptor);
674
675                        Time adjustedTime = TimeUtil.changeTimezone(conn, sessionCalendar,
676                                        targetCalendar, time, conn.getServerTimezoneTZ(), tz,
677                                        rollForward);
678
679                        return adjustedTime;
680                }
681        }
682
683        public abstract Time getNativeTime(int columnIndex,
684                        Calendar targetCalendar, TimeZone tz, boolean rollForward,
685                        MySQLConnection conn, ResultSetImpl rs) throws SQLException;
686
687        protected Timestamp getNativeTimestamp(byte[] bits, int offset, int length,
688                        Calendar targetCalendar, TimeZone tz, boolean rollForward,
689                        MySQLConnection conn, ResultSetImpl rs) throws SQLException {
690                int year = 0;
691                int month = 0;
692                int day = 0;
693
694                int hour = 0;
695                int minute = 0;
696                int seconds = 0;
697
698                int nanos = 0;
699
700                if (length != 0) {
701                        year = (bits[offset + 0] & 0xff) | ((bits[offset + 1] & 0xff) << 8);
702                        month = bits[offset + 2];
703                        day = bits[offset + 3];
704
705                        if (length > 4) {
706                                hour = bits[offset + 4];
707                                minute = bits[offset + 5];
708                                seconds = bits[offset + 6];
709                        }
710
711                        if (length > 7) {
712                                // MySQL uses microseconds
713                                nanos = ((bits[offset + 7] & 0xff)
714                                                | ((bits[offset + 8] & 0xff) << 8)
715                                                | ((bits[offset + 9] & 0xff) << 16) | ((bits[offset + 10] & 0xff) << 24)) * 1000;
716                        }
717                }
718
719                if (length == 0 || ((year == 0) && (month == 0) && (day == 0))) {
720                        if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
721                                        .equals(conn.getZeroDateTimeBehavior())) {
722
723                                return null;
724                        } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
725                                        .equals(conn.getZeroDateTimeBehavior())) {
726                                throw SQLError
727                                                .createSQLException(
728                                                                "Value '0000-00-00' can not be represented as java.sql.Timestamp",
729                                                                SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor);
730                        }
731
732                        year = 1;
733                        month = 1;
734                        day = 1;
735                }
736
737                if (!rs.useLegacyDatetimeCode) {
738                        return TimeUtil.fastTimestampCreate(tz, year, month,
739                                        day, hour, minute, seconds, nanos);
740                }
741               
742                Calendar sessionCalendar = conn.getUseJDBCCompliantTimezoneShift() ? conn
743                                .getUtcCalendar()
744                                : rs.getCalendarInstanceForSessionOrNew();
745
746                synchronized (sessionCalendar) {
747                        Timestamp ts = rs.fastTimestampCreate(sessionCalendar, year, month,
748                                        day, hour, minute, seconds, nanos);
749
750                        Timestamp adjustedTs = TimeUtil.changeTimezone(conn,
751                                        sessionCalendar, targetCalendar, ts, conn
752                                                        .getServerTimezoneTZ(), tz, rollForward);
753
754                        return adjustedTs;
755                }
756        }
757
758        public abstract Timestamp getNativeTimestamp(int columnIndex,
759                        Calendar targetCalendar, TimeZone tz, boolean rollForward,
760                        MySQLConnection conn, ResultSetImpl rs) throws SQLException;
761
762        public abstract Reader getReader(int columnIndex) throws SQLException;
763
764        /**
765         * Returns the value at the given column (index starts at 0) as a
766         * java.lang.String with the requested encoding, using the given
767         * MySQLConnection to find character converters.
768         *
769         * @param index
770         *            of the column value (starting at 0) to return.
771         * @param encoding
772         *            the Java name for the character encoding
773         * @param conn
774         *            the connection that created this result set row
775         *
776         * @return the value for the given column (including NULL if it is) as a
777         *         String
778         *
779         * @throws SQLException
780         *             if an error occurs while retrieving the value.
781         */
782        public abstract String getString(int index, String encoding,
783                        MySQLConnection conn) throws SQLException;
784
785        /**
786         * Convenience method for turning a byte[] into a string with the given
787         * encoding.
788         *
789         * @param encoding
790         *            the Java encoding name for the byte[] -> char conversion
791         * @param conn
792         *            the MySQLConnection that created the result set
793         * @param value
794         *            the String value as a series of bytes, encoded using
795         *            "encoding"
796         * @param offset
797         *            where to start the decoding
798         * @param length
799         *            how many bytes to decode
800         *
801         * @return the String as decoded from bytes with the given encoding
802         *
803         * @throws SQLException
804         *             if an error occurs
805         */
806        protected String getString(String encoding, MySQLConnection conn,
807                        byte[] value, int offset, int length) throws SQLException {
808                String stringVal = null;
809
810                if ((conn != null) && conn.getUseUnicode()) {
811                        try {
812                                if (encoding == null) {
813                                        stringVal = StringUtils.toString(value);
814                                } else {
815                                        SingleByteCharsetConverter converter = conn
816                                                        .getCharsetConverter(encoding);
817
818                                        if (converter != null) {
819                                                stringVal = converter.toString(value, offset, length);
820                                        } else {
821                                                stringVal = StringUtils.toString(value, offset, length, encoding);
822                                        }
823                                }
824                        } catch (java.io.UnsupportedEncodingException E) {
825                                throw SQLError
826                                                .createSQLException(
827                                                                Messages
828                                                                                .getString("ResultSet.Unsupported_character_encoding____101") //$NON-NLS-1$
829                                                                                + encoding + "'.", "0S100", this.exceptionInterceptor);
830                        }
831                } else {
832                        stringVal = StringUtils.toAsciiString(value, offset, length);
833                }
834
835                return stringVal;
836        }
837
838        protected Time getTimeFast(int columnIndex, byte[] timeAsBytes, int offset,
839                        int length, Calendar targetCalendar, TimeZone tz,
840                        boolean rollForward, MySQLConnection conn, ResultSetImpl rs)
841                        throws SQLException {
842
843                int hr = 0;
844                int min = 0;
845                int sec = 0;
846
847                try {
848
849                        if (timeAsBytes == null) {
850                                return null;
851                        }
852
853                        boolean allZeroTime = true;
854                        boolean onlyTimePresent = false;
855
856                        for (int i = 0; i < length; i++) {
857                                if (timeAsBytes[offset + i] == ':') {
858                                        onlyTimePresent = true;
859                                        break;
860                                }
861                        }
862
863                        for (int i = 0; i < length; i++) {
864                                byte b = timeAsBytes[offset + i];
865
866                                if (b == ' ' || b == '-' || b == '/') {
867                                        onlyTimePresent = false;
868                                }
869
870                                if (b != '0' && b != ' ' && b != ':' && b != '-' && b != '/'
871                                                && b != '.') {
872                                        allZeroTime = false;
873
874                                        break;
875                                }
876                        }
877
878                        if (!onlyTimePresent && allZeroTime) {
879                                if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
880                                                .equals(conn.getZeroDateTimeBehavior())) {
881                                        return null;
882                                } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
883                                                .equals(conn.getZeroDateTimeBehavior())) {
884                                        throw SQLError.createSQLException("Value '"
885                                                        + StringUtils.toString(timeAsBytes)
886                                                        + "' can not be represented as java.sql.Time",
887                                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor);
888                                }
889
890                                // We're left with the case of 'round' to a time Java _can_
891                                // represent, which is '00:00:00'
892                                return rs.fastTimeCreate(targetCalendar, 0, 0, 0);
893                        }
894
895                        Field timeColField = this.metadata[columnIndex];
896
897                        if (timeColField.getMysqlType() == MysqlDefs.FIELD_TYPE_TIMESTAMP) {
898
899                                switch (length) {
900                                case 19: { // YYYY-MM-DD hh:mm:ss
901
902                                        hr = StringUtils.getInt(timeAsBytes, offset + length - 8,
903                                                        offset + length - 6);
904                                        min = StringUtils.getInt(timeAsBytes, offset + length - 5,
905                                                        offset + length - 3);
906                                        sec = StringUtils.getInt(timeAsBytes, offset + length - 2,
907                                                        offset + length);
908                                }
909
910                                        break;
911                                case 14:
912                                case 12: {
913                                        hr = StringUtils.getInt(timeAsBytes, offset + length - 6,
914                                                        offset + length - 4);
915                                        min = StringUtils.getInt(timeAsBytes, offset + length - 4,
916                                                        offset + length - 2);
917                                        sec = StringUtils.getInt(timeAsBytes, offset + length - 2,
918                                                        offset + length);
919                                }
920
921                                        break;
922
923                                case 10: {
924                                        hr = StringUtils
925                                                        .getInt(timeAsBytes, offset + 6, offset + 8);
926                                        min = StringUtils.getInt(timeAsBytes, offset + 8,
927                                                        offset + 10);
928                                        sec = 0;
929                                }
930
931                                        break;
932
933                                default:
934                                        throw SQLError
935                                                        .createSQLException(
936                                                                        Messages
937                                                                                        .getString("ResultSet.Timestamp_too_small_to_convert_to_Time_value_in_column__257") //$NON-NLS-1$
938                                                                                        + (columnIndex + 1)
939                                                                                        + "("
940                                                                                        + timeColField + ").",
941                                                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor);
942                                } /* endswitch */
943
944                                @SuppressWarnings("unused")
945                                SQLWarning precisionLost = new SQLWarning(
946                                                Messages
947                                                                .getString("ResultSet.Precision_lost_converting_TIMESTAMP_to_Time_with_getTime()_on_column__261") //$NON-NLS-1$
948                                                                + columnIndex + "(" + timeColField + ").");
949                                /*
950                                 * if (this.warningChain == null) { this.warningChain =
951                                 * precisionLost; } else {
952                                 * this.warningChain.setNextWarning(precisionLost); }
953                                 */
954                        } else if (timeColField.getMysqlType() == MysqlDefs.FIELD_TYPE_DATETIME) {
955                                hr = StringUtils.getInt(timeAsBytes, offset + 11, offset + 13);
956                                min = StringUtils.getInt(timeAsBytes, offset + 14, offset + 16);
957                                sec = StringUtils.getInt(timeAsBytes, offset + 17, offset + 19);
958
959                                @SuppressWarnings("unused")
960                                SQLWarning precisionLost = new SQLWarning(
961                                                Messages
962                                                                .getString("ResultSet.Precision_lost_converting_DATETIME_to_Time_with_getTime()_on_column__264") //$NON-NLS-1$
963                                                                + (columnIndex + 1) + "(" + timeColField + ").");
964
965                                /*
966                                 * if (this.warningChain == null) { this.warningChain =
967                                 * precisionLost; } else {
968                                 * this.warningChain.setNextWarning(precisionLost); }
969                                 */
970                        } else if (timeColField.getMysqlType() == MysqlDefs.FIELD_TYPE_DATE) {
971                                return rs.fastTimeCreate(null, 0, 0, 0); // midnight on the
972                                // given
973                                // date
974                        } else {
975                                // convert a String to a Time
976                                if ((length != 5) && (length != 8)) {
977                                        throw SQLError.createSQLException(Messages
978                                                        .getString("ResultSet.Bad_format_for_Time____267") //$NON-NLS-1$
979                                                        + StringUtils.toString(timeAsBytes)
980                                                        + Messages.getString("ResultSet.___in_column__268")
981                                                        + (columnIndex + 1),
982                                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor);
983                                }
984
985                                hr = StringUtils.getInt(timeAsBytes, offset + 0, offset + 2);
986                                min = StringUtils.getInt(timeAsBytes, offset + 3, offset + 5);
987                                sec = (length == 5) ? 0 : StringUtils.getInt(timeAsBytes,
988                                                offset + 6, offset + 8);
989                        }
990
991                        Calendar sessionCalendar = rs.getCalendarInstanceForSessionOrNew();
992
993                        if (!rs.useLegacyDatetimeCode) {
994                                return rs.fastTimeCreate(targetCalendar, hr, min, sec);
995                        }
996                       
997                        synchronized (sessionCalendar) {
998                                return TimeUtil.changeTimezone(conn, sessionCalendar,
999                                                targetCalendar, rs.fastTimeCreate(sessionCalendar, hr,
1000                                                                min, sec), conn.getServerTimezoneTZ(), tz,
1001                                                rollForward);
1002                        }
1003                } catch (RuntimeException ex) {
1004                        SQLException sqlEx = SQLError.createSQLException(ex.toString(),
1005                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor);
1006                        sqlEx.initCause(ex);
1007                       
1008                        throw sqlEx;
1009                }
1010        }
1011
1012        public abstract Time getTimeFast(int columnIndex, Calendar targetCalendar,
1013                        TimeZone tz, boolean rollForward, MySQLConnection conn,
1014                        ResultSetImpl rs) throws SQLException;
1015
1016        protected Timestamp getTimestampFast(int columnIndex,
1017                        byte[] timestampAsBytes, int offset, int length,
1018                        Calendar targetCalendar, TimeZone tz, boolean rollForward,
1019                        MySQLConnection conn, ResultSetImpl rs) throws SQLException {
1020
1021                try {
1022                        Calendar sessionCalendar = conn.getUseJDBCCompliantTimezoneShift() ? conn
1023                                        .getUtcCalendar()
1024                                        : rs.getCalendarInstanceForSessionOrNew();
1025
1026                        synchronized (sessionCalendar) {
1027                                boolean allZeroTimestamp = true;
1028
1029                                boolean onlyTimePresent = false;
1030
1031                                for (int i = 0; i < length; i++) {
1032                                        if (timestampAsBytes[offset + i] == ':') {
1033                                                onlyTimePresent = true;
1034                                                break;
1035                                        }
1036                                }
1037
1038                                for (int i = 0; i < length; i++) {
1039                                        byte b = timestampAsBytes[offset + i];
1040
1041                                        if (b == ' ' || b == '-' || b == '/') {
1042                                                onlyTimePresent = false;
1043                                        }
1044
1045                                        if (b != '0' && b != ' ' && b != ':' && b != '-'
1046                                                        && b != '/' && b != '.') {
1047                                                allZeroTimestamp = false;
1048
1049                                                break;
1050                                        }
1051                                }
1052
1053                                if (!onlyTimePresent && allZeroTimestamp) {
1054
1055                                        if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
1056                                                        .equals(conn.getZeroDateTimeBehavior())) {
1057
1058                                                return null;
1059                                        } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
1060                                                        .equals(conn.getZeroDateTimeBehavior())) {
1061                                                throw SQLError
1062                                                                .createSQLException(
1063                                                                                "Value '"
1064                                                                                                + StringUtils.toString(timestampAsBytes)
1065                                                                                                + "' can not be represented as java.sql.Timestamp",
1066                                                                                SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor);
1067                                        }
1068
1069                                        if (!rs.useLegacyDatetimeCode) {
1070                                                return TimeUtil.fastTimestampCreate(tz, 1, 1, 1, 0, 0, 0, 0);
1071                                        }
1072                                        // We're left with the case of 'round' to a date Java _can_
1073                                        // represent, which is '0001-01-01'.
1074                                        return rs.fastTimestampCreate(null, 1, 1, 1, 0, 0, 0, 0);
1075
1076                                } else if (this.metadata[columnIndex].getMysqlType() == MysqlDefs.FIELD_TYPE_YEAR) {
1077
1078                                        if (!rs.useLegacyDatetimeCode) {
1079                                                return TimeUtil.fastTimestampCreate(tz, StringUtils
1080                                                                .getInt(timestampAsBytes, offset, 4), 1, 1, 0,
1081                                                                0, 0, 0);
1082                                        }
1083                                       
1084                                        return TimeUtil.changeTimezone(conn, sessionCalendar,
1085                                                targetCalendar, rs.fastTimestampCreate(
1086                                                                sessionCalendar, StringUtils.getInt(
1087                                                                                timestampAsBytes, offset, 4), 1, 1,
1088                                                                0, 0, 0, 0), conn.getServerTimezoneTZ(),
1089                                                tz, rollForward);
1090                                } else {
1091                                        if (timestampAsBytes[offset + length - 1] == '.') {
1092                                                length--;
1093                                        }
1094
1095                                        // Convert from TIMESTAMP or DATE
1096                                       
1097                                        int year = 0;
1098                                        int month = 0;
1099                                        int day = 0;
1100                                        int hour = 0;
1101                                        int minutes = 0;
1102                                        int seconds = 0;
1103                                        int nanos = 0;
1104                                       
1105                                        switch (length) {
1106                                        case 29:
1107                                        case 26:
1108                                        case 25:
1109                                        case 24:
1110                                        case 23:
1111                                        case 22:
1112                                        case 21:
1113                                        case 20:
1114                                        case 19: {
1115                                                year = StringUtils.getInt(timestampAsBytes,
1116                                                                offset + 0, offset + 4);
1117                                                month = StringUtils.getInt(timestampAsBytes,
1118                                                                offset + 5, offset + 7);
1119                                                day = StringUtils.getInt(timestampAsBytes,
1120                                                                offset + 8, offset + 10);
1121                                                hour = StringUtils.getInt(timestampAsBytes,
1122                                                                offset + 11, offset + 13);
1123                                                minutes = StringUtils.getInt(timestampAsBytes,
1124                                                                offset + 14, offset + 16);
1125                                                seconds = StringUtils.getInt(timestampAsBytes,
1126                                                                offset + 17, offset + 19);
1127
1128                                                nanos = 0;
1129
1130                                                if (length > 19) {
1131                                                        int decimalIndex = -1;
1132
1133                                                        for (int i = 0; i < length; i++) {
1134                                                                if (timestampAsBytes[offset + i] == '.') {
1135                                                                        decimalIndex = i;
1136                                                                }
1137                                                        }
1138
1139                                                        if (decimalIndex != -1) {
1140                                                                if ((decimalIndex + 2) <= length) {
1141                                                                        nanos = StringUtils.getInt(
1142                                                                                        timestampAsBytes, offset + decimalIndex + 1,
1143                                                                                        offset + length);
1144                                                                       
1145                                                                        int numDigits = (length) - (decimalIndex + 1);
1146                                                                       
1147                                                                        if (numDigits < 9) {
1148                                                                                int factor = (int)(Math.pow(10, 9 - numDigits));
1149                                                                                nanos = nanos * factor;
1150                                                                        }
1151                                                                } else {
1152                                                                        throw new IllegalArgumentException(); // re-thrown
1153                                                                        // further
1154                                                                        // down
1155                                                                        // with
1156                                                                        // a
1157                                                                        // much better error message
1158                                                                }
1159                                                        }
1160                                                }
1161
1162                                                break;
1163                                        }
1164
1165                                        case 14: {
1166                                                year = StringUtils.getInt(timestampAsBytes,
1167                                                                offset + 0, offset + 4);
1168                                                month = StringUtils.getInt(timestampAsBytes,
1169                                                                offset + 4, offset + 6);
1170                                                day = StringUtils.getInt(timestampAsBytes,
1171                                                                offset + 6, offset + 8);
1172                                                hour = StringUtils.getInt(timestampAsBytes,
1173                                                                offset + 8, offset + 10);
1174                                                minutes = StringUtils.getInt(timestampAsBytes,
1175                                                                offset + 10, offset + 12);
1176                                                seconds = StringUtils.getInt(timestampAsBytes,
1177                                                                offset + 12, offset + 14);
1178
1179                                                break;
1180                                        }
1181
1182                                        case 12: {
1183                                                year = StringUtils.getInt(timestampAsBytes,
1184                                                                offset + 0, offset + 2);
1185
1186                                                if (year <= 69) {
1187                                                        year = (year + 100);
1188                                                }
1189                                               
1190                                                year += 1900;
1191
1192                                                month = StringUtils.getInt(timestampAsBytes,
1193                                                                offset + 2, offset + 4);
1194                                                day = StringUtils.getInt(timestampAsBytes,
1195                                                                offset + 4, offset + 6);
1196                                                hour = StringUtils.getInt(timestampAsBytes,
1197                                                                offset + 6, offset + 8);
1198                                                minutes = StringUtils.getInt(timestampAsBytes,
1199                                                                offset + 8, offset + 10);
1200                                                seconds = StringUtils.getInt(timestampAsBytes,
1201                                                                offset + 10, offset + 12);
1202
1203                                                break;
1204                                        }
1205
1206                                        case 10: {
1207                                                boolean hasDash = false;
1208
1209                                                for (int i = 0; i < length; i++) {
1210                                                        if (timestampAsBytes[offset + i] == '-') {
1211                                                                hasDash = true;
1212                                                                break;
1213                                                        }
1214                                                }
1215
1216                                                if ((this.metadata[columnIndex].getMysqlType() == MysqlDefs.FIELD_TYPE_DATE)
1217                                                                || hasDash) {
1218                                                        year = StringUtils.getInt(timestampAsBytes,
1219                                                                        offset + 0, offset + 4);
1220                                                        month = StringUtils.getInt(timestampAsBytes,
1221                                                                        offset + 5, offset + 7);
1222                                                        day = StringUtils.getInt(timestampAsBytes,
1223                                                                        offset + 8, offset + 10);
1224                                                        hour = 0;
1225                                                        minutes = 0;
1226                                                } else {
1227                                                        year = StringUtils.getInt(timestampAsBytes,
1228                                                                        offset + 0, offset + 2);
1229
1230                                                        if (year <= 69) {
1231                                                                year = (year + 100);
1232                                                        }
1233
1234                                                        month = StringUtils.getInt(timestampAsBytes,
1235                                                                        offset + 2, offset + 4);
1236                                                        day = StringUtils.getInt(timestampAsBytes,
1237                                                                        offset + 4, offset + 6);
1238                                                        hour = StringUtils.getInt(timestampAsBytes,
1239                                                                        offset + 6, offset + 8);
1240                                                        minutes = StringUtils.getInt(timestampAsBytes,
1241                                                                        offset + 8, offset + 10);
1242
1243                                                        year += 1900; // two-digit year
1244                                                }
1245
1246                                                break;
1247                                        }
1248
1249                                        case 8: {
1250                                                boolean hasColon = false;
1251
1252                                                for (int i = 0; i < length; i++) {
1253                                                        if (timestampAsBytes[offset + i] == ':') {
1254                                                                hasColon = true;
1255                                                                break;
1256                                                        }
1257                                                }
1258
1259                                                if (hasColon) {
1260                                                        hour = StringUtils.getInt(timestampAsBytes,
1261                                                                        offset + 0, offset + 2);
1262                                                        minutes = StringUtils.getInt(timestampAsBytes,
1263                                                                        offset + 3, offset + 5);
1264                                                        seconds = StringUtils.getInt(timestampAsBytes,
1265                                                                        offset + 6, offset + 8);
1266                                                       
1267                                                        year = 1970;
1268                                                        month = 1;
1269                                                        day = 1;
1270
1271                                                        break;
1272                                                }
1273
1274                                                year = StringUtils.getInt(timestampAsBytes,
1275                                                                offset + 0, offset + 4);
1276                                                month = StringUtils.getInt(timestampAsBytes,
1277                                                                offset + 4, offset + 6);
1278                                                day = StringUtils.getInt(timestampAsBytes,
1279                                                                offset + 6, offset + 8);
1280
1281                                                year -= 1900;
1282                                                month--;
1283                                               
1284                                                break;
1285                                        }
1286
1287                                        case 6: {
1288                                                year = StringUtils.getInt(timestampAsBytes,
1289                                                                offset + 0, offset + 2);
1290
1291                                                if (year <= 69) {
1292                                                        year = (year + 100);
1293                                                }
1294
1295                                                year += 1900;
1296                                               
1297                                                month = StringUtils.getInt(timestampAsBytes,
1298                                                                offset + 2, offset + 4);
1299                                                day = StringUtils.getInt(timestampAsBytes,
1300                                                                offset + 4, offset + 6);
1301
1302                                                break;
1303                                        }
1304
1305                                        case 4: {
1306                                                year = StringUtils.getInt(timestampAsBytes,
1307                                                                offset + 0, offset + 2);
1308
1309                                                if (year <= 69) {
1310                                                        year = (year + 100);
1311                                                }
1312
1313                                                month = StringUtils.getInt(timestampAsBytes,
1314                                                                offset + 2, offset + 4);
1315                                               
1316                                                day = 1;
1317                                               
1318                                                break;
1319                                        }
1320
1321                                        case 2: {
1322                                                year = StringUtils.getInt(timestampAsBytes,
1323                                                                offset + 0, offset + 2);
1324
1325                                                if (year <= 69) {
1326                                                        year = (year + 100);
1327                                                }
1328
1329                                                year += 1900;
1330                                                month = 1;
1331                                                day = 1;
1332                                               
1333                                                break;
1334                                        }
1335
1336                                        default:
1337                                                throw new java.sql.SQLException(
1338                                                                "Bad format for Timestamp '"
1339                                                                                + StringUtils.toString(timestampAsBytes)
1340                                                                                + "' in column " + (columnIndex + 1)
1341                                                                                + ".",
1342                                                                SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
1343                                        }
1344                                       
1345                                        if (!rs.useLegacyDatetimeCode) {
1346                                                return TimeUtil.fastTimestampCreate(tz,
1347                                                                year, month,
1348                                                                day, hour, minutes, seconds,
1349                                                                nanos);
1350                                        }
1351                                               
1352                                        return TimeUtil
1353                                                        .changeTimezone(conn, sessionCalendar,
1354                                                                        targetCalendar, rs.fastTimestampCreate(
1355                                                                                        sessionCalendar, year, month,
1356                                                                                        day, hour, minutes, seconds,
1357                                                                                        nanos), conn
1358                                                                                        .getServerTimezoneTZ(), tz,
1359                                                                        rollForward);
1360                                }
1361                        }
1362                } catch (RuntimeException e) {
1363                        SQLException sqlEx = SQLError.createSQLException("Cannot convert value '"
1364                                        + getString(columnIndex, "ISO8859_1", conn)
1365                                        + "' from column " + (columnIndex + 1) + " to TIMESTAMP.",
1366                                        SQLError.SQL_STATE_ILLEGAL_ARGUMENT, this.exceptionInterceptor);
1367                        sqlEx.initCause(e);
1368                       
1369                        throw sqlEx;
1370                }
1371        }
1372
1373        public abstract Timestamp getTimestampFast(int columnIndex,
1374                        Calendar targetCalendar, TimeZone tz, boolean rollForward,
1375                        MySQLConnection conn, ResultSetImpl rs) throws SQLException;
1376
1377        /**
1378         * Could the column value at the given index (which starts at 0) be
1379         * interpreted as a floating-point number (has +/-/E/e in it)?
1380         *
1381         * @param index
1382         *            of the column value (starting at 0) to check.
1383         *
1384         * @return true if the column value at the given index looks like it might
1385         *         be a floating-point number, false if not.
1386         *
1387         * @throws SQLException
1388         *             if an error occurs
1389         */
1390        public abstract boolean isFloatingPointNumber(int index)
1391                        throws SQLException;
1392
1393        /**
1394         * Is the column value at the given index (which starts at 0) NULL?
1395         *
1396         * @param index
1397         *            of the column value (starting at 0) to check.
1398         *
1399         * @return true if the column value is NULL, false if not.
1400         *
1401         * @throws SQLException
1402         *             if an error occurs
1403         */
1404        public abstract boolean isNull(int index) throws SQLException;
1405
1406        /**
1407         * Returns the length of the column at the given index (which starts at 0).
1408         *
1409         * @param index
1410         *            of the column value (starting at 0) for which to return the
1411         *            length.
1412         * @return the length of the requested column, 0 if null (clients of this
1413         *         interface should use isNull() beforehand to determine status of
1414         *         NULL values in the column).
1415         *
1416         * @throws SQLException
1417         */
1418        public abstract long length(int index) throws SQLException;
1419
1420        /**
1421         * Sets the given column value (only works currently with
1422         * ByteArrayRowHolder).
1423         *
1424         * @param index
1425         *            index of the column value (starting at 0) to set.
1426         * @param value
1427         *            the (raw) value to set
1428         *
1429         * @throws SQLException
1430         *             if an error occurs, or the concrete RowHolder doesn't support
1431         *             this operation.
1432         */
1433        public abstract void setColumnValue(int index, byte[] value)
1434                        throws SQLException;
1435
1436        public ResultSetRow setMetadata(Field[] f) throws SQLException {
1437                this.metadata = f;
1438               
1439                return this;
1440        }
1441       
1442        public abstract int getBytesSize();
1443}
Note: See TracBrowser for help on using the repository browser.