Pantek Library
Hosting Provided By
CybrHost
High Speed Hosting

Connector/J commit: r6655 - branches/branch_5_1/src/com/mysql/jdbc

From: <mmatthews(at)mysql.com>
Date: Wed Oct 31 2007 - 23:34:32 EDT


Modified:

   branches/branch_5_1/src/com/mysql/jdbc/ServerPreparedStatement.java Log:
Pulled up batch rewriting from 5.0.

Modified: branches/branch_5_1/src/com/mysql/jdbc/ServerPreparedStatement.java


  • branches/branch_5_1/src/com/mysql/jdbc/ServerPreparedStatement.java 2007-10-29 18:15:35 UTC (rev 6654)
    +++ branches/branch_5_1/src/com/mysql/jdbc/ServerPreparedStatement.java 2007-11-01 03:34:31 UTC (rev 6655)
    @@ -24,6 +24,7 @@ */ package com.mysql.jdbc;

+import com.mysql.jdbc.StatementImpl.CancelTask;

 import com.mysql.jdbc.exceptions.MySQLStatementCancelledException;
 import com.mysql.jdbc.exceptions.MySQLTimeoutException;
 import com.mysql.jdbc.profiler.ProfilerEventHandlerFactory;
@@ -208,6 +209,51 @@
 				}
 			}
 		}

+
+ long getBoundLength() {
+ if (isNull) {
+ return 0;
+ }
+
+ if (isLongData) {
+ return bindLength;
+ }
+
+ switch (bufferType) {
+
+ case MysqlDefs.FIELD_TYPE_TINY:
+ return 1;
+ case MysqlDefs.FIELD_TYPE_SHORT:
+ return 2;
+ case MysqlDefs.FIELD_TYPE_LONG:
+ return 4;
+ case MysqlDefs.FIELD_TYPE_LONGLONG:
+ return 8;
+ case MysqlDefs.FIELD_TYPE_FLOAT:
+ return 4;
+ case MysqlDefs.FIELD_TYPE_DOUBLE:
+ return 8;
+ case MysqlDefs.FIELD_TYPE_TIME:
+ return 9;
+ case MysqlDefs.FIELD_TYPE_DATE:
+ return 7;
+ case MysqlDefs.FIELD_TYPE_DATETIME:
+ case MysqlDefs.FIELD_TYPE_TIMESTAMP:
+ return 11;
+ case MysqlDefs.FIELD_TYPE_VAR_STRING:
+ case MysqlDefs.FIELD_TYPE_STRING:
+ case MysqlDefs.FIELD_TYPE_VARCHAR:
+ case MysqlDefs.FIELD_TYPE_DECIMAL:
+ case MysqlDefs.FIELD_TYPE_NEW_DECIMAL:
+ if (value instanceof byte[]) {
+ return ((byte[]) value).length;
+ } else {
+ return ((String) value).length();
+ }
+ default:
+ return 0;
+ }
+ }
} /* 1 (length) + 2 (year) + 1 (month) + 1 (day) */ @@ -616,10 +662,7 @@ this.connection.dumpTestcaseQuery(buf.toString()); } - /** - * @see java.sql.Statement#executeBatch() - */ - public synchronized int[] executeBatch() throws SQLException {
+ protected int[] executeBatchSerially(int batchTimeout) throws SQLException {
if (this.connection.isReadOnly()) { throw SQLError.createSQLException(Messages .getString("ServerPreparedStatement.2") //$NON-NLS-1$
@@ -657,77 +700,97 @@  

                                         BindValue[] previousBindValuesForBatch = null;  

  • for (commandIndex = 0; commandIndex < nbrCommands; commandIndex++) {
  • Object arg = this.batchedArgs.get(commandIndex); -
  • if (arg instanceof String) {
  • updateCounts[commandIndex] = executeUpdate((String) arg);
  • } else {
  • this.parameterBindings = ((BatchedBindValues) arg).batchedParameterValues; -
  • try {
  • // We need to check types each time, as
  • // the user might have bound different
  • // types in each addBatch() -
  • if (previousBindValuesForBatch != null) {
  • for (int j = 0; j < this.parameterBindings.length; j++) {
  • if (this.parameterBindings[j].bufferType != previousBindValuesForBatch[j].bufferType) {
  • this.sendTypesToServer = true; -
  • break;
    + CancelTask timeoutTask = null;
    +
    + try {
    + if (this.connection.getEnableQueryTimeouts() &&
    + batchTimeout != 0
    + && this.connection.versionMeetsMinimum(5, 0, 0)) {
    + timeoutTask = new CancelTask(this);
    + ConnectionImpl.getCancelTimer().schedule(timeoutTask,
    + batchTimeout);
    + }
    +
    + for (commandIndex = 0; commandIndex < nbrCommands; commandIndex++) {
    + Object arg = this.batchedArgs.get(commandIndex);
    +
    + if (arg instanceof String) {
    + updateCounts[commandIndex] = executeUpdate((String) arg);
    + } else {
    + this.parameterBindings = ((BatchedBindValues) arg).batchedParameterValues;
    +
    + try {
    + // We need to check types each time, as
    + // the user might have bound different
    + // types in each addBatch()
    +
    + if (previousBindValuesForBatch != null) {
    + for (int j = 0; j < this.parameterBindings.length; j++) {
    + if (this.parameterBindings[j].bufferType != previousBindValuesForBatch[j].bufferType) {
    + this.sendTypesToServer = true;
    +
    + break;
    + }
    } }
  • } -
  • try {
  • updateCounts[commandIndex] = executeUpdate(false, true);
  • } finally {
  • previousBindValuesForBatch = this.parameterBindings;
  • } -
  • if (this.retrieveGeneratedKeys) {
  • java.sql.ResultSet rs = null; -
    +
    try {
  • // we don't want to use our version,
  • // because we've altered the behavior of
  • // ours to support batch updates
  • // (catch-22)
  • // Ideally, what we need here is
  • // super.super.getGeneratedKeys()
  • // but that construct doesn't exist in
  • // Java, so that's why there's
  • // this kludge.
  • rs = getGeneratedKeysInternal(); -
  • while (rs.next()) {
  • this.batchedGeneratedKeys
  • .add(new ByteArrayRow(new byte[][] { rs
  • .getBytes(1) }));
  • }
    + updateCounts[commandIndex] = executeUpdate(false, true);
    } finally {
  • if (rs != null) {
  • rs.close();
    + previousBindValuesForBatch = this.parameterBindings;
    + }
    +
    + if (this.retrieveGeneratedKeys) {
    + java.sql.ResultSet rs = null;
    +
    + try {
    + // we don't want to use our version,
    + // because we've altered the behavior of
    + // ours to support batch updates
    + // (catch-22)
    + // Ideally, what we need here is
    + // super.super.getGeneratedKeys()
    + // but that construct doesn't exist in
    + // Java, so that's why there's
    + // this kludge.
    + rs = getGeneratedKeysInternal();
    +
    + while (rs.next()) {
    + this.batchedGeneratedKeys
    + .add(new ByteArrayRow(new byte[][] { rs
    + .getBytes(1) }));
    + }
    + } finally {
    + if (rs != null) {
    + rs.close();
    + }
    } }
    + } catch (SQLException ex) {
    + updateCounts[commandIndex] = EXECUTE_FAILED;
    +
    + if (this.continueBatchOnError &&
    + !(ex instanceof MySQLTimeoutException) &&
    + !(ex instanceof MySQLStatementCancelledException)) {
    + sqlEx = ex;
    + } else {
    + int[] newUpdateCounts = new int[commandIndex];
    + System.arraycopy(updateCounts, 0,
    + newUpdateCounts, 0, commandIndex);
    +
    + throw new java.sql.BatchUpdateException(ex
    + .getMessage(), ex.getSQLState(), ex
    + .getErrorCode(), newUpdateCounts);
    + }
    }
  • } catch (SQLException ex) {
  • updateCounts[commandIndex] = EXECUTE_FAILED; -
  • if (this.continueBatchOnError) {
  • sqlEx = ex;
  • } else {
  • int[] newUpdateCounts = new int[commandIndex];
  • System.arraycopy(updateCounts, 0,
  • newUpdateCounts, 0, commandIndex); -
  • throw new java.sql.BatchUpdateException(ex
  • .getMessage(), ex.getSQLState(), ex
  • .getErrorCode(), newUpdateCounts);
  • } } }
    + } finally {
    + if (timeoutTask != null) {
    + timeoutTask.cancel();
    + }
    +
    + resetCancelledState();
    }

                                         if (sqlEx != null) {
@@ -2576,5 +2639,184 @@

 		return serverStatementId;
 	}
 

+ public synchronized boolean canRewriteAsMultivalueInsertStatement() {
+ if (!super.canRewriteAsMultivalueInsertStatement()) {
+ return false;
+ }
+
+ BindValue[] currentBindValues = null;
+ BindValue[] previousBindValues = null;
+
+ int nbrCommands = this.batchedArgs.size();
+
+ // Can't have type changes between sets of bindings for this to work...
+
+ for (int commandIndex = 0; commandIndex < nbrCommands; commandIndex++) {
+ Object arg = this.batchedArgs.get(commandIndex);
+
+ if (!(arg instanceof String)) {
+
+ currentBindValues = ((BatchedBindValues) arg).batchedParameterValues;
+
+ // We need to check types each time, as
+ // the user might have bound different
+ // types in each addBatch()
+
+ if (previousBindValues != null) {
+ for (int j = 0; j < this.parameterBindings.length; j++) {
+ if (currentBindValues[j].bufferType != previousBindValues[j].bufferType) {
+ return false;
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+ }

+ /**
+ * Computes the maximum parameter set size, and entire batch size given
+ * the number of arguments in the batch.
+ */
+ protected long[] computeMaxParameterSetSizeAndBatchSize(int numBatchedArgs) {
+ long sizeOfEntireBatch = 1 + /* com_execute */ + 4 /* stmt id */ + 1 /* flags */ + 4 /* batch count padding */;
+ long maxSizeOfParameterSet = 0;
+
+ for (int i = 0; i < numBatchedArgs; i++) {
+ BindValue[] paramArg = ((BatchedBindValues) this.batchedArgs.get(i)).batchedParameterValues;
+
+ long sizeOfParameterSet = 0;
+
+ sizeOfParameterSet += (this.parameterCount + 7) / 8; // for isNull
+
+ sizeOfParameterSet += this.parameterCount * 2; // have to send types
+
+ for (int j = 0; j < this.parameterBindings.length; j++) {
+ if (!paramArg[j].isNull) {
+
+ long size = paramArg[j].getBoundLength();
+
+ if (paramArg[j].isLongData) {
+ if (size != -1) {
+ sizeOfParameterSet += size;
+ }
+ } else {
+ sizeOfParameterSet += size;
+ }
+ }
+ }
+
+ sizeOfEntireBatch += sizeOfParameterSet;
+
+ if (sizeOfParameterSet > maxSizeOfParameterSet) {
+ maxSizeOfParameterSet = sizeOfParameterSet;
+ }
+ }
+
+ return new long[] {maxSizeOfParameterSet, sizeOfEntireBatch};
+ }
+
+ protected int setOneBatchedParameterSet(
+ java.sql.PreparedStatement batchedStatement, int batchedParamIndex,
+ Object paramSet) throws SQLException {
+ BindValue[] paramArg = ((BatchedBindValues) paramSet).batchedParameterValues;
+
+ for (int j = 0; j < paramArg.length; j++) {
+ if (paramArg[j].isNull) {
+ batchedStatement.setNull(batchedParamIndex++, Types.NULL);
+ } else {
+ if (paramArg[j].isLongData) {
+ Object value = paramArg[j].value;
+
+ if (value instanceof InputStream) {
+ batchedStatement.setBinaryStream(batchedParamIndex++,
+ (InputStream) value,
+ (int) paramArg[j].bindLength);
+ } else {
+ batchedStatement.setCharacterStream(
+ batchedParamIndex++, (Reader) value,
+ (int) paramArg[j].bindLength);
+ }
+ } else {
+
+ switch (paramArg[j].bufferType) {
+
+ case MysqlDefs.FIELD_TYPE_TINY:
+ batchedStatement.setByte(batchedParamIndex++,
+ paramArg[j].byteBinding);
+ break;
+ case MysqlDefs.FIELD_TYPE_SHORT:
+ batchedStatement.setShort(batchedParamIndex++,
+ paramArg[j].shortBinding);
+ break;
+ case MysqlDefs.FIELD_TYPE_LONG:
+ batchedStatement.setInt(batchedParamIndex++,
+ paramArg[j].intBinding);
+ break;
+ case MysqlDefs.FIELD_TYPE_LONGLONG:
+ batchedStatement.setLong(batchedParamIndex++,
+ paramArg[j].longBinding);
+ break;
+ case MysqlDefs.FIELD_TYPE_FLOAT:
+ batchedStatement.setFloat(batchedParamIndex++,
+ paramArg[j].floatBinding);
+ break;
+ case MysqlDefs.FIELD_TYPE_DOUBLE:
+ batchedStatement.setDouble(batchedParamIndex++,
+ paramArg[j].doubleBinding);
+ break;
+ case MysqlDefs.FIELD_TYPE_TIME:
+ batchedStatement.setTime(batchedParamIndex++,
+ (Time) paramArg[j].value);
+ break;
+ case MysqlDefs.FIELD_TYPE_DATE:
+ batchedStatement.setDate(batchedParamIndex++,
+ (Date) paramArg[j].value);
+ break;
+ case MysqlDefs.FIELD_TYPE_DATETIME:
+ case MysqlDefs.FIELD_TYPE_TIMESTAMP:
+ batchedStatement.setTimestamp(batchedParamIndex++,
+ (Timestamp) paramArg[j].value);
+ break;
+ case MysqlDefs.FIELD_TYPE_VAR_STRING:
+ case MysqlDefs.FIELD_TYPE_STRING:
+ case MysqlDefs.FIELD_TYPE_VARCHAR:
+ case MysqlDefs.FIELD_TYPE_DECIMAL:
+ case MysqlDefs.FIELD_TYPE_NEW_DECIMAL:
+ Object value = paramArg[j].value;
+
+ if (value instanceof byte[]) {
+ batchedStatement.setBytes(batchedParamIndex,
+ (byte[]) value);
+ } else {
+ batchedStatement.setString(batchedParamIndex,
+ (String) value);
+ }
+
+ BindValue asBound = ((ServerPreparedStatement) batchedStatement)
+ .getBinding(
+ batchedParamIndex + 1 /*
+ * uses 1-based
+ * offset
+ */,
+ false);
+ asBound.bufferType = paramArg[j].bufferType;
+
+ batchedParamIndex++;
+
+ break;
+ default:
+ throw new IllegalArgumentException(
+ "Unknown type when re-binding parameter into batched statement for parameter index "
+ + batchedParamIndex);
+ }
+ }
+ }
+ }
+
+ return batchedParamIndex;
+ }
+
+

 }
-- 
MySQL Code Commits Mailing List
For list archives: 
http://lists.mysql.com/commits
To unsubscribe:    
http://lists.mysql.com/commits?unsub=lists@pantek.com
Received on Wed Oct 31 23:34:36 2007

This archive was generated by hypermail 2.1.8 : Thu Jul 03 2008 - 11:15:58 EDT


Contact Us  Legal Notices  Order Services Online 
Pantek Home  Privacy Policy  IT news  Site Map  Pantek Library