001: /*
002:
003: Derby - Class org.apache.derby.impl.sql.execute.DeleteVTIResultSet
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.impl.sql.execute;
023:
024: import org.apache.derby.iapi.services.sanity.SanityManager;
025: import org.apache.derby.iapi.error.StandardException;
026: import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
027: import org.apache.derby.iapi.sql.execute.CursorResultSet;
028: import org.apache.derby.iapi.sql.execute.ExecRow;
029: import org.apache.derby.iapi.sql.execute.NoPutResultSet;
030: import org.apache.derby.iapi.sql.Activation;
031: import org.apache.derby.iapi.sql.ResultDescription;
032:
033: import org.apache.derby.iapi.store.access.TransactionController;
034:
035: import org.apache.derby.iapi.types.SQLInteger;
036:
037: import java.util.Properties;
038:
039: /**
040: * Delete the rows from the specified
041: * base table. This will cause constraints to be checked
042: * and triggers to be executed based on the c's and t's
043: * compiled into the insert plan.
044: */
045: class DeleteVTIResultSet extends DMLVTIResultSet {
046:
047: private java.sql.ResultSet rs;
048: private TemporaryRowHolderImpl rowHolder;
049:
050: /* If the delete is deferred use a row holder to keep the list of IDs of the rows to be deleted.
051: * A RowHolder is used instead of a simple list because a RowHolder will spill to disk when it becomes
052: * too large. The row will consist of just one column -- an integer.
053: */
054:
055: /*
056: * class interface
057: *
058: */
059: /**
060: *
061: * @exception StandardException Thrown on error
062: */
063: public DeleteVTIResultSet(NoPutResultSet source,
064: Activation activation) throws StandardException {
065: super (source, activation);
066: }
067:
068: /**
069: @exception StandardException Standard Cloudscape error policy
070: */
071: protected void openCore() throws StandardException {
072: lcc.getStatementContext().setTopResultSet(this ,
073: subqueryTrackingArray);
074:
075: ExecRow row = getNextRowCore(sourceResultSet);
076:
077: if (row != null) {
078: rs = activation.getTargetVTI();
079:
080: if (SanityManager.DEBUG) {
081: SanityManager.ASSERT(rs != null,
082: "rs expected to be non-null");
083: }
084: }
085:
086: /* The source does not know whether or not we are doing a
087: * deferred mode delete. If we are, then we must clear the
088: * index scan info from the activation so that the row changer
089: * does not re-use that information (which won't be valid for
090: * a deferred mode delete).
091: */
092: if (constants.deferred) {
093: activation.clearIndexScanInfo();
094: if (null == rowHolder)
095: rowHolder = new TemporaryRowHolderImpl(activation,
096: new Properties(), (ResultDescription) null);
097: }
098:
099: try {
100: while (row != null) {
101: if (!constants.deferred)
102: rs.deleteRow();
103: else {
104: ExecRow rowId = new ValueRow(1);
105: rowId.setColumn(1, new SQLInteger(rs.getRow()));
106: rowHolder.insert(rowId);
107: }
108:
109: rowCount++;
110:
111: // No need to do a next on a single row source
112: if (constants.singleRowSource) {
113: row = null;
114: } else {
115: row = getNextRowCore(sourceResultSet);
116: }
117: }
118: } catch (StandardException se) {
119: throw se;
120: } catch (Throwable t) {
121: throw StandardException.unexpectedUserException(t);
122: }
123:
124: if (constants.deferred) {
125: CursorResultSet tempRS = rowHolder.getResultSet();
126: try {
127: ExecRow deferredRowBuffer = null;
128:
129: tempRS.open();
130: while ((deferredRowBuffer = tempRS.getNextRow()) != null) {
131: int rowNumber = deferredRowBuffer.getColumn(1)
132: .getInt();
133: rs.absolute(rowNumber);
134: rs.deleteRow();
135: }
136: } catch (Throwable t) {
137: throw StandardException.unexpectedUserException(t);
138: } finally {
139: sourceResultSet.clearCurrentRow();
140: tempRS.close();
141: }
142: }
143:
144: if (rowHolder != null) {
145: rowHolder.close();
146: // rowHolder kept across opens
147: }
148: } // end of openCore
149: }
|