Added:
branches/branch_5_1/connector-j/src/com/mysql/jdbc/configs/5-0-Compat.properties
Modified:
branches/branch_5_1/connector-j/src/com/mysql/jdbc/BufferRowHolder.java
branches/branch_5_1/connector-j/src/com/mysql/jdbc/ByteArrayRowHolder.java
branches/branch_5_1/connector-j/src/com/mysql/jdbc/ConnectionProperties.java
branches/branch_5_1/connector-j/src/com/mysql/jdbc/ConnectionPropertiesImpl.java
branches/branch_5_1/connector-j/src/com/mysql/jdbc/MysqlIO.java
branches/branch_5_1/connector-j/src/com/mysql/jdbc/PreparedStatement.java
branches/branch_5_1/connector-j/src/com/mysql/jdbc/ResultSetImpl.java
branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowDataDynamic.java
branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowHolder.java
branches/branch_5_1/connector-j/src/com/mysql/jdbc/SingleByteCharsetConverter.java
branches/branch_5_1/connector-j/src/com/mysql/jdbc/StringUtils.java
branches/branch_5_1/connector-j/src/com/mysql/jdbc/configs/3-0-Compat.properties
Log:
Implementations of all "complex" types for result sets now represented in RowHolders.
Added "direct" row unpack (bypassing packet code) in MysqlIO.nextRow(), 2x speedup for
this method (doesn't equate to 2x speedup in the driver, but there is a performance
increase of around 5-10% for most use cases).
Modified: branches/branch_5_1/connector-j/src/com/mysql/jdbc/BufferRowHolder.java
===================================================================
--- branches/branch_5_1/connector-j/src/com/mysql/jdbc/BufferRowHolder.java 2007-06-07
15:40:36 UTC (rev 6448)
+++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/BufferRowHolder.java 2007-06-14
16:11:19 UTC (rev 6449)
@@ -22,10 +22,21 @@
*/
package com.mysql.jdbc;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+import java.sql.Date;
import java.sql.SQLException;
+import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.Calendar;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
import java.util.TimeZone;
/**
@@ -77,6 +88,8 @@
*/
private boolean[] isNull;
+ private List openStreams;
+
public BufferRowHolder(Buffer buf, Field[] fields, boolean isBinaryEncoded)
throws SQLException {
this.rowFromServer = buf;
@@ -89,147 +102,28 @@
}
}
- public void setMetadata(Field[] f) throws SQLException {
- super.setMetadata(f);
+ public synchronized void closeOpenStreams() {
+ if (this.openStreams != null) {
+ // This would've looked slicker in a "for" loop
+ // but we want to skip over streams that fail to
+ // close (they probably won't ever)
+ // to be more robust and close everything we _can_
- if (this.isBinaryEncoded) {
- setupIsNullBitmask();
- }
- }
+ Iterator iter = this.openStreams.iterator();
- /**
- * Unpacks the bitmask at the head of the row packet that tells us what
- * columns hold null values, and sets the "home" position directly after the
- * bitmask.
- */
- private void setupIsNullBitmask() throws SQLException {
- int nullCount = (this.metadata.length + 9) / 8;
+ while (iter.hasNext()) {
- byte[] nullBitMask = new byte[nullCount];
-
- for (int i = 0; i < nullCount; i++) {
- nullBitMask[i] = this.rowFromServer.readByte();
- }
-
- this.homePosition = this.rowFromServer.getPosition();
-
- this.isNull = new boolean[this.metadata.length];
-
- int nullMaskPos = 0;
- int bit = 4; // first two bits are reserved for future use
-
- for (int i = 0; i < this.metadata.length; i++) {
-
- this.isNull[i] = ((nullBitMask[nullMaskPos] & bit) != 0);
-
- if (((bit <<= 1) & 255) == 0) {
- bit = 1; /* To next byte */
-
- nullMaskPos++;
+ try {
+ ((InputStream) iter.next()).close();
+ } catch (IOException e) {
+ // ignore - it can't really happen in this case
+ }
}
- }
- }
- public byte[] getColumnValue(int index) throws SQLException {
- findAndSeekToOffset(index);
-
- if (!this.isBinaryEncoded) {
- return this.rowFromServer.readLenByteArray(0);
+ this.openStreams.clear();
}
-
- if (this.isNull[index]) {
- return null;
- }
-
- switch (this.metadata[index].getMysqlType()) {
- case MysqlDefs.FIELD_TYPE_NULL:
- return null;
-
- case MysqlDefs.FIELD_TYPE_TINY:
- return new byte[] { this.rowFromServer.readByte() };
-
- case MysqlDefs.FIELD_TYPE_SHORT:
- case MysqlDefs.FIELD_TYPE_YEAR:
- return this.rowFromServer.getBytes(2);
-
- case MysqlDefs.FIELD_TYPE_LONG:
- case MysqlDefs.FIELD_TYPE_INT24:
- return this.rowFromServer.getBytes(4);
-
- case MysqlDefs.FIELD_TYPE_LONGLONG:
- return this.rowFromServer.getBytes(8);
-
- case MysqlDefs.FIELD_TYPE_FLOAT:
- return this.rowFromServer.getBytes(4);
-
- case MysqlDefs.FIELD_TYPE_DOUBLE:
- return this.rowFromServer.getBytes(8);
-
- case MysqlDefs.FIELD_TYPE_TIME:
- case MysqlDefs.FIELD_TYPE_DATE:
- case MysqlDefs.FIELD_TYPE_DATETIME:
- case MysqlDefs.FIELD_TYPE_TIMESTAMP:
- case MysqlDefs.FIELD_TYPE_TINY_BLOB:
- case MysqlDefs.FIELD_TYPE_MEDIUM_BLOB:
- case MysqlDefs.FIELD_TYPE_LONG_BLOB:
- case MysqlDefs.FIELD_TYPE_BLOB:
- case MysqlDefs.FIELD_TYPE_VAR_STRING:
- case MysqlDefs.FIELD_TYPE_VARCHAR:
- case MysqlDefs.FIELD_TYPE_STRING:
- case MysqlDefs.FIELD_TYPE_DECIMAL:
- case MysqlDefs.FIELD_TYPE_NEW_DECIMAL:
- case MysqlDefs.FIELD_TYPE_GEOMETRY:
- case MysqlDefs.FIELD_TYPE_BIT:
- return this.rowFromServer.readLenByteArray(0);
-
- default:
- throw SQLError.createSQLException(Messages.getString("MysqlIO.97") //$NON-NLS-1$
- + this.metadata[index].getMysqlType()
- + Messages.getString("MysqlIO.98")
- + (index + 1)
- + Messages.getString("MysqlIO.99") //$NON-NLS-1$ //$NON-NLS-2$
- + this.metadata.length + Messages.getString("MysqlIO.100"), //$NON-NLS-1$
- SQLError.SQL_STATE_GENERAL_ERROR);
- }
}
- public String getString(int index, String encoding, ConnectionImpl conn)
- throws SQLException {
- findAndSeekToOffset(index);
-
- long length = this.rowFromServer.readFieldLength();
-
- if (length == Buffer.NULL_LENGTH) {
- return null;
- }
-
- if (length == 0) {
- return "";
- }
-
- // TODO: I don't like this, would like to push functionality back
- // to the buffer class somehow
-
- int offset = this.rowFromServer.getPosition();
-
- return getString(encoding, conn, this.rowFromServer.getByteBuffer(),
- offset, (int) length);
- }
-
- public boolean isNull(int index) throws SQLException {
- if (!this.isBinaryEncoded) {
- findAndSeekToOffset(index);
-
- return this.rowFromServer.readFieldLength() == Buffer.NULL_LENGTH;
- }
-
- return this.isNull[index];
- }
-
- public void setColumnValue(int index, byte[] value) throws SQLException {
- throw new OperationNotSupportedException();
- }
-
private int findAndSeekToOffset(int index) throws SQLException {
if (!this.isBinaryEncoded) {
@@ -379,52 +273,87 @@
return this.lastRequestedPos;
}
- public boolean isFloatingPointNumber(int index) throws SQLException {
- if (this.isBinaryEncoded) {
- switch (this.metadata[index].getSQLType()) {
- case Types.FLOAT:
- case Types.DOUBLE:
- case Types.DECIMAL:
- case Types.NUMERIC:
- return true;
- default:
- return false;
- }
- }
+ public synchronized InputStream getBinaryInputStream(int columnIndex)
+ throws SQLException {
+ int offset = findAndSeekToOffset(columnIndex);
- findAndSeekToOffset(index);
-
long length = this.rowFromServer.readFieldLength();
if (length == Buffer.NULL_LENGTH) {
- return false;
+ return null;
}
- if (length == 0) {
- return false;
- }
+ InputStream stream = new ByteArrayInputStream(this.rowFromServer
+ .getByteBuffer(), offset, (int) length);
- for (int i = 0; i < (int) length; i++) {
- char c = (char) this.rowFromServer.readByte();
-
- if ((c == 'e') || (c == 'E')) {
- return true;
- }
+ if (this.openStreams == null) {
+ this.openStreams = new LinkedList();
}
- return false;
+ return stream;
}
- public long length(int index) throws SQLException {
+ public byte[] getColumnValue(int index) throws SQLException {
findAndSeekToOffset(index);
- long length = this.rowFromServer.readFieldLength();
+ if (!this.isBinaryEncoded) {
+ return this.rowFromServer.readLenByteArray(0);
+ }
- if (length == Buffer.NULL_LENGTH) {
- return 0;
+ if (this.isNull[index]) {
+ return null;
}
- return length;
+ switch (this.metadata[index].getMysqlType()) {
+ case MysqlDefs.FIELD_TYPE_NULL:
+ return null;
+
+ case MysqlDefs.FIELD_TYPE_TINY:
+ return new byte[] { this.rowFromServer.readByte() };
+
+ case MysqlDefs.FIELD_TYPE_SHORT:
+ case MysqlDefs.FIELD_TYPE_YEAR:
+ return this.rowFromServer.getBytes(2);
+
+ case MysqlDefs.FIELD_TYPE_LONG:
+ case MysqlDefs.FIELD_TYPE_INT24:
+ return this.rowFromServer.getBytes(4);
+
+ case MysqlDefs.FIELD_TYPE_LONGLONG:
+ return this.rowFromServer.getBytes(8);
+
+ case MysqlDefs.FIELD_TYPE_FLOAT:
+ return this.rowFromServer.getBytes(4);
+
+ case MysqlDefs.FIELD_TYPE_DOUBLE:
+ return this.rowFromServer.getBytes(8);
+
+ case MysqlDefs.FIELD_TYPE_TIME:
+ case MysqlDefs.FIELD_TYPE_DATE:
+ case MysqlDefs.FIELD_TYPE_DATETIME:
+ case MysqlDefs.FIELD_TYPE_TIMESTAMP:
+ case MysqlDefs.FIELD_TYPE_TINY_BLOB:
+ case MysqlDefs.FIELD_TYPE_MEDIUM_BLOB:
+ case MysqlDefs.FIELD_TYPE_LONG_BLOB:
+ case MysqlDefs.FIELD_TYPE_BLOB:
+ case MysqlDefs.FIELD_TYPE_VAR_STRING:
+ case MysqlDefs.FIELD_TYPE_VARCHAR:
+ case MysqlDefs.FIELD_TYPE_STRING:
+ case MysqlDefs.FIELD_TYPE_DECIMAL:
+ case MysqlDefs.FIELD_TYPE_NEW_DECIMAL:
+ case MysqlDefs.FIELD_TYPE_GEOMETRY:
+ case MysqlDefs.FIELD_TYPE_BIT:
+ return this.rowFromServer.readLenByteArray(0);
+
+ default:
+ throw SQLError.createSQLException(Messages.getString("MysqlIO.97") //$NON-NLS-1$
+ + this.metadata[index].getMysqlType()
+ + Messages.getString("MysqlIO.98")
+ + (index + 1)
+ + Messages.getString("MysqlIO.99") //$NON-NLS-1$ //$NON-NLS-2$
+ + this.metadata.length + Messages.getString("MysqlIO.100"), //$NON-NLS-1$
+ SQLError.SQL_STATE_GENERAL_ERROR);
+ }
}
public int getInt(int columnIndex) throws SQLException {
@@ -442,8 +371,6 @@
}
public long getLong(int columnIndex) throws SQLException {
- // TODO: Server-side prepared statements
-
int offset = findAndSeekToOffset(columnIndex);
long length = this.rowFromServer.readFieldLength();
@@ -456,22 +383,6 @@
offset + (int) length);
}
- public Timestamp getTimestampFast(int columnIndex, ConnectionImpl conn,
- ResultSetImpl rs, Calendar targetCalendar, TimeZone tz,
- boolean rollForward) throws SQLException {
- if (isNull(columnIndex)) {
- return null;
- }
-
- int offset = findAndSeekToOffset(columnIndex);
-
- int length = (int) this.rowFromServer.readFieldLength();
-
- return getTimestampFast(this.rowFromServer.getByteBuffer(),
- columnIndex, conn, rs, targetCalendar, tz, rollForward, offset,
- length);
- }
-
public double getNativeDouble(int columnIndex) throws SQLException {
int offset = findAndSeekToOffset(columnIndex);
@@ -546,4 +457,240 @@
return getNativeTimestamp(this.rowFromServer.getByteBuffer(), offset,
(int) length, targetCalendar, tz, rollForward, conn, rs);
}
+
+ public Reader getReader(int columnIndex) throws SQLException {
+ InputStream stream = getBinaryInputStream(columnIndex);
+
+ if (stream == null) {
+ return null;
+ }
+
+ try {
+ return new InputStreamReader(stream, this.metadata[columnIndex]
+ .getCharacterSet());
+ } catch (UnsupportedEncodingException e) {
+ SQLException sqlEx = SQLError.createSQLException("");
+
+ sqlEx.initCause(e);
+
+ throw sqlEx;
+ }
+ }
+
+ public String getString(int index, String encoding, ConnectionImpl conn)
+ throws SQLException {
+ findAndSeekToOffset(index);
+
+ long length = this.rowFromServer.readFieldLength();
+
+ if (length == Buffer.NULL_LENGTH) {
+ return null;
+ }
+
+ if (length == 0) {
+ return "";
+ }
+
+ // TODO: I don't like this, would like to push functionality back
+ // to the buffer class somehow
+
+ int offset = this.rowFromServer.getPosition();
+
+ return getString(encoding, conn, this.rowFromServer.getByteBuffer(),
+ offset, (int) length);
+ }
+
+ public Time getTimeFast(int columnIndex, Calendar targetCalendar,
+ TimeZone tz, boolean rollForward, ConnectionImpl conn,
+ ResultSetImpl rs) throws SQLException {
+ if (isNull(columnIndex)) {
+ return null;
+ }
+
+ int offset = findAndSeekToOffset(columnIndex);
+
+ int length = (int) this.rowFromServer.readFieldLength();
+
+ return getTimeFast(columnIndex, this.rowFromServer.getByteBuffer(),
+ offset, length, targetCalendar, tz, rollForward, conn, rs);
+ }
+
+ public Timestamp getTimestampFast(int columnIndex, Calendar targetCalendar,
+ TimeZone tz, boolean rollForward, ConnectionImpl conn,
+ ResultSetImpl rs) throws SQLException {
+ if (isNull(columnIndex)) {
+ return null;
+ }
+
+ int offset = findAndSeekToOffset(columnIndex);
+
+ int length = (int) this.rowFromServer.readFieldLength();
+
+ return getTimestampFast(columnIndex,
+ this.rowFromServer.getByteBuffer(), offset, length, targetCalendar, tz,
+ rollForward, conn, rs);
+ }
+
+ public boolean isFloatingPointNumber(int index) throws SQLException {
+ if (this.isBinaryEncoded) {
+ switch (this.metadata[index].getSQLType()) {
+ case Types.FLOAT:
+ case Types.DOUBLE:
+ case Types.DECIMAL:
+ case Types.NUMERIC:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ findAndSeekToOffset(index);
+
+ long length = this.rowFromServer.readFieldLength();
+
+ if (length == Buffer.NULL_LENGTH) {
+ return false;
+ }
+
+ if (length == 0) {
+ return false;
+ }
+
+ for (int i = 0; i < (int) length; i++) {
+ char c = (char) this.rowFromServer.readByte();
+
+ if ((c == 'e') || (c == 'E')) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public boolean isNull(int index) throws SQLException {
+ if (!this.isBinaryEncoded) {
+ findAndSeekToOffset(index);
+
+ return this.rowFromServer.readFieldLength() == Buffer.NULL_LENGTH;
+ }
+
+ return this.isNull[index];
+ }
+
+ public long length(int index) throws SQLException {
+ findAndSeekToOffset(index);
+
+ long length = this.rowFromServer.readFieldLength();
+
+ if (length == Buffer.NULL_LENGTH) {
+ return 0;
+ }
+
+ return length;
+ }
+
+ public void setColumnValue(int index, byte[] value) throws SQLException {
+ throw new OperationNotSupportedException();
+ }
+
+ public void setMetadata(Field[] f) throws SQLException {
+ super.setMetadata(f);
+
+ if (this.isBinaryEncoded) {
+ setupIsNullBitmask();
+ }
+ }
+
+ /**
+ * Unpacks the bitmask at the head of the row packet that tells us what
+ * columns hold null values, and sets the "home" position directly after the
+ * bitmask.
+ */
+ private void setupIsNullBitmask() throws SQLException {
+ int nullCount = (this.metadata.length + 9) / 8;
+
+ byte[] nullBitMask = new byte[nullCount];
+
+ for (int i = 0; i < nullCount; i++) {
+ nullBitMask[i] = this.rowFromServer.readByte();
+ }
+
+ this.homePosition = this.rowFromServer.getPosition();
+
+ this.isNull = new boolean[this.metadata.length];
+
+ int nullMaskPos = 0;
+ int bit = 4; // first two bits are reserved for future use
+
+ for (int i = 0; i < this.metadata.length; i++) {
+
+ this.isNull[i] = ((nullBitMask[nullMaskPos] & bit) != 0);
+
+ if (((bit <<= 1) & 255) == 0) {
+ bit = 1; /* To next byte */
+
+ nullMaskPos++;
+ }
+ }
+ }
+
+ public Date getDateFast(int columnIndex, ConnectionImpl conn,
+ ResultSetImpl rs) throws SQLException {
+ if (isNull(columnIndex)) {
+ return null;
+ }
+
+ int offset = findAndSeekToOffset(columnIndex);
+
+ int length = (int) this.rowFromServer.readFieldLength();
+
+ return getDateFast(columnIndex, this.rowFromServer.getByteBuffer(),
+ offset, length, conn, rs);
+ }
+
+ public java.sql.Date getNativeDate(int columnIndex, ConnectionImpl conn,
+ ResultSetImpl rs) throws SQLException {
+ int offset = findAndSeekToOffset(columnIndex);
+
+ long length = this.rowFromServer.readFieldLength();
+
+ if (length == Buffer.NULL_LENGTH) {
+ return null;
+ }
+
+ return getNativeDate(columnIndex, this.rowFromServer.getByteBuffer(),
+ offset, (int) length, conn, rs);
+ }
+
+ public Object getNativeDateTimeValue(int columnIndex, Calendar targetCalendar,
+ int jdbcType, int mysqlType, TimeZone tz,
+ boolean rollForward, ConnectionImpl conn, ResultSetImpl rs)
+ throws SQLException {
+ int offset = findAndSeekToOffset(columnIndex);
+
+ long length = this.rowFromServer.readFieldLength();
+
+ if (length == Buffer.NULL_LENGTH) {
+ return null;
+ }
+
+ return getNativeDateTimeValue(columnIndex, this.rowFromServer
+ .getByteBuffer(), offset, (int) length, targetCalendar, jdbcType,
+ mysqlType, tz, rollForward, conn, rs);
+ }
+
+ public Time getNativeTime(int columnIndex, Calendar targetCalendar,
+ TimeZone tz, boolean rollForward, ConnectionImpl conn,
+ ResultSetImpl rs) throws SQLException {
+ int offset = findAndSeekToOffset(columnIndex);
+
+ long length = this.rowFromServer.readFieldLength();
+
+ if (length == Buffer.NULL_LENGTH) {
+ return null;
+ }
+
+ return getNativeTime(columnIndex, this.rowFromServer.getByteBuffer(),
+ offset, (int) length, targetCalendar, tz, rollForward, conn, rs);
+ }
}
\ No newline at end of file
Modified: branches/branch_5_1/connector-j/src/com/mysql/jdbc/ByteArrayRowHolder.java
===================================================================
--- branches/branch_5_1/connector-j/src/com/mysql/jdbc/ByteArrayRowHolder.java 2007-06-07
15:40:36 UTC (rev 6448)
+++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/ByteArrayRowHolder.java 2007-06-14
16:11:19 UTC (rev 6449)
@@ -22,7 +22,14 @@
*/
package com.mysql.jdbc;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+import java.sql.Date;
import java.sql.SQLException;
+import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.TimeZone;
@@ -105,18 +112,18 @@
return StringUtils.getLong(this.internalRowData[columnIndex]);
}
- public Timestamp getTimestampFast(int columnIndex, ConnectionImpl conn,
- ResultSetImpl rs, Calendar targetCalendar, TimeZone tz,
- boolean rollForward) throws SQLException {
+ public Timestamp getTimestampFast(int columnIndex, Calendar targetCalendar,
+ TimeZone tz, boolean rollForward, ConnectionImpl conn,
+ ResultSetImpl rs) throws SQLException {
byte[] columnValue = this.internalRowData[columnIndex];
if (columnValue == null) {
return null;
}
- return getTimestampFast(this.internalRowData[columnIndex], columnIndex,
- conn, rs, targetCalendar, tz, rollForward, 0,
- columnValue.length);
+ return getTimestampFast(columnIndex, this.internalRowData[columnIndex],
+ 0, columnValue.length, targetCalendar, tz, rollForward, conn,
+ rs);
}
public double getNativeDouble(int columnIndex) throws SQLException {
@@ -171,4 +178,101 @@
return getNativeTimestamp(bits, 0, bits.length, targetCalendar, tz,
rollForward, conn, rs);
}
+
+ public void closeOpenStreams() {
+ // no-op for this type
+ }
+
+ public InputStream getBinaryInputStream(int columnIndex)
+ throws SQLException {
+ if (this.internalRowData[columnIndex] == null) {
+ return null;
+ }
+
+ return new ByteArrayInputStream(this.internalRowData[columnIndex]);
+ }
+
+ public Reader getReader(int columnIndex) throws SQLException {
+ InputStream stream = getBinaryInputStream(columnIndex);
+
+ if (stream == null) {
+ return null;
+ }
+
+ try {
+ return new InputStreamReader(stream, this.metadata[columnIndex]
+ .getCharacterSet());
+ } catch (UnsupportedEncodingException e) {
+ SQLException sqlEx = SQLError.createSQLException("");
+
+ sqlEx.initCause(e);
+
+ throw sqlEx;
+ }
+ }
+
+ public Time getTimeFast(int columnIndex, Calendar targetCalendar,
+ TimeZone tz, boolean rollForward, ConnectionImpl conn,
+ ResultSetImpl rs) throws SQLException {
+ byte[] columnValue = this.internalRowData[columnIndex];
+
+ if (columnValue == null) {
+ return null;
+ }
+
+ return getTimeFast(columnIndex, this.internalRowData[columnIndex], 0,
+ columnValue.length, targetCalendar, tz, rollForward, conn, rs);
+ }
+
+ public Date getDateFast(int columnIndex, ConnectionImpl conn,
+ ResultSetImpl rs) throws SQLException {
+ byte[] columnValue = this.internalRowData[columnIndex];
+
+ if (columnValue == null) {
+ return null;
+ }
+
+ return getDateFast(columnIndex, this.internalRowData[columnIndex], 0,
+ columnValue.length, conn, rs);
+ }
+
+ public Object getNativeDateTimeValue(int columnIndex, Calendar targetCalendar,
+ int jdbcType, int mysqlType, TimeZone tz,
+ boolean rollForward, ConnectionImpl conn, ResultSetImpl rs)
+ throws SQLException {
+ byte[] columnValue = this.internalRowData[columnIndex];
+
+ if (columnValue == null) {
+ return null;
+ }
+
+ return getNativeDateTimeValue(columnIndex, columnValue, 0,
+ columnValue.length, targetCalendar, jdbcType, mysqlType, tz,
+ rollForward, conn, rs);
+ }
+
+ public Date getNativeDate(int columnIndex, ConnectionImpl conn,
+ ResultSetImpl rs) throws SQLException {
+ byte[] columnValue = this.internalRowData[columnIndex];
+
+ if (columnValue == null) {
+ return null;
+ }
+
+ return getNativeDate(columnIndex, columnValue, 0, columnValue.length,
+ conn, rs);
+ }
+
+ public Time getNativeTime(int columnIndex, Calendar targetCalendar,
+ TimeZone tz, boolean rollForward, ConnectionImpl conn,
+ ResultSetImpl rs) throws SQLException {
+ byte[] columnValue = this.internalRowData[columnIndex];
+
+ if (columnValue == null) {
+ return null;
+ }
+
+ return getNativeTime(columnIndex, columnValue, 0, columnValue.length,
+ targetCalendar, tz, rollForward, conn, rs);
+ }
}
\ No newline at end of file
Modified: branches/branch_5_1/connector-j/src/com/mysql/jdbc/ConnectionProperties.java
===================================================================
---
branches/branch_5_1/connector-j/src/com/mysql/jdbc/ConnectionProperties.java 2007-06-07
15:40:36 UTC (rev 6448)
+++
branches/branch_5_1/connector-j/src/com/mysql/jdbc/ConnectionProperties.java 2007-06-14
16:11:19 UTC (rev 6449)
@@ -1511,4 +1511,8 @@
public abstract String getStatementInterceptors();
public abstract void setStatementInterceptors(String value);
+
+ public abstract boolean getUseDirectRowUnpack();
+
+ public abstract void setUseDirectRowUnpack(boolean flag);
}
\ No newline at end of file
Modified: branches/branch_5_1/connector-j/src/com/mysql/jdbc/ConnectionPropertiesImpl.java
===================================================================
---
branches/branch_5_1/connector-j/src/com/mysql/jdbc/ConnectionPropertiesImpl.java 2007-06-07
15:40:36 UTC (rev 6448)
+++
branches/branch_5_1/connector-j/src/com/mysql/jdbc/ConnectionPropertiesImpl.java 2007-06-14
16:11:19 UTC (rev 6449)
@@ -1365,6 +1365,12 @@
Messages.getString("ConnectionProperties.useDynamicCharsetInfo") //$NON-NLS-1$
, "5.0.6", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); //$NON-NLS-1$
+ private BooleanConnectionProperty useDirectRowUnpack = new BooleanConnectionProperty(
+ "useDirectRowUnpack",
+ true, "Use newer result set row unpacking code that skips a copy from network buffers
"
+ + " to a MySQL packet instance and instead reads directly into the result set row data
buffers.",
+ "5.1.1", PERFORMANCE_CATEGORY, Integer.MIN_VALUE);
+
private BooleanConnectionProperty useFastIntParsing = new BooleanConnectionProperty(
"useFastIntParsing", //$NON-NLS-1$
true,
@@ -4126,4 +4132,12 @@
public void setStatementInterceptors(String value) {
this.statementInterceptors.setValue(value);
}
+
+ public boolean getUseDirectRowUnpack() {
+ return this.useDirectRowUnpack.getValueAsBoolean();
+ }
+
+ public void setUseDirectRowUnpack(boolean flag) {
+ this.useDirectRowUnpack.setValue(flag);
+ }
}
Modified: branches/branch_5_1/connector-j/src/com/mysql/jdbc/MysqlIO.java
===================================================================
--- branches/branch_5_1/connector-j/src/com/mysql/jdbc/MysqlIO.java 2007-06-07 15:40:36
UTC (rev 6448)
+++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/MysqlIO.java 2007-06-14 16:11:19
UTC (rev 6449)
@@ -229,6 +229,7 @@
private long slowQueryThreshold;
private String queryTimingUnits;
private List statementInterceptors;
+ private boolean useDirectRowUnpack = true;
/**
* Constructor: Connect to the MySQL server and setup a stream connection.
@@ -253,6 +254,8 @@
this.packetDebugRingBuffer = new LinkedList();
}
+ this.useDirectRowUnpack = this.connection.getUseDirectRowUnpack();
+
this.logSlowQueries = this.connection.getLogSlowQueries();
this.reusablePacket = new Buffer(INITIAL_PACKET_SIZE);
@@ -412,6 +415,7 @@
skipPacket();
}
}
+
packet = reuseAndReadPacket(this.reusablePacket);
readServerStatusForResultSets(packet);
@@ -1371,11 +1375,29 @@
final RowHolder nextRow(Field[] fields, int columnCount,
boolean isBinaryEncoded, int resultSetConcurrency,
boolean useBufferRowHolderIfPossible,
- boolean reuseRowPacket)
+ boolean reuseRowPacket,
+ Buffer existingRowPacket)
throws SQLException {
- // Get the next incoming packet, re-using the packet because
- // all the data we need gets copied out of it.
- Buffer rowPacket = checkErrorPacket();
+
+ if (this.useDirectRowUnpack && existingRowPacket == null
+ && !isBinaryEncoded && !useBufferRowHolderIfPossible
+ && reuseRowPacket) {
+ return nextRowFast(fields, columnCount, isBinaryEncoded, resultSetConcurrency,
+ useBufferRowHolderIfPossible, reuseRowPacket);
+ }
+
+ Buffer rowPacket = null;
+
+ if (existingRowPacket == null) {
+ // Get the next incoming packet, re-using the packet because
+ // all the data we need gets copied out of it.
+ rowPacket = checkErrorPacket();
+ } else {
+ // We attempted to do nextRowFast(), but the packet was a
+ // multipacket, so we couldn't unpack it directly
+ rowPacket = existingRowPacket;
+ checkErrorPacket(existingRowPacket);
+ }
if (!isBinaryEncoded) {
//
@@ -1433,7 +1455,148 @@
return null;
}
+
+ final RowHolder nextRowFast(Field[] fields, int columnCount,
+ boolean isBinaryEncoded, int resultSetConcurrency,
+ boolean useBufferRowHolderIfPossible,
+ boolean reuseRowPacket)
+ throws SQLException {
+ try {
+ int lengthRead = readFully(this.mysqlInput, this.packetHeaderBuf,
+ 0, 4);
+ if (lengthRead < 4) {
+ forceClose();
+ throw new RuntimeException(Messages.getString("MysqlIO.43")); //$NON-NLS-1$
+ }
+
+ int packetLength = (this.packetHeaderBuf[0] & 0xff)
+ + ((this.packetHeaderBuf[1] & 0xff) << 8)
+ + ((this.packetHeaderBuf[2] & 0xff) << 16);
+
+ // Have we stumbled upon a multi-packet?
+ if (packetLength == this.maxThreeBytes) {
+ reuseAndReadPacket(this.reusablePacket, packetLength);
+
+ // Go back to "old" way which uses packets
+ return nextRow(fields, columnCount, isBinaryEncoded, resultSetConcurrency,
+ useBufferRowHolderIfPossible, reuseRowPacket, this.reusablePacket);
+ }
+
+ int remaining = packetLength;
+
+ boolean firstTime = true;
+
+ byte[][] rowData = null;
+
+ for (int i = 0; i < columnCount; i++) {
+
+ int sw = this.mysqlInput.read() & 0xff;
+ remaining--;
+
+ if (firstTime) {
+ if (sw == 255) {
+ // error packet
+ Buffer errorPacket = new Buffer(packetLength);
+ errorPacket.writeByte((byte)sw);
+ readFully(this.mysqlInput, errorPacket.getByteBuffer(), 1, packetLength - 1);
+
+ checkErrorPacket(errorPacket);
+ }
+
+ if (sw == 254 && packetLength < 9) {
+ this.warningCount = (this.mysqlInput.read() & 0xff)
+ | ((this.mysqlInput.read() & 0xff) << 8);
+ remaining -= 2;
+
+ if (this.warningCount > 0) {
+ this.hadWarnings = true; // this is a 'latch', it's reset by
sendCommand()
+ }
+
+ this.serverStatus = (this.mysqlInput.read() & 0xff)
+ | ((this.mysqlInput.read() & 0xff) << 8);
+ remaining -= 2;
+
+ if (remaining > 0) {
+ skipFully(this.mysqlInput, remaining);
+ }
+
+ return null; // last data packet
+ }
+
+ rowData = new byte[columnCount][];
+
+ firstTime = false;
+ }
+
+ int len = 0;
+
+ switch (sw) {
+ case 251:
+ len = NULL_LENGTH;
+ break;
+
+ case 252:
+ len = (this.mysqlInput.read() & 0xff)
+ | ((this.mysqlInput.read() & 0xff) << 8);
+ remaining -= 2;
+ break;
+
+ case 253:
+ len = (this.mysqlInput.read() & 0xff)
+ | ((this.mysqlInput.read() & 0xff) << 8)
+ | ((this.mysqlInput.read() & 0xff) << 16);
+
+ remaining -= 3;
+ break;
+
+ case 254:
+ len = (int) ((this.mysqlInput.read() & 0xff)
+ | ((long) (this.mysqlInput.read() & 0xff) << 8)
+ | ((long) (this.mysqlInput.read() & 0xff) << 16)
+ | ((long) (this.mysqlInput.read() & 0xff) << 24)
+ | ((long) (this.mysqlInput.read() & 0xff) << 32)
+ | ((long) (this.mysqlInput.read() & 0xff) << 40)
+ | ((long) (this.mysqlInput.read() & 0xff) << 48)
+ | ((long) (this.mysqlInput.read() & 0xff) << 56));
+ remaining -= 8;
+ break;
+
+ default:
+ len = sw;
+ }
+
+ if (len == NULL_LENGTH) {
+ rowData[i] = null;
+ } else if (len == 0) {
+ rowData[i] = Constants.EMPTY_BYTE_ARRAY;
+ } else {
+ rowData[i] = new byte[len];
+
+ int bytesRead = readFully(this.mysqlInput, rowData[i], 0,
+ len);
+
+ if (bytesRead != len) {
+ throw SQLError.createCommunicationsException(this.connection,
+ this.lastPacketSentTimeMs,
+ new IOException(Messages.getString("MysqlIO.43")));
+ }
+
+ remaining -= bytesRead;
+ }
+ }
+
+ if (remaining > 0) {
+ skipFully(this.mysqlInput, remaining);
+ }
+
+ return new ByteArrayRowHolder(rowData);
+ } catch (IOException ioEx) {
+ throw SQLError.createCommunicationsException(this.connection,
+ this.lastPacketSentTimeMs, ioEx);
+ }
+ }
+
/**
* Log-off of the MySQL server and close the socket.
*
@@ -2509,7 +2672,7 @@
// Now read the data
Object rowBytes = nextRow(fields, (int) columnCount, isBinaryEncoded,
- resultSetConcurrency, false, true);
+ resultSetConcurrency, false, true, null);
int rowCount = 0;
@@ -2520,7 +2683,7 @@
while (rowBytes != null) {
rowBytes = nextRow(fields, (int) columnCount, isBinaryEncoded,
- resultSetConcurrency, false, true);
+ resultSetConcurrency, false, true, null);
if (rowBytes != null) {
if ((maxRows == -1) || (rowCount < maxRows)) {
@@ -2555,24 +2718,33 @@
* @throws SQLException DOCUMENT ME!
* @throws SQLException DOCUMENT ME!
*/
- private final Buffer reuseAndReadPacket(Buffer reuse)
+ private final Buffer reuseAndReadPacket(Buffer reuse) throws SQLException {
+ return reuseAndReadPacket(reuse, -1);
+ }
+
+ private final Buffer reuseAndReadPacket(Buffer reuse, int existingPacketLength)
throws SQLException {
try {
reuse.setWasMultiPacket(false);
+ int packetLength = 0;
- int lengthRead = readFully(this.mysqlInput,
- this.packetHeaderBuf, 0, 4);
-
- if (lengthRead < 4) {
- forceClose();
- throw new IOException(Messages.getString("MysqlIO.43")); //$NON-NLS-1$
+ if (existingPacketLength == -1) {
+ int lengthRead = readFully(this.mysqlInput,
+ this.packetHeaderBuf, 0, 4);
+
+ if (lengthRead < 4) {
+ forceClose();
+ throw new IOException(Messages.getString("MysqlIO.43")); //$NON-NLS-1$
+ }
+
+ packetLength = (this.packetHeaderBuf[0] & 0xff) +
+ ((this.packetHeaderBuf[1] & 0xff) << 8) +
+ ((this.packetHeaderBuf[2] & 0xff) << 16);
+ } else {
+ packetLength = existingPacketLength;
}
- int packetLength = (this.packetHeaderBuf[0] & 0xff) +
- ((this.packetHeaderBuf[1] & 0xff) << 8) +
- ((this.packetHeaderBuf[2] & 0xff) << 16);
-
if (this.traceProtocol) {
StringBuffer traceMessageBuf = new StringBuffer();
@@ -2647,123 +2819,8 @@
// it's multi-packet
isMultiPacket = true;
- lengthRead = readFully(this.mysqlInput,
- this.packetHeaderBuf, 0, 4);
-
- if (lengthRead < 4) {
- forceClose();
- throw new IOException(Messages.getString("MysqlIO.47")); //$NON-NLS-1$
- }
-
- packetLength = (this.packetHeaderBuf[0] & 0xff) +
- ((this.packetHeaderBuf[1] & 0xff) << 8) +
- ((this.packetHeaderBuf[2] & 0xff) << 16);
-
- Buffer multiPacket = new Buffer(packetLength);
- boolean firstMultiPkt = true;
-
- while (true) {
- if (!firstMultiPkt) {
- lengthRead = readFully(this.mysqlInput,
- this.packetHeaderBuf, 0, 4);
-
- if (lengthRead < 4) {
- forceClose();
- throw new IOException(Messages.getString(
- "MysqlIO.48")); //$NON-NLS-1$
- }
-
- packetLength = (this.packetHeaderBuf[0] & 0xff) +
- ((this.packetHeaderBuf[1] & 0xff) << 8) +
- ((this.packetHeaderBuf[2] & 0xff) << 16);
- } else {
- firstMultiPkt = false;
- }
-
- if (!this.useNewLargePackets && (packetLength == 1)) {
- clearInputStream();
-
- break;
- } else if (packetLength < this.maxThreeBytes) {
- byte newPacketSeq = this.packetHeaderBuf[3];
-
- if (newPacketSeq != (multiPacketSeq + 1)) {
- throw new IOException(Messages.getString(
- "MysqlIO.49")); //$NON-NLS-1$
- }
-
- multiPacketSeq = newPacketSeq;
-
- // Set the Buffer to it's original state
- multiPacket.setPosition(0);
-
- // Set the new length
- multiPacket.setBufLength(packetLength);
-
- // Read the data from the server
- byte[] byteBuf = multiPacket.getByteBuffer();
- int lengthToWrite = packetLength;
-
- int bytesRead = readFully(this.mysqlInput, byteBuf,
- 0, packetLength);
-
- if (bytesRead != lengthToWrite) {
- throw SQLError.createCommunicationsException(this.connection,
- this.lastPacketSentTimeMs,
- SQLError.createSQLException(Messages.getString(
- "MysqlIO.50") //$NON-NLS-1$
- +lengthToWrite +
- Messages.getString("MysqlIO.51") +
- bytesRead //$NON-NLS-1$
- +".")); //$NON-NLS-1$
- }
-
- reuse.writeBytesNoNull(byteBuf, 0, lengthToWrite);
-
- packetEndPoint += lengthToWrite;
-
- break; // end of multipacket sequence
- }
-
- byte newPacketSeq = this.packetHeaderBuf[3];
-
- if (newPacketSeq != (multiPacketSeq + 1)) {
- throw new IOException(Messages.getString(
- "MysqlIO.53")); //$NON-NLS-1$
- }
-
- multiPacketSeq = newPacketSeq;
-
- // Set the Buffer to it's original state
- multiPacket.setPosition(0);
-
- // Set the new length
- multiPacket.setBufLength(packetLength);
-
- // Read the data from the server
- byte[] byteBuf = multiPacket.getByteBuffer();
- int lengthToWrite = packetLength;
-
- int bytesRead = readFully(this.mysqlInput, byteBuf, 0,
- packetLength);
-
- if (bytesRead != lengthToWrite) {
- throw SQLError.createCommunicationsException(this.connection,
- this.lastPacketSentTimeMs,
- SQLError.createSQLException(Messages.getString(
- "MysqlIO.54") //$NON-NLS-1$
- +lengthToWrite +
- Messages.getString("MysqlIO.55") //$NON-NLS-1$
- +bytesRead + ".")); //$NON-NLS-1$
- }
-
- reuse.writeBytesNoNull(byteBuf, 0, lengthToWrite);
-
- packetEndPoint += lengthToWrite;
- }
-
- reuse.setPosition(0);
- reuse.setWasMultiPacket(true);
+ packetLength = readRemainingMultiPackets(reuse, multiPacketSeq,
+ packetEndPoint);
}
if (!isMultiPacket) {
@@ -2789,6 +2846,130 @@
}
+ private int readRemainingMultiPackets(Buffer reuse, byte multiPacketSeq,
+ int packetEndPoint) throws IOException, SQLException {
+ int lengthRead;
+ int packetLength;
+ lengthRead = readFully(this.mysqlInput,
+ this.packetHeaderBuf, 0, 4);
+
+ if (lengthRead < 4) {
+ forceClose();
+ throw new IOException(Messages.getString("MysqlIO.47")); //$NON-NLS-1$
+ }
+
+ packetLength = (this.packetHeaderBuf[0] & 0xff) +
+ ((this.packetHeaderBuf[1] & 0xff) << 8) +
+ ((this.packetHeaderBuf[2] & 0xff) << 16);
+
+ Buffer multiPacket = new Buffer(packetLength);
+ boolean firstMultiPkt = true;
+
+ while (true) {
+ if (!firstMultiPkt) {
+ lengthRead = readFully(this.mysqlInput,
+ this.packetHeaderBuf, 0, 4);
+
+ if (lengthRead < 4) {
+ forceClose();
+ throw new IOException(Messages.getString(
+ "MysqlIO.48")); //$NON-NLS-1$
+ }
+
+ packetLength = (this.packetHeaderBuf[0] & 0xff) +
+ ((this.packetHeaderBuf[1] & 0xff) << 8) +
+ ((this.packetHeaderBuf[2] & 0xff) << 16);
+ } else {
+ firstMultiPkt = false;
+ }
+
+ if (!this.useNewLargePackets && (packetLength == 1)) {
+ clearInputStream();
+
+ break;
+ } else if (packetLength < this.maxThreeBytes) {
+ byte newPacketSeq = this.packetHeaderBuf[3];
+
+ if (newPacketSeq != (multiPacketSeq + 1)) {
+ throw new IOException(Messages.getString(
+ "MysqlIO.49")); //$NON-NLS-1$
+ }
+
+ multiPacketSeq = newPacketSeq;
+
+ // Set the Buffer to it's original state
+ multiPacket.setPosition(0);
+
+ // Set the new length
+ multiPacket.setBufLength(packetLength);
+
+ // Read the data from the server
+ byte[] byteBuf = multiPacket.getByteBuffer();
+ int lengthToWrite = packetLength;
+
+ int bytesRead = readFully(this.mysqlInput, byteBuf,
+ 0, packetLength);
+
+ if (bytesRead != lengthToWrite) {
+ throw SQLError.createCommunicationsException(this.connection,
+ this.lastPacketSentTimeMs,
+ SQLError.createSQLException(Messages.getString(
+ "MysqlIO.50") //$NON-NLS-1$
+ +lengthToWrite +
+ Messages.getString("MysqlIO.51") +
+ bytesRead //$NON-NLS-1$
+ +".")); //$NON-NLS-1$
+ }
+
+ reuse.writeBytesNoNull(byteBuf, 0, lengthToWrite);
+
+ packetEndPoint += lengthToWrite;
+
+ break; // end of multipacket sequence
+ }
+
+ byte newPacketSeq = this.packetHeaderBuf[3];
+
+ if (newPacketSeq != (multiPacketSeq + 1)) {
+ throw new IOException(Messages.getString(
+ "MysqlIO.53")); //$NON-NLS-1$
+ }
+
+ multiPacketSeq = newPacketSeq;
+
+ // Set the Buffer to it's original state
+ multiPacket.setPosition(0);
+
+ // Set the new length
+ multiPacket.setBufLength(packetLength);
+
+ // Read the data from the server
+ byte[] byteBuf = multiPacket.getByteBuffer();
+ int lengthToWrite = packetLength;
+
+ int bytesRead = readFully(this.mysqlInput, byteBuf, 0,
+ packetLength);
+
+ if (bytesRead != lengthToWrite) {
+ throw SQLError.createCommunicationsException(this.connection,
+ this.lastPacketSentTimeMs,
+ SQLError.createSQLException(Messages.getString(
+ "MysqlIO.54") //$NON-NLS-1$
+ +lengthToWrite +
+ Messages.getString("MysqlIO.55") //$NON-NLS-1$
+ +bytesRead + ".")); //$NON-NLS-1$
+ }
+
+ reuse.writeBytesNoNull(byteBuf, 0, lengthToWrite);
+
+ packetEndPoint += lengthToWrite;
+ }
+
+ reuse.setPosition(0);
+ reuse.setWasMultiPacket(true);
+ return packetLength;
+ }
+
/**
* @param multiPacketSeq
* @throws CommunicationsException
@@ -3061,7 +3242,6 @@
// exception chain and let someone higher up decide
// what to do (barf, reconnect, etc).
resultPacket = reuseAndReadPacket(this.reusablePacket);
- statusCode = resultPacket.readByte();
} catch (SQLException sqlEx) {
// Don't wrap SQL Exceptions
throw sqlEx;
@@ -3070,6 +3250,15 @@
this.lastPacketSentTimeMs, fallThru);
}
+ checkErrorPacket(resultPacket);
+
+ return resultPacket;
+ }
+
+ private void checkErrorPacket(Buffer resultPacket) throws SQLException {
+
+ int statusCode = resultPacket.readByte();
+
// Error handling
if (statusCode == (byte) 0xff) {
String serverErrorMessage;
@@ -3152,8 +3341,6 @@
SQLError.SQL_STATE_GENERAL_ERROR) + ", " //$NON-NLS-1$
+errorBuf.toString(), SQLError.SQL_STATE_GENERAL_ERROR, -1);
}
-
- return resultPacket;
}
/**
@@ -4137,7 +4324,7 @@
RowHolder row = null;
while ((row = nextRow(columnTypes, columnTypes.length, true,
- ResultSet.CONCUR_READ_ONLY, false, true)) != null) {
+ ResultSet.CONCUR_READ_ONLY, false, true, null)) != null) {
fetchedRows.add(row);
}
Modified: branches/branch_5_1/connector-j/src/com/mysql/jdbc/PreparedStatement.java
===================================================================
--- branches/branch_5_1/connector-j/src/com/mysql/jdbc/PreparedStatement.java 2007-06-07
15:40:36 UTC (rev 6448)
+++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/PreparedStatement.java 2007-06-14
16:11:19 UTC (rev 6449)
@@ -2236,7 +2236,7 @@
this.streamLengths = new int[this.parameterCount];
this.isNull = new boolean[this.parameterCount];
this.parameterTypes = new int[this.parameterCount];
-
+
clearParameters();
for (int j = 0; j < this.parameterCount; j++) {
@@ -3603,53 +3603,9 @@
if (this.connection.isNoBackslashEscapesSet()) {
// Scan for any nasty chars
- boolean needsHexEscape = false;
+ boolean needsHexEscape = isEscapeNeededForString(x,
+ stringLength);
- for (int i = 0; i < stringLength; ++i) {
- char c = x.charAt(i);
-
- switch (c) {
- case 0: /* Must be escaped for 'mysql' */
-
- needsHexEscape = true;
- break;
-
- case '\n': /* Must be escaped for logs */
- needsHexEscape = true;
-
- break;
-
- case '\r':
- needsHexEscape = true;
- break;
-
- case '\\':
- needsHexEscape = true;
-
- break;
-
- case '\'':
- needsHexEscape = true;
-
- break;
-
- case '"': /* Better safe than sorry */
- needsHexEscape = true;
-
- break;
-
- case '\032': /* This gives problems on Win32 */
- needsHexEscape = true;
- break;
- }
-
- if (needsHexEscape) {
- break; // no need to scan more
- }
- }
-
-
-
if (!needsHexEscape) {
byte[] parameterAsBytes = null;
@@ -3688,90 +3644,153 @@
return;
}
- StringBuffer buf = new StringBuffer((int) (x.length() * 1.1));
- buf.append('\'');
+ String parameterAsString = x;
+ boolean needsQuoted = true;
+
+ if (this.isLoadDataQuery || isEscapeNeededForString(x, stringLength)) {
+ needsQuoted = false; // saves an allocation later
+
+ StringBuffer buf = new StringBuffer((int) (x.length() * 1.1));
+
+ buf.append('\'');
+
+ //
+ // Note: buf.append(char) is _faster_ than
+ // appending in blocks, because the block
+ // append requires a System.arraycopy()....
+ // go figure...
+ //
+
+ for (int i = 0; i < stringLength; ++i) {
+ char c = x.charAt(i);
+
+ switch (c) {
+ case 0: /* Must be escaped for 'mysql' */
+ buf.append('\\');
+ buf.append('0');
+
+ break;
+
+ case '\n': /* Must be escaped for logs */
+ buf.append('\\');
+ buf.append('n');
+
+ break;
+
+ case '\r':
+ buf.append('\\');
+ buf.append('r');
+
+ break;
+
+ case '\\':
+ buf.append('\\');
+ buf.append('\\');
+
+ break;
+
+ case '\'':
+ buf.append('\\');
+ buf.append('\'');
+
+ break;
+
+ case '"': /* Better safe than sorry */
+ if (this.usingAnsiMode) {
+ buf.append('\\');
+ }
+
+ buf.append('"');
+
+ break;
+
+ case '\032': /* This gives problems on Win32 */
+ buf.append('\\');
+ buf.append('Z');
+
+ break;
+
+ default:
+ buf.append(c);
+ }
+ }
+
+ buf.append('\'');
+
+ parameterAsString = buf.toString();
+ }
- //
- // Note: buf.append(char) is _faster_ than
- // appending in blocks, because the block
- // append requires a System.arraycopy()....
- // go figure...
- //
+ byte[] parameterAsBytes = null;
- for (int i = 0; i < stringLength; ++i) {
- char c = x.charAt(i);
+ if (!this.isLoadDataQuery) {
+ if (needsQuoted) {
+ parameterAsBytes = StringUtils.getBytesWrapped(parameterAsString,
+ '\'', '\'', this.charConverter, this.charEncoding, this.connection
+ .getServerCharacterEncoding(), this.connection
+ .parserKnowsUnicode());
+ } else {
+ parameterAsBytes = StringUtils.getBytes(parameterAsString,
+ this.charConverter, this.charEncoding, this.connection
+ .getServerCharacterEncoding(), this.connection
+ .parserKnowsUnicode());
+ }
+ } else {
+ // Send with platform character encoding
+ parameterAsBytes = parameterAsString.getBytes();
+ }
- switch (c) {
- case 0: /* Must be escaped for 'mysql' */
- buf.append('\\');
- buf.append('0');
+ setInternal(parameterIndex, parameterAsBytes);
+
+ this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = Types.VARCHAR;
+ }
+ }
- break;
+ private boolean isEscapeNeededForString(String x, int stringLength) {
+ boolean needsHexEscape = false;
- case '\n': /* Must be escaped for logs */
- buf.append('\\');
- buf.append('n');
+ for (int i = 0; i < stringLength; ++i) {
+ char c = x.charAt(i);
- break;
+ switch (c) {
+ case 0: /* Must be escaped for 'mysql' */
- case '\r':
- buf.append('\\');
- buf.append('r');
+ needsHexEscape = true;
+ break;
- break;
+ case '\n': /* Must be escaped for logs */
+ needsHexEscape = true;
- case '\\':
- buf.append('\\');
- buf.append('\\');
+ break;
- break;
+ case '\r':
+ needsHexEscape = true;
+ break;
- case '\'':
- buf.append('\\');
- buf.append('\'');
+ case '\\':
+ needsHexEscape = true;
- break;
+ break;
- case '"': /* Better safe than sorry */
- if (this.usingAnsiMode) {
- buf.append('\\');
- }
+ case '\'':
+ needsHexEscape = true;
- buf.append('"');
+ break;
- break;
+ case '"': /* Better safe than sorry */
+ needsHexEscape = true;
- case '\032': /* This gives problems on Win32 */
- buf.append('\\');
- buf.append('Z');
+ break;
- break;
-
- default:
- buf.append(c);
- }
+ case '\032': /* This gives problems on Win32 */
+ needsHexEscape = true;
+ break;
}
- buf.append('\'');
-
- String parameterAsString = buf.toString();
-
- byte[] parameterAsBytes = null;
-
- if (!this.isLoadDataQuery) {
- parameterAsBytes = StringUtils.getBytes(parameterAsString,
- this.charConverter, this.charEncoding, this.connection
- .getServerCharacterEncoding(), this.connection
- .parserKnowsUnicode());
- } else {
- // Send with platform character encoding
- parameterAsBytes = parameterAsString.getBytes();
+ if (needsHexEscape) {
+ break; // no need to scan more
}
-
- setInternal(parameterIndex, parameterAsBytes);
-
- this.parameterTypes[parameterIndex - 1 + getParameterIndexOffset()] = Types.VARCHAR;
}
+ return needsHexEscape;
}
/**
Modified: branches/branch_5_1/connector-j/src/com/mysql/jdbc/ResultSetImpl.java
===================================================================
--- branches/branch_5_1/connector-j/src/com/mysql/jdbc/ResultSetImpl.java 2007-06-07
15:40:36 UTC (rev 6448)
+++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/ResultSetImpl.java 2007-06-14
16:11:19 UTC (rev 6449)
@@ -1434,13 +1434,19 @@
checkRowPos();
if (!this.isBinaryEncoded) {
- byte[] b = getBytes(columnIndex);
-
- if (b != null) {
- return new ByteArrayInputStream(b);
+ checkColumnBounds(columnIndex);
+
+ int columnIndexMinusOne = columnIndex - 1;
+
+ if (this.thisRow.isNull(columnIndexMinusOne)) {
+ this.wasNullFlag = true;
+
+ return null;
}
-
- return null;
+
+ this.wasNullFlag = false;
+
+ return this.thisRow.getBinaryInputStream(columnIndexMinusOne);
}
return getNativeBinaryStream(columnIndex);
@@ -1860,13 +1866,19 @@
public java.io.Reader getCharacterStream(int columnIndex)
throws SQLException {
if (!this.isBinaryEncoded) {
- String asString = getStringForClob(columnIndex);
-
- if (asString == null) {
+ checkColumnBounds(columnIndex);
+
+ int columnIndexMinusOne = columnIndex - 1;
+
+ if (this.thisRow.isNull(columnIndexMinusOne)) {
+ this.wasNullFlag = true;
+
return null;
}
-
- return new StringReader(asString);
+
+ this.wasNullFlag = false;
+
+ return this.thisRow.getReader(columnIndexMinusOne);
}
return getNativeCharacterStream(columnIndex);
@@ -2036,11 +2048,21 @@
}
return getDateFromString(stringVal, columnIndex);
- } else {
- checkColumnBounds(columnIndex);
+ }
+
+ checkColumnBounds(columnIndex);
+
+ int columnIndexMinusOne = columnIndex - 1;
+
+ if (this.thisRow.isNull(columnIndexMinusOne)) {
+ this.wasNullFlag = true;
- return getDateFromBytes((byte[])this.thisRow.getColumnValue(columnIndex - 1),
columnIndex);
+ return null;
}
+
+ this.wasNullFlag = false;
+
+ return this.thisRow.getDateFast(columnIndexMinusOne, this.connection, this);
}
/**
@@ -2242,181 +2264,6 @@
SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
}
}
-
- private final java.sql.Date getDateFromBytes(byte[] dateAsBytes,
- int columnIndex) throws SQLException {
- checkColumnBounds(columnIndex);
-
- int year = 0;
- int month = 0;
- int day = 0;
-
- try {
- this.wasNullFlag = false;
-
- if (dateAsBytes == null) {
- this.wasNullFlag = true;
-
- return null;
- }
-
-
- boolean allZeroDate = true;
-
- boolean onlyTimePresent = StringUtils.indexOf(dateAsBytes, ':') != -1;
-
- int length = dateAsBytes.length;
-
- for (int i = 0; i < length; i++) {
- byte b = dateAsBytes[i];
-
- if (b == ' ' || b == '-' || b == '/') {
- onlyTimePresent = false;
- }
-
- if (b != '0' && b != ' ' && b != ':' && b != '-' && b
!= '/'
- && b != '.') {
- allZeroDate = false;
-
- break;
- }
- }
-
- if (!onlyTimePresent && allZeroDate) {
-
- if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
- .equals(this.connection.getZeroDateTimeBehavior())) {
- this.wasNullFlag = true;
-
- return null;
- } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
- .equals(this.connection.getZeroDateTimeBehavior())) {
- throw SQLError.createSQLException("Value '" + new String(dateAsBytes)
- + "' can not be represented as java.sql.Date",
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
- }
-
- // We're left with the case of 'round' to a date Java _can_
- // represent, which is '0001-01-01'.
- return fastDateCreate(null, 1, 1, 1);
-
- } else if (this.fields[columnIndex - 1].getMysqlType() ==
MysqlDefs.FIELD_TYPE_TIMESTAMP) {
- // Convert from TIMESTAMP
- switch (length) {
- case 21:
- case 19: { // java.sql.Timestamp format
- year = StringUtils.getInt(dateAsBytes, 0, 4);
- month = StringUtils.getInt(dateAsBytes, 5, 7);
- day = StringUtils.getInt(dateAsBytes, 8, 10);
-
- return fastDateCreate(null, year, month, day);
- }
-
- case 14:
- case 8: {
- year = StringUtils.getInt(dateAsBytes, 0, 4);
- month = StringUtils.getInt(dateAsBytes, 4, 6);
- day = StringUtils.getInt(dateAsBytes, 6, 8);
-
- return fastDateCreate(null, year, month, day);
- }
-
- case 12:
- case 10:
- case 6: {
- year = StringUtils.getInt(dateAsBytes, 0, 2);
-
- if (year <= 69) {
- year = year + 100;
- }
-
- month = StringUtils.getInt(dateAsBytes, 2, 4);
- day = StringUtils.getInt(dateAsBytes, 4, 6);
-
- return fastDateCreate(null, year + 1900, month, day);
- }
-
- case 4: {
- year = StringUtils.getInt(dateAsBytes, 0, 4);
-
- if (year <= 69) {
- year = year + 100;
- }
-
- month = StringUtils.getInt(dateAsBytes, 2, 4);
-
- return fastDateCreate(null, year + 1900, month, 1);
- }
-
- case 2: {
- year = StringUtils.getInt(dateAsBytes, 0, 2);
-
- if (year <= 69) {
- year = year + 100;
- }
-
- return fastDateCreate(null, year + 1900, 1, 1);
- }
-
- default:
- throw SQLError.createSQLException(Messages.getString(
- "ResultSet.Bad_format_for_Date", new Object[] {
- new String(dateAsBytes), Constants.integerValueOf(columnIndex) }),
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
- } /* endswitch */
- } else if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_YEAR) {
-
- if (length == 2 || length == 1) {
- year = StringUtils.getInt(dateAsBytes);
-
- if (year <= 69) {
- year = year + 100;
- }
-
- year += 1900;
- } else {
- year = StringUtils.getInt(dateAsBytes, 0, 4);
- }
-
- return fastDateCreate(null, year, 1, 1);
- } else if (this.fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_TIME) {
- return fastDateCreate(null, 1970, 1, 1); // Return EPOCH
- } else {
- if (length < 10) {
- if (length == 8) {
- return fastDateCreate(null, 1970, 1, 1); // Return EPOCH for TIME
- }
-
- throw SQLError.createSQLException(Messages.getString(
- "ResultSet.Bad_format_for_Date", new Object[] {
- new String(dateAsBytes), Constants.integerValueOf(columnIndex) }),
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
- }
-
- if (length != 18) {
- year = StringUtils.getInt(dateAsBytes, 0, 4);
- month = StringUtils.getInt(dateAsBytes, 5, 7);
- day = StringUtils.getInt(dateAsBytes, 8, 10);
- } else {
- // JDK-1.3 timestamp format, not real easy to parse positionally :p
- StringTokenizer st = new StringTokenizer(new String(dateAsBytes), "- ");
-
- year = Integer.parseInt(st.nextToken());
- month = Integer.parseInt(st.nextToken());
- day = Integer.parseInt(st.nextToken());
- }
- }
-
- return fastDateCreate(null, year, month, day);
- } catch (SQLException sqlEx) {
- throw sqlEx; // don't re-wrap
- } catch (Exception e) {
- throw SQLError.createSQLException(Messages.getString(
- "ResultSet.Bad_format_for_Date", new Object[] { new String(dateAsBytes),
- Constants.integerValueOf(columnIndex) }),
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
- }
- }
private TimeZone getDefaultTimeZone() {
return this.connection.getDefaultTimeZone();
@@ -3226,6 +3073,25 @@
throws SQLException {
checkRowPos();
+ int columnIndexMinusOne = columnIndex - 1;
+
+ if (this.thisRow.isNull(columnIndexMinusOne)) {
+ this.wasNullFlag = true;
+
+ return null;
+ }
+
+ this.wasNullFlag = false;
+
+ switch (this.fields[columnIndexMinusOne].getSQLType()) {
+ case Types.BIT:
+ case Types.BINARY:
+ case Types.VARBINARY:
+ case Types.BLOB:
+ case Types.LONGVARBINARY:
+ return this.thisRow.getBinaryInputStream(columnIndexMinusOne);
+ }
+
byte[] b = getNativeBytes(columnIndex, false);
if (b != null) {
@@ -3539,6 +3405,24 @@
*/
protected java.io.Reader getNativeCharacterStream(int columnIndex)
throws SQLException {
+ int columnIndexMinusOne = columnIndex - 1;
+
+ switch (this.fields[columnIndexMinusOne].getSQLType()) {
+ case Types.CHAR:
+ case Types.VARCHAR:
+ case Types.LONGVARCHAR:
+ case Types.CLOB:
+ if (this.thisRow.isNull(columnIndexMinusOne)) {
+ this.wasNullFlag = true;
+
+ return null;
+ }
+
+ this.wasNullFlag = false;
+
+ return this.thisRow.getReader(columnIndexMinusOne);
+ }
+
String asString = null;
asString = getStringForClob(columnIndex);
@@ -3546,6 +3430,7 @@
if (asString == null) {
return null;
}
+
return getCharacterStreamFromString(asString, columnIndex);
}
@@ -3859,65 +3744,45 @@
checkRowPos();
checkColumnBounds(columnIndex);
- int mysqlType = this.fields[columnIndex - 1].getMysqlType();
+ int columnIndexMinusOne = columnIndex - 1;
+ int mysqlType = this.fields[columnIndexMinusOne].getMysqlType();
+
+ java.sql.Date dateToReturn = null;
+
if (mysqlType == MysqlDefs.FIELD_TYPE_DATE) {
- byte[] bits = (byte[]) this.thisRow.getColumnValue(columnIndex - 1);
- if (bits == null) {
- this.wasNullFlag = true;
+ dateToReturn = this.thisRow.getNativeDate(columnIndexMinusOne,
+ this.connection, this);
+ } else {
- return null;
- }
+ boolean rollForward = (tz != null && !tz.equals(this.getDefaultTimeZone()));
+
+ dateToReturn = (Date) this.thisRow.getNativeDateTimeValue(columnIndexMinusOne,
+ null, Types.DATE, mysqlType, tz, rollForward, this.connection,
+ this);
+ }
+
+ //
+ // normally, we allow ResultSetImpl methods to check for null first,
+ // but with DATETIME values we have this wacky need to support
+ // 0000-00-00 00:00:00 -> NULL, so we have to defer
+ // to the RowHolder implementation, and check the return value.
+ //
- this.wasNullFlag = false;
+ if (dateToReturn == null) {
- java.sql.Date dateToReturn = null;
+ this.wasNullFlag = true;
- int year = 0;
- int month = 0;
- int day = 0;
-
- int hour = 0;
- int minute = 0;
- int seconds = 0;
-
- if (bits.length != 0) {
- year = (bits[0] & 0xff) | ((bits[1] & 0xff) << 8);
-
- month = bits[2];
- day = bits[3];
- }
-
- if ((year == 0) && (month == 0) && (day == 0)) {
- if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
- .equals(this.connection.getZeroDateTimeBehavior())) {
- this.wasNullFlag = true;
-
- return null;
- } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
- .equals(this.connection.getZeroDateTimeBehavior())) {
- throw SQLError.createSQLException(
- "Value '0000-00-00' can not be represented as java.sql.Date",
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
- }
-
- year = 1;
- month = 1;
- day = 1;
- }
-
- return fastDateCreate(
- getCalendarInstanceForSessionOrNew(), year, month, day);
+ return null;
}
- boolean rollForward = (tz != null && !tz.equals(this.getDefaultTimeZone()));
+ this.wasNullFlag = false;
- return (Date)getNativeDateTimeValue(columnIndex, null, Types.DATE, mysqlType,
- tz, rollForward);
+ return dateToReturn;
}
- private java.sql.Date getNativeDateViaParseConversion(int columnIndex) throws
SQLException {
+ java.sql.Date getNativeDateViaParseConversion(int columnIndex) throws SQLException {
if (this.useUsageAdvisor) {
issueConversionViaParsingWarning("getDate()", columnIndex,
this.thisRow.getColumnValue(columnIndex - 1), this.fields[columnIndex - 1],
@@ -4602,58 +4467,42 @@
checkRowPos();
checkColumnBounds(columnIndex);
- Object value = this.thisRow.getColumnValue(columnIndex - 1);
+ int columnIndexMinusOne = columnIndex - 1;
- if (value == null) {
- this.wasNullFlag = true;
+ int mysqlType = this.fields[columnIndexMinusOne].getMysqlType();
- return null;
+ Time timeVal = null;
+
+ if (mysqlType == MysqlDefs.FIELD_TYPE_TIME) {
+ timeVal = this.thisRow.getNativeTime(columnIndexMinusOne,
+ targetCalendar, tz, rollForward, this.connection, this);
+
} else {
- this.wasNullFlag = false;
+ timeVal = (Time) this.thisRow.getNativeDateTimeValue(columnIndexMinusOne,
+ null, Types.TIME, mysqlType, tz, rollForward, this.connection,
+ this);
}
+
+ //
+ // normally, we allow ResultSetImpl methods to check for null first,
+ // but with DATETIME values we have this wacky need to support
+ // 0000-00-00 00:00:00 -> NULL, so we have to defer
+ // to the RowHolder implementation, and check the return value.
+ //
- int mysqlType = this.fields[columnIndex - 1].getMysqlType();
+ if (timeVal == null) {
- if (mysqlType == MysqlDefs.FIELD_TYPE_TIME) {
+ this.wasNullFlag = true;
- byte[] bits = (byte[]) value;
-
- int length = bits.length;
- int hour = 0;
- int minute = 0;
- int seconds = 0;
-
- if (length != 0) {
- // bits[0] // skip tm->neg
- // binaryData.readLong(); // skip daysPart
- hour = bits[5];
- minute = bits[6];
- seconds = bits[7];
- }
-
- Calendar sessionCalendar = getCalendarInstanceForSessionOrNew();
-
- synchronized (sessionCalendar) {
- Time time = TimeUtil
- .fastTimeCreate(sessionCalendar, hour,
- minute, seconds);
-
- Time adjustedTime = TimeUtil.changeTimezone(this.connection,
- sessionCalendar,
- targetCalendar,
- time,
- this.connection.getServerTimezoneTZ(), tz, rollForward);
-
- return adjustedTime;
- }
+ return null;
}
- return (Time)getNativeDateTimeValue(columnIndex, targetCalendar,
- Types.TIME, mysqlType,
- tz, rollForward);
+ this.wasNullFlag = false;
+
+ return timeVal;
}
- private Time getNativeTimeViaParseConversion(int columnIndex, Calendar targetCalendar,
+ Time getNativeTimeViaParseConversion(int columnIndex, Calendar targetCalendar,
TimeZone tz, boolean rollForward) throws SQLException {
if (this.useUsageAdvisor) {
issueConversionViaParsingWarning("getTime()", columnIndex,
@@ -4673,32 +4522,47 @@
checkRowPos();
checkColumnBounds(columnIndex);
- Object value = this.thisRow.getColumnValue(columnIndex - 1);
+ int columnIndexMinusOne = columnIndex - 1;
- if (value == null) {
- this.wasNullFlag = true;
+ Timestamp tsVal = null;
- return null;
- }
+ int mysqlType = this.fields[columnIndexMinusOne].getMysqlType();
- this.wasNullFlag = false;
-
- int mysqlType = this.fields[columnIndex - 1].getMysqlType();
-
switch (mysqlType) {
case MysqlDefs.FIELD_TYPE_DATETIME:
case MysqlDefs.FIELD_TYPE_TIMESTAMP:
- return this.thisRow.getNativeTimestamp(columnIndex - 1,
+ tsVal = this.thisRow.getNativeTimestamp(columnIndexMinusOne,
targetCalendar, tz, rollForward, this.connection, this);
+ break;
default:
- return (Timestamp)getNativeDateTimeValue(columnIndex, targetCalendar,
- Types.TIMESTAMP, mysqlType,
- tz, rollForward);
+
+
+ tsVal = (Timestamp) this.thisRow.getNativeDateTimeValue(
+ columnIndexMinusOne, null, Types.TIMESTAMP, mysqlType, tz,
+ rollForward, this.connection, this);
}
+
+ //
+ // normally, we allow ResultSetImpl methods to check for null first,
+ // but with DATETIME values we have this wacky need to support
+ // 0000-00-00 00:00:00 -> NULL, so we have to defer
+ // to the RowHolder implementation, and check the return value.
+ //
+
+ if (tsVal == null) {
+
+ this.wasNullFlag = true;
+
+ return null;
+ }
+
+ this.wasNullFlag = false;
+
+ return tsVal;
}
- private Timestamp getNativeTimestampViaParseConversion(int columnIndex, Calendar
targetCalendar,
+ Timestamp getNativeTimestampViaParseConversion(int columnIndex, Calendar targetCalendar,
TimeZone tz, boolean rollForward) throws SQLException {
if (this.useUsageAdvisor) {
issueConversionViaParsingWarning("getTimestamp()", columnIndex,
@@ -5990,175 +5854,6 @@
SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
}
}
-
- private Time getTimeFromBytes(byte[] timeAsBytes, Calendar targetCalendar,
- int columnIndex,
- TimeZone tz,
- boolean rollForward) throws SQLException {
- checkColumnBounds(columnIndex);
-
- int hr = 0;
- int min = 0;
- int sec = 0;
-
- try {
-
- if (timeAsBytes == null) {
- this.wasNullFlag = true;
-
- return null;
- }
-
- int length = timeAsBytes.length;
-
- boolean allZeroTime = true;
- boolean onlyTimePresent = StringUtils.indexOf(timeAsBytes, ':') != -1;
-
- for (int i = 0; i < length; i++) {
- byte b = timeAsBytes[i];
-
- if (b == ' ' || b == '-' || b == '/') {
- onlyTimePresent = false;
- }
-
- if (b != '0' && b != ' ' && b != ':' && b != '-' && b
!= '/'
- && b != '.') {
- allZeroTime = false;
-
- break;
- }
- }
-
- if (!onlyTimePresent && allZeroTime) {
- if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
- .equals(this.connection.getZeroDateTimeBehavior())) {
- this.wasNullFlag = true;
-
- return null;
- } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
- .equals(this.connection.getZeroDateTimeBehavior())) {
- throw SQLError.createSQLException("Value '" + new String(timeAsBytes)
- + "' can not be represented as java.sql.Time",
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
- }
-
- // We're left with the case of 'round' to a time Java _can_
- // represent, which is '00:00:00'
- return fastTimeCreate(null, 0, 0, 0);
- }
-
- this.wasNullFlag = false;
-
- Field timeColField = this.fields[columnIndex - 1];
-
- if (timeColField.getMysqlType() == MysqlDefs.FIELD_TYPE_TIMESTAMP) {
-
- switch (length) {
- case 19: { // YYYY-MM-DD hh:mm:ss
-
- hr = StringUtils.getInt(timeAsBytes, length - 8,
- length - 6);
- min = StringUtils.getInt(timeAsBytes, length - 5,
- length - 3);
- sec = StringUtils.getInt(timeAsBytes, length - 2,
- length);
- }
-
- break;
- case 14:
- case 12: {
- hr = StringUtils.getInt(timeAsBytes, length - 6,
- length - 4);
- min = StringUtils.getInt(timeAsBytes, length - 4,
- length - 2);
- sec = StringUtils.getInt(timeAsBytes, length - 2,
- length);
- }
-
- break;
-
- case 10: {
- hr = StringUtils.getInt(timeAsBytes, 6, 8);
- min = StringUtils.getInt(timeAsBytes, 8, 10);
- sec = 0;
- }
-
- break;
-
- default:
- throw SQLError.createSQLException(
- Messages
- .getString("ResultSet.Timestamp_too_small_to_convert_to_Time_value_in_column__257")
//$NON-NLS-1$
- + columnIndex
- + "("
- + this.fields[columnIndex - 1] + ").",
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
- } /* endswitch */
-
- SQLWarning precisionLost = new SQLWarning(
- Messages
- .getString("ResultSet.Precision_lost_converting_TIMESTAMP_to_Time_with_getTime()_on_column__261")
//$NON-NLS-1$
- + columnIndex
- + "("
- + this.fields[columnIndex - 1] + ").");
-
- if (this.warningChain == null) {
- this.warningChain = precisionLost;
- } else {
- this.warningChain.setNextWarning(precisionLost);
- }
- } else if (timeColField.getMysqlType() == MysqlDefs.FIELD_TYPE_DATETIME) {
- hr = StringUtils.getInt(timeAsBytes, 11, 13);
- min = StringUtils.getInt(timeAsBytes, 14, 16);
- sec = StringUtils.getInt(timeAsBytes, 17, 19);
-
- SQLWarning precisionLost = new SQLWarning(
- Messages
- .getString("ResultSet.Precision_lost_converting_DATETIME_to_Time_with_getTime()_on_column__264")
//$NON-NLS-1$
- + columnIndex
- + "("
- + this.fields[columnIndex - 1] + ").");
-
- if (this.warningChain == null) {
- this.warningChain = precisionLost;
- } else {
- this.warningChain.setNextWarning(precisionLost);
- }
- } else if (timeColField.getMysqlType() == MysqlDefs.FIELD_TYPE_DATE) {
- return fastTimeCreate(null, 0, 0, 0); // midnight on the given
- // date
- } else {
- // convert a String to a Time
- if ((length != 5)
- && (length != 8)) {
- throw SQLError.createSQLException(Messages
- .getString("ResultSet.Bad_format_for_Time____267") //$NON-NLS-1$
- + new String(timeAsBytes)
- + Messages.getString("ResultSet.___in_column__268")
- + columnIndex, SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
- }
-
- hr = StringUtils.getInt(timeAsBytes, 0, 2);
- min = StringUtils.getInt(timeAsBytes, 3, 5);
- sec = (length == 5) ? 0 : StringUtils.getInt(timeAsBytes, 6, 8);
- }
-
- Calendar sessionCalendar = this.getCalendarInstanceForSessionOrNew();
-
- synchronized (sessionCalendar) {
- return TimeUtil.changeTimezone(this.connection,
- sessionCalendar,
- targetCalendar,
- fastTimeCreate(
- sessionCalendar, hr, min, sec),
- this.connection.getServerTimezoneTZ(),
- tz, rollForward);
- }
- } catch (Exception ex) {
- throw SQLError.createSQLException(ex.toString(),
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
- }
- }
/**
* Get the value of a column in the current row as a java.sql.Time object in
@@ -6186,12 +5881,22 @@
return getTimeFromString(timeAsString, targetCalendar,
columnIndex, tz, rollForward);
- } else {
- checkColumnBounds(columnIndex);
+ }
+
+ checkColumnBounds(columnIndex);
+
+ int columnIndexMinusOne = columnIndex - 1;
+
+ if (this.thisRow.isNull(columnIndexMinusOne)) {
+ this.wasNullFlag = true;
- return getTimeFromBytes((byte[])this.thisRow.getColumnValue(columnIndex - 1),
targetCalendar,
- columnIndex, tz, rollForward);
+ return null;
}
+
+ this.wasNullFlag = false;
+
+ return this.thisRow.getTimeFast(columnIndexMinusOne,
+ targetCalendar, tz, rollForward, this.connection, this);
}
/**
@@ -6882,16 +6587,26 @@
return getNativeTimestamp(columnIndex, targetCalendar, tz, rollForward);
}
+ Timestamp tsVal = null;
+
if (!this.useFastDateParsing) {
String timestampValue = getStringInternal(columnIndex, false);
- return getTimestampFromString(columnIndex, targetCalendar,
+ tsVal = getTimestampFromString(columnIndex, targetCalendar,
timestampValue, tz,
rollForward);
- }
+ } else {
+ tsVal = this.thisRow.getTimestampFast(columnIndex - 1,
+ targetCalendar, tz, rollForward, this.connection, this);
+ }
- return this.thisRow.getTimestampFast(columnIndex - 1,
- this.connection, this, targetCalendar, tz, rollForward);
+ if (tsVal == null) {
+ this.wasNullFlag = true;
+ } else {
+ this.wasNullFlag = false;
+ }
+
+ return tsVal;
}
/**
@@ -8924,176 +8639,4 @@
return this.gmtCalendar;
}
-
- private Object getNativeDateTimeValue(int columnIndex, Calendar targetCalendar,
- int jdbcType,
- int mysqlType, TimeZone tz, boolean rollForward)
- throws SQLException {
-
- int year = 0;
- int month = 0;
- int day = 0;
-
- int hour = 0;
- int minute = 0;
- int seconds = 0;
-
- int nanos = 0;
-
- byte[] bits = (byte[]) this.thisRow.getColumnValue(columnIndex - 1);
-
- if (bits == null) {
- this.wasNullFlag = true;
-
- return null;
- }
-
- Calendar sessionCalendar = this.connection.getUseJDBCCompliantTimezoneShift() ?
- this.connection.getUtcCalendar() :
- getCalendarInstanceForSessionOrNew();
-
- this.wasNullFlag = false;
-
- boolean populatedFromDateTimeValue = false;
-
- switch (mysqlType) {
- case MysqlDefs.FIELD_TYPE_DATETIME:
- case MysqlDefs.FIELD_TYPE_TIMESTAMP:
- populatedFromDateTimeValue = true;
-
- int length = bits.length;
-
- if (length != 0) {
- year = (bits[0] & 0xff) | ((bits[1] & 0xff) << 8);
- month = bits[2];
- day = bits[3];
-
- if (length > 4) {
- hour = bits[4];
- minute = bits[5];
- seconds = bits[6];
- }
-
- if (length > 7) {
- nanos = (bits[7] & 0xff) | ((bits[8] & 0xff) << 8)
- | ((bits[9] & 0xff) << 16)
- | ((bits[10] & 0xff) << 24);
- }
- }
-
- break;
- case MysqlDefs.FIELD_TYPE_DATE:
- populatedFromDateTimeValue = true;
-
- if (bits.length != 0) {
- year = (bits[0] & 0xff) | ((bits[1] & 0xff) << 8);
- month = bits[2];
- day = bits[3];
- }
-
- break;
- case MysqlDefs.FIELD_TYPE_TIME:
- populatedFromDateTimeValue = true;
-
- if (bits.length != 0) {
- // bits[0] // skip tm->neg
- // binaryData.readLong(); // skip daysPart
- hour = bits[5];
- minute = bits[6];
- seconds = bits[7];
- }
-
- year = 1970;
- month = 1;
- day = 1;
-
- break;
- default:
- populatedFromDateTimeValue = false;
- }
-
- switch (jdbcType) {
- case Types.TIME:
- if (populatedFromDateTimeValue) {
- Time time = TimeUtil.fastTimeCreate(
- getCalendarInstanceForSessionOrNew(), hour, minute,
- seconds);
-
- Time adjustedTime = TimeUtil.changeTimezone(this.connection,
- sessionCalendar,
- targetCalendar,
- time, this.connection.getServerTimezoneTZ(), tz,
- rollForward);
-
- return adjustedTime;
- }
-
- return getNativeTimeViaParseConversion(columnIndex, targetCalendar,
- tz, rollForward);
-
- case Types.DATE:
- if (populatedFromDateTimeValue) {
- if ((year == 0) && (month == 0) && (day == 0)) {
- if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
- .equals(this.connection.getZeroDateTimeBehavior())) {
- this.wasNullFlag = true;
-
- return null;
- } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
- .equals(this.connection.getZeroDateTimeBehavior())) {
- throw new SQLException(
- "Value '0000-00-00' can not be represented as java.sql.Date",
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
- }
-
- year = 1;
- month = 1;
- day = 1;
- }
-
- return fastDateCreate(getCalendarInstanceForSessionOrNew(),
- year, month, day);
- }
-
- return getNativeDateViaParseConversion(columnIndex);
- case Types.TIMESTAMP:
- if (populatedFromDateTimeValue) {
- if ((year == 0) && (month == 0) && (day == 0)) {
- if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
- .equals(this.connection.getZeroDateTimeBehavior())) {
- this.wasNullFlag = true;
-
- return null;
- } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
- .equals(this.connection.getZeroDateTimeBehavior())) {
- throw new SQLException(
- "Value '0000-00-00' can not be represented as java.sql.Timestamp",
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
- }
-
- year = 1;
- month = 1;
- day = 1;
- }
-
- Timestamp ts = fastTimestampCreate(
- getCalendarInstanceForSessionOrNew(), year, month, day,
- hour, minute, seconds, nanos);
-
- Timestamp adjustedTs = TimeUtil.changeTimezone(this.connection,
- sessionCalendar,
- targetCalendar,
- ts, this.connection.getServerTimezoneTZ(), tz,
- rollForward);
-
- return adjustedTs;
- }
-
- return getNativeTimestampViaParseConversion(columnIndex, targetCalendar, tz,
rollForward);
-
- default:
- throw new SQLException("Internal error - conversion method doesn't support this type",
- SQLError.SQL_STATE_GENERAL_ERROR);
- }
- }
}
Modified: branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowDataDynamic.java
===================================================================
--- branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowDataDynamic.java 2007-06-07
15:40:36 UTC (rev 6448)
+++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowDataDynamic.java 2007-06-14
16:11:19 UTC (rev 6449)
@@ -406,7 +406,7 @@
this.nextRow = this.io.nextRow(this.fields, this.columnCount,
this.isBinaryEncoded,
- java.sql.ResultSet.CONCUR_READ_ONLY, true, true);
+ java.sql.ResultSet.CONCUR_READ_ONLY, true, true, null);
if (this.nextRow == null) {
this.isAtEnd = true;
Modified: branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowHolder.java
===================================================================
--- branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowHolder.java 2007-06-07 15:40:36
UTC (rev 6448)
+++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/RowHolder.java 2007-06-14 16:11:19
UTC (rev 6449)
@@ -22,15 +22,22 @@
*/
package com.mysql.jdbc;
+import java.io.InputStream;
+import java.io.Reader;
+import java.sql.Date;
import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Time;
import java.sql.Timestamp;
+import java.sql.Types;
import java.util.Calendar;
+import java.util.StringTokenizer;
import java.util.TimeZone;
/**
* Classes that implement this interface represent one row of data from the
* MySQL server that might be stored in different ways depending on whether the
- * result set was streaming (so they wrap a reuseable packet), or whether the
+ * result set was streaming (so they wrap a reusable packet), or whether the
* result set was cached or via a server-side cursor (so they represent a
* byte[][]).
*
@@ -45,6 +52,11 @@
*/
protected Field[] metadata;
+ public abstract void closeOpenStreams();
+
+ public abstract InputStream getBinaryInputStream(int columnIndex)
+ throws SQLException;
+
/**
* Returns the value at the given column (index starts at 0) "raw" (i.e.
* as-returned by the server).
@@ -57,6 +69,220 @@
*/
public abstract byte[] getColumnValue(int index) throws SQLException;
+ protected final java.sql.Date getDateFast(int columnIndex,
+ byte[] dateAsBytes, int offset, int length, ConnectionImpl conn,
+ ResultSetImpl rs) throws SQLException {
+
+ int year = 0;
+ int month = 0;
+ int day = 0;
+
+ try {
+ if (dateAsBytes == null) {
+ return null;
+ }
+
+ boolean allZeroDate = true;
+
+ boolean onlyTimePresent = false;
+
+ for (int i = 0; i < length; i++) {
+ if (dateAsBytes[offset + i] == ':') {
+ onlyTimePresent = true;
+ break;
+ }
+ }
+
+ for (int i = 0; i < length; i++) {
+ byte b = dateAsBytes[offset + i];
+
+ if (b == ' ' || b == '-' || b == '/') {
+ onlyTimePresent = false;
+ }
+
+ if (b != '0' && b != ' ' && b != ':' && b != '-' && b
!= '/'
+ && b != '.') {
+ allZeroDate = false;
+
+ break;
+ }
+ }
+
+ if (!onlyTimePresent && allZeroDate) {
+
+ if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
+ .equals(conn.getZeroDateTimeBehavior())) {
+
+ return null;
+ } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
+ .equals(conn.getZeroDateTimeBehavior())) {
+ throw SQLError.createSQLException("Value '"
+ + new String(dateAsBytes)
+ + "' can not be represented as java.sql.Date",
+ SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+ }
+
+ // We're left with the case of 'round' to a date Java _can_
+ // represent, which is '0001-01-01'.
+ return rs.fastDateCreate(null, 1, 1, 1);
+
+ } else if (this.metadata[columnIndex].getMysqlType() ==
MysqlDefs.FIELD_TYPE_TIMESTAMP) {
+ // Convert from TIMESTAMP
+ switch (length) {
+ case 21:
+ case 19: { // java.sql.Timestamp format
+ year = StringUtils.getInt(dateAsBytes, offset + 0,
+ offset + 4);
+ month = StringUtils.getInt(dateAsBytes, offset + 5,
+ offset + 7);
+ day = StringUtils.getInt(dateAsBytes, offset + 8,
+ offset + 10);
+
+ return rs.fastDateCreate(null, year, month, day);
+ }
+
+ case 14:
+ case 8: {
+ year = StringUtils.getInt(dateAsBytes, offset + 0,
+ offset + 4);
+ month = StringUtils.getInt(dateAsBytes, offset + 4,
+ offset + 6);
+ day = StringUtils.getInt(dateAsBytes, offset + 6,
+ offset + 8);
+
+ return rs.fastDateCreate(null, year, month, day);
+ }
+
+ case 12:
+ case 10:
+ case 6: {
+ year = StringUtils.getInt(dateAsBytes, offset + 0,
+ offset + 2);
+
+ if (year <= 69) {
+ year = year + 100;
+ }
+
+ month = StringUtils.getInt(dateAsBytes, offset + 2,
+ offset + 4);
+ day = StringUtils.getInt(dateAsBytes, offset + 4,
+ offset + 6);
+
+ return rs.fastDateCreate(null, year + 1900, month, day);
+ }
+
+ case 4: {
+ year = StringUtils.getInt(dateAsBytes, offset + 0,
+ offset + 4);
+
+ if (year <= 69) {
+ year = year + 100;
+ }
+
+ month = StringUtils.getInt(dateAsBytes, offset + 2,
+ offset + 4);
+
+ return rs.fastDateCreate(null, year + 1900, month, 1);
+ }
+
+ case 2: {
+ year = StringUtils.getInt(dateAsBytes, offset + 0,
+ offset + 2);
+
+ if (year <= 69) {
+ year = year + 100;
+ }
+
+ return rs.fastDateCreate(null, year + 1900, 1, 1);
+ }
+
+ default:
+ throw SQLError
+ .createSQLException(
+ Messages
+ .getString(
+ "ResultSet.Bad_format_for_Date",
+ new Object[] {
+ new String(
+ dateAsBytes),
+ Constants
+ .integerValueOf(columnIndex + 1) }),
+ SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
+ } /* endswitch */
+ } else if (this.metadata[columnIndex].getMysqlType() == MysqlDefs.FIELD_TYPE_YEAR) {
+
+ if (length == 2 || length == 1) {
+ year = StringUtils.getInt(dateAsBytes, offset, offset
+ + length);
+
+ if (year <= 69) {
+ year = year + 100;
+ }
+
+ year += 1900;
+ } else {
+ year = StringUtils.getInt(dateAsBytes, offset + 0,
+ offset + 4);
+ }
+
+ return rs.fastDateCreate(null, year, 1, 1);
+ } else if (this.metadata[columnIndex].getMysqlType() == MysqlDefs.FIELD_TYPE_TIME) {
+ return rs.fastDateCreate(null, 1970, 1, 1); // Return EPOCH
+ } else {
+ if (length < 10) {
+ if (length == 8) {
+ return rs.fastDateCreate(null, 1970, 1, 1); // Return
+ // EPOCH for
+ // TIME
+ }
+
+ throw SQLError
+ .createSQLException(
+ Messages
+ .getString(
+ "ResultSet.Bad_format_for_Date",
+ new Object[] {
+ new String(
+ dateAsBytes),
+ Constants
+ .integerValueOf(columnIndex + 1) }),
+ SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
+ }
+
+ if (length != 18) {
+ year = StringUtils.getInt(dateAsBytes, offset + 0,
+ offset + 4);
+ month = StringUtils.getInt(dateAsBytes, offset + 5,
+ offset + 7);
+ day = StringUtils.getInt(dateAsBytes, offset + 8,
+ offset + 10);
+ } else {
+ // JDK-1.3 timestamp format, not real easy to parse
+ // positionally :p
+ StringTokenizer st = new StringTokenizer(new String(
+ dateAsBytes, offset, length, "ISO8859_1"), "- ");
+
+ year = Integer.parseInt(st.nextToken());
+ month = Integer.parseInt(st.nextToken());
+ day = Integer.parseInt(st.nextToken());
+ }
+ }
+
+ return rs.fastDateCreate(null, year, month, day);
+ } catch (SQLException sqlEx) {
+ throw sqlEx; // don't re-wrap
+ } catch (Exception e) {
+ throw SQLError.createSQLException(Messages.getString(
+ "ResultSet.Bad_format_for_Date", new Object[] {
+ new String(dateAsBytes),
+ Constants.integerValueOf(columnIndex + 1) }),
+ SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
+ }
+ }
+
+ public abstract java.sql.Date getDateFast(int columnIndex,
+ ConnectionImpl conn, ResultSetImpl rs) throws SQLException;
+
/**
* Returns the value at the given column (index starts at 0) as an int. *
*
@@ -81,6 +307,216 @@
*/
public abstract long getLong(int columnIndex) throws SQLException;
+ protected java.sql.Date getNativeDate(int columnIndex, byte[] bits,
+ int offset, int length, ConnectionImpl conn, ResultSetImpl rs)
+ throws SQLException {
+
+ int year = 0;
+ int month = 0;
+ int day = 0;
+
+ if (length != 0) {
+ year = (bits[offset + 0] & 0xff) | ((bits[offset + 1] & 0xff) << 8);
+
+ month = bits[offset + 2];
+ day = bits[offset + 3];
+ }
+
+ if ((year == 0) && (month == 0) && (day == 0)) {
+ if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
+ .equals(conn.getZeroDateTimeBehavior())) {
+ return null;
+ } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
+ .equals(conn.getZeroDateTimeBehavior())) {
+ throw SQLError
+ .createSQLException(
+ "Value '0000-00-00' can not be represented as java.sql.Date",
+ SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+ }
+
+ year = 1;
+ month = 1;
+ day = 1;
+ }
+
+ return rs.fastDateCreate(rs.getCalendarInstanceForSessionOrNew(), year,
+ month, day);
+ }
+
+ public abstract Date getNativeDate(int columnIndex, ConnectionImpl conn,
+ ResultSetImpl rs) throws SQLException;
+
+ protected Object getNativeDateTimeValue(int columnIndex, byte[] bits,
+ int offset, int length, Calendar targetCalendar, int jdbcType,
+ int mysqlType, TimeZone tz, boolean rollForward, ConnectionImpl conn,
+ ResultSetImpl rs) throws SQLException {
+
+ int year = 0;
+ int month = 0;
+ int day = 0;
+
+ int hour = 0;
+ int minute = 0;
+ int seconds = 0;
+
+ int nanos = 0;
+
+ if (bits == null) {
+
+ return null;
+ }
+
+ Calendar sessionCalendar = conn.getUseJDBCCompliantTimezoneShift() ? conn
+ .getUtcCalendar()
+ : rs.getCalendarInstanceForSessionOrNew();
+
+ boolean populatedFromDateTimeValue = false;
+
+ switch (mysqlType) {
+ case MysqlDefs.FIELD_TYPE_DATETIME:
+ case MysqlDefs.FIELD_TYPE_TIMESTAMP:
+ populatedFromDateTimeValue = true;
+
+ if (length != 0) {
+ year = (bits[offset + 0] & 0xff)
+ | ((bits[offset + 1] & 0xff) << 8);
+ month = bits[offset + 2];
+ day = bits[offset + 3];
+
+ if (length > 4) {
+ hour = bits[offset + 4];
+ minute = bits[offset + 5];
+ seconds = bits[offset + 6];
+ }
+
+ if (length > 7) {
+ // MySQL uses microseconds
+ nanos = ((bits[offset + 7] & 0xff)
+ | ((bits[offset + 8] & 0xff) << 8)
+ | ((bits[offset + 9] & 0xff) << 16) | ((bits[offset + 10] & 0xff)
<< 24)) * 1000;
+ }
+ }
+
+ break;
+ case MysqlDefs.FIELD_TYPE_DATE:
+ populatedFromDateTimeValue = true;
+
+ if (bits.length != 0) {
+ year = (bits[offset + 0] & 0xff)
+ | ((bits[offset + 1] & 0xff) << 8);
+ month = bits[offset + 2];
+ day = bits[offset + 3];
+ }
+
+ break;
+ case MysqlDefs.FIELD_TYPE_TIME:
+ populatedFromDateTimeValue = true;
+
+ if (bits.length != 0) {
+ // bits[0] // skip tm->neg
+ // binaryData.readLong(); // skip daysPart
+ hour = bits[offset + 5];
+ minute = bits[offset + 6];
+ seconds = bits[offset + 7];
+ }
+
+ year = 1970;
+ month = 1;
+ day = 1;
+
+ break;
+ default:
+ populatedFromDateTimeValue = false;
+ }
+
+ switch (jdbcType) {
+ case Types.TIME:
+ if (populatedFromDateTimeValue) {
+ Time time = TimeUtil.fastTimeCreate(rs
+ .getCalendarInstanceForSessionOrNew(), hour, minute,
+ seconds);
+
+ Time adjustedTime = TimeUtil.changeTimezone(conn,
+ sessionCalendar, targetCalendar, time, conn
+ .getServerTimezoneTZ(), tz, rollForward);
+
+ return adjustedTime;
+ }
+
+ return rs.getNativeTimeViaParseConversion(columnIndex + 1,
+ targetCalendar, tz, rollForward);
+
+ case Types.DATE:
+ if (populatedFromDateTimeValue) {
+ if ((year == 0) && (month == 0) && (day == 0)) {
+ if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
+ .equals(conn.getZeroDateTimeBehavior())) {
+
+ return null;
+ } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
+ .equals(conn.getZeroDateTimeBehavior())) {
+ throw new SQLException(
+ "Value '0000-00-00' can not be represented as java.sql.Date",
+ SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+ }
+
+ year = 1;
+ month = 1;
+ day = 1;
+ }
+
+ return rs
+ .fastDateCreate(
+ rs.getCalendarInstanceForSessionOrNew(), year,
+ month, day);
+ }
+
+ return rs.getNativeDateViaParseConversion(columnIndex + 1);
+ case Types.TIMESTAMP:
+ if (populatedFromDateTimeValue) {
+ if ((year == 0) && (month == 0) && (day == 0)) {
+ if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
+ .equals(conn.getZeroDateTimeBehavior())) {
+
+ return null;
+ } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
+ .equals(conn.getZeroDateTimeBehavior())) {
+ throw new SQLException(
+ "Value '0000-00-00' can not be represented as java.sql.Timestamp",
+ SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+ }
+
+ year = 1;
+ month = 1;
+ day = 1;
+ }
+
+ Timestamp ts = rs.fastTimestampCreate(rs
+ .getCalendarInstanceForSessionOrNew(), year, month,
+ day, hour, minute, seconds, nanos);
+
+ Timestamp adjustedTs = TimeUtil.changeTimezone(conn,
+ sessionCalendar, targetCalendar, ts, conn
+ .getServerTimezoneTZ(), tz, rollForward);
+
+ return adjustedTs;
+ }
+
+ return rs.getNativeTimestampViaParseConversion(columnIndex + 1,
+ targetCalendar, tz, rollForward);
+
+ default:
+ throw new SQLException(
+ "Internal error - conversion method doesn't support this type",
+ SQLError.SQL_STATE_GENERAL_ERROR);
+ }
+ }
+
+ public abstract Object getNativeDateTimeValue(int columnIndex,
+ Calendar targetCalendar, int jdbcType, int mysqlType,
+ TimeZone tz, boolean rollForward, ConnectionImpl conn, ResultSetImpl rs)
+ throws SQLException;
+
protected double getNativeDouble(byte[] bits, int offset) {
long valueAsLong = (bits[offset + 0] & 0xff)
| ((long) (bits[offset + 1] & 0xff) << 8)
@@ -142,6 +578,113 @@
public abstract short getNativeShort(int columnIndex) throws SQLException;
+ protected Time getNativeTime(int columnIndex, byte[] bits, int offset,
+ int length, Calendar targetCalendar, TimeZone tz,
+ boolean rollForward, ConnectionImpl conn, ResultSetImpl rs)
+ throws SQLException {
+
+ int hour = 0;
+ int minute = 0;
+ int seconds = 0;
+
+ if (length != 0) {
+ // bits[0] // skip tm->neg
+ // binaryData.readLong(); // skip daysPart
+ hour = bits[offset + 5];
+ minute = bits[offset + 6];
+ seconds = bits[offset + 7];
+ }
+
+ Calendar sessionCalendar = rs.getCalendarInstanceForSessionOrNew();
+
+ synchronized (sessionCalendar) {
+ Time time = TimeUtil.fastTimeCreate(sessionCalendar, hour, minute,
+ seconds);
+
+ Time adjustedTime = TimeUtil.changeTimezone(conn, sessionCalendar,
+ targetCalendar, time, conn.getServerTimezoneTZ(), tz,
+ rollForward);
+
+ return adjustedTime;
+ }
+ }
+
+ public abstract Time getNativeTime(int columnIndex,
+ Calendar targetCalendar, TimeZone tz, boolean rollForward,
+ ConnectionImpl conn, ResultSetImpl rs) throws SQLException;
+
+ protected Timestamp getNativeTimestamp(byte[] bits, int offset, int length,
+ Calendar targetCalendar, TimeZone tz, boolean rollForward,
+ ConnectionImpl conn, ResultSetImpl rs) throws SQLException {
+ int year = 0;
+ int month = 0;
+ int day = 0;
+
+ int hour = 0;
+ int minute = 0;
+ int seconds = 0;
+
+ int nanos = 0;
+
+ if (length != 0) {
+ year = (bits[offset + 0] & 0xff) | ((bits[offset + 1] & 0xff) << 8);
+ month = bits[2];
+ day = bits[3];
+
+ if (length > 4) {
+ hour = bits[offset + 4];
+ minute = bits[offset + 5];
+ seconds = bits[offset + 6];
+ }
+
+ if (length > 7) {
+ // MySQL uses microseconds
+ nanos = ((bits[offset + 7] & 0xff)
+ | ((bits[offset + 8] & 0xff) << 8)
+ | ((bits[offset + 9] & 0xff) << 16) | ((bits[offset + 10] & 0xff)
<< 24)) * 1000;
+ }
+ }
+
+ if ((year == 0) && (month == 0) && (day == 0)) {
+ if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
+ .equals(conn.getZeroDateTimeBehavior())) {
+
+ return null;
+ } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
+ .equals(conn.getZeroDateTimeBehavior())) {
+ throw SQLError
+ .createSQLException(
+ "Value '0000-00-00' can not be represented as java.sql.Timestamp",
+ SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+ }
+
+ year = 1;
+ month = 1;
+ day = 1;
+ }
+
+ Calendar sessionCalendar = conn.getUseJDBCCompliantTimezoneShift() ? conn
+ .getUtcCalendar()
+ : rs.getCalendarInstanceForSessionOrNew();
+
+ synchronized (sessionCalendar) {
+ Timestamp ts = rs.fastTimestampCreate(sessionCalendar, year, month,
+ day, hour, minute, seconds, nanos);
+
+ Timestamp adjustedTs = TimeUtil.changeTimezone(conn,
+ sessionCalendar, targetCalendar, ts, conn
+ .getServerTimezoneTZ(), tz, rollForward);
+
+ return adjustedTs;
+ }
+ }
+
+ public abstract Timestamp getNativeTimestamp(int columnIndex,
+ Calendar targetCalendar, TimeZone tz, boolean rollForward,
+ ConnectionImpl conn, ResultSetImpl rs) throws SQLException;
+
+ public abstract Reader getReader(int columnIndex) throws SQLException;
+
/**
* Returns the value at the given column (index starts at 0) as a
* java.lang.String with the requested encoding, using the given
@@ -216,10 +759,179 @@
return stringVal;
}
- protected Timestamp getTimestampFast(byte[] timestampAsBytes,
- int columnIndex, ConnectionImpl conn, ResultSetImpl rs,
+ protected Time getTimeFast(int columnIndex, byte[] timeAsBytes, int offset,
+ int length, Calendar targetCalendar, TimeZone tz,
+ boolean rollForward, ConnectionImpl conn, ResultSetImpl rs)
+ throws SQLException {
+
+ int hr = 0;
+ int min = 0;
+ int sec = 0;
+
+ try {
+
+ if (timeAsBytes == null) {
+ return null;
+ }
+
+ boolean allZeroTime = true;
+ boolean onlyTimePresent = false;
+
+ for (int i = 0; i < length; i++) {
+ if (timeAsBytes[offset + i] == ':') {
+ onlyTimePresent = true;
+ break;
+ }
+ }
+
+ for (int i = 0; i < length; i++) {
+ byte b = timeAsBytes[offset + i];
+
+ if (b == ' ' || b == '-' || b == '/') {
+ onlyTimePresent = false;
+ }
+
+ if (b != '0' && b != ' ' && b != ':' && b != '-' && b
!= '/'
+ && b != '.') {
+ allZeroTime = false;
+
+ break;
+ }
+ }
+
+ if (!onlyTimePresent && allZeroTime) {
+ if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
+ .equals(conn.getZeroDateTimeBehavior())) {
+ return null;
+ } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
+ .equals(conn.getZeroDateTimeBehavior())) {
+ throw SQLError.createSQLException("Value '"
+ + new String(timeAsBytes)
+ + "' can not be represented as java.sql.Time",
+ SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+ }
+
+ // We're left with the case of 'round' to a time Java _can_
+ // represent, which is '00:00:00'
+ return rs.fastTimeCreate(null, 0, 0, 0);
+ }
+
+ Field timeColField = this.metadata[columnIndex];
+
+ if (timeColField.getMysqlType() == MysqlDefs.FIELD_TYPE_TIMESTAMP) {
+
+ switch (length) {
+ case 19: { // YYYY-MM-DD hh:mm:ss
+
+ hr = StringUtils.getInt(timeAsBytes, offset + length - 8,
+ offset + length - 6);
+ min = StringUtils.getInt(timeAsBytes, offset + length - 5,
+ offset + length - 3);
+ sec = StringUtils.getInt(timeAsBytes, offset + length - 2,
+ offset + length);
+ }
+
+ break;
+ case 14:
+ case 12: {
+ hr = StringUtils.getInt(timeAsBytes, offset + length - 6,
+ offset + length - 4);
+ min = StringUtils.getInt(timeAsBytes, offset + length - 4,
+ offset + length - 2);
+ sec = StringUtils.getInt(timeAsBytes, offset + length - 2,
+ offset + length);
+ }
+
+ break;
+
+ case 10: {
+ hr = StringUtils
+ .getInt(timeAsBytes, offset + 6, offset + 8);
+ min = StringUtils.getInt(timeAsBytes, offset + 8,
+ offset + 10);
+ sec = 0;
+ }
+
+ break;
+
+ default:
+ throw SQLError
+ .createSQLException(
+ Messages
+ .getString("ResultSet.Timestamp_too_small_to_convert_to_Time_value_in_column__257")
//$NON-NLS-1$
+ + (columnIndex + 1)
+ + "("
+ + timeColField + ").",
+ SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+ } /* endswitch */
+
+ SQLWarning precisionLost = new SQLWarning(
+ Messages
+ .getString("ResultSet.Precision_lost_converting_TIMESTAMP_to_Time_with_getTime()_on_column__261")
//$NON-NLS-1$
+ + columnIndex + "(" + timeColField + ").");
+ /*
+ * if (this.warningChain == null) { this.warningChain =
+ * precisionLost; } else {
+ * this.warningChain.setNextWarning(precisionLost); }
+ */
+ } else if (timeColField.getMysqlType() == MysqlDefs.FIELD_TYPE_DATETIME) {
+ hr = StringUtils.getInt(timeAsBytes, offset + 11, offset + 13);
+ min = StringUtils.getInt(timeAsBytes, offset + 14, offset + 16);
+ sec = StringUtils.getInt(timeAsBytes, offset + 17, offset + 19);
+
+ SQLWarning precisionLost = new SQLWarning(
+ Messages
+ .getString("ResultSet.Precision_lost_converting_DATETIME_to_Time_with_getTime()_on_column__264")
//$NON-NLS-1$
+ + (columnIndex + 1) + "(" + timeColField + ").");
+
+ /*
+ * if (this.warningChain == null) { this.warningChain =
+ * precisionLost; } else {
+ * this.warningChain.setNextWarning(precisionLost); }
+ */
+ } else if (timeColField.getMysqlType() == MysqlDefs.FIELD_TYPE_DATE) {
+ return rs.fastTimeCreate(null, 0, 0, 0); // midnight on the
+ // given
+ // date
+ } else {
+ // convert a String to a Time
+ if ((length != 5) && (length != 8)) {
+ throw SQLError.createSQLException(Messages
+ .getString("ResultSet.Bad_format_for_Time____267") //$NON-NLS-1$
+ + new String(timeAsBytes)
+ + Messages.getString("ResultSet.___in_column__268")
+ + (columnIndex + 1),
+ SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+ }
+
+ hr = StringUtils.getInt(timeAsBytes, offset + 0, offset + 2);
+ min = StringUtils.getInt(timeAsBytes, offset + 3, offset + 5);
+ sec = (length == 5) ? 0 : StringUtils.getInt(timeAsBytes,
+ offset + 6, offset + 8);
+ }
+
+ Calendar sessionCalendar = rs.getCalendarInstanceForSessionOrNew();
+
+ synchronized (sessionCalendar) {
+ return TimeUtil.changeTimezone(conn, sessionCalendar,
+ targetCalendar, rs.fastTimeCreate(sessionCalendar, hr,
+ min, sec), conn.getServerTimezoneTZ(), tz,
+ rollForward);
+ }
+ } catch (Exception ex) {
+ throw SQLError.createSQLException(ex.toString(),
+ SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+ }
+ }
+
+ public abstract Time getTimeFast(int columnIndex, Calendar targetCalendar,
+ TimeZone tz, boolean rollForward, ConnectionImpl conn,
+ ResultSetImpl rs) throws SQLException;
+
+ protected Timestamp getTimestampFast(int columnIndex,
+ byte[] timestampAsBytes, int offset, int length,
Calendar targetCalendar, TimeZone tz, boolean rollForward,
- int offset, int length) throws SQLException {
+ ConnectionImpl conn, ResultSetImpl rs) throws SQLException {
try {
Calendar sessionCalendar = conn.getUseJDBCCompliantTimezoneShift() ? conn
@@ -231,15 +943,15 @@
boolean onlyTimePresent = false;
- for (int i = offset; i < length; i++) {
- if (timestampAsBytes[i] == ':') {
+ for (int i = 0; i < length; i++) {
+ if (timestampAsBytes[offset + i] == ':') {
onlyTimePresent = true;
break;
}
}
for (int i = 0; i < length; i++) {
- byte b = timestampAsBytes[i + offset];
+ byte b = timestampAsBytes[offset + i];
if (b == ' ' || b == '-' || b == '/') {
onlyTimePresent = false;
@@ -283,7 +995,7 @@
tz, rollForward);
} else {
- if (timestampAsBytes[length - 1] == '.') {
+ if (timestampAsBytes[offset + length - 1] == '.') {
length--;
}
@@ -298,29 +1010,34 @@
case 20:
case 19: {
int year = StringUtils.getInt(timestampAsBytes,
- offset + 0, 4);
+ offset + 0, offset + 4);
int month = StringUtils.getInt(timestampAsBytes,
- offset + 5, 7);
+ offset + 5, offset + 7);
int day = StringUtils.getInt(timestampAsBytes,
- offset + 8, 10);
+ offset + 8, offset + 10);
int hour = StringUtils.getInt(timestampAsBytes,
- offset + 11, 13);
+ offset + 11, offset + 13);
int minutes = StringUtils.getInt(timestampAsBytes,
- offset + 14, 16);
+ offset + 14, offset + 16);
int seconds = StringUtils.getInt(timestampAsBytes,
- offset + 17, 19);
+ offset + 17, offset + 19);
int nanos = 0;
if (length > 19) {
- int decimalIndex = StringUtils.lastIndexOf(
- timestampAsBytes, '.');
+ int decimalIndex = -1;
+ for (int i = 0; i < length; i++) {
+ if (timestampAsBytes[offset + i] == '.') {
+ decimalIndex = i;
+ }
+ }
+
if (decimalIndex != -1) {
if ((decimalIndex + 2) <= length) {
nanos = StringUtils.getInt(
timestampAsBytes, decimalIndex + 1,
- length);
+ offset + length);
} else {
throw new IllegalArgumentException(); // re-thrown
// further
@@ -404,8 +1121,8 @@
boolean hasDash = false;
- for (int i = offset; i < length; i++) {
- if (timestampAsBytes[i] == '-') {
+ for (int i = 0; i < length; i++) {
+ if (timestampAsBytes[offset + i] == '-') {
hasDash = true;
break;
}
@@ -453,14 +1170,14 @@
case 8: {
boolean hasColon = false;
- for (int i = offset; i < length; i++) {
- if (timestampAsBytes[i] == ':') {
+ for (int i = 0; i < length; i++) {
+ if (timestampAsBytes[offset + i] == ':') {
hasColon = true;
break;
}
}
- if (StringUtils.indexOf(timestampAsBytes, ':') != -1) {
+ if (hasColon) {
int hour = StringUtils.getInt(timestampAsBytes,
offset + 0, offset + 2);
int minutes = StringUtils.getInt(timestampAsBytes,
@@ -519,7 +1236,7 @@
case 4: {
int year = StringUtils.getInt(timestampAsBytes,
- offset + 0, 2);
+ offset + 0, offset + 2);
if (year <= 69) {
year = (year + 100);
@@ -556,7 +1273,8 @@
throw new java.sql.SQLException(
"Bad format for Timestamp '"
+ new String(timestampAsBytes)
- + "' in column " + columnIndex + ".",
+ + "' in column " + (columnIndex + 1)
+ + ".",
SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
}
}
@@ -570,8 +1288,8 @@
}
public abstract Timestamp getTimestampFast(int columnIndex,
- ConnectionImpl conn, ResultSetImpl rs, Calendar targetCalendar,
- TimeZone tz, boolean rollForward) throws SQLException;
+ Calendar targetCalendar, TimeZone tz, boolean rollForward,
+ ConnectionImpl conn, ResultSetImpl rs) throws SQLException;
/**
* Could the column value at the given index (which starts at 0) be
@@ -635,74 +1353,4 @@
public void setMetadata(Field[] f) throws SQLException {
this.metadata = f;
}
-
- public abstract Timestamp getNativeTimestamp(int columnIndex,
- Calendar targetCalendar, TimeZone tz, boolean rollForward,
- ConnectionImpl conn, ResultSetImpl rs) throws SQLException;
-
- protected Timestamp getNativeTimestamp(byte[] bits, int offset, int length,
- Calendar targetCalendar, TimeZone tz, boolean rollForward,
- ConnectionImpl conn, ResultSetImpl rs) throws SQLException {
- int year = 0;
- int month = 0;
- int day = 0;
-
- int hour = 0;
- int minute = 0;
- int seconds = 0;
-
- int nanos = 0;
-
- if (length != 0) {
- year = (bits[offset + 0] & 0xff) | ((bits[offset + 1] & 0xff) << 8);
- month = bits[2];
- day = bits[3];
-
- if (length > 4) {
- hour = bits[offset + 4];
- minute = bits[offset + 5];
- seconds = bits[offset + 6];
- }
-
- if (length > 7) {
- nanos = (bits[offset + 7] & 0xff)
- | ((bits[offset + 8] & 0xff) << 8)
- | ((bits[offset + 9] & 0xff) << 16)
- | ((bits[offset + 10] & 0xff) << 24);
- }
- }
-
- if ((year == 0) && (month == 0) && (day == 0)) {
- if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_CONVERT_TO_NULL
- .equals(conn.getZeroDateTimeBehavior())) {
-
- return null;
- } else if (ConnectionPropertiesImpl.ZERO_DATETIME_BEHAVIOR_EXCEPTION
- .equals(conn.getZeroDateTimeBehavior())) {
- throw SQLError
- .createSQLException(
- "Value '0000-00-00' can not be represented as java.sql.Timestamp",
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
- }
-
- year = 1;
- month = 1;
- day = 1;
- }
-
- Calendar sessionCalendar = conn.getUseJDBCCompliantTimezoneShift() ? conn
- .getUtcCalendar()
- : rs.getCalendarInstanceForSessionOrNew();
-
- synchronized (sessionCalendar) {
- Timestamp ts = rs.fastTimestampCreate(sessionCalendar, year, month,
- day, hour, minute, seconds, nanos);
-
- Timestamp adjustedTs = TimeUtil.changeTimezone(conn,
- sessionCalendar, targetCalendar, ts, conn
- .getServerTimezoneTZ(), tz, rollForward);
-
- return adjustedTs;
- }
- }
}
Modified:
branches/branch_5_1/connector-j/src/com/mysql/jdbc/SingleByteCharsetConverter.java
===================================================================
---
branches/branch_5_1/connector-j/src/com/mysql/jdbc/SingleByteCharsetConverter.java 2007-06-07
15:40:36 UTC (rev 6448)
+++
branches/branch_5_1/connector-j/src/com/mysql/jdbc/SingleByteCharsetConverter.java 2007-06-14
16:11:19 UTC (rev 6449)
@@ -178,7 +178,27 @@
return bytes;
}
+
+ public final byte[] toBytesWrapped(char[] c, char beginWrap, char endWrap) {
+ if (c == null) {
+ return null;
+ }
+ int length = c.length + 2;
+ int charLength = c.length;
+
+ byte[] bytes = new byte[length];
+ bytes[0] = this.charToByteMap[beginWrap];
+
+ for (int i = 0; i < charLength; i++) {
+ bytes[i + 1] = this.charToByteMap[c[i]];
+ }
+
+ bytes[length - 1] = this.charToByteMap[endWrap];
+
+ return bytes;
+ }
+
public final byte[] toBytes(char[] chars, int offset, int length) {
if (chars == null) {
return null;
@@ -218,7 +238,29 @@
return bytes;
}
+
+ public final byte[] toBytesWrapped(String s, char beginWrap, char endWrap) {
+ if (s == null) {
+ return null;
+ }
+ int stringLength = s.length();
+
+ int length = stringLength + 2;
+
+ byte[] bytes = new byte[length];
+
+ bytes[0] = this.charToByteMap[beginWrap];
+
+ for (int i = 0; i < stringLength; i++) {
+ bytes[i + 1] = this.charToByteMap[s.charAt(i)];
+ }
+
+ bytes[length - 1] = this.charToByteMap[endWrap];
+
+ return bytes;
+ }
+
/**
* Convert the given string to an array of bytes.
*
Modified: branches/branch_5_1/connector-j/src/com/mysql/jdbc/StringUtils.java
===================================================================
--- branches/branch_5_1/connector-j/src/com/mysql/jdbc/StringUtils.java 2007-06-07
15:40:36 UTC (rev 6448)
+++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/StringUtils.java 2007-06-14
16:11:19 UTC (rev 6449)
@@ -527,6 +527,48 @@
}
}
+ public static final byte[] getBytesWrapped(String s, char beginWrap, char endWrap,
+ SingleByteCharsetConverter converter, String encoding,
+ String serverEncoding, boolean parserKnowsUnicode)
+ throws SQLException {
+ try {
+ byte[] b = null;
+
+ if (converter != null) {
+ b = converter.toBytesWrapped(s, beginWrap, endWrap);
+ } else if (encoding == null) {
+ StringBuffer buf = new StringBuffer(s.length() + 2);
+ buf.append(beginWrap);
+ buf.append(s);
+ buf.append(endWrap);
+
+ b = buf.toString().getBytes();
+ } else {
+ StringBuffer buf = new StringBuffer(s.length() + 2);
+ buf.append(beginWrap);
+ buf.append(s);
+ buf.append(endWrap);
+
+ b = buf.toString().getBytes(encoding);
+
+ if (!parserKnowsUnicode && (encoding.equalsIgnoreCase("SJIS") //$NON-NLS-1$
+ || encoding.equalsIgnoreCase("BIG5") //$NON-NLS-1$
+ || encoding.equalsIgnoreCase("GBK"))) { //$NON-NLS-1$
+
+ if (!encoding.equalsIgnoreCase(serverEncoding)) {
+ b = escapeEasternUnicodeByteStream(b, s, 0, s.length());
+ }
+ }
+ }
+
+ return b;
+ } catch (UnsupportedEncodingException uee) {
+ throw SQLError.createSQLException(Messages.getString("StringUtils.5") //$NON-NLS-1$
+ + encoding + Messages.getString("StringUtils.6"),
+ SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
+ }
+ }
+
/**
* DOCUMENT ME!
*
Modified: branches/branch_5_1/connector-j/src/com/mysql/jdbc/configs/3-0-Compat.properties
===================================================================
---
branches/branch_5_1/connector-j/src/com/mysql/jdbc/configs/3-0-Compat.properties 2007-06-07
15:40:36 UTC (rev 6448)
+++
branches/branch_5_1/connector-j/src/com/mysql/jdbc/configs/3-0-Compat.properties 2007-06-14
16:11:19 UTC (rev 6449)
@@ -15,4 +15,5 @@
autoClosePStmtStreams=true
processEscapeCodesForPrepStmts=false
useFastDateParsing=false
-populateInsertRowWithDefaultValues=false
\ No newline at end of file
+populateInsertRowWithDefaultValues=false
+useDirectRowUnpack=false
\ No newline at end of file
Added: branches/branch_5_1/connector-j/src/com/mysql/jdbc/configs/5-0-Compat.properties
===================================================================
---
branches/branch_5_1/connector-j/src/com/mysql/jdbc/configs/5-0-Compat.properties 2007-06-07
15:40:36 UTC (rev 6448)
+++
branches/branch_5_1/connector-j/src/com/mysql/jdbc/configs/5-0-Compat.properties 2007-06-14
16:11:19 UTC (rev 6449)
@@ -0,0 +1,6 @@
+#
+# Settings to maintain Connector/J 5.0.x compatibility
+# (as much as it can be)
+#
+
+useDirectRowUnpack=false
\ No newline at end of file
| Thread |
|---|
| • Connector/J commit: r6449 - in branches/branch_5_1/connector-j/src/com/mysql/jdbc: . configs | mmatthews | 14 Jun |