📄 serverpreparedstatement.java
字号:
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()); } /** * @see java.sql.PreparedStatement#getParameterMetaData() */ public ParameterMetaData getParameterMetaData() throws SQLException { checkClosed(); if (this.parameterMetaData == null) { this.parameterMetaData = new MysqlParameterMetadata( this.parameterFields, this.parameterCount); } 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); 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()) { 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); } 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); //$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 // MysqlIO mysql = this.connection.getIO(); 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(); 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(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -