0001: /*
0002:
0003: Derby - Class org.apache.derby.client.am.PreparedStatement
0004:
0005: Licensed to the Apache Software Foundation (ASF) under one or more
0006: contributor license agreements. See the NOTICE file distributed with
0007: this work for additional information regarding copyright ownership.
0008: The ASF licenses this file to You under the Apache License, Version 2.0
0009: (the "License"); you may not use this file except in compliance with
0010: the License. You may obtain a copy of the License at
0011:
0012: http://www.apache.org/licenses/LICENSE-2.0
0013:
0014: Unless required by applicable law or agreed to in writing, software
0015: distributed under the License is distributed on an "AS IS" BASIS,
0016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017: See the License for the specific language governing permissions and
0018: limitations under the License.
0019:
0020: */
0021:
0022: package org.apache.derby.client.am;
0023:
0024: import org.apache.derby.shared.common.reference.JDBC40Translation;
0025: import org.apache.derby.shared.common.reference.SQLState;
0026:
0027: import java.io.InputStream;
0028: import java.io.Reader;
0029: import java.sql.SQLException;
0030: import java.util.ArrayList;
0031: import org.apache.derby.client.ClientPooledConnection;
0032: import org.apache.derby.jdbc.ClientDriver;
0033:
0034: public class PreparedStatement extends Statement implements
0035: java.sql.PreparedStatement, PreparedStatementCallbackInterface {
0036: //---------------------navigational cheat-links-------------------------------
0037: // Cheat-links are for convenience only, and are not part of the conceptual model.
0038: // Warning:
0039: // Cheat-links should only be defined for invariant state data.
0040: // That is, the state data is set by the constructor and never changes.
0041:
0042: // Alias for downcast (MaterialPreparedStatementProxy) super.materialStatement.
0043: public MaterialPreparedStatement materialPreparedStatement_ = null;
0044:
0045: //-----------------------------state------------------------------------------
0046:
0047: public String sql_;
0048:
0049: // This variable is only used by Batch.
0050: // True if a call sql statement has an OUT or INOUT parameter registered.
0051: public boolean outputRegistered_ = false;
0052:
0053: // Parameter inputs are cached as objects so they may be sent on execute()
0054: public Object[] parameters_;
0055:
0056: boolean[] parameterSet_;
0057: boolean[] parameterRegistered_;
0058:
0059: void setInput(int parameterIndex, Object input) {
0060: parameters_[parameterIndex - 1] = input;
0061: parameterSet_[parameterIndex - 1] = true;
0062: }
0063:
0064: public ColumnMetaData parameterMetaData_; // type information for input sqlda
0065:
0066: private ArrayList parameterTypeList;
0067:
0068: // The problem with storing the scrollable ResultSet associated with cursorName in scrollableRS_ is
0069: // that when the PreparedStatement is re-executed, it has a new ResultSet, however, we always do
0070: // the reposition on the ResultSet that was stored in scrollableRS_, and we never update scrollableRS_
0071: // when PreparedStatement is re-execute. So the new ResultSet that needs to be repositioned never
0072: // gets repositioned.
0073: // So instead of caching the scrollableRS_, we will cache the cursorName. And re-retrieve the scrollable
0074: // result set from the map using this cursorName every time the PreparedStatement excutes.
0075: String positionedUpdateCursorName_ = null;
0076:
0077: // the ClientPooledConnection object used to notify of the events that occur
0078: // on this prepared statement object
0079: protected final ClientPooledConnection pooledConnection_;
0080:
0081: private void initPreparedStatement() {
0082: materialPreparedStatement_ = null;
0083: sql_ = null;
0084: outputRegistered_ = false;
0085: parameters_ = null;
0086: parameterSet_ = null;
0087: parameterRegistered_ = null;
0088: parameterMetaData_ = null;
0089: parameterTypeList = null;
0090: isAutoCommittableStatement_ = true;
0091: isPreparedStatement_ = true;
0092: }
0093:
0094: protected void initResetPreparedStatement() {
0095: outputRegistered_ = false;
0096: isPreparedStatement_ = true;
0097:
0098: if (parameterMetaData_ != null) {
0099: resetParameters();
0100: }
0101: }
0102:
0103: public void reset(boolean fullReset) throws SqlException {
0104: if (fullReset) {
0105: connection_.resetPrepareStatement(this );
0106: } else {
0107: super .initResetPreparedStatement();
0108: initResetPreparedStatement();
0109: }
0110: }
0111:
0112: private void resetParameters() {
0113: for (int i = 0; i < parameterMetaData_.columns_; i++) {
0114: parameters_[i] = null;
0115: parameterSet_[i] = false;
0116: parameterRegistered_[i] = false;
0117: }
0118: }
0119:
0120: /**
0121: *
0122: * The PreparedStatement constructor used for JDBC 2 positioned update
0123: * statements. Called by material statement constructors.
0124: * It has the ClientPooledConnection as one of its parameters
0125: * this is used to raise the Statement Events when the prepared
0126: * statement is closed
0127: *
0128: * @param agent The instance of NetAgent associated with this
0129: * CallableStatement object.
0130: * @param connection The connection object associated with this
0131: * PreparedStatement Object.
0132: * @param sql A String object that is the SQL statement to be sent
0133: * to the database.
0134: * @param section Section
0135: * @param cpc The ClientPooledConnection wraps the underlying physical
0136: * connection associated with this prepared statement.
0137: * It is used to pass the Statement closed and the Statement
0138: * error occurred events that occur back to the
0139: * ClientPooledConnection.
0140: * @throws SqlException
0141: *
0142: */
0143:
0144: public PreparedStatement(Agent agent, Connection connection,
0145: String sql, Section section, ClientPooledConnection cpc)
0146: throws SqlException {
0147: super (agent, connection);
0148: // PreparedStatement is poolable by default
0149: isPoolable = true;
0150: initPreparedStatement(sql, section);
0151: pooledConnection_ = cpc;
0152: }
0153:
0154: public void resetPreparedStatement(Agent agent,
0155: Connection connection, String sql, Section section)
0156: throws SqlException {
0157: super .resetStatement(agent, connection);
0158: initPreparedStatement();
0159: initPreparedStatement(sql, section);
0160: }
0161:
0162: private void initPreparedStatement(String sql, Section section)
0163: throws SqlException {
0164: sql_ = sql;
0165: isPreparedStatement_ = true;
0166:
0167: parseSqlAndSetSqlModes(sql_);
0168: section_ = section;
0169: }
0170:
0171: /**
0172: * The PreparedStatementConstructor used for jdbc 2 prepared statements
0173: * with scroll attributes. Called by material statement constructors.
0174: * It has the ClientPooledConnection as one of its parameters
0175: * this is used to raise the Statement Events when the prepared
0176: * statement is closed
0177: *
0178: * @param agent The instance of NetAgent associated with this
0179: * CallableStatement object.
0180: * @param connection The connection object associated with this
0181: * PreparedStatement Object.
0182: * @param sql A String object that is the SQL statement
0183: * to be sent to the database.
0184: * @param type One of the ResultSet type constants.
0185: * @param concurrency One of the ResultSet concurrency constants.
0186: * @param holdability One of the ResultSet holdability constants.
0187: * @param autoGeneratedKeys a flag indicating whether auto-generated
0188: * keys should be returned.
0189: * @param columnNames an array of column names indicating the columns that
0190: * should be returned from the inserted row or rows.
0191: * @param cpc The ClientPooledConnection wraps the underlying physical
0192: * connection associated with this prepared statement
0193: * it is used to pass the Statement closed and the Statement
0194: * error occurred events that occur back to the
0195: * ClientPooledConnection.
0196: * @throws SqlException
0197: */
0198: public PreparedStatement(Agent agent, Connection connection,
0199: String sql, int type, int concurrency, int holdability,
0200: int autoGeneratedKeys, String[] columnNames,
0201: ClientPooledConnection cpc) throws SqlException {
0202: super (agent, connection, type, concurrency, holdability,
0203: autoGeneratedKeys, columnNames);
0204: // PreparedStatement is poolable by default
0205: isPoolable = true;
0206: initPreparedStatement(sql);
0207: pooledConnection_ = cpc;
0208: }
0209:
0210: public void resetPreparedStatement(Agent agent,
0211: Connection connection, String sql, int type,
0212: int concurrency, int holdability, int autoGeneratedKeys,
0213: String[] columnNames) throws SqlException {
0214: super .resetStatement(agent, connection, type, concurrency,
0215: holdability, autoGeneratedKeys, columnNames);
0216: initPreparedStatement();
0217: initPreparedStatement(sql);
0218: }
0219:
0220: private void initPreparedStatement(String sql) throws SqlException {
0221: sql_ = super .escape(sql);
0222: parseSqlAndSetSqlModes(sql_);
0223: isPreparedStatement_ = true;
0224:
0225: // Check for positioned update statement and assign a section from the
0226: // same package as the corresponding query section.
0227: // Scan the sql for an "update...where current of <cursor-name>".
0228: String cursorName = null;
0229: if (sqlUpdateMode_ == isDeleteSql__
0230: || sqlUpdateMode_ == isUpdateSql__) {
0231: String[] sqlAndCursorName = extractCursorNameFromWhereCurrentOf(sql_);
0232: if (sqlAndCursorName != null) {
0233: cursorName = sqlAndCursorName[0];
0234: sql_ = sqlAndCursorName[1];
0235: }
0236: }
0237: if (cursorName != null) {
0238: positionedUpdateCursorName_ = cursorName;
0239: // Get a new section from the same package as the query section
0240: section_ = agent_.sectionManager_
0241: .getPositionedUpdateSection(cursorName, false); // false means get a regular section
0242:
0243: if (section_ == null) {
0244: throw new SqlException(agent_.logWriter_,
0245: new ClientMessageId(
0246: SQLState.CURSOR_INVALID_CURSOR_NAME),
0247: cursorName);
0248: }
0249:
0250: //scrollableRS_ = agent_.sectionManager_.getPositionedUpdateResultSet (cursorName);
0251:
0252: // if client's cursor name is set, and the cursor name in the positioned update
0253: // string is the same as the client's cursor name, replace client's cursor name
0254: // with the server's cursor name.
0255: // if the cursor name supplied in the sql string is different from the cursorName
0256: // set by setCursorName(), then server will return "cursor name not defined" error,
0257: // and no subsititution is made here.
0258: if (section_.getClientCursorName() != null && // cursor name is user defined
0259: cursorName
0260: .compareTo(section_.getClientCursorName()) == 0)
0261: // client's cursor name is substituted with section's server cursor name
0262: {
0263: sql_ = substituteClientCursorNameWithServerCursorName(
0264: sql_, section_);
0265: }
0266: } else {
0267: // We don't need to analyze the sql text to determine if it is a query or not.
0268: // This is up to the server to decide, we just pass thru the sql on flowPrepare().
0269: section_ = agent_.sectionManager_
0270: .getDynamicSection(resultSetHoldability_);
0271: }
0272: }
0273:
0274: public void resetPreparedStatement(Agent agent,
0275: Connection connection, String sql, Section section,
0276: ColumnMetaData parameterMetaData,
0277: ColumnMetaData resultSetMetaData) throws SqlException {
0278: resetPreparedStatement(agent, connection, sql, section);
0279: initPreparedStatement(parameterMetaData, resultSetMetaData);
0280: }
0281:
0282: private void initPreparedStatement(
0283: ColumnMetaData parameterMetaData,
0284: ColumnMetaData resultSetMetaData) throws SqlException {
0285: isPreparedStatement_ = true;
0286: parameterMetaData_ = parameterMetaData;
0287: resultSetMetaData_ = resultSetMetaData;
0288: if (parameterMetaData_ != null) {
0289: parameters_ = new Object[parameterMetaData_.columns_];
0290: //parameterSetOrRegistered_ = new boolean[parameterMetaData_.columns_];
0291: parameterSet_ = new boolean[parameterMetaData_.columns_];
0292: parameterRegistered_ = new boolean[parameterMetaData_.columns_];
0293: }
0294: }
0295:
0296: // called immediately after the constructor by Connection prepare*() methods
0297: void prepare() throws SqlException {
0298: try {
0299: // flow prepare, no static initialization is needed
0300: // already checked if columnNames is not null and server supports select from insert
0301: // in prepareStatementX()
0302: if (sqlUpdateMode_ == isInsertSql__
0303: && generatedKeysColumnNames_ != null) {
0304: flowPrepareForSelectFromInsert();
0305: } else {
0306: flowPrepareDescribeInputOutput();
0307: }
0308: } catch (SqlException e) {
0309: this .markClosed();
0310: throw e;
0311: }
0312: }
0313:
0314: //------------------- Prohibited overrides from Statement --------------------
0315:
0316: public boolean execute(String sql) throws SQLException {
0317: if (agent_.loggingEnabled()) {
0318: agent_.logWriter_.traceEntry(this , "execute", sql);
0319: }
0320: throw new SqlException(agent_.logWriter_, new ClientMessageId(
0321: SQLState.NOT_FOR_PREPARED_STATEMENT), "execute(String)")
0322: .getSQLException();
0323: }
0324:
0325: public java.sql.ResultSet executeQuery(String sql)
0326: throws SQLException {
0327: if (agent_.loggingEnabled()) {
0328: agent_.logWriter_.traceEntry(this , "executeQuery", sql);
0329: }
0330: throw new SqlException(agent_.logWriter_, new ClientMessageId(
0331: SQLState.NOT_FOR_PREPARED_STATEMENT),
0332: "executeQuery(String)").getSQLException();
0333: }
0334:
0335: public int executeUpdate(String sql) throws SQLException {
0336: if (agent_.loggingEnabled()) {
0337: agent_.logWriter_.traceEntry(this , "executeUpdate", sql);
0338: }
0339: throw new SqlException(agent_.logWriter_, new ClientMessageId(
0340: SQLState.NOT_FOR_PREPARED_STATEMENT),
0341: "executeUpdate(String)").getSQLException();
0342: }
0343:
0344: // ---------------------------jdbc 1------------------------------------------
0345:
0346: public java.sql.ResultSet executeQuery() throws SQLException {
0347: try {
0348: synchronized (connection_) {
0349: if (agent_.loggingEnabled()) {
0350: agent_.logWriter_.traceEntry(this , "executeQuery");
0351: }
0352: ResultSet resultSet = executeQueryX();
0353: if (agent_.loggingEnabled()) {
0354: agent_.logWriter_.traceExit(this , "executeQuery",
0355: resultSet);
0356: }
0357: return resultSet;
0358: }
0359: } catch (SqlException se) {
0360: checkStatementValidity(se);
0361: throw se.getSQLException();
0362: }
0363: }
0364:
0365: // also called by some DBMD methods
0366: ResultSet executeQueryX() throws SqlException {
0367: flowExecute(executeQueryMethod__);
0368: return resultSet_;
0369: }
0370:
0371: public int executeUpdate() throws SQLException {
0372: try {
0373: synchronized (connection_) {
0374: if (agent_.loggingEnabled()) {
0375: agent_.logWriter_.traceEntry(this , "executeUpdate");
0376: }
0377: int updateValue = executeUpdateX();
0378: if (agent_.loggingEnabled()) {
0379: agent_.logWriter_.traceExit(this , "executeUpdate",
0380: updateValue);
0381: }
0382: return updateValue;
0383: }
0384: } catch (SqlException se) {
0385: checkStatementValidity(se);
0386: throw se.getSQLException();
0387: }
0388: }
0389:
0390: private int executeUpdateX() throws SqlException {
0391: flowExecute(executeUpdateMethod__);
0392: return updateCount_;
0393: }
0394:
0395: public void setNull(int parameterIndex, int jdbcType)
0396: throws SQLException {
0397: try {
0398: synchronized (connection_) {
0399: if (agent_.loggingEnabled()) {
0400: agent_.logWriter_.traceEntry(this , "setNull",
0401: parameterIndex, jdbcType);
0402: }
0403: setNullX(parameterIndex, jdbcType);
0404: }
0405: } catch (SqlException se) {
0406: throw se.getSQLException();
0407: }
0408: }
0409:
0410: // also used by DBMD methods
0411: void setNullX(int parameterIndex, int jdbcType) throws SqlException {
0412: checkForSupportedDataType(jdbcType);
0413: super .checkForClosedStatement(); // investigate what can be pushed up to setNull
0414: parameterIndex = checkSetterPreconditions(parameterIndex);
0415: parameterMetaData_.clientParamtertype_[parameterIndex - 1] = jdbcType;
0416:
0417: if (!parameterMetaData_.nullable_[parameterIndex - 1]) {
0418: throw new SqlException(agent_.logWriter_,
0419: new ClientMessageId(
0420: SQLState.LANG_NULL_INTO_NON_NULL),
0421: new Integer(parameterIndex));
0422: }
0423: setInput(parameterIndex, null);
0424: }
0425:
0426: public void setNull(int parameterIndex, int jdbcType,
0427: String typeName) throws SQLException {
0428: try {
0429: synchronized (connection_) {
0430: if (agent_.loggingEnabled()) {
0431: agent_.logWriter_.traceEntry(this , "setNull",
0432: parameterIndex, jdbcType, typeName);
0433: }
0434: super .checkForClosedStatement();
0435: setNull(parameterIndex, jdbcType);
0436: }
0437: } catch (SqlException se) {
0438: throw se.getSQLException();
0439: }
0440: }
0441:
0442: public void setBoolean(int parameterIndex, boolean x)
0443: throws SQLException {
0444: try {
0445: synchronized (connection_) {
0446: if (agent_.loggingEnabled()) {
0447: agent_.logWriter_.traceEntry(this , "setBoolean",
0448: parameterIndex, x);
0449: }
0450: parameterIndex = checkSetterPreconditions(parameterIndex);
0451: parameterMetaData_.clientParamtertype_[parameterIndex - 1] = java.sql.Types.BIT;
0452: setInput(parameterIndex, new Short((short) (x ? 1 : 0)));
0453: }
0454: } catch (SqlException se) {
0455: throw se.getSQLException();
0456: }
0457: }
0458:
0459: public void setByte(int parameterIndex, byte x) throws SQLException {
0460: try {
0461: synchronized (connection_) {
0462: if (agent_.loggingEnabled()) {
0463: agent_.logWriter_.traceEntry(this , "setByte",
0464: parameterIndex, x);
0465: }
0466: parameterIndex = checkSetterPreconditions(parameterIndex);
0467: parameterMetaData_.clientParamtertype_[parameterIndex - 1] = java.sql.Types.TINYINT;
0468: setInput(parameterIndex, new Short(x));
0469: }
0470: } catch (SqlException se) {
0471: throw se.getSQLException();
0472: }
0473: }
0474:
0475: public void setShort(int parameterIndex, short x)
0476: throws SQLException {
0477: try {
0478: synchronized (connection_) {
0479: if (agent_.loggingEnabled()) {
0480: agent_.logWriter_.traceEntry(this , "setShort",
0481: parameterIndex, x);
0482: }
0483: setShortX(parameterIndex, x);
0484: }
0485: } catch (SqlException se) {
0486: throw se.getSQLException();
0487: }
0488: }
0489:
0490: // also used by DBMD methods
0491: void setShortX(int parameterIndex, short x) throws SqlException {
0492: parameterIndex = checkSetterPreconditions(parameterIndex);
0493: parameterMetaData_.clientParamtertype_[parameterIndex - 1] = java.sql.Types.SMALLINT;
0494: setInput(parameterIndex, new Short(x));
0495:
0496: }
0497:
0498: public void setInt(int parameterIndex, int x) throws SQLException {
0499: try {
0500: synchronized (connection_) {
0501: if (agent_.loggingEnabled()) {
0502: agent_.logWriter_.traceEntry(this , "setInt",
0503: parameterIndex, x);
0504: }
0505: setIntX(parameterIndex, x);
0506: }
0507: } catch (SqlException se) {
0508: throw se.getSQLException();
0509: }
0510: }
0511:
0512: // also used by DBMD methods
0513: void setIntX(int parameterIndex, int x) throws SqlException {
0514: parameterIndex = checkSetterPreconditions(parameterIndex);
0515: parameterMetaData_.clientParamtertype_[parameterIndex - 1] = java.sql.Types.INTEGER;
0516: setInput(parameterIndex, new Integer(x));
0517: }
0518:
0519: public void setLong(int parameterIndex, long x) throws SQLException {
0520: try {
0521: synchronized (connection_) {
0522: if (agent_.loggingEnabled()) {
0523: agent_.logWriter_.traceEntry(this , "setLong",
0524: parameterIndex, x);
0525: }
0526: parameterIndex = checkSetterPreconditions(parameterIndex);
0527: parameterMetaData_.clientParamtertype_[parameterIndex - 1] = java.sql.Types.BIGINT;
0528: setInput(parameterIndex, new Long(x));
0529: }
0530: } catch (SqlException se) {
0531: throw se.getSQLException();
0532: }
0533: }
0534:
0535: public void setFloat(int parameterIndex, float x)
0536: throws SQLException {
0537: try {
0538: synchronized (connection_) {
0539: if (agent_.loggingEnabled()) {
0540: agent_.logWriter_.traceEntry(this , "setFloat",
0541: parameterIndex, x);
0542: }
0543: parameterIndex = checkSetterPreconditions(parameterIndex);
0544: parameterMetaData_.clientParamtertype_[parameterIndex - 1] = java.sql.Types.REAL;
0545: setInput(parameterIndex, new Float(x));
0546: }
0547: } catch (SqlException se) {
0548: throw se.getSQLException();
0549: }
0550: }
0551:
0552: public void setDouble(int parameterIndex, double x)
0553: throws SQLException {
0554: try {
0555: synchronized (connection_) {
0556: if (agent_.loggingEnabled()) {
0557: agent_.logWriter_.traceEntry(this , "setDouble",
0558: parameterIndex, x);
0559: }
0560: parameterIndex = checkSetterPreconditions(parameterIndex);
0561: parameterMetaData_.clientParamtertype_[parameterIndex - 1] = java.sql.Types.DOUBLE;
0562: setInput(parameterIndex, new Double(x));
0563: }
0564: } catch (SqlException se) {
0565: throw se.getSQLException();
0566: }
0567: }
0568:
0569: public void setBigDecimal(int parameterIndex, java.math.BigDecimal x)
0570: throws SQLException {
0571: try {
0572: synchronized (connection_) {
0573: if (agent_.loggingEnabled()) {
0574: agent_.logWriter_.traceEntry(this , "setBigDecimal",
0575: parameterIndex, x);
0576: }
0577: parameterIndex = checkSetterPreconditions(parameterIndex);
0578: parameterMetaData_.clientParamtertype_[parameterIndex - 1] = java.sql.Types.DECIMAL;
0579: if (x == null) {
0580: setNull(parameterIndex, java.sql.Types.DECIMAL);
0581: return;
0582: }
0583: int registerOutScale = 0;
0584: setInput(parameterIndex, x);
0585: }
0586: } catch (SqlException se) {
0587: throw se.getSQLException();
0588: }
0589: }
0590:
0591: public void setDate(int parameterIndex, java.sql.Date x)
0592: throws SQLException {
0593: try {
0594: synchronized (connection_) {
0595: if (agent_.loggingEnabled()) {
0596: agent_.logWriter_.traceEntry(this , "setDate",
0597: parameterIndex, x);
0598: }
0599: checkForClosedStatement();
0600: parameterIndex = checkSetterPreconditions(parameterIndex);
0601: parameterMetaData_.clientParamtertype_[parameterIndex - 1] = java.sql.Types.DATE;
0602: if (x == null) {
0603: setNull(parameterIndex, java.sql.Types.DATE);
0604: return;
0605: }
0606: setInput(parameterIndex, x);
0607: }
0608: } catch (SqlException se) {
0609: throw se.getSQLException();
0610: }
0611: }
0612:
0613: public void setDate(int parameterIndex, java.sql.Date x,
0614: java.util.Calendar calendar) throws SQLException {
0615: try {
0616: synchronized (connection_) {
0617: if (agent_.loggingEnabled()) {
0618: agent_.logWriter_.traceEntry(this , "setDate",
0619: parameterIndex, x, calendar);
0620: }
0621: checkForClosedStatement();
0622: if (calendar == null) {
0623: throw new SqlException(agent_.logWriter_,
0624: new ClientMessageId(
0625: SQLState.INVALID_API_PARAMETER),
0626: "null", "calendar", "setDate");
0627: }
0628: java.util.Calendar targetCalendar = java.util.Calendar
0629: .getInstance(calendar.getTimeZone());
0630: targetCalendar.clear();
0631: targetCalendar.setTime(x);
0632: java.util.Calendar defaultCalendar = java.util.Calendar
0633: .getInstance();
0634: defaultCalendar.clear();
0635: defaultCalendar.setTime(x);
0636: long timeZoneOffset = targetCalendar
0637: .get(java.util.Calendar.ZONE_OFFSET)
0638: - defaultCalendar
0639: .get(java.util.Calendar.ZONE_OFFSET)
0640: + targetCalendar
0641: .get(java.util.Calendar.DST_OFFSET)
0642: - defaultCalendar
0643: .get(java.util.Calendar.DST_OFFSET);
0644: java.sql.Date adjustedDate = ((timeZoneOffset == 0) || (x == null)) ? x
0645: : new java.sql.Date(x.getTime()
0646: + timeZoneOffset);
0647: setDate(parameterIndex, adjustedDate);
0648: }
0649: } catch (SqlException se) {
0650: throw se.getSQLException();
0651: }
0652: }
0653:
0654: public void setTime(int parameterIndex, java.sql.Time x)
0655: throws SQLException {
0656: try {
0657: synchronized (connection_) {
0658: if (agent_.loggingEnabled()) {
0659: agent_.logWriter_.traceEntry(this , "setTime",
0660: parameterIndex, x);
0661: }
0662: parameterIndex = checkSetterPreconditions(parameterIndex);
0663: parameterMetaData_.clientParamtertype_[parameterIndex - 1] = java.sql.Types.TIME;
0664: if (x == null) {
0665: setNull(parameterIndex, java.sql.Types.TIME);
0666: return;
0667: }
0668: setInput(parameterIndex, x);
0669:
0670: }
0671: } catch (SqlException se) {
0672: throw se.getSQLException();
0673: }
0674: }
0675:
0676: public void setTime(int parameterIndex, java.sql.Time x,
0677: java.util.Calendar calendar) throws SQLException {
0678: try {
0679: synchronized (connection_) {
0680: if (agent_.loggingEnabled()) {
0681: agent_.logWriter_.traceEntry(this , "setTime",
0682: parameterIndex, x, calendar);
0683: }
0684: checkForClosedStatement();
0685: if (calendar == null) {
0686: throw new SqlException(agent_.logWriter_,
0687: new ClientMessageId(
0688: SQLState.INVALID_API_PARAMETER),
0689: "null", "calendar", "setTime()");
0690: }
0691: java.util.Calendar targetCalendar = java.util.Calendar
0692: .getInstance(calendar.getTimeZone());
0693: targetCalendar.clear();
0694: targetCalendar.setTime(x);
0695: java.util.Calendar defaultCalendar = java.util.Calendar
0696: .getInstance();
0697: defaultCalendar.clear();
0698: defaultCalendar.setTime(x);
0699: long timeZoneOffset = targetCalendar
0700: .get(java.util.Calendar.ZONE_OFFSET)
0701: - defaultCalendar
0702: .get(java.util.Calendar.ZONE_OFFSET)
0703: + targetCalendar
0704: .get(java.util.Calendar.DST_OFFSET)
0705: - defaultCalendar
0706: .get(java.util.Calendar.DST_OFFSET);
0707: java.sql.Time adjustedTime = ((timeZoneOffset == 0) || (x == null)) ? x
0708: : new java.sql.Time(x.getTime()
0709: + timeZoneOffset);
0710: setTime(parameterIndex, adjustedTime);
0711: }
0712: } catch (SqlException se) {
0713: throw se.getSQLException();
0714: }
0715: }
0716:
0717: public void setTimestamp(int parameterIndex, java.sql.Timestamp x)
0718: throws SQLException {
0719: try {
0720: synchronized (connection_) {
0721: if (agent_.loggingEnabled()) {
0722: agent_.logWriter_.traceEntry(this , "setTimestamp",
0723: parameterIndex, x);
0724: }
0725: parameterIndex = checkSetterPreconditions(parameterIndex);
0726: parameterMetaData_.clientParamtertype_[parameterIndex - 1] = java.sql.Types.TIMESTAMP;
0727:
0728: if (x == null) {
0729: setNull(parameterIndex, java.sql.Types.TIMESTAMP);
0730: return;
0731: }
0732: setInput(parameterIndex, x);
0733: // once the nanosecond field of timestamp is trim to microsecond for DERBY, should we throw a warning
0734: //if (getParameterType (parameterIndex) == java.sql.Types.TIMESTAMP && x.getNanos() % 1000 != 0)
0735: // accumulateWarning (new SqlWarning (agent_.logWriter_, "DERBY timestamp can only store up to microsecond, conversion from nanosecond to microsecond causes rounding."));
0736: }
0737: } catch (SqlException se) {
0738: throw se.getSQLException();
0739: }
0740: }
0741:
0742: public void setTimestamp(int parameterIndex, java.sql.Timestamp x,
0743: java.util.Calendar calendar) throws SQLException {
0744: try {
0745: synchronized (connection_) {
0746: if (agent_.loggingEnabled()) {
0747: agent_.logWriter_.traceEntry(this , "setTimestamp",
0748: parameterIndex, x, calendar);
0749: }
0750: checkForClosedStatement();
0751: if (calendar == null) {
0752: throw new SqlException(agent_.logWriter_,
0753: new ClientMessageId(
0754: SQLState.INVALID_API_PARAMETER),
0755: "null", "calendar", "setTimestamp()");
0756: }
0757: java.util.Calendar targetCalendar = java.util.Calendar
0758: .getInstance(calendar.getTimeZone());
0759: targetCalendar.clear();
0760: targetCalendar.setTime(x);
0761: java.util.Calendar defaultCalendar = java.util.Calendar
0762: .getInstance();
0763: defaultCalendar.clear();
0764: defaultCalendar.setTime(x);
0765: long timeZoneOffset = targetCalendar
0766: .get(java.util.Calendar.ZONE_OFFSET)
0767: - defaultCalendar
0768: .get(java.util.Calendar.ZONE_OFFSET)
0769: + targetCalendar
0770: .get(java.util.Calendar.DST_OFFSET)
0771: - defaultCalendar
0772: .get(java.util.Calendar.DST_OFFSET);
0773: java.sql.Timestamp adjustedTimestamp = ((timeZoneOffset == 0) || (x == null)) ? x
0774: : new java.sql.Timestamp(x.getTime()
0775: + timeZoneOffset);
0776: if (x != null) {
0777: adjustedTimestamp.setNanos(x.getNanos());
0778: }
0779: setTimestamp(parameterIndex, adjustedTimestamp);
0780: }
0781: } catch (SqlException se) {
0782: throw se.getSQLException();
0783: }
0784: }
0785:
0786: public void setString(int parameterIndex, String x)
0787: throws SQLException {
0788: try {
0789: synchronized (connection_) {
0790: if (agent_.loggingEnabled()) {
0791: agent_.logWriter_.traceEntry(this , "setString",
0792: parameterIndex, x);
0793: }
0794: setStringX(parameterIndex, x);
0795: }
0796: } catch (SqlException se) {
0797: throw se.getSQLException();
0798: }
0799: }
0800:
0801: // also used by DBMD methods
0802: void setStringX(int parameterIndex, String x) throws SqlException {
0803: parameterIndex = checkSetterPreconditions(parameterIndex);
0804: parameterMetaData_.clientParamtertype_[parameterIndex - 1] = java.sql.Types.LONGVARCHAR;
0805: if (x == null) {
0806: setNullX(parameterIndex, java.sql.Types.LONGVARCHAR);
0807: return;
0808: }
0809: setInput(parameterIndex, x);
0810: }
0811:
0812: public void setBytes(int parameterIndex, byte[] x)
0813: throws SQLException {
0814: try {
0815: synchronized (connection_) {
0816: if (agent_.loggingEnabled()) {
0817: agent_.logWriter_.traceEntry(this , "setBytes",
0818: parameterIndex, x);
0819: }
0820: setBytesX(parameterIndex, x);
0821: }
0822: } catch (SqlException se) {
0823: throw se.getSQLException();
0824: }
0825: }
0826:
0827: // also used by BLOB
0828: public void setBytesX(int parameterIndex, byte[] x)
0829: throws SqlException {
0830: parameterIndex = checkSetterPreconditions(parameterIndex);
0831: parameterMetaData_.clientParamtertype_[parameterIndex - 1] = java.sql.Types.LONGVARBINARY;
0832: if (x == null) {
0833: setNullX(parameterIndex, java.sql.Types.LONGVARBINARY);
0834: return;
0835: }
0836: setInput(parameterIndex, x);
0837:
0838: }
0839:
0840: /**
0841: * sets the parameter to the Binary Stream object
0842: *
0843: * @param parameterIndex the first parameter is 1, the second is 2, ...
0844: * @param x the java input stream which contains the binary parameter value
0845: * @param length the number of bytes in the stream
0846: * @exception SQLException thrown on failure.
0847: */
0848:
0849: public void setBinaryStream(int parameterIndex,
0850: java.io.InputStream x, long length) throws SQLException {
0851: try {
0852: synchronized (connection_) {
0853: if (agent_.loggingEnabled()) {
0854: agent_.logWriter_.traceEntry(this ,
0855: "setBinaryStream", parameterIndex,
0856: "<input stream>", new Long(length));
0857: }
0858: if (length > Integer.MAX_VALUE) {
0859: throw new SqlException(
0860: agent_.logWriter_,
0861: new ClientMessageId(
0862: SQLState.CLIENT_LENGTH_OUTSIDE_RANGE_FOR_DATATYPE),
0863: new Long(length), new Integer(
0864: Integer.MAX_VALUE))
0865: .getSQLException();
0866: }
0867: setBinaryStreamX(parameterIndex, x, (int) length);
0868: }
0869: } catch (SqlException se) {
0870: throw se.getSQLException();
0871: }
0872: }
0873:
0874: /**
0875: * sets the parameter to the Binary Stream object
0876: *
0877: * @param parameterIndex the first parameter is 1, the second is 2, ...
0878: * @param x the java input stream which contains the binary parameter value
0879: * @param length the number of bytes in the stream
0880: * @exception SQLException thrown on failure.
0881: */
0882:
0883: public void setBinaryStream(int parameterIndex,
0884: java.io.InputStream x, int length) throws SQLException {
0885: setBinaryStream(parameterIndex, x, (long) length);
0886: }
0887:
0888: protected void setBinaryStreamX(int parameterIndex,
0889: java.io.InputStream x, int length) throws SqlException {
0890: parameterIndex = checkSetterPreconditions(parameterIndex);
0891: parameterMetaData_.clientParamtertype_[parameterIndex - 1] = java.sql.Types.BLOB;
0892: if (x == null) {
0893: setNullX(parameterIndex, java.sql.Types.BLOB);
0894: return;
0895: }
0896: Blob blob;
0897: if (length == -1) {
0898: // Create a blob of unknown length. This might cause an
0899: // OutOfMemoryError due to the temporary implementation in Blob.
0900: // The whole stream will be materialzied. See comments in Blob.
0901: blob = new Blob(agent_, x);
0902: } else {
0903: blob = new Blob(agent_, x, length);
0904: }
0905: setInput(parameterIndex, blob);
0906: }
0907:
0908: /**
0909: * We do this inefficiently and read it all in here. The target type
0910: * is assumed to be a String.
0911: *
0912: * @param parameterIndex the first parameter is 1, the second is 2, ...
0913: * @param x the java input stream which contains the ASCII parameter value
0914: * @param length the number of bytes in the stream
0915: * @exception SQLException thrown on failure.
0916: */
0917:
0918: public void setAsciiStream(int parameterIndex,
0919: java.io.InputStream x, long length) throws SQLException {
0920: try {
0921: synchronized (connection_) {
0922: if (agent_.loggingEnabled()) {
0923: agent_.logWriter_.traceEntry(this ,
0924: "setAsciiStream", parameterIndex,
0925: "<input stream>", new Long(length));
0926: }
0927: parameterIndex = checkSetterPreconditions(parameterIndex);
0928: parameterMetaData_.clientParamtertype_[parameterIndex - 1] = java.sql.Types.CLOB;
0929: if (x == null) {
0930: setNull(parameterIndex, java.sql.Types.CLOB);
0931: return;
0932: }
0933: if (length > Integer.MAX_VALUE) {
0934: throw new SqlException(
0935: agent_.logWriter_,
0936: new ClientMessageId(
0937: SQLState.CLIENT_LENGTH_OUTSIDE_RANGE_FOR_DATATYPE),
0938: new Long(length), new Integer(
0939: Integer.MAX_VALUE))
0940: .getSQLException();
0941: }
0942: setInput(parameterIndex, new Clob(agent_, x,
0943: "US-ASCII", (int) length));
0944: }
0945: } catch (SqlException se) {
0946: throw se.getSQLException();
0947: }
0948: }
0949:
0950: /**
0951: * We do this inefficiently and read it all in here. The target type
0952: * is assumed to be a String.
0953: *
0954: * @param parameterIndex the first parameter is 1, the second is 2, ...
0955: * @param x the java input stream which contains the ASCII parameter value
0956: * @param length the number of bytes in the stream
0957: * @exception SQLException thrown on failure.
0958: */
0959: public void setAsciiStream(int parameterIndex,
0960: java.io.InputStream x, int length) throws SQLException {
0961: setAsciiStream(parameterIndex, x, (long) length);
0962: }
0963:
0964: /**
0965: * Sets the specified parameter to the given input stream. Deprecated
0966: * in JDBC 3.0 and this method will always just throw a feature not
0967: * implemented exception.
0968: *
0969: * @param parameterIndex the first parameter is 1, the second is 2, ...
0970: * @param x the java input stream which contains the UNICODE parameter
0971: * value
0972: * @param length the number of bytes in the stream
0973: * @exception SQLException throws feature not implemented.
0974: */
0975: public void setUnicodeStream(int parameterIndex,
0976: java.io.InputStream x, int length) throws SQLException {
0977: if (agent_.loggingEnabled()) {
0978: agent_.logWriter_.traceDeprecatedEntry(this ,
0979: "setUnicodeStream", parameterIndex,
0980: "<input stream>", length);
0981: }
0982:
0983: throw SQLExceptionFactory.notImplemented("setUnicodeStream");
0984: }
0985:
0986: /**
0987: * Sets the designated parameter to the given <code>Reader</code> object.
0988: * When a very large UNICODE value is input to a LONGVARCHAR parameter, it
0989: * may be more practical to send it via a <code>java.io.Reader</code>
0990: * object. The data will be read from the stream as needed until
0991: * end-of-file is reached. The JDBC driver will do any necessary conversion
0992: * from UNICODE to the database char format.
0993: *
0994: * @param parameterIndex the first parameter is 1, the second is 2, ...
0995: * @param x the <code>java.io.Reader</code> object that contains the
0996: * Unicode data
0997: * @throws SQLException if a database access error occurs or this method is
0998: * called on a closed <code>PreparedStatement</code>
0999: */
1000: public void setCharacterStream(int parameterIndex, Reader x)
1001: throws SQLException {
1002: synchronized (connection_) {
1003: if (agent_.loggingEnabled()) {
1004: agent_.logWriter_.traceEntry(this ,
1005: "setCharacterStream", parameterIndex, x);
1006: }
1007: try {
1008: parameterIndex = checkSetterPreconditions(parameterIndex);
1009: parameterMetaData_.clientParamtertype_[parameterIndex - 1] = java.sql.Types.CLOB;
1010: if (x == null) {
1011: setNull(parameterIndex, java.sql.Types.CLOB);
1012: return;
1013: }
1014: setInput(parameterIndex, new Clob(agent_, x));
1015: } catch (SqlException se) {
1016: throw se.getSQLException();
1017: }
1018: }
1019: }
1020:
1021: /**
1022: * Sets the designated parameter to the given Reader, which will have
1023: * the specified number of bytes.
1024: *
1025: * @param parameterIndex the index of the parameter to which this set
1026: * method is applied
1027: * @param x the java Reader which contains the UNICODE value
1028: * @param length the number of bytes in the stream
1029: * @exception SQLException thrown on failure.
1030: *
1031: */
1032:
1033: public void setCharacterStream(int parameterIndex,
1034: java.io.Reader x, long length) throws SQLException {
1035: try {
1036: synchronized (connection_) {
1037: if (agent_.loggingEnabled()) {
1038: agent_.logWriter_.traceEntry(this ,
1039: "setCharacterStream", parameterIndex, x,
1040: new Long(length));
1041: }
1042: parameterIndex = checkSetterPreconditions(parameterIndex);
1043: parameterMetaData_.clientParamtertype_[parameterIndex - 1] = java.sql.Types.CLOB;
1044: if (x == null) {
1045: setNull(parameterIndex, java.sql.Types.CLOB);
1046: return;
1047: }
1048: if (length > Integer.MAX_VALUE) {
1049: throw new SqlException(
1050: agent_.logWriter_,
1051: new ClientMessageId(
1052: SQLState.CLIENT_LENGTH_OUTSIDE_RANGE_FOR_DATATYPE),
1053: new Long(length), new Integer(
1054: Integer.MAX_VALUE))
1055: .getSQLException();
1056: }
1057: setInput(parameterIndex, new Clob(agent_, x,
1058: (int) length));
1059: }
1060: } catch (SqlException se) {
1061: throw se.getSQLException();
1062: }
1063: }
1064:
1065: /**
1066: * Sets the designated parameter to the given Reader, which will have
1067: * the specified number of bytes.
1068: *
1069: * @param parameterIndex the index of the parameter to which this
1070: * set method is applied
1071: * @param x the java Reader which contains the UNICODE value
1072: * @param length the number of bytes in the stream
1073: * @exception SQLException thrown on failure.
1074: *
1075: */
1076:
1077: public void setCharacterStream(int parameterIndex,
1078: java.io.Reader x, int length) throws SQLException {
1079: setCharacterStream(parameterIndex, x, (long) length);
1080: }
1081:
1082: public void setBlob(int parameterIndex, java.sql.Blob x)
1083: throws SQLException {
1084: try {
1085: synchronized (connection_) {
1086: if (agent_.loggingEnabled()) {
1087: agent_.logWriter_.traceEntry(this , "setBlob",
1088: parameterIndex, x);
1089: }
1090: setBlobX(parameterIndex, x);
1091: }
1092: } catch (SqlException se) {
1093: throw se.getSQLException();
1094: }
1095: }
1096:
1097: // also used by Blob
1098: public void setBlobX(int parameterIndex, java.sql.Blob x)
1099: throws SqlException {
1100: parameterIndex = checkSetterPreconditions(parameterIndex);
1101: parameterMetaData_.clientParamtertype_[parameterIndex - 1] = java.sql.Types.BLOB;
1102: if (x == null) {
1103: setNullX(parameterIndex, java.sql.Types.BLOB);
1104: return;
1105: }
1106: setInput(parameterIndex, x);
1107: }
1108:
1109: public void setClob(int parameterIndex, java.sql.Clob x)
1110: throws SQLException {
1111: try {
1112: synchronized (connection_) {
1113: if (agent_.loggingEnabled()) {
1114: agent_.logWriter_.traceEntry(this , "setClob",
1115: parameterIndex, x);
1116: }
1117: setClobX(parameterIndex, x);
1118: }
1119: } catch (SqlException se) {
1120: throw se.getSQLException();
1121: }
1122: }
1123:
1124: // also used by Clob
1125: void setClobX(int parameterIndex, java.sql.Clob x)
1126: throws SqlException {
1127: parameterIndex = checkSetterPreconditions(parameterIndex);
1128: parameterMetaData_.clientParamtertype_[parameterIndex - 1] = java.sql.Types.CLOB;
1129: if (x == null) {
1130: this .setNullX(parameterIndex, Types.CLOB);
1131: return;
1132: }
1133: setInput(parameterIndex, x);
1134: }
1135:
1136: public void setArray(int parameterIndex, java.sql.Array x)
1137: throws SQLException {
1138: try {
1139: synchronized (connection_) {
1140: if (agent_.loggingEnabled()) {
1141: agent_.logWriter_.traceEntry(this , "setArray",
1142: parameterIndex, x);
1143: }
1144: parameterIndex = checkSetterPreconditions(parameterIndex);
1145: throw new SqlException(agent_.logWriter_,
1146: new ClientMessageId(
1147: SQLState.JDBC_METHOD_NOT_IMPLEMENTED));
1148: }
1149: } catch (SqlException se) {
1150: throw se.getSQLException();
1151: }
1152: }
1153:
1154: public void setRef(int parameterIndex, java.sql.Ref x)
1155: throws SQLException {
1156: try {
1157: synchronized (connection_) {
1158: if (agent_.loggingEnabled()) {
1159: agent_.logWriter_.traceEntry(this , "setRef",
1160: parameterIndex, x);
1161: }
1162: parameterIndex = checkSetterPreconditions(parameterIndex);
1163: throw new SqlException(agent_.logWriter_,
1164: new ClientMessageId(
1165: SQLState.JDBC_METHOD_NOT_IMPLEMENTED));
1166: }
1167: } catch (SqlException se) {
1168: throw se.getSQLException();
1169: }
1170: }
1171:
1172: // The Java compiler uses static binding, so we must use instanceof
1173: // rather than to rely on separate setObject() methods for
1174: // each of the Java Object instance types recognized below.
1175: public void setObject(int parameterIndex, Object x)
1176: throws SQLException {
1177: try {
1178: synchronized (connection_) {
1179: if (agent_.loggingEnabled()) {
1180: agent_.logWriter_.traceEntry(this , "setObject",
1181: parameterIndex, x);
1182: }
1183: super .checkForClosedStatement();
1184: if (x instanceof String) {
1185: setString(parameterIndex, (String) x);
1186: } else if (x instanceof Integer) {
1187: setInt(parameterIndex, ((Integer) x).intValue());
1188: } else if (x instanceof Double) {
1189: setDouble(parameterIndex, ((Double) x)
1190: .doubleValue());
1191: } else if (x instanceof Float) {
1192: setFloat(parameterIndex, ((Float) x).floatValue());
1193: } else if (x instanceof Boolean) {
1194: setBoolean(parameterIndex, ((Boolean) x)
1195: .booleanValue());
1196: } else if (x instanceof Long) {
1197: setLong(parameterIndex, ((Long) x).longValue());
1198: } else if (x instanceof byte[]) {
1199: setBytes(parameterIndex, (byte[]) x);
1200: } else if (x instanceof java.math.BigDecimal) {
1201: setBigDecimal(parameterIndex,
1202: (java.math.BigDecimal) x);
1203: } else if (x instanceof java.sql.Date) {
1204: setDate(parameterIndex, (java.sql.Date) x);
1205: } else if (x instanceof java.sql.Time) {
1206: setTime(parameterIndex, (java.sql.Time) x);
1207: } else if (x instanceof java.sql.Timestamp) {
1208: setTimestamp(parameterIndex, (java.sql.Timestamp) x);
1209: } else if (x instanceof java.sql.Blob) {
1210: setBlob(parameterIndex, (java.sql.Blob) x);
1211: } else if (x instanceof java.sql.Clob) {
1212: setClob(parameterIndex, (java.sql.Clob) x);
1213: } else if (x instanceof java.sql.Array) {
1214: setArray(parameterIndex, (java.sql.Array) x);
1215: } else if (x instanceof java.sql.Ref) {
1216: setRef(parameterIndex, (java.sql.Ref) x);
1217: } else if (x instanceof Short) {
1218: setShort(parameterIndex, ((Short) x).shortValue());
1219: } else if (x instanceof Byte) {
1220: setByte(parameterIndex, ((Byte) x).byteValue());
1221: } else {
1222: checkSetterPreconditions(parameterIndex);
1223: throw new SqlException(agent_.logWriter_,
1224: new ClientMessageId(
1225: SQLState.UNSUPPORTED_TYPE));
1226: }
1227: }
1228: } catch (SqlException se) {
1229: throw se.getSQLException();
1230: }
1231: }
1232:
1233: public void setObject(int parameterIndex, Object x,
1234: int targetJdbcType) throws SQLException {
1235: try {
1236: synchronized (connection_) {
1237: if (agent_.loggingEnabled()) {
1238: agent_.logWriter_.traceEntry(this , "setObject",
1239: parameterIndex, x, targetJdbcType);
1240: }
1241: setObjectX(parameterIndex, x, targetJdbcType, 0);
1242: }
1243: } catch (SqlException se) {
1244: throw se.getSQLException();
1245: }
1246: }
1247:
1248: public void setObject(int parameterIndex, Object x,
1249: int targetJdbcType, int scale) throws SQLException {
1250: try {
1251: synchronized (connection_) {
1252: if (agent_.loggingEnabled()) {
1253: agent_.logWriter_.traceEntry(this , "setObject",
1254: parameterIndex, x, targetJdbcType, scale);
1255: }
1256: setObjectX(parameterIndex, x, targetJdbcType, scale);
1257: }
1258: } catch (SqlException se) {
1259: throw se.getSQLException();
1260: }
1261: }
1262:
1263: private void setObjectX(int parameterIndex, Object x,
1264: int targetJdbcType, int scale) throws SqlException {
1265: parameterIndex = checkSetterPreconditions(parameterIndex);
1266: checkForValidScale(scale);
1267:
1268: if (x == null) {
1269: setNullX(parameterIndex, targetJdbcType);
1270: return;
1271: }
1272:
1273: checkForSupportedDataType(targetJdbcType);
1274:
1275: // JDBC Spec specifies that conversion should occur on the client if
1276: // the targetJdbcType is specified.
1277:
1278: int inputParameterType = CrossConverters
1279: .getInputJdbcType(targetJdbcType);
1280: parameterMetaData_.clientParamtertype_[parameterIndex - 1] = inputParameterType;
1281: x = agent_.crossConverters_.setObject(inputParameterType, x);
1282:
1283: // Set to round down on setScale like embedded does in SQLDecimal
1284: try {
1285: if (targetJdbcType == java.sql.Types.DECIMAL
1286: || targetJdbcType == java.sql.Types.NUMERIC) {
1287: x = ((java.math.BigDecimal) x).setScale(scale,
1288: java.math.BigDecimal.ROUND_DOWN);
1289: }
1290: } catch (ArithmeticException ae) {
1291: // Any problems with scale should have already been caught by
1292: // checkForvalidScale
1293: throw new SqlException(agent_.logWriter_,
1294: new ClientMessageId(SQLState.JAVA_EXCEPTION),
1295: new Object[] { ae.getClass().getName(),
1296: ae.getMessage() }, ae);
1297: }
1298: try {
1299: setObject(parameterIndex, x);
1300: } catch (SQLException se) {
1301: throw new SqlException(se);
1302: }
1303: }
1304:
1305: // Since parameters are cached as objects in parameters_[],
1306: // java null may be used to represent SQL null.
1307: public void clearParameters() throws SQLException {
1308: try {
1309: synchronized (connection_) {
1310: if (agent_.loggingEnabled()) {
1311: agent_.logWriter_.traceEntry(this ,
1312: "clearParameters");
1313: }
1314: checkForClosedStatement();
1315: if (parameterMetaData_ != null) {
1316: for (int i = 0; i < parameters_.length; i++) {
1317: parameters_[i] = null;
1318: }
1319:
1320: for (int i = 0; i < parameterSet_.length; i++) {
1321: parameterSet_[i] = false;
1322: }
1323: }
1324: }
1325: } catch (SqlException se) {
1326: throw se.getSQLException();
1327: }
1328: }
1329:
1330: public boolean execute() throws SQLException {
1331: try {
1332: synchronized (connection_) {
1333: if (agent_.loggingEnabled()) {
1334: agent_.logWriter_.traceEntry(this , "execute");
1335: }
1336: boolean b = executeX();
1337: if (agent_.loggingEnabled()) {
1338: agent_.logWriter_.traceExit(this , "execute", b);
1339: }
1340: return b;
1341: }
1342: } catch (SqlException se) {
1343: checkStatementValidity(se);
1344: throw se.getSQLException();
1345: }
1346: }
1347:
1348: // also used by SQLCA
1349: boolean executeX() throws SqlException {
1350: flowExecute(executeMethod__);
1351:
1352: return resultSet_ != null;
1353: }
1354:
1355: //--------------------------JDBC 2.0-----------------------------
1356:
1357: public void addBatch() throws SQLException {
1358: try {
1359: synchronized (connection_) {
1360: if (agent_.loggingEnabled()) {
1361: agent_.logWriter_.traceEntry(this , "addBatch");
1362: }
1363: checkForClosedStatement();
1364: checkThatAllParametersAreSet();
1365:
1366: if (parameterTypeList == null) {
1367: parameterTypeList = new ArrayList();
1368: }
1369:
1370: // ASSERT: since OUT/INOUT parameters are not allowed, there should
1371: // be no problem in sharing the JDBC Wrapper object instances
1372: // since they will not be modified by the driver.
1373:
1374: // batch up the parameter values -- deep copy req'd
1375:
1376: if (parameterMetaData_ != null) {
1377: Object[] inputsClone = new Object[parameters_.length];
1378: System.arraycopy(parameters_, 0, inputsClone, 0,
1379: parameters_.length);
1380:
1381: batch_.add(inputsClone);
1382:
1383: // Get a copy of the parameter type data and save it in a list
1384: // which will be used later on at the time of batch execution.
1385: parameterTypeList
1386: .add(parameterMetaData_.clientParamtertype_
1387: .clone());
1388: } else {
1389: batch_.add(null);
1390: parameterTypeList.add(null);
1391: }
1392: }
1393: } catch (SqlException se) {
1394: throw se.getSQLException();
1395: }
1396: }
1397:
1398: // Batch requires that input types are exact, we perform no input cross conversion for Batch.
1399: // If so, this is an external semantic, and should go into the release notes
1400: public int[] executeBatch() throws SQLException,
1401: BatchUpdateException {
1402: try {
1403: synchronized (connection_) {
1404: if (agent_.loggingEnabled()) {
1405: agent_.logWriter_.traceEntry(this , "executeBatch");
1406: }
1407: int[] updateCounts = null;
1408: updateCounts = executeBatchX(false);
1409:
1410: if (agent_.loggingEnabled()) {
1411: agent_.logWriter_.traceExit(this , "executeBatch",
1412: updateCounts);
1413: }
1414: return updateCounts;
1415: }
1416: } catch (SqlException se) {
1417: throw se.getSQLException();
1418: }
1419: }
1420:
1421: public java.sql.ResultSetMetaData getMetaData() throws SQLException {
1422: try {
1423: synchronized (connection_) {
1424: if (agent_.loggingEnabled()) {
1425: agent_.logWriter_.traceEntry(this , "getMetaData");
1426: }
1427: ColumnMetaData resultSetMetaData = getMetaDataX();
1428: if (agent_.loggingEnabled()) {
1429: agent_.logWriter_.traceExit(this , "getMetaData",
1430: resultSetMetaData);
1431: }
1432: return resultSetMetaData;
1433: }
1434: } catch (SqlException se) {
1435: throw se.getSQLException();
1436: }
1437: }
1438:
1439: private ColumnMetaData getMetaDataX() throws SqlException {
1440: super .checkForClosedStatement();
1441: return resultSetMetaData_;
1442: }
1443:
1444: //------------------------- JDBC 3.0 -----------------------------------
1445:
1446: public boolean execute(String sql, int autoGeneratedKeys)
1447: throws SQLException {
1448: if (agent_.loggingEnabled()) {
1449: agent_.logWriter_.traceEntry(this , "execute", sql,
1450: autoGeneratedKeys);
1451: }
1452: throw new SqlException(agent_.logWriter_, new ClientMessageId(
1453: SQLState.NOT_FOR_PREPARED_STATEMENT),
1454: "execute(String, int)").getSQLException();
1455: }
1456:
1457: public boolean execute(String sql, String[] columnNames)
1458: throws SQLException {
1459: if (agent_.loggingEnabled()) {
1460: agent_.logWriter_.traceEntry(this , "execute", sql,
1461: columnNames);
1462: }
1463: throw new SqlException(agent_.logWriter_, new ClientMessageId(
1464: SQLState.NOT_FOR_PREPARED_STATEMENT),
1465: "execute(String, String[])").getSQLException();
1466: }
1467:
1468: public boolean execute(String sql, int[] columnIndexes)
1469: throws SQLException {
1470: if (agent_.loggingEnabled()) {
1471: agent_.logWriter_.traceEntry(this , "execute", sql,
1472: columnIndexes);
1473: }
1474: throw new SqlException(agent_.logWriter_, new ClientMessageId(
1475: SQLState.NOT_FOR_PREPARED_STATEMENT),
1476: "execute(String, int[])").getSQLException();
1477: }
1478:
1479: public int executeUpdate(String sql, int autoGeneratedKeys)
1480: throws SQLException {
1481: if (agent_.loggingEnabled()) {
1482: agent_.logWriter_.traceEntry(this , "executeUpdate",
1483: autoGeneratedKeys);
1484: }
1485: throw new SqlException(agent_.logWriter_, new ClientMessageId(
1486: SQLState.NOT_FOR_PREPARED_STATEMENT),
1487: "executeUpdate(String, int)").getSQLException();
1488: }
1489:
1490: public int executeUpdate(String sql, String[] columnNames)
1491: throws SQLException {
1492: if (agent_.loggingEnabled()) {
1493: agent_.logWriter_.traceEntry(this , "executeUpdate",
1494: columnNames);
1495: }
1496: throw new SqlException(agent_.logWriter_, new ClientMessageId(
1497: SQLState.NOT_FOR_PREPARED_STATEMENT),
1498: "executeUpdate(String, String[])").getSQLException();
1499: }
1500:
1501: public int executeUpdate(String sql, int[] columnIndexes)
1502: throws SQLException {
1503: if (agent_.loggingEnabled()) {
1504: agent_.logWriter_.traceEntry(this , "executeUpdate",
1505: columnIndexes);
1506: }
1507: throw new SqlException(agent_.logWriter_, new ClientMessageId(
1508: SQLState.NOT_FOR_PREPARED_STATEMENT),
1509: "execute(String, int[])").getSQLException();
1510: }
1511:
1512: public void setURL(int parameterIndex, java.net.URL x)
1513: throws SQLException {
1514: if (agent_.loggingEnabled()) {
1515: agent_.logWriter_.traceEntry(this , "setURL",
1516: parameterIndex, x);
1517: }
1518: jdbc3FeatureNotSupported(false);
1519: }
1520:
1521: public java.sql.ParameterMetaData getParameterMetaData()
1522: throws SQLException {
1523: try {
1524: synchronized (connection_) {
1525: if (agent_.loggingEnabled()) {
1526: agent_.logWriter_.traceEntry(this ,
1527: "getParameterMetaData");
1528: }
1529: Object parameterMetaData = getParameterMetaDataX();
1530: if (agent_.loggingEnabled()) {
1531: agent_.logWriter_.traceExit(this ,
1532: "getParameterMetaData", parameterMetaData);
1533: }
1534: return (java.sql.ParameterMetaData) parameterMetaData;
1535: }
1536: } catch (SqlException se) {
1537: throw se.getSQLException();
1538: }
1539: }
1540:
1541: private ParameterMetaData getParameterMetaDataX()
1542: throws SqlException {
1543: super .checkForClosedStatement();
1544: ParameterMetaData pm = ClientDriver.getFactory()
1545: .newParameterMetaData(
1546: parameterMetaData_ != null ? parameterMetaData_
1547: : ClientDriver.getFactory()
1548: .newColumnMetaData(
1549: agent_.logWriter_, 0));
1550: if (escapedProcedureCallWithResult_) {
1551: pm.escapedProcedureCallWithResult_ = true;
1552: }
1553: return pm;
1554: }
1555:
1556: // ------------------------ box car and callback methods --------------------------------
1557:
1558: public void writeExecute(Section section,
1559: ColumnMetaData parameterMetaData, Object[] inputs,
1560: int numInputColumns, boolean outputExpected,
1561: // This is a hint to the material layer that more write commands will follow.
1562: // It is ignored by the driver in all cases except when blob data is written,
1563: // in which case this boolean is used to optimize the implementation.
1564: // Otherwise we wouldn't be able to chain after blob data is sent.
1565: // Current servers have a restriction that blobs can only be chained with blobs
1566: boolean chainedWritesFollowingSetLob) throws SqlException {
1567: materialPreparedStatement_.writeExecute_(section,
1568: parameterMetaData, inputs, numInputColumns,
1569: outputExpected, chainedWritesFollowingSetLob);
1570: }
1571:
1572: public void readExecute() throws SqlException {
1573: materialPreparedStatement_.readExecute_();
1574: }
1575:
1576: public void writeOpenQuery(Section section, int fetchSize,
1577: int resultSetType, int numInputColumns,
1578: ColumnMetaData parameterMetaData, Object[] inputs)
1579: throws SqlException {
1580: materialPreparedStatement_.writeOpenQuery_(section, fetchSize,
1581: resultSetType, numInputColumns, parameterMetaData,
1582: inputs);
1583: }
1584:
1585: public void writeDescribeInput(Section section) throws SqlException {
1586: materialPreparedStatement_.writeDescribeInput_(section);
1587: }
1588:
1589: public void readDescribeInput() throws SqlException {
1590: materialPreparedStatement_.readDescribeInput_();
1591: }
1592:
1593: public void completeDescribeInput(ColumnMetaData parameterMetaData,
1594: Sqlca sqlca) {
1595: int sqlcode = super .completeSqlca(sqlca);
1596: if (sqlcode < 0) {
1597: return;
1598: }
1599:
1600: parameterMetaData_ = parameterMetaData;
1601:
1602: // The following code handles the case when
1603: // sqlxParmmode is not supported, in which case server will return 0 (unknown), and
1604: // this could clobber our guessed value for sqlxParmmode. This is a problem.
1605: // We can solve this problem for Non-CALL statements, since the parmmode is always IN (1).
1606: // But what about CALL statements. If CALLs are describable, then we have no
1607: // problem, we assume server won't return unknown.
1608: // If CALLs are not describable then nothing gets clobbered because we won't
1609: // parse out extended describe, so again no problem.
1610: if (sqlMode_ != isCall__ && parameterMetaData_ != null) {
1611: for (int i = 0; i < parameterMetaData_.columns_; i++) {
1612: parameterMetaData_.sqlxParmmode_[i] = 1; // 1 means IN parameter
1613: }
1614: }
1615:
1616: if (agent_.loggingEnabled()) {
1617: agent_.logWriter_.traceParameterMetaData(this ,
1618: parameterMetaData_);
1619: }
1620: }
1621:
1622: public void writeDescribeOutput(Section section)
1623: throws SqlException {
1624: materialPreparedStatement_.writeDescribeOutput_(section);
1625: }
1626:
1627: public void readDescribeOutput() throws SqlException {
1628: materialPreparedStatement_.readDescribeOutput_();
1629: }
1630:
1631: public void completeDescribeOutput(
1632: ColumnMetaData resultSetMetaData, Sqlca sqlca) {
1633: int sqlcode = super .completeSqlca(sqlca);
1634: if (sqlcode < 0) {
1635: return;
1636: }
1637: resultSetMetaData_ = resultSetMetaData;
1638: if (agent_.loggingEnabled()) {
1639: agent_.logWriter_.traceResultSetMetaData(this ,
1640: resultSetMetaData);
1641: }
1642: }
1643:
1644: void writePrepareDescribeInputOutput() throws SqlException {
1645: // Notice that sql_ is passed in since in general ad hoc sql must be passed in for unprepared statements
1646: writePrepareDescribeOutput(sql_, section_);
1647: writeDescribeInput(section_);
1648: }
1649:
1650: void readPrepareDescribeInputOutput() throws SqlException {
1651: readPrepareDescribeOutput();
1652: readDescribeInput();
1653: completePrepareDescribe();
1654: }
1655:
1656: void writePrepareDescribeInput() throws SqlException {
1657: // performance will be better if we flow prepare with output enable vs. prepare then describe input for callable
1658: // Notice that sql_ is passed in since in general ad hoc sql must be passed in for unprepared statements
1659: writePrepare(sql_, section_);
1660: writeDescribeInput(section_);
1661: }
1662:
1663: void readPrepareDescribeInput() throws SqlException {
1664: readPrepare();
1665: readDescribeInput();
1666: completePrepareDescribe();
1667: }
1668:
1669: void completePrepareDescribe() {
1670: if (parameterMetaData_ == null) {
1671: return;
1672: }
1673: parameters_ = expandObjectArray(parameters_,
1674: parameterMetaData_.columns_);
1675: parameterSet_ = expandBooleanArray(parameterSet_,
1676: parameterMetaData_.columns_);
1677: parameterRegistered_ = expandBooleanArray(parameterRegistered_,
1678: parameterMetaData_.columns_);
1679: }
1680:
1681: private Object[] expandObjectArray(Object[] array, int newLength) {
1682: if (array == null) {
1683: Object[] newArray = new Object[newLength];
1684: return newArray;
1685: }
1686: if (array.length < newLength) {
1687: Object[] newArray = new Object[newLength];
1688: System.arraycopy(array, 0, newArray, 0, array.length);
1689: return newArray;
1690: }
1691: return array;
1692: }
1693:
1694: private boolean[] expandBooleanArray(boolean[] array, int newLength) {
1695: if (array == null) {
1696: boolean[] newArray = new boolean[newLength];
1697: return newArray;
1698: }
1699: if (array.length < newLength) {
1700: boolean[] newArray = new boolean[newLength];
1701: System.arraycopy(array, 0, newArray, 0, array.length);
1702: return newArray;
1703: }
1704: return array;
1705: }
1706:
1707: void flowPrepareForSelectFromInsert() throws SqlException {
1708: agent_.beginWriteChain(this );
1709: writePrepareDescribeInputOutput(
1710: constructSelectFromInsertSQL(sql_), section_);
1711: agent_.flow(this );
1712: readPrepareDescribeInputOutput();
1713: agent_.endReadChain();
1714: }
1715:
1716: void writePrepareDescribeInputOutput(String sql, Section section)
1717: throws SqlException {
1718: // Notice that sql_ is passed in since in general ad hoc sql must be passed in for unprepared statements
1719: writePrepareDescribeOutput(sql, section);
1720: writeDescribeInput(section);
1721: }
1722:
1723: void flowPrepareDescribeInputOutput() throws SqlException {
1724: agent_.beginWriteChain(this );
1725: if (sqlMode_ == isCall__) {
1726: writePrepareDescribeInput();
1727: agent_.flow(this );
1728: readPrepareDescribeInput();
1729: agent_.endReadChain();
1730: } else {
1731: writePrepareDescribeInputOutput();
1732: agent_.flow(this );
1733: readPrepareDescribeInputOutput();
1734: agent_.endReadChain();
1735: }
1736: }
1737:
1738: void flowExecute(int executeType) throws SqlException {
1739: super .checkForClosedStatement();
1740: super .clearWarningsX();
1741: super .checkForAppropriateSqlMode(executeType, sqlMode_);
1742: checkThatAllParametersAreSet();
1743:
1744: if (sqlMode_ == isUpdate__) {
1745: updateCount_ = 0;
1746: } else {
1747: updateCount_ = -1;
1748: }
1749:
1750: // DERBY-1036: Moved check till execute time to comply with embedded
1751: // behavior. Since we check here and not in setCursorName, several
1752: // statements can have the same cursor name as long as their result
1753: // sets are not simultaneously open.
1754:
1755: if (sqlMode_ == isQuery__) {
1756: checkForDuplicateCursorName();
1757: }
1758:
1759: agent_.beginWriteChain(this );
1760:
1761: boolean piggybackedAutocommit = super
1762: .writeCloseResultSets(true); // true means permit auto-commits
1763:
1764: int numInputColumns;
1765: boolean outputExpected;
1766: try {
1767: numInputColumns = (parameterMetaData_ != null) ? parameterMetaData_
1768: .getColumnCount()
1769: : 0;
1770: outputExpected = (resultSetMetaData_ != null && resultSetMetaData_
1771: .getColumnCount() > 0);
1772: } catch (SQLException se) {
1773: // Generate a SqlException for this, we don't want to throw
1774: // SQLException in this internal method
1775: throw new SqlException(se);
1776: }
1777: boolean chainAutoCommit = false;
1778: boolean commitSubstituted = false;
1779: boolean repositionedCursor = false;
1780: boolean timeoutSent = false;
1781: ResultSet scrollableRS = null;
1782:
1783: if (doWriteTimeout) {
1784: timeoutArrayList.set(0, TIMEOUT_STATEMENT + timeout_);
1785: writeSetSpecialRegister(timeoutArrayList);
1786: doWriteTimeout = false;
1787: timeoutSent = true;
1788: }
1789: switch (sqlMode_) {
1790: case isUpdate__:
1791: if (positionedUpdateCursorName_ != null) {
1792: scrollableRS = agent_.sectionManager_
1793: .getPositionedUpdateResultSet(positionedUpdateCursorName_);
1794: }
1795: if (scrollableRS != null && !scrollableRS.isRowsetCursor_) {
1796: repositionedCursor = scrollableRS
1797: .repositionScrollableResultSetBeforeJDBC1PositionedUpdateDelete();
1798: if (!repositionedCursor) {
1799: scrollableRS = null;
1800: }
1801: }
1802:
1803: chainAutoCommit = connection_.willAutoCommitGenerateFlow()
1804: && isAutoCommittableStatement_;
1805:
1806: if (sqlUpdateMode_ == isInsertSql__
1807: && generatedKeysColumnNames_ != null) {
1808: writeOpenQuery(section_, fetchSize_, resultSetType_,
1809: numInputColumns, parameterMetaData_,
1810: parameters_);
1811: } else {
1812: boolean chainOpenQueryForAutoGeneratedKeys = (sqlUpdateMode_ == isInsertSql__ && autoGeneratedKeys_ == RETURN_GENERATED_KEYS);
1813: writeExecute(
1814: section_,
1815: parameterMetaData_,
1816: parameters_,
1817: numInputColumns,
1818: outputExpected,
1819: (chainAutoCommit || chainOpenQueryForAutoGeneratedKeys)// chain flag
1820: ); // chain flag
1821:
1822: if (chainOpenQueryForAutoGeneratedKeys) {
1823: prepareAutoGeneratedKeysStatement();
1824: writeOpenQuery(
1825: preparedStatementForAutoGeneratedKeys_.section_,
1826: preparedStatementForAutoGeneratedKeys_.fetchSize_,
1827: preparedStatementForAutoGeneratedKeys_.resultSetType_);
1828: }
1829: }
1830:
1831: if (chainAutoCommit) {
1832: // we have encountered an error in writing the execute, so do not
1833: // flow an autocommit
1834: if (agent_.accumulatedReadExceptions_ != null) {
1835: // currently, the only write exception we encounter is for
1836: // data truncation: SQLSTATE 01004, so we don't bother checking for this
1837: connection_.writeCommitSubstitute_();
1838: commitSubstituted = true;
1839: } else {
1840: // there is no write error, so flow the commit
1841: connection_.writeCommit();
1842: }
1843: }
1844: break;
1845:
1846: case isQuery__:
1847: writeOpenQuery(section_, fetchSize_, resultSetType_,
1848: numInputColumns, parameterMetaData_, parameters_);
1849: break;
1850:
1851: case isCall__:
1852: writeExecuteCall(outputRegistered_, // if no out/inout parameter, outputExpected = false
1853: null, section_, fetchSize_, false, // do not suppress ResultSets for regular CALLs
1854: resultSetType_, parameterMetaData_, parameters_); // cross conversion
1855: break;
1856: }
1857:
1858: agent_.flow(this );
1859:
1860: super .readCloseResultSets(true); // true means permit auto-commits
1861:
1862: // turn inUnitOfWork_ flag back on and add statement
1863: // back on commitListeners_ list if they were off
1864: // by an autocommit chained to a close cursor.
1865: if (piggybackedAutocommit) {
1866: connection_.completeTransactionStart();
1867: }
1868:
1869: super .markResultSetsClosed(true); // true means remove from list of commit and rollback listeners
1870:
1871: if (timeoutSent) {
1872: readSetSpecialRegister(); // Read response to the EXCSQLSET
1873: }
1874:
1875: switch (sqlMode_) {
1876: case isUpdate__:
1877: // do not need to reposition for a rowset cursor
1878: if (scrollableRS != null && !scrollableRS.isRowsetCursor_) {
1879: scrollableRS.readPositioningFetch_();
1880: }
1881:
1882: if (sqlUpdateMode_ == isInsertSql__
1883: && generatedKeysColumnNames_ != null) {
1884: readOpenQuery();
1885: if (resultSet_ != null) {
1886: generatedKeysResultSet_ = resultSet_;
1887: resultSet_ = null;
1888: updateCount_ = 1;
1889: }
1890: } else {
1891: readExecute();
1892:
1893: if (sqlUpdateMode_ == isInsertSql__
1894: && autoGeneratedKeys_ == RETURN_GENERATED_KEYS) {
1895: readPrepareAutoGeneratedKeysStatement();
1896: preparedStatementForAutoGeneratedKeys_
1897: .readOpenQuery();
1898: generatedKeysResultSet_ = preparedStatementForAutoGeneratedKeys_.resultSet_;
1899: preparedStatementForAutoGeneratedKeys_.resultSet_ = null;
1900: }
1901: }
1902:
1903: if (chainAutoCommit) {
1904: if (commitSubstituted) {
1905: connection_.readCommitSubstitute_();
1906: } else {
1907: connection_.readCommit();
1908: }
1909: }
1910: break;
1911:
1912: case isQuery__:
1913: try {
1914: readOpenQuery();
1915: } catch (DisconnectException dise) {
1916: throw dise;
1917: } catch (SqlException e) {
1918: throw e;
1919: }
1920: // resultSet_ is null if open query failed.
1921: // check for null resultSet_ before using it.
1922: if (resultSet_ != null) {
1923: resultSet_.parseScrollableRowset();
1924: //if (resultSet_.scrollable_) resultSet_.getRowCount();
1925:
1926: // DERBY-1183: If we set it up earlier, the entry in
1927: // clientCursorNameCache_ gets wiped out by the closing of
1928: // result sets happening during readCloseResultSets above
1929: // because ResultSet#markClosed calls
1930: // Statement#removeClientCursorNameFromCache.
1931: setupCursorNameCacheAndMappings();
1932: }
1933: break;
1934:
1935: case isCall__:
1936: readExecuteCall();
1937: break;
1938:
1939: }
1940:
1941: try {
1942: agent_.endReadChain();
1943: } catch (SqlException e) {
1944: throw e;
1945:
1946: }
1947:
1948: if (sqlMode_ == isCall__) {
1949: parseStorProcReturnedScrollableRowset();
1950: checkForStoredProcResultSetCount(executeType);
1951: // When there are no result sets back, we will commit immediately when autocommit is true.
1952: // make sure a commit is not performed when making the call to the sqlca message procedure
1953: if (connection_.autoCommit_ && resultSet_ == null
1954: && resultSetList_ == null
1955: && isAutoCommittableStatement_) {
1956: connection_.flowAutoCommit();
1957: }
1958: }
1959:
1960: // The JDBC spec says that executeUpdate() should return 0
1961: // when no row count is returned.
1962: if (executeType == executeUpdateMethod__ && updateCount_ < 0) {
1963: updateCount_ = 0;
1964: }
1965:
1966: // Throw an exception if holdability returned by the server is different from requested.
1967: if (resultSet_ != null
1968: && resultSet_.resultSetHoldability_ != resultSetHoldability_
1969: && sqlMode_ != isCall__) {
1970: throw new SqlException(
1971: agent_.logWriter_,
1972: new ClientMessageId(
1973: SQLState.UNABLE_TO_OPEN_RESULTSET_WITH_REQUESTED_HOLDABILTY),
1974: new Integer(resultSetHoldability_));
1975: }
1976: }
1977:
1978: public int[] executeBatchX(boolean supportsQueryBatchRequest)
1979: throws SqlException, SQLException, BatchUpdateException {
1980: synchronized (connection_) {
1981: checkForClosedStatement(); // Per jdbc spec (see Statement.close() javadoc)
1982: clearWarningsX(); // Per jdbc spec 0.7, also see getWarnings() javadoc
1983: return executeBatchRequestX(supportsQueryBatchRequest);
1984: }
1985: }
1986:
1987: private int[] executeBatchRequestX(boolean supportsQueryBatchRequest)
1988: throws SqlException, BatchUpdateException {
1989: SqlException chainBreaker = null;
1990: int batchSize = batch_.size();
1991: int[] updateCounts = new int[batchSize];
1992: int numInputColumns;
1993: try {
1994: numInputColumns = parameterMetaData_ == null ? 0
1995: : parameterMetaData_.getColumnCount();
1996: } catch (SQLException se) {
1997: throw new SqlException(se);
1998: }
1999: Object[] savedInputs = null; // used to save/restore existing parameters
2000: boolean timeoutSent = false;
2001:
2002: if (batchSize == 0) {
2003: return updateCounts;
2004: }
2005: // The network client has a hard limit of 65,534 commands in a single
2006: // DRDA request. This is because DRDA uses a 2-byte correlation ID,
2007: // and the values 0 and 0xffff are reserved as special values. So
2008: // that imposes an upper limit on the batch size we can support:
2009: if (batchSize > 65534)
2010: throw new BatchUpdateException(agent_.logWriter_,
2011: new ClientMessageId(
2012: SQLState.TOO_MANY_COMMANDS_FOR_BATCH),
2013: new Integer(65534), updateCounts);
2014:
2015: // Initialize all the updateCounts to indicate failure
2016: // This is done to account for "chain-breaking" errors where we cannot
2017: // read any more replies
2018: for (int i = 0; i < batchSize; i++) {
2019: updateCounts[i] = -3;
2020: }
2021:
2022: if (!supportsQueryBatchRequest && sqlMode_ == isQuery__) {
2023: throw new BatchUpdateException(agent_.logWriter_,
2024: new ClientMessageId(SQLState.CANNOT_BATCH_QUERIES),
2025: updateCounts);
2026: }
2027: if (supportsQueryBatchRequest && sqlMode_ != isQuery__) {
2028: throw new BatchUpdateException(
2029: agent_.logWriter_,
2030: new ClientMessageId(
2031: SQLState.QUERY_BATCH_ON_NON_QUERY_STATEMENT),
2032: updateCounts);
2033: }
2034:
2035: resultSetList_ = null;
2036:
2037: if (sqlMode_ == isQuery__) {
2038: indexOfCurrentResultSet_ = -1; //reset ResultSetList
2039: resultSetList_ = new ResultSet[batchSize];
2040: }
2041:
2042: //save the current input set so it can be restored
2043: savedInputs = parameters_;
2044:
2045: agent_.beginBatchedWriteChain(this );
2046: boolean chainAutoCommit = connection_
2047: .willAutoCommitGenerateFlow()
2048: && isAutoCommittableStatement_;
2049:
2050: if (doWriteTimeout) {
2051: timeoutArrayList.set(0, TIMEOUT_STATEMENT + timeout_);
2052: writeSetSpecialRegister(timeoutArrayList);
2053: doWriteTimeout = false;
2054: timeoutSent = true;
2055: }
2056:
2057: for (int i = 0; i < batchSize; i++) {
2058: parameterMetaData_.clientParamtertype_ = (int[]) parameterTypeList
2059: .get(i);
2060: parameters_ = (Object[]) batch_.get(i);
2061:
2062: if (sqlMode_ != isCall__) {
2063: boolean outputExpected;
2064: try {
2065: outputExpected = (resultSetMetaData_ != null && resultSetMetaData_
2066: .getColumnCount() > 0);
2067: } catch (SQLException se) {
2068: throw new SqlException(se);
2069: }
2070:
2071: writeExecute(section_, parameterMetaData_, parameters_,
2072: numInputColumns, outputExpected,
2073: chainAutoCommit || (i != batchSize - 1)); // more statements to chain
2074: } else if (outputRegistered_) // make sure no output parameters are registered
2075: {
2076: throw new BatchUpdateException(agent_.logWriter_,
2077: new ClientMessageId(
2078: SQLState.OUTPUT_PARAMS_NOT_ALLOWED),
2079: updateCounts);
2080: } else {
2081: writeExecuteCall(false, // no output expected for batched CALLs
2082: null, // no procedure name supplied for prepared CALLs
2083: section_, fetchSize_, true, // suppress ResultSets for batch
2084: resultSetType_, parameterMetaData_, parameters_);
2085: }
2086: }
2087:
2088: boolean commitSubstituted = false;
2089: if (chainAutoCommit) {
2090: // we have encountered an error in writing the execute, so do not
2091: // flow an autocommit
2092: if (agent_.accumulatedReadExceptions_ != null) {
2093: // currently, the only write exception we encounter is for
2094: // data truncation: SQLSTATE 01004, so we don't bother checking for this
2095: connection_.writeCommitSubstitute_();
2096: commitSubstituted = true;
2097: } else {
2098: // there is no write error, so flow the commit
2099: connection_.writeCommit();
2100: }
2101: }
2102:
2103: agent_.flowBatch(this , batchSize);
2104:
2105: if (timeoutSent) {
2106: readSetSpecialRegister(); // Read response to the EXCSQLSET
2107: }
2108:
2109: try {
2110: for (int i = 0; i < batchSize; i++) {
2111: agent_.setBatchedExceptionLabelIndex(i);
2112: parameters_ = (Object[]) batch_.get(i);
2113: if (sqlMode_ != isCall__) {
2114: readExecute();
2115: } else {
2116: readExecuteCall();
2117: }
2118: updateCounts[i] = updateCount_;
2119:
2120: }
2121:
2122: agent_.disableBatchedExceptionTracking(); // to prvent the following readCommit() from getting a batch label
2123: if (chainAutoCommit) {
2124: if (!commitSubstituted) {
2125: connection_.readCommit();
2126: } else {
2127: connection_.readCommitSubstitute_();
2128: }
2129: }
2130: }
2131:
2132: // for chain-breaking exception only, all read() methods do their own accumulation
2133: // this catches the entire accumulated chain, we need to be careful not to
2134: // reaccumulate it on the agent since the batch labels will be overwritten if
2135: // batch exception tracking is enabled.
2136: catch (SqlException e) { // for chain-breaking exception only
2137: chainBreaker = e;
2138: chainBreaker.setNextException(new SqlException(
2139: agent_.logWriter_, new ClientMessageId(
2140: SQLState.BATCH_CHAIN_BREAKING_EXCEPTION)));
2141: }
2142: // We need to clear the batch before any exception is thrown from agent_.endBatchedReadChain().
2143: batch_.clear();
2144: parameterTypeList = null;
2145:
2146: // restore the saved input set, setting it to "current"
2147: parameters_ = savedInputs;
2148:
2149: agent_.endBatchedReadChain(updateCounts, chainBreaker);
2150:
2151: return updateCounts;
2152:
2153: }
2154:
2155: //------------------material layer event callbacks follow-----------------------
2156:
2157: boolean listenToUnitOfWork_ = false;
2158:
2159: public void listenToUnitOfWork() {
2160: if (!listenToUnitOfWork_) {
2161: listenToUnitOfWork_ = true;
2162: connection_.CommitAndRollbackListeners_.put(this , null);
2163: }
2164: }
2165:
2166: public void completeLocalCommit(java.util.Iterator listenerIterator) {
2167: if (section_ != null) {
2168: openOnServer_ = false;
2169: }
2170: listenerIterator.remove();
2171: listenToUnitOfWork_ = false;
2172: }
2173:
2174: public void completeLocalRollback(
2175: java.util.Iterator listenerIterator) {
2176: if (section_ != null) {
2177: openOnServer_ = false;
2178: }
2179: listenerIterator.remove();
2180: listenToUnitOfWork_ = false;
2181: }
2182:
2183: //----------------------------internal use only helper methods----------------
2184:
2185: /**
2186: * Returns the name of the java.sql interface implemented by this class.
2187: * @return name of java.sql interface
2188: */
2189: protected String getJdbcStatementInterfaceName() {
2190: return "java.sql.PreparedStatement";
2191: }
2192:
2193: private int checkSetterPreconditions(int parameterIndex)
2194: throws SqlException {
2195: super .checkForClosedStatement();
2196: parameterIndex = checkForEscapedCallWithResult(parameterIndex);
2197: checkForValidParameterIndex(parameterIndex);
2198: return parameterIndex;
2199: }
2200:
2201: void checkForValidParameterIndex(int parameterIndex)
2202: throws SqlException {
2203: if (parameterMetaData_ == null || parameterIndex < 1
2204: || parameterIndex > parameterMetaData_.columns_) {
2205: throw new SqlException(agent_.logWriter_,
2206: new ClientMessageId(
2207: SQLState.LANG_INVALID_PARAM_POSITION),
2208: new Integer(parameterIndex), new Integer(
2209: parameterMetaData_.columns_));
2210: }
2211: }
2212:
2213: private void checkThatAllParametersAreSet() throws SqlException {
2214: if (parameterMetaData_ != null) {
2215: for (int i = 0; i < parameterMetaData_.columns_; i++) {
2216: if (!parameterSet_[i] && !parameterRegistered_[i]) {
2217: throw new SqlException(agent_.logWriter_,
2218: new ClientMessageId(
2219: SQLState.LANG_MISSING_PARMS));
2220: }
2221: }
2222: }
2223: }
2224:
2225: private int checkForEscapedCallWithResult(int parameterIndex)
2226: throws SqlException {
2227: if (escapedProcedureCallWithResult_) {
2228: if (parameterIndex == 1) {
2229: throw new SqlException(
2230: agent_.logWriter_,
2231: new ClientMessageId(
2232: SQLState.LANG_RETURN_OUTPUT_PARAM_CANNOT_BE_SET));
2233: } else {
2234: parameterIndex--;
2235: }
2236: }
2237: return parameterIndex;
2238: }
2239:
2240: void checkForValidScale(int scale) throws SqlException {
2241: if (scale < 0 || scale > 31) {
2242: throw new SqlException(agent_.logWriter_,
2243: new ClientMessageId(SQLState.BAD_SCALE_VALUE),
2244: new Integer(scale));
2245: }
2246: }
2247:
2248: /**
2249: * Checks whether a data type is supported for
2250: * <code>setObject(int, Object, int)</code> and
2251: * <code>setObject(int, Object, int, int)</code>.
2252: *
2253: * @param dataType the data type to check
2254: * @exception SqlException if the type is not supported
2255: */
2256: private void checkForSupportedDataType(int dataType)
2257: throws SqlException {
2258:
2259: // JDBC 4.0 javadoc for setObject() says:
2260: //
2261: // Throws: (...) SQLFeatureNotSupportedException - if
2262: // targetSqlType is a ARRAY, BLOB, CLOB, DATALINK,
2263: // JAVA_OBJECT, NCHAR, NCLOB, NVARCHAR, LONGNVARCHAR, REF,
2264: // ROWID, SQLXML or STRUCT data type and the JDBC driver does
2265: // not support this data type
2266: //
2267: // Of these types, we only support BLOB, CLOB and
2268: // (sort of) JAVA_OBJECT.
2269:
2270: switch (dataType) {
2271: case java.sql.Types.ARRAY:
2272: case java.sql.Types.DATALINK:
2273: case JDBC40Translation.NCHAR:
2274: case JDBC40Translation.NCLOB:
2275: case JDBC40Translation.NVARCHAR:
2276: case JDBC40Translation.LONGNVARCHAR:
2277: case java.sql.Types.REF:
2278: case JDBC40Translation.ROWID:
2279: case JDBC40Translation.SQLXML:
2280: case java.sql.Types.STRUCT:
2281: throw new SqlException(agent_.logWriter_,
2282: new ClientMessageId(
2283: SQLState.DATA_TYPE_NOT_SUPPORTED), Types
2284: .getTypeString(dataType));
2285: }
2286: }
2287:
2288: void checkScaleForINOUTDecimal(int parameterIndex,
2289: int registerOutScale) throws SqlException {
2290: java.math.BigDecimal decimalInput = (java.math.BigDecimal) parameters_[parameterIndex - 1];
2291: if (decimalInput == null) {
2292: return;
2293: }
2294: // if the register out scale is greater than input scale, input scale is stored in sqlScale_
2295: if (registerOutScale > parameterMetaData_.sqlScale_[parameterIndex - 1]) {
2296: int inputLength = decimalInput.toString().length();
2297: int scaleDifference = registerOutScale
2298: - decimalInput.scale();
2299: if (decimalInput.signum() == -1) {
2300: inputLength--;
2301: }
2302: // if the new Decimal (with bigger scale) cannot fit into the DA
2303: if ((32 - scaleDifference) < inputLength) {
2304: // TODO - FINISH THIS
2305: throw new SqlException(
2306: agent_.logWriter_,
2307: new ClientMessageId(
2308: SQLState.REGOUTPARAM_SCALE_DOESNT_MATCH_SETTER));
2309: }
2310: // if the new Decimal (with bigger scale) can fit
2311: else {
2312: parameters_[parameterIndex - 1] = decimalInput
2313: .setScale(registerOutScale);
2314: parameterMetaData_.sqlScale_[parameterIndex - 1] = registerOutScale;
2315: }
2316: }
2317: // if the register out sacle is smaller than input scale
2318: else if (registerOutScale < parameterMetaData_.sqlScale_[parameterIndex - 1]) {
2319: // remove 0's at the end of input
2320: try {
2321: // if the new Decimal (with smaller scale) can fit
2322: parameters_[parameterIndex - 1] = decimalInput
2323: .setScale(registerOutScale);
2324: parameterMetaData_.sqlScale_[parameterIndex - 1] = registerOutScale;
2325: } catch (ArithmeticException e) {
2326: // if the new Decimal (with smaller scale) cannot fit into the DA
2327: throw new SqlException(
2328: agent_.logWriter_,
2329: new ClientMessageId(
2330: SQLState.REGOUTPARAM_SCALE_DOESNT_MATCH_SETTER));
2331: }
2332: }
2333: }
2334:
2335: /* (non-Javadoc)
2336: * @see org.apache.derby.client.am.Statement#markClosed(boolean)
2337: */
2338: protected void markClosed(boolean removeListener) {
2339: if (pooledConnection_ != null)
2340: pooledConnection_.onStatementClose(this );
2341: super .markClosed(removeListener);
2342:
2343: if (parameterMetaData_ != null) {
2344: parameterMetaData_.markClosed();
2345: parameterMetaData_ = null;
2346: }
2347: sql_ = null;
2348:
2349: // Apparently, the JVM is not smart enough to traverse parameters_[] and null
2350: // out its members when the entire array is set to null (parameters_=null;).
2351: if (parameters_ != null) {
2352: for (int i = 0; i < parameters_.length; i++) {
2353: parameters_[i] = null;
2354: }
2355: }
2356: parameters_ = null;
2357:
2358: if (removeListener)
2359: connection_.CommitAndRollbackListeners_.remove(this );
2360: }
2361:
2362: //jdbc 4.0 methods
2363:
2364: /**
2365: * Sets the designated parameter to the given input stream.
2366: * When a very large ASCII value is input to a <code>LONGVARCHAR</code>
2367: * parameter, it may be more practical to send it via a
2368: * <code>java.io.InputStream</code>. Data will be read from the stream as
2369: * needed until end-of-file is reached. The JDBC driver will do any
2370: * necessary conversion from ASCII to the database char format.
2371: *
2372: * @param parameterIndex the first parameter is 1, the second is 2, ...
2373: * @param x the Java input stream that contains the ASCII parameter value
2374: * @throws SQLException if a database access error occurs or this method is
2375: * called on a closed <code>PreparedStatement</code>
2376: */
2377: public void setAsciiStream(int parameterIndex, InputStream x)
2378: throws SQLException {
2379: synchronized (connection_) {
2380: if (agent_.loggingEnabled()) {
2381: agent_.logWriter_.traceEntry(this , "setAsciiStream",
2382: parameterIndex, x);
2383: }
2384: try {
2385: parameterIndex = checkSetterPreconditions(parameterIndex);
2386: parameterMetaData_.clientParamtertype_[parameterIndex - 1] = java.sql.Types.CLOB;
2387: if (x == null) {
2388: setNull(parameterIndex, java.sql.Types.CLOB);
2389: return;
2390: }
2391: setInput(parameterIndex,
2392: new Clob(agent_, x, "US-ASCII"));
2393: } catch (SqlException se) {
2394: throw se.getSQLException();
2395: }
2396: }
2397: }
2398:
2399: /**
2400: * Sets the designated parameter to the given input stream.
2401: * When a very large binary value is input to a <code>LONGVARBINARY</code>
2402: * parameter, it may be more practical to send it via a
2403: * <code>java.io.InputStream</code> object. The data will be read from the
2404: * stream as needed until end-of-file is reached.
2405: *
2406: * @param parameterIndex the first parameter is 1, the second is 2, ...
2407: * @param x the java input stream which contains the binary parameter value
2408: * @throws SQLException if a database access error occurs or this method is
2409: * called on a closed <code>PreparedStatement</code>
2410: */
2411: public void setBinaryStream(int parameterIndex, InputStream x)
2412: throws SQLException {
2413: synchronized (connection_) {
2414: if (agent_.loggingEnabled()) {
2415: agent_.logWriter_.traceEntry(this , "setBinaryStream",
2416: parameterIndex, x);
2417: }
2418: try {
2419: setBinaryStreamX(parameterIndex, x, -1);
2420: } catch (SqlException se) {
2421: throw se.getSQLException();
2422: }
2423: }
2424: }
2425:
2426: /**
2427: * Sets the designated parameter to a <code>Reader</code> object.
2428: *
2429: * @param parameterIndex index of the first parameter is 1, the second is
2430: * 2, ...
2431: * @param reader an object that contains the data to set the parameter
2432: * value to.
2433: * @throws SQLException if parameterIndex does not correspond to a
2434: * parameter marker in the SQL statement; if a database access error
2435: * occurs; this method is called on a closed PreparedStatementor if
2436: * parameterIndex does not correspond to a parameter marker in the SQL
2437: * statement
2438: */
2439: public void setClob(int parameterIndex, Reader reader)
2440: throws SQLException {
2441: synchronized (connection_) {
2442: if (agent_.loggingEnabled()) {
2443: agent_.logWriter_.traceEntry(this , "setClob",
2444: parameterIndex, reader);
2445: }
2446: try {
2447: checkForClosedStatement();
2448: } catch (SqlException se) {
2449: throw se.getSQLException();
2450: }
2451: setInput(parameterIndex, new Clob(agent_, reader));
2452: }
2453: }
2454:
2455: /**
2456: * Sets the designated parameter to a Reader object.
2457: *
2458: * @param parameterIndex index of the first parameter is 1, the second is 2, ...
2459: * @param reader An object that contains the data to set the parameter value to.
2460: * @param length the number of characters in the parameter data.
2461: * @throws SQLException if parameterIndex does not correspond to a parameter
2462: * marker in the SQL statement, or if the length specified is less than zero.
2463: *
2464: */
2465:
2466: public void setClob(int parameterIndex, Reader reader, long length)
2467: throws SQLException {
2468: synchronized (connection_) {
2469: if (agent_.loggingEnabled()) {
2470: agent_.logWriter_.traceEntry(this , "setClob",
2471: parameterIndex, reader, new Long(length));
2472: }
2473: try {
2474: checkForClosedStatement();
2475: } catch (SqlException se) {
2476: throw se.getSQLException();
2477: }
2478: if (length > Integer.MAX_VALUE)
2479: throw new SqlException(agent_.logWriter_,
2480: new ClientMessageId(
2481: SQLState.BLOB_TOO_LARGE_FOR_CLIENT),
2482: new Long(length),
2483: new Integer(Integer.MAX_VALUE))
2484: .getSQLException();
2485: else
2486: setInput(parameterIndex, new Clob(agent_, reader,
2487: (int) length));
2488: }
2489: }
2490:
2491: /**
2492: * Sets the designated parameter to a <code>InputStream</code> object.
2493: * This method differs from the <code>setBinaryStream(int, InputStream)
2494: * </code> method because it informs the driver that the parameter value
2495: * should be sent to the server as a <code>BLOB</code>. When the
2496: * <code>setBinaryStream</code> method is used, the driver may have to do
2497: * extra work to determine whether the parameter data should be sent to the
2498: * server as a <code>LONGVARBINARY</code> or a <code>BLOB</code>
2499: *
2500: * @param parameterIndex index of the first parameter is 1, the second is
2501: * 2, ...
2502: * @param inputStream an object that contains the data to set the parameter
2503: * value to.
2504: * @throws SQLException if a database access error occurs, this method is
2505: * called on a closed <code>PreparedStatement</code> or if
2506: * <code>parameterIndex</code> does not correspond to a parameter
2507: * marker in the SQL statement
2508: */
2509: public void setBlob(int parameterIndex, InputStream inputStream)
2510: throws SQLException {
2511: synchronized (connection_) {
2512: if (agent_.loggingEnabled()) {
2513: agent_.logWriter_.traceEntry(this , "setBlob",
2514: parameterIndex, inputStream);
2515: }
2516: try {
2517: setBinaryStreamX(parameterIndex, inputStream, -1);
2518: } catch (SqlException se) {
2519: throw se.getSQLException();
2520: }
2521: }
2522: }
2523:
2524: /**
2525: * Sets the designated parameter to a InputStream object.
2526: *
2527: * @param parameterIndex index of the first parameter is 1,
2528: * the second is 2, ...
2529: * @param inputStream An object that contains the data to set the parameter
2530: * value to.
2531: * @param length the number of bytes in the parameter data.
2532: * @throws SQLException if parameterIndex does not correspond
2533: * to a parameter marker in the SQL statement, if the length specified
2534: * is less than zero or if the number of bytes in the inputstream does not match
2535: * the specfied length.
2536: *
2537: */
2538:
2539: public void setBlob(int parameterIndex, InputStream inputStream,
2540: long length) throws SQLException {
2541: synchronized (connection_) {
2542: if (agent_.loggingEnabled()) {
2543: agent_.logWriter_.traceEntry(this , "setBlob",
2544: parameterIndex, inputStream, new Long(length));
2545: }
2546: if (length > Integer.MAX_VALUE)
2547: throw new SqlException(agent_.logWriter_,
2548: new ClientMessageId(
2549: SQLState.BLOB_TOO_LARGE_FOR_CLIENT),
2550: new Long(length),
2551: new Integer(Integer.MAX_VALUE))
2552: .getSQLException();
2553: else {
2554: try {
2555: setBinaryStreamX(parameterIndex, inputStream,
2556: (int) length);
2557: } catch (SqlException se) {
2558: throw se.getSQLException();
2559: }
2560: }
2561: }
2562: }
2563:
2564: /*
2565: * Method calls onStatementError occurred on the
2566: * BrokeredConnectionControl class after checking the
2567: * SQLState of the SQLException thrown.
2568: * @param sqle SqlException
2569: * @throws java.sql.SQLException
2570: */
2571:
2572: private void checkStatementValidity(SqlException sqle)
2573: throws SQLException {
2574: //check if the statement is already closed
2575: //This might be caused because the connection associated
2576: //with this prepared statement has been closed marking
2577: //its associated prepared statements also as
2578: //closed
2579:
2580: if (pooledConnection_ != null && isClosed()) {
2581: pooledConnection_.onStatementErrorOccurred(this, sqle
2582: .getSQLException());
2583: }
2584: }
2585:
2586: }
|