001: /*
002:
003: Derby - Class org.apache.derby.impl.sql.execute.RowResultSet
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.monitor.Monitor;
025:
026: import org.apache.derby.iapi.services.sanity.SanityManager;
027:
028: import org.apache.derby.iapi.services.stream.HeaderPrintWriter;
029: import org.apache.derby.iapi.services.stream.InfoStreams;
030:
031: import org.apache.derby.iapi.sql.execute.CursorResultSet;
032: import org.apache.derby.iapi.sql.execute.ExecRow;
033: import org.apache.derby.iapi.sql.execute.NoPutResultSet;
034:
035: import org.apache.derby.iapi.sql.Activation;
036: import org.apache.derby.iapi.sql.ResultDescription;
037:
038: import org.apache.derby.iapi.error.StandardException;
039:
040: import org.apache.derby.iapi.services.loader.GeneratedMethod;
041:
042: import org.apache.derby.iapi.types.RowLocation;
043:
044: /**
045: * Takes a constant row value and returns it as
046: * a result set.
047: * <p>
048: * This class actually probably never underlies a select statement,
049: * but in case it might and because it has the same behavior as the
050: * ones that do, we have it implement CursorResultSet and give
051: * reasonable answers.
052: *
053: * @author ames
054: */
055: class RowResultSet extends NoPutResultSetImpl implements
056: CursorResultSet {
057:
058: /* Run time statistics variables */
059: public int rowsReturned;
060:
061: private boolean canCacheRow;
062: private boolean next;
063: private GeneratedMethod row;
064: private ExecRow cachedRow;
065:
066: //
067: // class interface
068: //
069: RowResultSet(Activation activation, GeneratedMethod row,
070: boolean canCacheRow, int resultSetNumber,
071: double optimizerEstimatedRowCount,
072: double optimizerEstimatedCost) {
073: super (activation, resultSetNumber, optimizerEstimatedRowCount,
074: optimizerEstimatedCost);
075:
076: this .row = row;
077: this .canCacheRow = canCacheRow;
078: constructorTime += getElapsedMillis(beginTime);
079: }
080:
081: /* This constructor takes in a constant row value, as the cache row. See the
082: * usage in beetle 4373 for materializing subquery.
083: */
084: RowResultSet(Activation activation, ExecRow constantRow,
085: boolean canCacheRow, int resultSetNumber,
086: double optimizerEstimatedRowCount,
087: double optimizerEstimatedCost) {
088: super (activation, resultSetNumber, optimizerEstimatedRowCount,
089: optimizerEstimatedCost);
090:
091: beginTime = getCurrentTimeMillis();
092: this .cachedRow = constantRow;
093: this .canCacheRow = canCacheRow;
094: constructorTime += getElapsedMillis(beginTime);
095: }
096:
097: //
098: // ResultSet interface (leftover from NoPutResultSet)
099: //
100:
101: /**
102: * Sets state to 'open'.
103: *
104: * @exception StandardException thrown if activation closed.
105: */
106: public void openCore() throws StandardException {
107: next = false;
108: beginTime = getCurrentTimeMillis();
109: isOpen = true;
110: numOpens++;
111:
112: openTime += getElapsedMillis(beginTime);
113: }
114:
115: /**
116: * If open and not returned yet, returns the row
117: * after plugging the parameters into the expressions.
118: *
119: * @exception StandardException thrown on failure.
120: */
121: public ExecRow getNextRowCore() throws StandardException {
122:
123: currentRow = null;
124: beginTime = getCurrentTimeMillis();
125: if (isOpen) {
126: if (!next) {
127: next = true;
128: if (currentRow == null) {
129: if (cachedRow != null) {
130: currentRow = cachedRow;
131: } else if (row != null) {
132: currentRow = (ExecRow) row.invoke(activation);
133: if (canCacheRow) {
134: cachedRow = currentRow;
135: }
136: }
137: }
138: rowsReturned++;
139: }
140: setCurrentRow(currentRow);
141:
142: nextTime += getElapsedMillis(beginTime);
143: }
144: return currentRow;
145: }
146:
147: /**
148: * @see org.apache.derby.iapi.sql.ResultSet#close
149: *
150: * @exception StandardException thrown on error
151: */
152: public void close() throws StandardException {
153: beginTime = getCurrentTimeMillis();
154: if (isOpen) {
155:
156: // we don't want to keep around a pointer to the
157: // row ... so it can be thrown away.
158: // REVISIT: does this need to be in a finally
159: // block, to ensure that it is executed?
160: clearCurrentRow();
161: next = false;
162:
163: super .close();
164: } else if (SanityManager.DEBUG)
165: SanityManager.DEBUG("CloseRepeatInfo",
166: "Close of RowResultSet repeated");
167:
168: closeTime += getElapsedMillis(beginTime);
169: }
170:
171: /**
172: * Return the total amount of time spent in this ResultSet
173: *
174: * @param type CURRENT_RESULTSET_ONLY - time spent only in this ResultSet
175: * ENTIRE_RESULTSET_TREE - time spent in this ResultSet and below.
176: *
177: * @return long The total amount of time spent (in milliseconds).
178: */
179: public long getTimeSpent(int type) {
180: long totTime = constructorTime + openTime + nextTime
181: + closeTime;
182: return totTime;
183: }
184:
185: //
186: // CursorResultSet interface
187: //
188:
189: /**
190: * This is not operating against a stored table,
191: * so it has no row location to report.
192: *
193: * @see CursorResultSet
194: *
195: * @return a null.
196: */
197: public RowLocation getRowLocation() {
198: if (SanityManager.DEBUG)
199: SanityManager
200: .THROWASSERT("RowResultSet used in positioned update/delete");
201: return null;
202: }
203:
204: /**
205: * This is not used in positioned update and delete,
206: * so just return a null.
207: *
208: * @see CursorResultSet
209: *
210: * @return a null.
211: */
212: public ExecRow getCurrentRow() {
213: if (SanityManager.DEBUG)
214: SanityManager
215: .THROWASSERT("RowResultSet used in positioned update/delete");
216: return null;
217: }
218: }
|