/EQEmuJSM/mysql-connector-java-5.1.13/src/com/mysql/jdbc/ServerPreparedStatement.java
Java | 2358 lines | 1472 code | 407 blank | 479 comment | 285 complexity | c998aec71828fb17aaf47ac6985f8e7a MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, Apache-2.0
Large files files are truncated, but you can click here to view the full file
- /*
- Copyright 2002-2007 MySQL AB, 2008-2010 Sun Microsystems
- All rights reserved. Use is subject to license terms.
- The MySQL Connector/J is licensed under the terms of the GPL,
- like most MySQL Connectors. There are special exceptions to the
- terms and conditions of the GPL as it is applied to this software,
- see the FLOSS License Exception available on mysql.com.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; version 2 of the
- License.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Â See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- 02110-1301 USA
- */
- package com.mysql.jdbc;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.Reader;
- import java.io.UnsupportedEncodingException;
- import java.lang.reflect.Constructor;
- import java.lang.reflect.InvocationTargetException;
- import java.math.BigDecimal;
- import java.net.URL;
- import java.sql.Array;
- import java.sql.Blob;
- import java.sql.Clob;
- import java.sql.Date;
- import java.sql.ParameterMetaData;
- import java.sql.Ref;
- import java.sql.ResultSet;
- import java.sql.SQLException;
- import java.sql.Time;
- import java.sql.Timestamp;
- import java.sql.Types;
- import java.util.ArrayList;
- import java.util.Calendar;
- import java.util.GregorianCalendar;
- import java.util.TimeZone;
- import com.mysql.jdbc.exceptions.MySQLStatementCancelledException;
- import com.mysql.jdbc.exceptions.MySQLTimeoutException;
- import com.mysql.jdbc.profiler.ProfilerEvent;
- /**
- * JDBC Interface for MySQL-4.1 and newer server-side PreparedStatements.
- *
- * @author Mark Matthews
- * @version $Id: ServerPreparedStatement.java,v 1.1.2.2 2005/05/17 14:58:56
- * mmatthews Exp $
- */
- public class ServerPreparedStatement extends PreparedStatement {
- private static final Constructor JDBC_4_SPS_CTOR;
-
- static {
- if (Util.isJdbc4()) {
- try {
- JDBC_4_SPS_CTOR = Class.forName("com.mysql.jdbc.JDBC4ServerPreparedStatement")
- .getConstructor(
- new Class[] { MySQLConnection.class, String.class, String.class,
- Integer.TYPE, Integer.TYPE});
- } catch (SecurityException e) {
- throw new RuntimeException(e);
- } catch (NoSuchMethodException e) {
- throw new RuntimeException(e);
- } catch (ClassNotFoundException e) {
- throw new RuntimeException(e);
- }
- } else {
- JDBC_4_SPS_CTOR = null;
- }
- }
-
- protected static final int BLOB_STREAM_READ_BUF_SIZE = 8192;
- static class BatchedBindValues {
- BindValue[] batchedParameterValues;
- BatchedBindValues(BindValue[] paramVals) {
- int numParams = paramVals.length;
- this.batchedParameterValues = new BindValue[numParams];
- for (int i = 0; i < numParams; i++) {
- this.batchedParameterValues[i] = new BindValue(paramVals[i]);
- }
- }
- }
- public static class BindValue {
- long boundBeforeExecutionNum = 0;
-
- public long bindLength; /* Default length of data */
- int bufferType; /* buffer type */
- byte byteBinding;
- double doubleBinding;
- float floatBinding;
- int intBinding;
- public boolean isLongData; /* long data indicator */
- public boolean isNull; /* NULL indicator */
- boolean isSet = false; /* has this parameter been set? */
- long longBinding;
- short shortBinding;
- public Object value; /* The value to store */
- BindValue() {
- }
- BindValue(BindValue copyMe) {
- this.value = copyMe.value;
- this.isSet = copyMe.isSet;
- this.isLongData = copyMe.isLongData;
- this.isNull = copyMe.isNull;
- this.bufferType = copyMe.bufferType;
- this.bindLength = copyMe.bindLength;
- this.byteBinding = copyMe.byteBinding;
- this.shortBinding = copyMe.shortBinding;
- this.intBinding = copyMe.intBinding;
- this.longBinding = copyMe.longBinding;
- this.floatBinding = copyMe.floatBinding;
- this.doubleBinding = copyMe.doubleBinding;
- }
- void reset() {
- this.isSet = false;
- this.value = null;
- this.isLongData = false;
- this.byteBinding = 0;
- this.shortBinding = 0;
- this.intBinding = 0;
- this.longBinding = 0L;
- this.floatBinding = 0;
- this.doubleBinding = 0D;
- }
- public String toString() {
- return toString(false);
- }
- public String toString(boolean quoteIfNeeded) {
- if (this.isLongData) {
- return "' STREAM DATA '";
- }
- switch (this.bufferType) {
- case MysqlDefs.FIELD_TYPE_TINY:
- return String.valueOf(byteBinding);
- case MysqlDefs.FIELD_TYPE_SHORT:
- return String.valueOf(shortBinding);
- case MysqlDefs.FIELD_TYPE_LONG:
- return String.valueOf(intBinding);
- case MysqlDefs.FIELD_TYPE_LONGLONG:
- return String.valueOf(longBinding);
- case MysqlDefs.FIELD_TYPE_FLOAT:
- return String.valueOf(floatBinding);
- case MysqlDefs.FIELD_TYPE_DOUBLE:
- return String.valueOf(doubleBinding);
- case MysqlDefs.FIELD_TYPE_TIME:
- case MysqlDefs.FIELD_TYPE_DATE:
- case MysqlDefs.FIELD_TYPE_DATETIME:
- case MysqlDefs.FIELD_TYPE_TIMESTAMP:
- case MysqlDefs.FIELD_TYPE_VAR_STRING:
- case MysqlDefs.FIELD_TYPE_STRING:
- case MysqlDefs.FIELD_TYPE_VARCHAR:
- if (quoteIfNeeded) {
- return "'" + String.valueOf(value) + "'";
- } else {
- return String.valueOf(value);
- }
- default:
- if (value instanceof byte[]) {
- return "byte data";
- } else {
- if (quoteIfNeeded) {
- return "'" + String.valueOf(value) + "'";
- } else {
- return String.valueOf(value);
- }
- }
- }
- }
-
- 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) */
- private static final byte MAX_DATE_REP_LENGTH = (byte) 5;
- /*
- * 1 (length) + 2 (year) + 1 (month) + 1 (day) + 1 (hour) + 1 (minute) + 1
- * (second) + 4 (microseconds)
- */
- private static final byte MAX_DATETIME_REP_LENGTH = 12;
- /*
- * 1 (length) + 1 (is negative) + 4 (day count) + 1 (hour) + 1 (minute) + 1
- * (seconds) + 4 (microseconds)
- */
- private static final byte MAX_TIME_REP_LENGTH = 13;
-
- private boolean hasOnDuplicateKeyUpdate = false;
- private void storeTime(Buffer intoBuf, Time tm) throws SQLException {
-
- intoBuf.ensureCapacity(9);
- intoBuf.writeByte((byte) 8); // length
- intoBuf.writeByte((byte) 0); // neg flag
- intoBuf.writeLong(0); // tm->day, not used
- Calendar sessionCalendar = getCalendarInstanceForSessionOrNew();
-
- synchronized (sessionCalendar) {
- java.util.Date oldTime = sessionCalendar.getTime();
- try {
- sessionCalendar.setTime(tm);
- intoBuf.writeByte((byte) sessionCalendar.get(Calendar.HOUR_OF_DAY));
- intoBuf.writeByte((byte) sessionCalendar.get(Calendar.MINUTE));
- intoBuf.writeByte((byte) sessionCalendar.get(Calendar.SECOND));
- // intoBuf.writeLongInt(0); // tm-second_part
- } finally {
- sessionCalendar.setTime(oldTime);
- }
- }
- }
- /**
- * Flag indicating whether or not the long parameters have been 'switched'
- * back to normal parameters. We can not execute() if clearParameters()
- * hasn't been called in this case.
- */
- private boolean detectedLongParameterSwitch = false;
- /**
- * The number of fields in the result set (if any) for this
- * PreparedStatement.
- */
- private int fieldCount;
- /** Has this prepared statement been marked invalid? */
- private boolean invalid = false;
- /** If this statement has been marked invalid, what was the reason? */
- private SQLException invalidationException;
- /** Does this query modify data? */
- private boolean isSelectQuery;
- private Buffer outByteBuffer;
- /** Bind values for individual fields */
- private BindValue[] parameterBindings;
- /** Field-level metadata for parameters */
- private Field[] parameterFields;
- /** Field-level metadata for result sets. */
- private Field[] resultFields;
- /** Do we need to send/resend types to the server? */
- private boolean sendTypesToServer = false;
- /** The ID that the server uses to identify this PreparedStatement */
- private long serverStatementId;
- /** The type used for string bindings, changes from version-to-version */
- private int stringTypeCode = MysqlDefs.FIELD_TYPE_STRING;
- private boolean serverNeedsResetBeforeEachExecution;
- /**
- * Creates a prepared statement instance -- We need to provide factory-style
- * methods so we can support both JDBC3 (and older) and JDBC4 runtimes,
- * otherwise the class verifier complains when it tries to load JDBC4-only
- * interface classes that are present in JDBC4 method signatures.
- */
- protected static ServerPreparedStatement getInstance(MySQLConnection conn,
- String sql, String catalog, int resultSetType,
- int resultSetConcurrency) throws SQLException {
- if (!Util.isJdbc4()) {
- return new ServerPreparedStatement(conn, sql, catalog,
- resultSetType, resultSetConcurrency);
- }
- try {
- return (ServerPreparedStatement) JDBC_4_SPS_CTOR.newInstance(new Object[] { conn,
- sql, catalog, Constants.integerValueOf(resultSetType),
- Constants.integerValueOf(resultSetConcurrency) });
- } catch (IllegalArgumentException e) {
- throw new SQLException(e.toString(), SQLError.SQL_STATE_GENERAL_ERROR);
- } catch (InstantiationException e) {
- throw new SQLException(e.toString(), SQLError.SQL_STATE_GENERAL_ERROR);
- } catch (IllegalAccessException e) {
- throw new SQLException(e.toString(), SQLError.SQL_STATE_GENERAL_ERROR);
- } catch (InvocationTargetException e) {
- Throwable target = e.getTargetException();
-
- if (target instanceof SQLException) {
- throw (SQLException)target;
- }
-
- throw new SQLException(target.toString(), SQLError.SQL_STATE_GENERAL_ERROR);
- }
- }
- /**
- * Creates a new ServerPreparedStatement object.
- *
- * @param conn
- * the connection creating us.
- * @param sql
- * the SQL containing the statement to prepare.
- * @param catalog
- * the catalog in use when we were created.
- *
- * @throws SQLException
- * If an error occurs
- */
- protected ServerPreparedStatement(MySQLConnection conn, String sql, String catalog,
- int resultSetType, int resultSetConcurrency)
- throws SQLException {
- super(conn, catalog);
- checkNullOrEmptyQuery(sql);
- this.hasOnDuplicateKeyUpdate = containsOnDuplicateKeyInString(sql);
-
- int startOfStatement = findStartOfStatement(sql);
-
- this.firstCharOfStmt = StringUtils.firstAlphaCharUc(sql, startOfStatement);
-
- this.isSelectQuery = 'S' == this.firstCharOfStmt;
-
- if (this.connection.versionMeetsMinimum(5, 0, 0)) {
- this.serverNeedsResetBeforeEachExecution =
- !this.connection.versionMeetsMinimum(5, 0, 3);
- } else {
- this.serverNeedsResetBeforeEachExecution =
- !this.connection.versionMeetsMinimum(4, 1, 10);
- }
-
- this.useAutoSlowLog = this.connection.getAutoSlowLog();
- this.useTrueBoolean = this.connection.versionMeetsMinimum(3, 21, 23);
- this.hasLimitClause = (StringUtils.indexOfIgnoreCase(sql, "LIMIT") != -1); //$NON-NLS-1$
-
- String statementComment = this.connection.getStatementComment();
- this.originalSql = (statementComment == null) ? sql : "/* "
- + statementComment + " */ " + sql;
- if (this.connection.versionMeetsMinimum(4, 1, 2)) {
- this.stringTypeCode = MysqlDefs.FIELD_TYPE_VAR_STRING;
- } else {
- this.stringTypeCode = MysqlDefs.FIELD_TYPE_STRING;
- }
- try {
- serverPrepare(sql);
- } catch (SQLException sqlEx) {
- realClose(false, true);
- // don't wrap SQLExceptions
- throw sqlEx;
- } catch (Exception ex) {
- realClose(false, true);
- SQLException sqlEx = SQLError.createSQLException(ex.toString(),
- SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor());
- sqlEx.initCause(ex);
-
- throw sqlEx;
- }
-
- setResultSetType(resultSetType);
- setResultSetConcurrency(resultSetConcurrency);
-
- this.parameterTypes = new int[this.parameterCount];
- }
- /**
- * JDBC 2.0 Add a set of parameters to the batch.
- *
- * @exception SQLException
- * if a database-access error occurs.
- *
- * @see StatementImpl#addBatch
- */
- public synchronized void addBatch() throws SQLException {
- checkClosed();
- if (this.batchedArgs == null) {
- this.batchedArgs = new ArrayList();
- }
- this.batchedArgs.add(new BatchedBindValues(this.parameterBindings));
- }
- protected String asSql(boolean quoteStreamsAndUnknowns) throws SQLException {
- if (this.isClosed) {
- return "statement has been closed, no further internal information available";
- }
-
- PreparedStatement pStmtForSub = null;
- try {
- pStmtForSub = PreparedStatement.getInstance(this.connection,
- this.originalSql, this.currentCatalog);
- int numParameters = pStmtForSub.parameterCount;
- int ourNumParameters = this.parameterCount;
- for (int i = 0; (i < numParameters) && (i < ourNumParameters); i++) {
- if (this.parameterBindings[i] != null) {
- if (this.parameterBindings[i].isNull) {
- pStmtForSub.setNull(i + 1, Types.NULL);
- } else {
- BindValue bindValue = this.parameterBindings[i];
- //
- // Handle primitives first
- //
- switch (bindValue.bufferType) {
- case MysqlDefs.FIELD_TYPE_TINY:
- pStmtForSub.setByte(i + 1, bindValue.byteBinding);
- break;
- case MysqlDefs.FIELD_TYPE_SHORT:
- pStmtForSub.setShort(i + 1, bindValue.shortBinding);
- break;
- case MysqlDefs.FIELD_TYPE_LONG:
- pStmtForSub.setInt(i + 1, bindValue.intBinding);
- break;
- case MysqlDefs.FIELD_TYPE_LONGLONG:
- pStmtForSub.setLong(i + 1, bindValue.longBinding);
- break;
- case MysqlDefs.FIELD_TYPE_FLOAT:
- pStmtForSub.setFloat(i + 1, bindValue.floatBinding);
- break;
- case MysqlDefs.FIELD_TYPE_DOUBLE:
- pStmtForSub.setDouble(i + 1,
- bindValue.doubleBinding);
- break;
- default:
- pStmtForSub.setObject(i + 1,
- this.parameterBindings[i].value);
- break;
- }
- }
- }
- }
- return pStmtForSub.asSql(quoteStreamsAndUnknowns);
- } finally {
- if (pStmtForSub != null) {
- try {
- pStmtForSub.close();
- } catch (SQLException sqlEx) {
- ; // ignore
- }
- }
- }
- }
- /*
- * (non-Javadoc)
- *
- * @see com.mysql.jdbc.Statement#checkClosed()
- */
- protected void checkClosed() throws SQLException {
- if (this.invalid) {
- throw this.invalidationException;
- }
- super.checkClosed();
- }
- /**
- * @see java.sql.PreparedStatement#clearParameters()
- */
- public void clearParameters() throws SQLException {
- checkClosed();
- clearParametersInternal(true);
- }
- private void clearParametersInternal(boolean clearServerParameters)
- throws SQLException {
- boolean hadLongData = false;
- if (this.parameterBindings != null) {
- for (int i = 0; i < this.parameterCount; i++) {
- if ((this.parameterBindings[i] != null)
- && this.parameterBindings[i].isLongData) {
- hadLongData = true;
- }
- this.parameterBindings[i].reset();
- }
- }
- if (clearServerParameters && hadLongData) {
- serverResetStatement();
- this.detectedLongParameterSwitch = false;
- }
- }
- protected boolean isCached = false;
- private boolean useAutoSlowLog;
- private Calendar serverTzCalendar;
- private Calendar defaultTzCalendar;
- protected void setClosed(boolean flag) {
- this.isClosed = flag;
- }
-
- /**
- * @see java.sql.Statement#close()
- */
- public synchronized void close() throws SQLException {
- if (this.isCached && !this.isClosed) {
- clearParameters();
-
- this.isClosed = true;
-
- this.connection.recachePreparedStatement(this);
- return;
- }
-
- realClose(true, true);
- }
- private void dumpCloseForTestcase() {
- StringBuffer buf = new StringBuffer();
- this.connection.generateConnectionCommentBlock(buf);
- buf.append("DEALLOCATE PREPARE debug_stmt_");
- buf.append(this.statementId);
- buf.append(";\n");
- this.connection.dumpTestcaseQuery(buf.toString());
- }
- private void dumpExecuteForTestcase() throws SQLException {
- StringBuffer buf = new StringBuffer();
- for (int i = 0; i < this.parameterCount; i++) {
- this.connection.generateConnectionCommentBlock(buf);
- buf.append("SET @debug_stmt_param");
- buf.append(this.statementId);
- buf.append("_");
- buf.append(i);
- buf.append("=");
- if (this.parameterBindings[i].isNull) {
- buf.append("NULL");
- } else {
- buf.append(this.parameterBindings[i].toString(true));
- }
- buf.append(";\n");
- }
- this.connection.generateConnectionCommentBlock(buf);
- buf.append("EXECUTE debug_stmt_");
- buf.append(this.statementId);
- if (this.parameterCount > 0) {
- buf.append(" USING ");
- for (int i = 0; i < this.parameterCount; i++) {
- if (i > 0) {
- buf.append(", ");
- }
- buf.append("@debug_stmt_param");
- buf.append(this.statementId);
- buf.append("_");
- buf.append(i);
- }
- }
- buf.append(";\n");
- this.connection.dumpTestcaseQuery(buf.toString());
- }
- private void dumpPrepareForTestcase() throws SQLException {
- StringBuffer buf = new StringBuffer(this.originalSql.length() + 64);
- this.connection.generateConnectionCommentBlock(buf);
- buf.append("PREPARE debug_stmt_");
- buf.append(this.statementId);
- buf.append(" FROM \"");
- buf.append(this.originalSql);
- buf.append("\";\n");
- this.connection.dumpTestcaseQuery(buf.toString());
- }
- protected int[] executeBatchSerially(int batchTimeout) throws SQLException {
- MySQLConnection locallyScopedConn = this.connection;
-
- if (locallyScopedConn == null) {
- checkClosed();
- }
-
- if (locallyScopedConn.isReadOnly()) {
- throw SQLError.createSQLException(Messages
- .getString("ServerPreparedStatement.2") //$NON-NLS-1$
- + Messages.getString("ServerPreparedStatement.3"), //$NON-NLS-1$
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor());
- }
- checkClosed();
- synchronized (locallyScopedConn.getMutex()) {
- clearWarnings();
- // Store this for later, we're going to 'swap' them out
- // as we execute each batched statement...
- BindValue[] oldBindValues = this.parameterBindings;
- try {
- int[] updateCounts = null;
- if (this.batchedArgs != null) {
- int nbrCommands = this.batchedArgs.size();
- updateCounts = new int[nbrCommands];
- if (this.retrieveGeneratedKeys) {
- this.batchedGeneratedKeys = new ArrayList(nbrCommands);
- }
- for (int i = 0; i < nbrCommands; i++) {
- updateCounts[i] = -3;
- }
- SQLException sqlEx = null;
- int commandIndex = 0;
- BindValue[] previousBindValuesForBatch = null;
- CancelTask timeoutTask = null;
-
- try {
- if (locallyScopedConn.getEnableQueryTimeouts() &&
- batchTimeout != 0
- && locallyScopedConn.versionMeetsMinimum(5, 0, 0)) {
- timeoutTask = new CancelTask(this);
- locallyScopedConn.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) }, getExceptionInterceptor()));
- }
- } finally {
- if (rs != null) {
- rs.close();
- }
- }
- }
- } catch (SQLException ex) {
- updateCounts[commandIndex] = EXECUTE_FAILED;
-
- if (this.continueBatchOnError &&
- !(ex instanceof MySQLTimeoutException) &&
- !(ex instanceof MySQLStatementCancelledException)
- && !hasDeadlockOrTimeoutRolledBackTx(ex)) {
- 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();
-
- locallyScopedConn.getCancelTimer().purge();
- }
-
- resetCancelledState();
- }
- if (sqlEx != null) {
- throw new java.sql.BatchUpdateException(sqlEx
- .getMessage(), sqlEx.getSQLState(), sqlEx
- .getErrorCode(), updateCounts);
- }
- }
- return (updateCounts != null) ? updateCounts : new int[0];
- } finally {
- this.parameterBindings = oldBindValues;
- this.sendTypesToServer = true;
- clearBatch();
- }
- }
- }
- /**
- * @see com.mysql.jdbc.PreparedStatement#executeInternal(int,
- * com.mysql.jdbc.Buffer, boolean, boolean)
- */
- protected com.mysql.jdbc.ResultSetInternalMethods executeInternal(int maxRowsToRetrieve,
- Buffer sendPacket, boolean createStreamingResultSet,
- boolean queryIsSelectOnly, Field[] metadataFromCache,
- boolean isBatch)
- throws SQLException {
- this.numberOfExecutions++;
- // We defer to server-side execution
- try {
- return serverExecute(maxRowsToRetrieve, createStreamingResultSet,
- metadataFromCache);
- } catch (SQLException sqlEx) {
- // don't wrap SQLExceptions
- if (this.connection.getEnablePacketDebug()) {
- this.connection.getIO().dumpPacketRingBuffer();
- }
- if (this.connection.getDumpQueriesOnException()) {
- String extractedSql = toString();
- StringBuffer messageBuf = new StringBuffer(extractedSql
- .length() + 32);
- messageBuf
- .append("\n\nQuery being executed when exception was thrown:\n");
- messageBuf.append(extractedSql);
- messageBuf.append("\n\n");
- sqlEx = ConnectionImpl.appendMessageToException(sqlEx, messageBuf
- .toString(), getExceptionInterceptor());
- }
- throw sqlEx;
- } catch (Exception ex) {
- if (this.connection.getEnablePacketDebug()) {
- this.connection.getIO().dumpPacketRingBuffer();
- }
- SQLException sqlEx = SQLError.createSQLException(ex.toString(),
- SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor());
- if (this.connection.getDumpQueriesOnException()) {
- String extractedSql = toString();
- StringBuffer messageBuf = new StringBuffer(extractedSql
- .length() + 32);
- messageBuf
- .append("\n\nQuery being executed when exception was thrown:\n");
- messageBuf.append(extractedSql);
- messageBuf.append("\n\n");
- sqlEx = ConnectionImpl.appendMessageToException(sqlEx, messageBuf
- .toString(), getExceptionInterceptor());
- }
- sqlEx.initCause(ex);
-
- throw sqlEx;
- }
- }
- /**
- * @see com.mysql.jdbc.PreparedStatement#fillSendPacket()
- */
- protected Buffer fillSendPacket() throws SQLException {
- return null; // we don't use this type of packet
- }
- /**
- * @see com.mysql.jdbc.PreparedStatement#fillSendPacket(byte,
- * java.io.InputStream, boolean, int)
- */
- protected Buffer fillSendPacket(byte[][] batchedParameterStrings,
- InputStream[] batchedParameterStreams, boolean[] batchedIsStream,
- int[] batchedStreamLengths) throws SQLException {
- return null; // we don't use this type of packet
- }
- /**
- * Returns the structure representing the value that (can be)/(is)
- * bound at the given parameter index.
- *
- * @param parameterIndex 1-based
- * @param forLongData is this for a stream?
- * @return
- * @throws SQLException
- */
- protected BindValue getBinding(int parameterIndex, boolean forLongData)
- throws SQLException {
- checkClosed();
-
- if (this.parameterBindings.length == 0) {
- throw SQLError.createSQLException(Messages
- .getString("ServerPreparedStatement.8"), //$NON-NLS-1$
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor());
- }
- parameterIndex--;
- if ((parameterIndex < 0)
- || (parameterIndex >= this.parameterBindings.length)) {
- throw SQLError.createSQLException(Messages
- .getString("ServerPreparedStatement.9") //$NON-NLS-1$
- + (parameterIndex + 1)
- + Messages.getString("ServerPreparedStatement.10") //$NON-NLS-1$
- + this.parameterBindings.length,
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor());
- }
- if (this.parameterBindings[parameterIndex] == null) {
- this.parameterBindings[parameterIndex] = new BindValue();
- } else {
- if (this.parameterBindings[parameterIndex].isLongData
- && !forLongData) {
- this.detectedLongParameterSwitch = true;
- }
- }
- this.parameterBindings[parameterIndex].isSet = true;
- this.parameterBindings[parameterIndex].boundBeforeExecutionNum = this.numberOfExecutions;
- return this.parameterBindings[parameterIndex];
- }
- /**
- * @see com.mysql.jdbc.PreparedStatement#getBytes(int)
- */
- byte[] getBytes(int parameterIndex) throws SQLException {
- BindValue bindValue = getBinding(parameterIndex, false);
- if (bindValue.isNull) {
- return null;
- } else if (bindValue.isLongData) {
- throw SQLError.notImplemented();
- } else {
- if (this.outByteBuffer == null) {
- this.outByteBuffer = new Buffer(this.connection
- .getNetBufferLength());
- }
- this.outByteBuffer.clear();
- int originalPosition = this.outByteBuffer.getPosition();
- storeBinding(this.outByteBuffer, bindValue, this.connection.getIO());
- int newPosition = this.outByteBuffer.getPosition();
- int length = newPosition - originalPosition;
- byte[] valueAsBytes = new byte[length];
- System.arraycopy(this.outByteBuffer.getByteBuffer(),
- originalPosition, valueAsBytes, 0, length);
- return valueAsBytes;
- }
- }
- /**
- * @see java.sql.PreparedStatement#getMetaData()
- */
- public java.sql.ResultSetMetaData getMetaData() throws SQLException {
- checkClosed();
- if (this.resultFields == null) {
- return null;
- }
- return new ResultSetMetaData(this.resultFields,
- this.connection.getUseOldAliasMetadataBehavior(), getExceptionInterceptor());
- }
- /**
- * @see java.sql.PreparedStatement#getParameterMetaData()
- */
- public ParameterMetaData getParameterMetaData() throws SQLException {
- checkClosed();
-
- if (this.parameterMetaData == null) {
- this.parameterMetaData = new MysqlParameterMetadata(
- this.parameterFields, this.parameterCount, getExceptionInterceptor());
- }
-
- return this.parameterMetaData;
- }
- /**
- * @see com.mysql.jdbc.PreparedStatement#isNull(int)
- */
- boolean isNull(int paramIndex) {
- throw new IllegalArgumentException(Messages
- .getString("ServerPreparedStatement.7")); //$NON-NLS-1$
- }
- /**
- * Closes this connection and frees all resources.
- *
- * @param calledExplicitly
- * was this called from close()?
- *
- * @throws SQLException
- * if an error occurs
- */
- protected void realClose(boolean calledExplicitly,
- boolean closeOpenResults) throws SQLException {
- if (this.isClosed) {
- return;
- }
- if (this.connection != null) {
- if (this.connection.getAutoGenerateTestcaseScript()) {
- dumpCloseForTestcase();
- }
- //
- // Don't communicate with the server if we're being
- // called from the finalizer...
- //
- // This will leak server resources, but if we don't do this,
- // we'll deadlock (potentially, because there's no guarantee
- // when, what order, and what concurrency finalizers will be
- // called with). Well-behaved programs won't rely on finalizers
- // to clean up their statements.
- //
- SQLException exceptionDuringClose = null;
- if (calledExplicitly && !this.connection.isClosed()) {
- synchronized (this.connection.getMutex()) {
- try {
- MysqlIO mysql = this.connection.getIO();
- Buffer packet = mysql.getSharedSendPacket();
- packet.writeByte((byte) MysqlDefs.COM_CLOSE_STATEMENT);
- packet.writeLong(this.serverStatementId);
- mysql.sendCommand(MysqlDefs.COM_CLOSE_STATEMENT, null,
- packet, true, null, 0);
- } catch (SQLException sqlEx) {
- exceptionDuringClose = sqlEx;
- }
- }
- }
- super.realClose(calledExplicitly, closeOpenResults);
- clearParametersInternal(false);
- this.parameterBindings = null;
- this.parameterFields = null;
- this.resultFields = null;
- if (exceptionDuringClose != null) {
- throw exceptionDuringClose;
- }
- }
- }
- /**
- * Used by Connection when auto-reconnecting to retrieve 'lost' prepared
- * statements.
- *
- * @throws SQLException
- * if an error occurs.
- */
- protected void rePrepare() throws SQLException {
- this.invalidationException = null;
- try {
- serverPrepare(this.originalSql);
- } catch (SQLException sqlEx) {
- // don't wrap SQLExceptions
- this.invalidationException = sqlEx;
- } catch (Exception ex) {
- this.invalidationException = SQLError.createSQLException(ex.toString(),
- SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor());
- this.invalidationException.initCause(ex);
- }
- if (this.invalidationException != null) {
- this.invalid = true;
- this.parameterBindings = null;
- this.parameterFields = null;
- this.resultFields = null;
- if (this.results != null) {
- try {
- this.results.close();
- } catch (Exception ex) {
- ;
- }
- }
- if (this.connection != null) {
- if (this.maxRowsChanged) {
- this.connection.unsetMaxRows(this);
- }
- if (!this.connection.getDontTrackOpenResources()) {
- this.connection.unregisterStatement(this);
- }
- }
- }
- }
- /**
- * Tells the server to execute this prepared statement with the current
- * parameter bindings.
- *
- * <pre>
- *
- *
- * - Server gets the command 'COM_EXECUTE' to execute the
- * previously prepared query. If there is any param markers;
- * then client will send the data in the following format:
- *
- * [COM_EXECUTE:1]
- * [STMT_ID:4]
- * [NULL_BITS:(param_count+7)/8)]
- * [TYPES_SUPPLIED_BY_CLIENT(0/1):1]
- * [[length]data]
- * [[length]data] .. [[length]data].
- *
- * (Note: Except for string/binary types; all other types will not be
- * supplied with length field)
- *
- *
- * </pre>
- *
- * @param maxRowsToRetrieve
- * DOCUMENT ME!
- * @param createStreamingResultSet
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- *
- * @throws SQLException
- */
- private com.mysql.jdbc.ResultSetInternalMethods serverExecute(int maxRowsToRetrieve,
- boolean createStreamingResultSet,
- Field[] metadataFromCache) throws SQLException {
- synchronized (this.connection.getMutex()) {
- MysqlIO mysql = this.connection.getIO();
- if (mysql.shouldIntercept()) {
- ResultSetInternalMethods interceptedResults =
- mysql.invokeStatementInterceptorsPre(this.originalSql, this, true);
-
- if (interceptedResults != null) {
- return interceptedResults;
- }
- }
-
- if (this.detectedLongParameterSwitch) {
- // Check when values were bound
- boolean firstFound = false;
- long boundTimeToCheck = 0;
-
- for (int i = 0; i < this.parameterCount - 1; i++) {
- if (this.parameterBindings[i].isLongData) {
- if (firstFound && boundTimeToCheck !=
- this.parameterBindings[i].boundBeforeExecutionNum) {
- throw SQLError.createSQLException(Messages
- .getString("ServerPreparedStatement.11") //$NON-NLS-1$
- + Messages.getString("ServerPreparedStatement.12"), //$NON-NLS-1$
- SQLError.SQL_STATE_DRIVER_NOT_CAPABLE, getExceptionInterceptor());
- } else {
- firstFound = true;
- boundTimeToCheck = this.parameterBindings[i].boundBeforeExecutionNum;
- }
- }
- }
-
- // Okay, we've got all "newly"-bound streams, so reset
- // server-side state to clear out previous bindings
-
- serverResetStatement();
- }
- // Check bindings
- for (int i = 0; i < this.parameterCount; i++) {
- if (!this.parameterBindings[i].isSet) {
- throw SQLError.createSQLException(Messages
- .getString("ServerPreparedStatement.13") + (i + 1) //$NON-NLS-1$
- + Messages.getString("ServerPreparedStatement.14"),
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor()); //$NON-NLS-1$
- }
- }
- //
- // Send all long data
- //
- for (int i = 0; i < this.parameterCount; i++) {
- if (this.parameterBindings[i].isLongData) {
- serverLongData(i, this.parameterBindings[i]);
- }
- }
- if (this.connection.getAutoGenerateTestcaseScript()) {
- dumpExecuteForTestcase();
- }
- //
- // store the parameter values
- //
- Buffer packet = mysql.getSharedSendPacket();
- packet.clear();
- packet.writeByte((byte) MysqlDefs.COM_EXECUTE);
- packet.writeLong(this.serverStatementId);
- boolean usingCursor = false;
- if (this.connection.versionMeetsMinimum(4, 1, 2)) {
- // we only create cursor-backed result sets if
- // a) The query is a SELECT
- // b) The server supports it
- // c) We know it is forward-only (note this doesn't
- // preclude updatable result sets)
- // d) The user has set a fetch size
- if (this.resultFields != null &&
- this.connection.isCursorFetchEnabled()
- && getResultSetType() == ResultSet.TYPE_FORWARD_ONLY
- && getResultSetConcurrency() == ResultSet.CONCUR_READ_ONLY
- && getFetchSize() > 0) {
- packet.writeByte(MysqlDefs.OPEN_CURSOR_FLAG);
- usingCursor = true;
- } else {
- packet.writeByte((byte) 0); // placeholder for flags
- }
- packet.writeLong(1); // placeholder for parameter
- // iterations
- }
- /* Reserve place for null-marker bytes */
- int nullCount = (this.parameterCount + 7) / 8;
- // if (mysql.versionMeetsMinimum(4, 1, 2)) {
- // nullCount = (this.parameterCount + 9) / 8;
- // }
- int nullBitsPosition = packet.getPosition();
- for (int i = 0; i < nullCount; i++) {
- packet.writeByte((byte) 0);
- }
- byte[] nullBitsBuffer = new byte[nullCount];
- /* In case if buffers (type) altered, indicate to server */
- packet.writeByte(this.sendTypesToServer ? (byte) 1 : (byte) 0);
- if (this.sendTypesToServer) {
- /*
- * Store types of parameters in first in first package that is
- * sent to the server.
- */
- for (int i = 0; i < this.parameterCount; i++) {
- packet.writeInt(this.parameterBindings[i].bufferType);
- }
- }
- //
- // store the parameter values
- //
- for (int i = 0; i < this.parameterCount; i++) {
- if (!this.parameterBindings[i].isLongData) {
- if (!this.parameterBindings[i].isNull) {
- storeBinding(packet, this.parameterBindings[i], mysql);
- } else {
- nullBitsBuffer[i / 8] |= (1 << (i & 7));
- }
- }
- }
- //
- // Go back and write the NULL flags
- // to the beginning of the packet
- //
- int endPosition = packet.getPosition();
- packet.setPosition(nullBitsPosition);
- packet.writeBytesNoNull(nullBitsBuffer);
- packet.setPosition(endPosition);
- long begin = 0;
- boolean logSlowQueries = this.connection.getLogSlowQueries();
- boolean gatherPerformanceMetrics = this.connection
- .getGatherPerformanceMetrics();
- if (this.profileSQL || logSlowQueries || gatherPerformanceMetrics) {
- begin = mysql.getCurrentTimeNanosOrMillis();
- }
- resetCancelledState();
-
- CancelTask timeoutTask = null;
- try {
- if (this.connection.getEnableQueryTimeouts() &&
- this.timeoutInMillis != 0
- && this.connection.versionMeetsMinimum(5, 0, 0)) {
- timeoutTask = new CancelTask(this);
- this.connection.getCancelTimer().schedule(timeoutTask,
- this.timeoutInMillis);
- }
-
- Buffer resultPacket = mysql.sendCommand(MysqlDefs.COM_EXECUTE,
- null, packet, false, null, 0);
-
- long queryEndTime = 0L;
-
- if (logSlowQueries || gatherPerformanceMetrics || this.profileSQL) {
- queryEndTime = mysql.getCurrentTimeNanosOrMillis();
- }
-
- if (timeoutTask != null) {
- timeoutTask.cancel();
-
- this.connection.getCancelTimer().purge();
-
- if (timeoutTask.caughtWhileCancelling != null) {
- throw timeoutTask.caughtWhileCancelling;
- }
-
- timeoutTask = null;
- }
-
- synchronized (this.cancelTimeoutMutex) {
- if (this.wasCancelled) {
- SQLException cause = null;
-
- if (this.wasCancelledByTimeout) {
- cause = new MySQLTimeoutException();
- } else {
- cause = new MySQLStatementCancelledException();
- }
-
- resetCancelledState();
-
- throw cause;
- }
- }
- boolean queryWasSlow = false;
-
- if (logSlowQueries || gatherPerformanceMetrics) {
- long elapsedTime = queryEndTime - begin;
- if (logSlowQueries) {
- if (this.useAutoSlowLog) {
- queryWasSlow = elapsedTime > this.connection.getSlowQueryThresholdMillis();
- } else {
- queryWasSlow = this.connection.isAbonormallyLongQuery(elapsedTime);
-
- this.connection.reportQueryTime(elapsedTime);
- }
- }
- if (queryWasSlow) {
-
- StringBuffer mesgBuf = new StringBuffer(
- 48 + this.originalSql.length());
- mesgBuf.append(Messages
- .getString("ServerPreparedStatement.15")); //$NON-NLS-1$
- mesgBuf.append(mysql.getSlowQueryThreshold());
- mesgBuf.append(Messages
- .getString("ServerPreparedStatement.15a")); //$NON-NLS-1$
- mesgBuf.append(elapsedTime);
- mesgBuf.append(Messages
- .getString("ServerPreparedStatement.16")); //$NON-NLS-1$
- mesgBuf.append("as prepared: ");
- mesgBuf.append(this.originalSql);
- mesgBuf.append("\n\n with parameters bound:\n\n");
- mesgBuf.append(asSql(true));
- this.eventSink
- .consumeEvent(new ProfilerEvent(
- ProfilerEvent.TYPE_SLOW_QUERY,
- "", this.currentCatalog, this.connection.getId(), //$NON-NLS-1$
- getId(), 0, System.currentTimeMillis(),
- elapsedTime, mysql
- .getQueryTimingUnits(), null,
- new Throwable(), mesgBuf.toString()));
- }
- if (gatherPerformanceMetrics) {
- this.connection.registerQueryExecutionTime(elapsedTime);
- }
- }
- this.connection.incrementNumberOfPreparedExecutes();
- if (this.profileSQL) {
- this.eventSink = ProfilerEventHandlerFactory
- .getInstance(this.connection);
- this.eventSink.consumeEvent(new ProfilerEvent(
- ProfilerEvent.TYPE_EXECUTE,
- "", this.currentCatalog, //$NON-NLS-1$
- this.connectionId, this.statementId, -1, System
- .currentTimeMillis(), (int) (mysql
- .getCurrentTimeNanosOrMillis() - begin),
- mysql.getQueryTimingUnits(), null, new Throwable(),
- truncateQueryToLog(asSql(true))));
- }
-
- com.mysql.jdbc.ResultSetInternalMethods rs = mysql.readAllResults(this,
- maxRowsToRetrieve, this.resultSetType,
- this.resultSetConcurrency, createStreamingResultSet,
- this.currentCatalog, resultPacket, true, this.fieldCount,
- metadataFromCache);
-
- if (mysql.shouldIntercept()) {
- ResultSetInternalMethods interceptedResults =
- mysql.invokeStatementInterceptorsPost(this.originalSql, this, rs, true, null);
-
- if (interceptedResults != null) {
- rs = interceptedResults;
- }
- }
-
- if (this.profileSQL) {
- long fetchEndTime = mysql.getCurrentTimeNanosOrMillis();
- this.eventSink.consumeEvent(new ProfilerEvent(
- ProfilerEvent.TYPE_FETCH,
- "", this.currentCatalog, this.connection.getId(), //$NON-NLS-1$
- getId(), 0 /* FIXME rs.resultId */, System.currentTimeMillis(),
- (fetchEndTime - queryEndTime), mysql
- .getQueryTimingUnits(), null,
- new Throwable(), null));
- }
-
- if (queryWasSlow && this.connection.getExplainSlowQueries()) {
- String queryAsString = asSql(true);
- mysql.explainSlowQuery(queryAsString.getBytes(),
- queryAsString);
- }
-
- if (!createStreamingResultSet &&
- this.serverNeedsResetBeforeEachExecution) {
- serverResetStatement(); // clear any long data...
- }
-
-
- this.sendTypesToServer = false;
- this.results = rs;
-
- if (mysql.hadWarnings()) {
- mysql.scanForAndThrowDataTruncation();
- }
-
- return rs;
- } catch (SQLException sqlEx) {
- if (mysql.shouldIntercept()) {
- mysql.invokeStatementInterceptorsPost(this.originalSql, this, null, true, sqlEx);
- }
-
- throw sqlEx;
- } finally {
- if (timeoutTask != null) {
- timeoutTask.cancel();
- this.connection.getCancelTimer().purge();
- }
- }
- }
- }
- /**
- * Sends stream-type data parameters to the server.
- *
- * <pre>
- *
- * Long data handling:
- *
- * - Server gets the long data in pieces with command type 'COM_LONG_DATA'.
- * - The packet recieved will have the format as:
- * [COM_LONG_DATA: 1][STMT_ID:4][parameter_number:2][type:2][data]
- * - Checks if the type is specified by client, and if yes reads the type,
- * and stores the data in that format.
- * - It's up to the client to check for read data ended. The server doesn't
- * care; and also server doesn't notify to the client that it got the
- * data or not; if there is any error; then during execute; the error
- * will be returned
- *
- * </pre>
- *
- * @param parameterIndex
- * DOCUMENT ME!
- * @param longData
- * DOCUMENT ME!
- *
- * @throws SQLException
- * if an error occurs.
- */
- private void serverLongData(int parameterIndex, BindValue longData)
- throws SQLException {
- synchronized (this.connection.getMutex()) {
- MysqlIO mysql = this.connection.getIO();
- Buffer packet = mysql.getSharedSendPacket();
- Object value = longData.value;
- if (value instanceof byte[]) {
- packet.clear();
- packet.writeByte((byte) MysqlDefs.COM_LONG_DATA);
- packet.writeLong(this.serverStatementId);
- packet.writeInt((parameterIndex));
- packet.writeBytesNoNull((byte[]) longData.value);
- mysql.sendCommand(MysqlDefs.COM_LONG_DATA, null, packet, true,
- null, 0);
- } else if (value instanceof InputStream) {
- storeStream(mysql, parameterIndex, packet, (InputStream) value);
- } else if (value instanceof java.sql.Blob) {
- storeStream(mysql, parameterIndex, packet,
- ((java.sql.Blob) value).getBinaryStream());
- } else if (value instanceof Reader) {
- storeReader(mysql, parameterIndex, packet, (Reader) value);
- } else {
- throw SQLError.createSQLException(Messages
- .getString("ServerPreparedStatement.18") //$NON-NLS-1$
- + value.getClass().getName() + "'", //$NON-NLS-1$
- SQLError.SQL_STATE_ILLEGAL_ARGUMENT, getExceptionInterceptor());
- }
- }
- }
- private void serverPrepare(String sql) throws SQLException {
- synchronized (this.connection.getMutex()) {
- MysqlIO mysql = this.connection.getIO();
- if (this.connection.getAutoGenerateTestcaseScript()) {
- dumpPrepareForTestcase();
- }
- try {
- long begin = 0;
- if (StringUtils.startsWithIgnoreCaseAndWs(sql, "LOAD DATA")) { //$NON-NLS-1$
- this.isLoadDataQuery = true;
- } else {
- this.isLoadDataQuery = false;
- }
- if (this.connection.getProfileSql()) {
- begin = System.currentTimeMillis();
- }
- String characterEncoding = null;
- String connectionEncoding = this.connection.getEncoding();
- if (!this.isLoadDataQuery && this.connection.getUseUnicode()
- && (connectionEncoding != null)) {
- characterEncoding = connectionEncoding;
- }
- Buffer prepareResultPacket = mysql.sendCommand(
- MysqlDefs.COM_PREPARE, sql, null, false,
- characterEncoding, 0);
- if (this.connection.versionMeetsMinimum(4, 1, 1)) {
- // 4.1.1 and newer use the first byte
- // as an 'ok' or 'error' flag, so move
- // the buffer pointer past it to
- // start reading the statement id.
- prepareResultPacket.setPosition(1);
- } else {
- // 4.1.0 doesn't use the first byte as an
- // 'ok' or 'error' flag
- prepareResultPacket.setPosition(0);
- }
- this.serverStatementId = prepareResultPacket.readLong();
- this.fieldCount = prepareResultPacket.readInt();
- this.parameterCount = prepareResultPacket.readInt();
- this.parameterBindings = new BindValue[this.parameterCount];
- for (int i = 0; i < this.parameterCount; i++) {
- this.parameterBindings[i] = new BindValue();
- }
- this.connection.incrementNumberOfPrepares();
- if (this.profileSQL) {
- this.eventSink.consumeEvent(new ProfilerEvent(
- ProfilerEvent.TYPE_PREPARE,
- "", this.currentCatalog, //$NON-NLS-1$
- this.connectionId, this.statementId, -1,
- System.currentTimeMillis(),
- mysql.getCurrentTimeNanosOrMillis() - begin,
- mysql.getQueryTimingUnits(), null,
- new Throwable(), truncateQueryToLog(sql)));
- }
- if (this.parameterCount > 0) {
- if (this.connection.versionMeetsMinimum(4, 1, 2)
- && !mysql.isVersion(5, 0, 0)) {
- this.parameterFields = new Field[this.parameterCount];
- Buffer metaDataPacket = mysql.readPacket();
- int i = 0;
- while (!metaDataPacket.isLastDataPacket()
- && (i < this.parameterCount)) {
- this.parameterFields[i++] = mysql.unpackField(
- metaDataPacket, false);
- metaDataPacket = mysql.readPacket();
- }
- }
- }
- if (this.fieldCount > 0) {
- this.resultFields = new Field[this.fieldCount];
- Buffer fieldPacket = mysql.readPacket();
- int i = 0;
- // Read in the result set column information
- while (!fieldPacket.isLastDataPacket()
- && (i < this.fieldCount)) {
- this.resultFields[i++] = mysql.unpackField(fieldPacket,
- false);
- fieldPacket = mysql.readPacket();
- }
- }
- } catch (SQLException sqlEx) {
- if (this.connection.getDumpQueriesOnException()) {
- StringBuffer messageBuf = new StringBuffer(this.originalSql
- .length() + 32);
- messageBuf
- .append("\n\nQuery being prepared when exception was thrown:\n\n");
- messageBuf.append(this.originalSql);
- sqlEx = ConnectionImpl.appendMessageToException(sqlEx,
- messageBuf.toString(), getExceptionInterceptor());
- }
- throw sqlEx;
- } finally {
- // Leave the I/O channel in a known state...there might be
- // packets out there
- // that we're not interested in
- this.connection.getIO().clearInputStream();
- }
- }
- }
- private String truncateQueryToLog(String sql) {
- String query = null;
-
- if (sql.length() > this.connection.getMaxQuerySizeToLog()) {
- StringBuffer queryBuf = new StringBuffer(
- this.connection.getMaxQuerySizeToLog() + 12);
- queryBuf.append(sql.substring(0, this.connection.getMaxQuerySizeToLog()));
- queryBuf.append(Messages.getString("MysqlIO.25"));
-
- query = queryBuf.toString();
- } else {
- query = sql;
- }
-
- return query;
- }
- private void serverResetStatement() throws SQLException {
- synchronized (this.connection.getMutex()) {
- MysqlIO mysql = this.connection.getIO();
- Buffer packet = mysql.getSharedSendPacket();
- packet.clear();
- packet.writeByte((byte) MysqlDefs.COM_RESET_STMT);
- packet.writeLong(this.serverStatementId);
- try {
- mysql.sendCommand(MysqlDefs.COM_RESET_STMT, null, packet,
- !this.connection.versionMeetsMinimum(4, 1, 2), null, 0);
- } catch (SQLException sqlEx) {
- throw sqlEx;
- } catch (Exception ex) {
- SQLException sqlEx = SQLError.createSQLException(ex.toString(),
- SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor());
- sqlEx.initCause(ex);
-
- throw sqlEx;
- } finally {
- mysql.clearInputStream();
- }
- }
- }
- /**
- * @see java.sql.PreparedStatement#setArray(int, java.sql.Array)
- */
- public void setArray(int i, Array x) throws SQLException {
- throw SQLError.notImplemented();
- }
- /**
- * @see java.sql.PreparedStatement#setAsciiStream(int, java.io.InputStream,
- * int)
- */
- public void setAsciiStream(int parameterIndex, InputStream x, int length)
- throws SQLException {
- checkClosed();
- if (x == null) {
- setNull(parameterIndex, java.sql.Types.BIN…
Large files files are truncated, but you can click here to view the full file