📄 statement.java
字号:
agent_.logWriter_.traceExit(this, "execute", b); } return b; } } public int getResultSetHoldability() throws SqlException { if (agent_.loggingEnabled()) { agent_.logWriter_.traceEntry(this, "getResultSetHoldability"); } checkForClosedStatement(); return resultSetHoldability_; } // ----------------------- box car and callback methods --------------------- // All callbacks must be client-side only operations. // Use of MaterialStatement interface is necessary to avoid multiple inheritance problem in Java. public void writeSetSpecialRegister(java.util.ArrayList sqlsttList) throws SqlException { materialStatement_.writeSetSpecialRegister_(sqlsttList); } public void readSetSpecialRegister() throws SqlException { materialStatement_.readSetSpecialRegister_(); } public void writeExecuteImmediate(String sql, Section section) throws SqlException { materialStatement_.writeExecuteImmediate_(sql, section); } public void readExecuteImmediate() throws SqlException { materialStatement_.readExecuteImmediate_(); } public void completeExecuteImmediate(Sqlca sqlca) { int sqlcode = completeSqlca(sqlca); if (sqlcode < 0) { return; } if (sqlca != null) { updateCount_ = sqlca.getUpdateCount(); } } public void readExecuteImmediateForBatch(String sql) throws SqlException { materialStatement_.readExecuteImmediateForBatch_(sql); } public void writePrepareDescribeOutput(String sql, Section section) throws SqlException { materialStatement_.writePrepareDescribeOutput_(sql, section); } public void readPrepareDescribeOutput() throws SqlException { materialStatement_.readPrepareDescribeOutput_(); } public void completePrepareDescribeOutput(ColumnMetaData resultSetMetaData, Sqlca sqlca) { completePrepare(sqlca); resultSetMetaData_ = resultSetMetaData; if (agent_.loggingEnabled()) { agent_.logWriter_.traceResultSetMetaData(this, resultSetMetaData_); } } // Used for re-prepares across commit only public void writePrepare(String sql, Section section) throws SqlException { materialStatement_.writePrepare_(sql, section); } public void readPrepare() throws SqlException { materialStatement_.readPrepare_(); } public void completePrepare(Sqlca sqlca) { int sqlcode = completeSqlca(sqlca); if (sqlcode < 0) { return; } markPrepared(); } public void writeOpenQuery(Section section, int fetchSize, int resultSetType) throws SqlException { materialStatement_.writeOpenQuery_(section, fetchSize, resultSetType); } public void readOpenQuery() throws SqlException { materialStatement_.readOpenQuery_(); } public void completeOpenQuery(Sqlca sqlca, ResultSet resultSet) { completeSqlca(sqlca); resultSet_ = resultSet; // For NET, resultSet_ == null when open query fails and receives OPNQFLRM. // Then, in NetStatementReply.parseOpenQueryFailure(), completeOpenQuery() is // invoked with resultSet explicitly set to null. if (resultSet == null) { return; } resultSet.resultSetMetaData_ = resultSetMetaData_; resultSet.resultSetMetaData_.resultSetConcurrency_ = resultSet.resultSetConcurrency_; // only cache the Cursor object for a PreparedStatement and if a Cursor object is // not already cached. if (cachedCursor_ == null && isPreparedStatement_) { cachedCursor_ = resultSet_.cursor_; } // The following two assignments should have already happened via prepareEvent(), // but are included here for safety for the time being. if (sqlca != null && sqlca.getSqlCode() < 0) { return; } openOnServer_ = true; resultSet.cursor_.rowsRead_ = 0; // Set fetchSize_ to the default(64) if not set by the user if the resultset is scrollable. // This fetchSize_ is used to check for a complete rowset when rowsets are parsed. // For scrollable cursors when the fetchSize_ is not set, (fetchSize_ == 0), a default // fetchSize of 64 is sent on behalf of the application, so we need to update the fetchSize_ // here to 64. if (resultSet_.fetchSize_ == 0 && (resultSet_.resultSetType_ == java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE || resultSet_.resultSetType_ == java.sql.ResultSet.TYPE_SCROLL_SENSITIVE)) { resultSet_.fetchSize_ = org.apache.derby.client.am.Configuration.defaultFetchSize; } } public void completeExecuteCallOpenQuery(Sqlca sqlca, ResultSet resultSet, ColumnMetaData resultSetMetaData, Section generatedSection) { resultSet.completeSqlca(sqlca); // For CallableStatements we can't just clobber the resultSet_ here, must use setResultSetEvent() separately resultSet.resultSetMetaData_ = resultSetMetaData; // The following two assignments should have already happened via prepareEvent(), // but are included here for safety for the time being. if (sqlca != null && sqlca.getSqlCode() < 0) { return; } openOnServer_ = true; resultSet.cursor_.rowsRead_ = 0; resultSet.generatedSection_ = generatedSection; // We are always sending the default fetchSize of 64 if not set for stored procedure calls. // This is different from the "normal" cursor case for forward_only cursors, where if // fetchSize_ is not set, we do not send any default value. Here since we always send // the fetchSize_, we need to set it to what we sent. if (resultSet.fetchSize_ == 0) { resultSet.fetchSize_ = org.apache.derby.client.am.Configuration.defaultFetchSize; } } public void writeExecuteCall(boolean outputExpected, String procedureName, Section section, int fetchSize, boolean suppressResultSets, // for batch updates == true int resultSetType, ColumnMetaData parameterMetaData, Object[] inputs) throws SqlException { materialStatement_.writeExecuteCall_(outputExpected, procedureName, section, fetchSize, suppressResultSets, resultSetType, parameterMetaData, inputs); } public void readExecuteCall() throws SqlException { materialStatement_.readExecuteCall_(); } public void completeExecuteCall(Sqlca sqlca, Cursor singletonParams, ResultSet[] resultSets) { completeExecuteCall(sqlca, singletonParams); resultSetList_ = resultSets; if (resultSets != null) { resultSet_ = resultSets[0]; } indexOfCurrentResultSet_ = 0; } public void completeExecuteCall(Sqlca sqlca, Cursor singletonParams) // no result sets returned { completeExecute(sqlca); //if ((sqlca != null) && ((sqlca.getSqlCode() < 0) || (sqlca.getSqlCode() == 100))) if (sqlca != null && sqlca.getSqlCode() < 0) { singletonRowData_ = null; } else { singletonRowData_ = singletonParams; if (cachedSingletonRowData_ == null && isPreparedStatement_) { cachedSingletonRowData_ = singletonRowData_; } } } // Callback for CALLS, and PreparedStatement updates. public void completeExecute(Sqlca sqlca) { if (sqlca == null) { return; } int sqlcode = sqlca.getSqlCode(); if (sqlcode < 0) { agent_.accumulateReadException(new SqlException(agent_.logWriter_, sqlca)); returnValueFromProcedure_ = sqlcode; } else { updateCount_ = sqlca.getUpdateCount(); // sometime for call statement, protocol will return updateCount_, we will always set that to 0 // sqlMode_ is not set for statements, only for prepared statements if (sqlMode_ == isCall__) { updateCount_ = -1; returnValueFromProcedure_ = sqlca.getSqlErrd()[0]; ////what is this for?? } // Sqlcode 466 indicates a call statement has issued and result sets returned. // This is a good place to set some state variable to indicate result sets are open // for call, so that when autocommit is true, commit will not be issued until the // result sets are closed. // Currently, commit is not issued even there is no result set. // do not externalize sqlcode +100 if (sqlcode > 0 && sqlcode != 466 && sqlcode != 100) { accumulateWarning(new SqlWarning(agent_.logWriter_, sqlca)); } } } public void setUpdateCount(int updateCount) { updateCount_ = updateCount; } private boolean willTickleServer(int number, boolean allowAutoCommits) throws SqlException { boolean requiresAutocommit = false; if (resultSetList_ != null) { for (int i = 0; i < number; i++) { if (resultSetList_[i] != null) { if (resultSetList_[i].openOnServer_) { return true; // for the writeClose flow } if (!resultSetList_[i].autoCommitted_ && allowAutoCommits) { requiresAutocommit = true; // for the commit flow } } } } else if (generatedKeysResultSet_ != null && generatedKeysResultSet_.openOnServer_) { generatedKeysResultSet_.writeClose(); } else if (resultSet_ != null) { if (resultSet_.openOnServer_) { return true; // for the writeClose flow } if (!resultSet_.autoCommitted_ && allowAutoCommits) { requiresAutocommit = true; } } if (connection_.autoCommit_ && requiresAutocommit) { // for the auto-commit; if (connection_.isXAConnection_) { return (connection_.getXAState() == Connection.XA_T0_NOT_ASSOCIATED) ; } else { return true; } } return false; } private void flowClose() throws SqlException { agent_.beginWriteChain(this); writeClose(true); // true means permit auto-commits agent_.flow(this); readClose(true); // true means permit auto-commits agent_.endReadChain(); } private void flowCloseOutsideUOW() throws SqlException { agent_.beginWriteChainOutsideUOW(); writeClose(true); // true means permit auto-commits agent_.flowOutsideUOW(); readClose(true); // true means permit auto-commits agent_.endReadChain(); } final void writeClose(boolean allowAutoCommits) throws SqlException { writeCloseResultSets(allowAutoCommits); } final void readClose(boolean allowAutoCommits) throws SqlException { readCloseResultSets(allowAutoCommits); } boolean writeCloseResultSets(boolean allowAutoCommits) throws SqlException { int numberOfResultSetsToClose = (resultSetList_ == null) ? 0 : resultSetList_.length; return writeCloseResultSets(numberOfResultSetsToClose, allowAutoCommits); } // The connection close processing passes allowAutoCommits=false because if we drove an // autocommits after each statement close, then when we issue close requests on non-held cursors // the server would complain that the non-held cursor was already closed from the previous statement's auto-commit. // So the solution is to never autocommit statements during connection close processing. // // Here's the operative explanation: // Given a sequence of open statements S1, S2, .... a logic problem is occuring after S1 close-query // drives an auto-commit, and S2 close-query is driven against a non-held cursor. // The first auto-commit driven by S1 triggers a callback that closes S2's non-held cursor, // and so the subsequent S2 close-query request generates an error from the server saying // that the cursor is already closed. // // This is fixed by passing a flag to our statement close processing that prevents // driving additional auto-commits after each statement close. // Connectino close drives its own final auto-commit.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -