0001: /*
0002:
0003: Derby - Class org.apache.derby.impl.sql.execute.TemporaryRowHolderResultSet
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.impl.sql.execute;
0023:
0024: import org.apache.derby.iapi.services.sanity.SanityManager;
0025: import org.apache.derby.iapi.error.StandardException;
0026:
0027: import org.apache.derby.iapi.store.access.ConglomerateController;
0028: import org.apache.derby.iapi.store.access.ScanController;
0029: import org.apache.derby.iapi.store.access.TransactionController;
0030:
0031: import org.apache.derby.iapi.reference.SQLState;
0032:
0033: import org.apache.derby.iapi.sql.execute.CursorResultSet;
0034: import org.apache.derby.iapi.sql.execute.ExecRow;
0035: import org.apache.derby.iapi.sql.execute.ExecutionContext;
0036: import org.apache.derby.iapi.sql.execute.NoPutResultSet;
0037: import org.apache.derby.iapi.sql.execute.ExecutionFactory;
0038: import org.apache.derby.iapi.sql.execute.TargetResultSet;
0039:
0040: import org.apache.derby.iapi.sql.Activation;
0041: import org.apache.derby.iapi.sql.ResultDescription;
0042: import org.apache.derby.iapi.sql.ResultSet;
0043: import org.apache.derby.iapi.sql.Row;
0044:
0045: import org.apache.derby.iapi.types.DataValueDescriptor;
0046: import org.apache.derby.iapi.types.RowLocation;
0047: import org.apache.derby.iapi.sql.execute.ExecIndexRow;
0048: import org.apache.derby.iapi.types.SQLLongint;
0049:
0050: import org.apache.derby.iapi.services.io.FormatableBitSet;
0051: import java.sql.Timestamp;
0052:
0053: /**
0054: * A result set to scan temporary row holders. Ultimately, this
0055: * may be returned to users, hence the extra junk from the ResultSet
0056: * interface.
0057: *
0058: * @author jamie
0059: */
0060: class TemporaryRowHolderResultSet implements CursorResultSet,
0061: NoPutResultSet, Cloneable {
0062: private ExecRow[] rowArray;
0063: private int numRowsOut;
0064: private ScanController scan;
0065: private TransactionController tc;
0066: private boolean isOpen;
0067: private boolean finished;
0068: private ExecRow currentRow;
0069: private ResultDescription resultDescription;
0070: private ExecutionFactory ef;
0071: private boolean isAppendable = false;
0072: private long positionIndexConglomId;
0073: private boolean isVirtualMemHeap;
0074: private boolean currRowFromMem;
0075: private TemporaryRowHolderImpl holder;
0076:
0077: // the following is used by position based scan, as well as virtual memory style heap
0078: ConglomerateController heapCC;
0079: private RowLocation baseRowLocation;
0080:
0081: /**
0082: * Constructor
0083: *
0084: * @param tc the xact controller
0085: * @param rowArray the row array
0086: * @param resultDescription value returned by getResultDescription()
0087: */
0088: public TemporaryRowHolderResultSet(TransactionController tc,
0089: ExecRow[] rowArray, ResultDescription resultDescription,
0090: boolean isVirtualMemHeap, TemporaryRowHolderImpl holder) {
0091:
0092: this (tc, rowArray, resultDescription, isVirtualMemHeap, false,
0093: 0, holder);
0094:
0095: }
0096:
0097: /**
0098: * Constructor
0099: *
0100: * @param tc the xact controller
0101: * @param rowArray the row array
0102: * @param resultDescription value returned by getResultDescription()
0103: * @param isAppendable true,if we can insert rows after this result is created
0104: * @param positionIndexConglomId conglomId of the index which has order rows
0105: * are inserted and their row location
0106: */
0107: public TemporaryRowHolderResultSet(TransactionController tc,
0108: ExecRow[] rowArray, ResultDescription resultDescription,
0109: boolean isVirtualMemHeap, boolean isAppendable,
0110: long positionIndexConglomId, TemporaryRowHolderImpl holder) {
0111: this .tc = tc;
0112: this .rowArray = rowArray;
0113: this .resultDescription = resultDescription;
0114: this .numRowsOut = 0;
0115: isOpen = false;
0116: finished = false;
0117: this .isVirtualMemHeap = isVirtualMemHeap;
0118: this .isAppendable = isAppendable;
0119: this .positionIndexConglomId = positionIndexConglomId;
0120:
0121: if (SanityManager.DEBUG) {
0122: SanityManager.ASSERT(rowArray != null, "rowArray is null");
0123: SanityManager.ASSERT(rowArray.length > 0,
0124: "rowArray has no elements, need at least one");
0125: }
0126:
0127: this .holder = holder;
0128: }
0129:
0130: /**
0131: * Reset the exec row array and reinitialize
0132: *
0133: * @param rowArray the row array
0134: */
0135: public void reset(ExecRow[] rowArray) {
0136: this .rowArray = rowArray;
0137: this .numRowsOut = 0;
0138: isOpen = false;
0139: finished = false;
0140:
0141: if (SanityManager.DEBUG) {
0142: SanityManager.ASSERT(rowArray != null, "rowArray is null");
0143: SanityManager.ASSERT(rowArray.length > 0,
0144: "rowArray has no elements, need at least one");
0145: }
0146: }
0147:
0148: /**
0149: * postion scan to start from after where we stopped earlier
0150: */
0151: public void reStartScan(long currentConglomId, long pconglomId)
0152: throws StandardException {
0153: if (isAppendable) {
0154: holder.CID = currentConglomId;
0155: positionIndexConglomId = pconglomId;
0156: setupPositionBasedScan(numRowsOut);
0157: } else {
0158: numRowsOut--;
0159: }
0160: }
0161:
0162: /**
0163: * Whip up a new Temp ResultSet that has a single
0164: * row, the current row of this result set.
0165: *
0166: * @param activation the activation
0167: * @param rs the result set
0168: *
0169: * @return a single row result set
0170: *
0171: * @exception StandardException on error
0172: */
0173: public static TemporaryRowHolderResultSet getNewRSOnCurrentRow(
0174: Activation activation, CursorResultSet rs)
0175: throws StandardException {
0176: TemporaryRowHolderImpl singleRow = new TemporaryRowHolderImpl(
0177: activation, null, rs.getResultDescription());
0178: singleRow.insert(rs.getCurrentRow());
0179: return (TemporaryRowHolderResultSet) singleRow.getResultSet();
0180: }
0181:
0182: /////////////////////////////////////////////////////////
0183: //
0184: // NoPutResultSet
0185: //
0186: /////////////////////////////////////////////////////////
0187: /**
0188: * Mark the ResultSet as the topmost one in the ResultSet tree.
0189: * Useful for closing down the ResultSet on an error.
0190: */
0191: public void markAsTopResultSet() {
0192: }
0193:
0194: /**
0195: * Open the scan and evaluate qualifiers and the like.
0196: * For us, there are no qualifiers, this is really a
0197: * noop.
0198: */
0199: public void openCore() throws StandardException {
0200: this .numRowsOut = 0;
0201: isOpen = true;
0202: currentRow = null;
0203:
0204: if (isAppendable)
0205: setupPositionBasedScan(numRowsOut);
0206: }
0207:
0208: /**
0209: * Reopen the scan. Typically faster than open()/close()
0210: *
0211: * @exception StandardException on error
0212: */
0213: public void reopenCore() throws StandardException {
0214: numRowsOut = 0;
0215: isOpen = true;
0216: currentRow = null;
0217:
0218: if (isAppendable) {
0219: setupPositionBasedScan(numRowsOut);
0220: return;
0221: }
0222:
0223: if (scan != null) {
0224: scan.reopenScan((DataValueDescriptor[]) null, // start key value
0225: 0, // start operator
0226: null, // qualifier
0227: (DataValueDescriptor[]) null, // stop key value
0228: 0); // stop operator
0229: }
0230: }
0231:
0232: /**
0233: * Get the next row.
0234: *
0235: * @return the next row, or null if none
0236: *
0237: * @exception StandardException on error
0238: */
0239: public ExecRow getNextRowCore() throws StandardException {
0240:
0241: if (!isOpen) {
0242: return (ExecRow) null;
0243: }
0244:
0245: if (isAppendable) {
0246: return getNextAppendedRow();
0247: }
0248:
0249: if (isVirtualMemHeap && holder.lastArraySlot >= 0) {
0250: numRowsOut++;
0251: currentRow = rowArray[holder.lastArraySlot];
0252: currRowFromMem = true;
0253: return currentRow;
0254: } else if (numRowsOut++ <= holder.lastArraySlot) {
0255: currentRow = rowArray[numRowsOut - 1];
0256: return currentRow;
0257: }
0258:
0259: if (holder.CID == 0) {
0260: return (ExecRow) null;
0261: }
0262:
0263: /*
0264: ** Advance in the temporary conglomerate
0265: */
0266: if (scan == null) {
0267: scan = tc.openScan(
0268: holder.CID,
0269: false, // hold
0270: 0, // open read only
0271: TransactionController.MODE_TABLE,
0272: TransactionController.ISOLATION_SERIALIZABLE,
0273: (FormatableBitSet) null,
0274: (DataValueDescriptor[]) null, // start key value
0275: 0, // start operator
0276: null, // qualifier
0277: (DataValueDescriptor[]) null, // stop key value
0278: 0); // stop operator
0279: } else if (isVirtualMemHeap
0280: && holder.state == TemporaryRowHolderImpl.STATE_INSERT) {
0281: holder.state = TemporaryRowHolderImpl.STATE_DRAIN;
0282: scan.reopenScan((DataValueDescriptor[]) null, // start key value
0283: 0, // start operator
0284: null, // qualifier
0285: (DataValueDescriptor[]) null, // stop key value
0286: 0); // stop operator
0287: }
0288:
0289: if (scan.next()) {
0290: currentRow = rowArray[0].getNewNullRow();
0291: scan.fetch(currentRow.getRowArray());
0292: currRowFromMem = false;
0293: return currentRow;
0294: }
0295: return (ExecRow) null;
0296: }
0297:
0298: public void deleteCurrentRow() throws StandardException {
0299: if (SanityManager.DEBUG) {
0300: SanityManager.ASSERT(isVirtualMemHeap,
0301: "deleteCurrentRow is not implemented");
0302: }
0303: if (currRowFromMem) {
0304: if (holder.lastArraySlot > 0) // 0 is kept for template
0305: rowArray[holder.lastArraySlot] = null; // erase reference
0306: holder.lastArraySlot--;
0307: } else {
0308: if (baseRowLocation == null)
0309: baseRowLocation = scan.newRowLocationTemplate();
0310: scan.fetchLocation(baseRowLocation);
0311: if (heapCC == null) {
0312: heapCC = tc.openConglomerate(holder.CID, false,
0313: TransactionController.OPENMODE_FORUPDATE,
0314: TransactionController.MODE_TABLE,
0315: TransactionController.ISOLATION_SERIALIZABLE);
0316: }
0317: heapCC.delete(baseRowLocation);
0318: }
0319: }
0320:
0321: //following variables are specific to the position based scans.
0322: DataValueDescriptor[] indexRow;
0323: ScanController indexsc;
0324:
0325: //open the scan of the temporary heap and the position index
0326: private void setupPositionBasedScan(long position)
0327: throws StandardException {
0328:
0329: //incase nothing is inserted yet into the temporary row holder
0330: if (holder.CID == 0)
0331: return;
0332: if (heapCC == null) {
0333: heapCC = tc.openConglomerate(holder.CID, false, 0,
0334: TransactionController.MODE_TABLE,
0335: TransactionController.ISOLATION_SERIALIZABLE);
0336:
0337: }
0338:
0339: currentRow = rowArray[0].getNewNullRow();
0340: indexRow = new DataValueDescriptor[2];
0341: indexRow[0] = new SQLLongint(position);
0342: indexRow[1] = heapCC.newRowLocationTemplate();
0343:
0344: DataValueDescriptor[] searchRow = new DataValueDescriptor[1];
0345: searchRow[0] = new SQLLongint(position);
0346:
0347: if (indexsc == null) {
0348: indexsc = tc.openScan(
0349: positionIndexConglomId,
0350: false, // don't hold open across commit
0351: 0, // for read
0352: TransactionController.MODE_TABLE,
0353: TransactionController.ISOLATION_SERIALIZABLE,
0354: (FormatableBitSet) null, // all fields as objects
0355: searchRow, // start position - first row
0356: ScanController.GE, // startSearchOperation
0357: null, //scanQualifier,
0358: null, // stop position - through last row
0359: ScanController.GT); // stopSearchOperation
0360: } else {
0361:
0362: indexsc.reopenScan(searchRow, // startKeyValue
0363: ScanController.GE, // startSearchOp
0364: null, // qualifier
0365: null, // stopKeyValue
0366: ScanController.GT // stopSearchOp
0367: );
0368: }
0369:
0370: }
0371:
0372: //get the next row inserted into the temporary holder
0373: private ExecRow getNextAppendedRow() throws StandardException {
0374: if (indexsc == null)
0375: return null;
0376: if (!indexsc.fetchNext(indexRow)) {
0377: return null;
0378: }
0379:
0380: RowLocation baseRowLocation = (RowLocation) indexRow[1];
0381: boolean base_row_exists = heapCC.fetch(baseRowLocation,
0382: currentRow.getRowArray(), (FormatableBitSet) null);
0383:
0384: if (SanityManager.DEBUG) {
0385: SanityManager.ASSERT(base_row_exists,
0386: "base row disappeared.");
0387: }
0388: numRowsOut++;
0389: return currentRow;
0390: }
0391:
0392: /**
0393: * Return the point of attachment for this subquery.
0394: * (Only meaningful for Any and Once ResultSets, which can and will only
0395: * be at the top of a ResultSet for a subquery.)
0396: *
0397: * @return int Point of attachment (result set number) for this
0398: * subquery. (-1 if not a subquery - also Sanity violation)
0399: */
0400: public int getPointOfAttachment() {
0401: return -1;
0402: }
0403:
0404: /**
0405: * Return the isolation level of the scan in the result set.
0406: * Only expected to be called for those ResultSets that
0407: * contain a scan.
0408: *
0409: * @return The isolation level of the scan (in TransactionController constants).
0410: */
0411: public int getScanIsolationLevel() {
0412: return TransactionController.ISOLATION_SERIALIZABLE;
0413: }
0414:
0415: /**
0416: * Notify a NPRS that it is the source for the specified
0417: * TargetResultSet. This is useful when doing bulk insert.
0418: *
0419: * @param trs The TargetResultSet.
0420: */
0421: public void setTargetResultSet(TargetResultSet trs) {
0422: }
0423:
0424: /**
0425: * Set whether or not the NPRS need the row location when acting
0426: * as a row source. (The target result set determines this.)
0427: *
0428: */
0429: public void setNeedsRowLocation(boolean needsRowLocation) {
0430: }
0431:
0432: /**
0433: * Get the estimated row count from this result set.
0434: *
0435: * @return The estimated row count (as a double) from this result set.
0436: */
0437: public double getEstimatedRowCount() {
0438: return 0d;
0439: }
0440:
0441: /**
0442: * Get the number of this ResultSet, which is guaranteed to be unique
0443: * within a statement.
0444: */
0445: public int resultSetNumber() {
0446: return 0;
0447: }
0448:
0449: /**
0450: * Set the current row to the row passed in.
0451: *
0452: * @param row the new current row
0453: *
0454: */
0455: public void setCurrentRow(ExecRow row) {
0456: currentRow = row;
0457: }
0458:
0459: /**
0460: * Clear the current row
0461: *
0462: */
0463: public void clearCurrentRow() {
0464: currentRow = null;
0465: }
0466:
0467: /**
0468: * This result set has its row from the last fetch done.
0469: * If the cursor is closed, a null is returned.
0470: *
0471: * @see CursorResultSet
0472: *
0473: * @return the last row returned;
0474: * @exception StandardException thrown on failure.
0475: */
0476: public ExecRow getCurrentRow() throws StandardException {
0477: if (SanityManager.DEBUG) {
0478: SanityManager.ASSERT(isOpen,
0479: "resultSet expected to be open");
0480: }
0481:
0482: return currentRow;
0483: }
0484:
0485: /**
0486: * Returns the row location of the current base table row of the cursor.
0487: * If this cursor's row is composed of multiple base tables' rows,
0488: * i.e. due to a join, then a null is returned. For
0489: * a temporary row holder, we always return null.
0490: *
0491: * @return the row location of the current cursor row.
0492: */
0493: public RowLocation getRowLocation() {
0494: if (SanityManager.DEBUG) {
0495: SanityManager.ASSERT(isOpen,
0496: "resultSet expected to be open");
0497: }
0498: return (RowLocation) null;
0499: }
0500:
0501: /**
0502: * Clean up
0503: *
0504: * @exception StandardException thrown on error
0505: */
0506: public void close() throws StandardException {
0507: isOpen = false;
0508: numRowsOut = 0;
0509: currentRow = null;
0510: if (scan != null) {
0511: scan.close();
0512: scan = null;
0513: }
0514: }
0515:
0516: //////////////////////////////////////////////////////////////////////////
0517: //
0518: // MISC FROM RESULT SET
0519: //
0520: /////////////////////////////////////////////////////////////////////////
0521:
0522: /**
0523: * Returns TRUE if the statement returns rows (i.e. is a SELECT
0524: * or FETCH statement), FALSE if it returns no rows.
0525: *
0526: * @return TRUE if the statement returns rows, FALSE if not.
0527: */
0528: public boolean returnsRows() {
0529: return true;
0530: }
0531:
0532: public int modifiedRowCount() {
0533: return 0;
0534: };
0535:
0536: /**
0537: * Returns a ResultDescription object, which describes the results
0538: * of the statement this ResultSet is in. This will *not* be a
0539: * description of this particular ResultSet, if this is not the
0540: * outermost ResultSet.
0541: *
0542: * @return A ResultDescription describing the results of the
0543: * statement.
0544: */
0545: public ResultDescription getResultDescription() {
0546: return resultDescription;
0547: }
0548:
0549: /**
0550: * Tells the system that there will be calls to getNextRow().
0551: *
0552: * @exception StandardException Thrown on failure
0553: */
0554: public void open() throws StandardException {
0555: openCore();
0556: }
0557:
0558: /**
0559: * Returns the row at the absolute position from the query,
0560: * and returns NULL when there is no such position.
0561: * (Negative position means from the end of the result set.)
0562: * Moving the cursor to an invalid position leaves the cursor
0563: * positioned either before the first row (negative position)
0564: * or after the last row (positive position).
0565: * NOTE: An exception will be thrown on 0.
0566: *
0567: * @param row The position.
0568: * @return The row at the absolute position, or NULL if no such position.
0569: *
0570: * @exception StandardException Thrown on failure
0571: * @see Row
0572: */
0573: public ExecRow getAbsoluteRow(int row) throws StandardException {
0574: if (SanityManager.DEBUG) {
0575: SanityManager
0576: .THROWASSERT("getAbsoluteRow() not expected to be called yet.");
0577: }
0578:
0579: return null;
0580: }
0581:
0582: /**
0583: * Returns the row at the relative position from the current
0584: * cursor position, and returns NULL when there is no such position.
0585: * (Negative position means toward the beginning of the result set.)
0586: * Moving the cursor to an invalid position leaves the cursor
0587: * positioned either before the first row (negative position)
0588: * or after the last row (positive position).
0589: * NOTE: 0 is valid.
0590: * NOTE: An exception is thrown if the cursor is not currently
0591: * positioned on a row.
0592: *
0593: * @param row The position.
0594: * @return The row at the relative position, or NULL if no such position.
0595: *
0596: * @exception StandardException Thrown on failure
0597: * @see Row
0598: */
0599: public ExecRow getRelativeRow(int row) throws StandardException {
0600: if (SanityManager.DEBUG) {
0601: SanityManager
0602: .THROWASSERT("getRelativeRow() not expected to be called yet.");
0603: }
0604:
0605: return null;
0606: }
0607:
0608: /**
0609: * Sets the current position to before the first row and returns NULL
0610: * because there is no current row.
0611: *
0612: * @return NULL.
0613: *
0614: * @exception StandardException Thrown on failure
0615: * @see Row
0616: */
0617: public ExecRow setBeforeFirstRow() throws StandardException {
0618: if (SanityManager.DEBUG) {
0619: SanityManager
0620: .THROWASSERT("setBeforeFirstRow() not expected to be called yet.");
0621: }
0622:
0623: return null;
0624: }
0625:
0626: /**
0627: * Returns the first row from the query, and returns NULL when there
0628: * are no rows.
0629: *
0630: * @return The first row, or NULL if no rows.
0631: *
0632: * @exception StandardException Thrown on failure
0633: * @see Row
0634: */
0635: public ExecRow getFirstRow() throws StandardException {
0636: if (SanityManager.DEBUG) {
0637: SanityManager
0638: .THROWASSERT("getFirstRow() not expected to be called yet.");
0639: }
0640:
0641: return null;
0642: }
0643:
0644: /**
0645: * Returns the next row from the query, and returns NULL when there
0646: * are no more rows.
0647: *
0648: * @return The next row, or NULL if no more rows.
0649: *
0650: * @exception StandardException Thrown on failure
0651: * @see Row
0652: */
0653: public ExecRow getNextRow() throws StandardException {
0654: return getNextRowCore();
0655: }
0656:
0657: /**
0658: * Returns the previous row from the query, and returns NULL when there
0659: * are no more previous rows.
0660: *
0661: * @return The previous row, or NULL if no more previous rows.
0662: *
0663: * @exception StandardException Thrown on failure
0664: * @see Row
0665: */
0666: public ExecRow getPreviousRow() throws StandardException {
0667: if (SanityManager.DEBUG) {
0668: SanityManager
0669: .THROWASSERT("getPreviousRow() not expected to be called yet.");
0670: }
0671:
0672: return null;
0673: }
0674:
0675: /**
0676: * Returns the last row from the query, and returns NULL when there
0677: * are no rows.
0678: *
0679: * @return The last row, or NULL if no rows.
0680: *
0681: * @exception StandardException Thrown on failure
0682: * @see Row
0683: */
0684: public ExecRow getLastRow() throws StandardException {
0685: if (SanityManager.DEBUG) {
0686: SanityManager
0687: .THROWASSERT("getLastRow() not expected to be called yet.");
0688: }
0689:
0690: return null;
0691: }
0692:
0693: /**
0694: * Sets the current position to after the last row and returns NULL
0695: * because there is no current row.
0696: *
0697: * @return NULL.
0698: *
0699: * @exception StandardException Thrown on failure
0700: * @see Row
0701: */
0702: public ExecRow setAfterLastRow() throws StandardException {
0703: if (SanityManager.DEBUG) {
0704: SanityManager
0705: .THROWASSERT("getLastRow() not expected to be called yet.");
0706: }
0707:
0708: return null;
0709: }
0710:
0711: /**
0712: * Determine if the cursor is before the first row in the result
0713: * set.
0714: *
0715: * @return true if before the first row, false otherwise. Returns
0716: * false when the result set contains no rows.
0717: */
0718: public boolean checkRowPosition(int isType) {
0719: return false;
0720: }
0721:
0722: /**
0723: * Returns the row number of the current row. Row
0724: * numbers start from 1 and go to 'n'. Corresponds
0725: * to row numbering used to position current row
0726: * in the result set (as per JDBC).
0727: *
0728: * @return the row number, or 0 if not on a row
0729: *
0730: */
0731: public int getRowNumber() {
0732: return 0;
0733: }
0734:
0735: /**
0736: * Tells the system to clean up on an error.
0737: *
0738: * @exception StandardException Thrown on error.
0739: */
0740: public void cleanUp() throws StandardException {
0741: close();
0742: }
0743:
0744: /**
0745: Find out if the ResultSet is closed or not.
0746: Will report true for result sets that do not return rows.
0747:
0748: @return true if the ResultSet has been closed.
0749: */
0750: public boolean isClosed() {
0751: return !isOpen;
0752: }
0753:
0754: /**
0755: * Tells the system that there will be no more access
0756: * to any database information via this result set;
0757: * in particular, no more calls to open().
0758: * Will close the result set if it is not already closed.
0759: *
0760: * @exception StandardException on error
0761: */
0762: public void finish() throws StandardException {
0763: finished = true;
0764: close();
0765: }
0766:
0767: /**
0768: * Get the execution time in milliseconds.
0769: *
0770: * @return long The execution time in milliseconds.
0771: */
0772: public long getExecuteTime() {
0773: return 0L;
0774: }
0775:
0776: /**
0777: * @see ResultSet#getAutoGeneratedKeysResultset
0778: */
0779: public ResultSet getAutoGeneratedKeysResultset() {
0780: //A non-null resultset would be returned only for an insert statement
0781: return (ResultSet) null;
0782: }
0783:
0784: /**
0785: * Get the Timestamp for the beginning of execution.
0786: *
0787: * @return Timestamp The Timestamp for the beginning of execution.
0788: */
0789: public Timestamp getBeginExecutionTimestamp() {
0790: return (Timestamp) null;
0791: }
0792:
0793: /**
0794: * Get the Timestamp for the end of execution.
0795: *
0796: * @return Timestamp The Timestamp for the end of execution.
0797: */
0798: public Timestamp getEndExecutionTimestamp() {
0799: return (Timestamp) null;
0800: }
0801:
0802: /**
0803: * Return the total amount of time spent in this ResultSet
0804: *
0805: * @param type CURRENT_RESULTSET_ONLY - time spent only in this ResultSet
0806: * ENTIRE_RESULTSET_TREE - time spent in this ResultSet and below.
0807: *
0808: * @return long The total amount of time spent (in milliseconds).
0809: */
0810: public long getTimeSpent(int type) {
0811: return 0L;
0812: }
0813:
0814: /**
0815: * Get the subquery ResultSet tracking array from the top ResultSet.
0816: * (Used for tracking open subqueries when closing down on an error.)
0817: *
0818: * @param numSubqueries The size of the array (For allocation on demand.)
0819: *
0820: * @return NoPutResultSet[] Array of NoPutResultSets for subqueries.
0821: */
0822: public NoPutResultSet[] getSubqueryTrackingArray(int numSubqueries) {
0823: return (NoPutResultSet[]) null;
0824: }
0825:
0826: /**
0827: * Returns the name of the cursor, if this is cursor statement of some
0828: * type (declare, open, fetch, positioned update, positioned delete,
0829: * close).
0830: *
0831: * @return A String with the name of the cursor, if any. Returns
0832: * NULL if this is not a cursor statement.
0833: */
0834: public String getCursorName() {
0835: return (String) null;
0836: }
0837:
0838: /**
0839: * @see NoPutResultSet#requiresRelocking
0840: */
0841: public boolean requiresRelocking() {
0842: if (SanityManager.DEBUG) {
0843: SanityManager
0844: .THROWASSERT("requiresRelocking() not expected to be called for "
0845: + getClass().getName());
0846: }
0847: return false;
0848: }
0849:
0850: /////////////////////////////////////////////////////////
0851: //
0852: // Access/RowSource -- not implemented
0853: //
0854: /////////////////////////////////////////////////////////
0855: /**
0856: Get the next row as an array of column objects. The column objects can
0857: be a JBMS Storable or any
0858: Serializable/Externalizable/Formattable/Streaming type.
0859: <BR>
0860: A return of null indicates that the complete set of rows has been read.
0861:
0862: <p>
0863: A null column can be specified by leaving the object null, or indicated
0864: by returning a non-null getValidColumns. On streaming columns, it can
0865: be indicated by returning a non-null get FieldStates.
0866:
0867: <p>
0868: If RowSource.needToClone() is true then the returned row (the
0869: DataValueDescriptor[]) is guaranteed not to be modified by drainer of
0870: the RowSource (except that the input stream will be read, of course)
0871: and drainer will keep no reference to it before making the subsequent
0872: nextRow call. So it is safe to return the same DataValueDescriptor[]
0873: in subsequent nextRow calls if that is desirable for performance
0874: reasons.
0875: <p>
0876: If RowSource.needToClone() is false then the returned row (the
0877: DataValueDescriptor[]) may be be modified by drainer of the RowSource,
0878: and the drainer may keep a reference to it after making the subsequent
0879: nextRow call. In this case the client should severe all references to
0880: the row after returning it from getNextRowFromRowSource().
0881:
0882: @exception StandardException Cloudscape Standard Error Policy
0883: */
0884: public DataValueDescriptor[] getNextRowFromRowSource()
0885: throws StandardException {
0886: return null;
0887: }
0888:
0889: /**
0890: Does the caller of getNextRowFromRowSource() need to clone the row
0891: in order to keep a reference to the row past the
0892: getNextRowFromRowSource() call which returned the row. This call
0893: must always return the same for all rows in a RowSource (ie. the
0894: caller will call this once per scan from a RowSource and assume the
0895: behavior is true for all rows in the RowSource).
0896:
0897: */
0898: public boolean needsToClone() {
0899: return false;
0900: }
0901:
0902: /**
0903: getValidColumns describes the DataValueDescriptor[] returned by all
0904: calls to the getNextRowFromRowSource() call.
0905:
0906: If getValidColumns returns null, the number of columns is given by the
0907: DataValueDescriptor.length where DataValueDescriptor[] is returned by the
0908: preceeding getNextRowFromRowSource() call. Column N maps to
0909: DataValueDescriptor[N], where column numbers start at zero.
0910:
0911: If getValidColumns return a non null validColumns FormatableBitSet the number of
0912: columns is given by the number of bits set in validColumns. Column N is
0913: not in the partial row if validColumns.get(N) returns false. Column N is
0914: in the partial row if validColumns.get(N) returns true. If column N is
0915: in the partial row then it maps to DataValueDescriptor[M] where M is the
0916: count of calls to validColumns.get(i) that return true where i < N. If
0917: DataValueDescriptor.length is greater than the number of columns
0918: indicated by validColumns the extra entries are ignored.
0919: */
0920: public FormatableBitSet getValidColumns() {
0921: return null;
0922: }
0923:
0924: /**
0925: closeRowSource tells the RowSource that it will no longer need to
0926: return any rows and it can release any resource it may have.
0927: Subsequent call to any method on the RowSource will result in undefined
0928: behavior. A closed rowSource can be closed again.
0929: */
0930: public void closeRowSource() {
0931: }
0932:
0933: /////////////////////////////////////////////////////////
0934: //
0935: // Access/RowLocationRetRowSource -- not implemented
0936: //
0937: /////////////////////////////////////////////////////////
0938: /**
0939: needsRowLocation returns true iff this the row source expects the
0940: drainer of the row source to call rowLocation after getting a row from
0941: getNextRowFromRowSource.
0942:
0943: @return true iff this row source expects some row location to be
0944: returned
0945: @see #rowLocation
0946: */
0947: public boolean needsRowLocation() {
0948: return false;
0949: }
0950:
0951: /**
0952: rowLocation is a callback for the drainer of the row source to return
0953: the rowLocation of the current row, i.e, the row that is being returned
0954: by getNextRowFromRowSource. This interface is for the purpose of
0955: loading a base table with index. In that case, the indices can be
0956: built at the same time the base table is laid down once the row
0957: location of the base row is known. This is an example pseudo code on
0958: how this call is expected to be used:
0959:
0960: <BR><pre>
0961: boolean needsRL = rowSource.needsRowLocation();
0962: DataValueDescriptor[] row;
0963: while((row = rowSource.getNextRowFromRowSource()) != null)
0964: {
0965: RowLocation rl = heapConglomerate.insertRow(row);
0966: if (needsRL)
0967: rowSource.rowLocation(rl);
0968: }
0969: </pre><BR>
0970:
0971: NeedsRowLocation and rowLocation will ONLY be called by a drainer of
0972: the row source which CAN return a row location. Drainer of row source
0973: which cannot return rowLocation will guarentee to not call either
0974: callbacks. Conversely, if NeedsRowLocation is called and it returns
0975: true, then for every row return by getNextRowFromRowSource, a
0976: rowLocation callback must also be issued with the row location of the
0977: row. Implementor of both the source and the drain of the row source
0978: must be aware of this protocol.
0979:
0980: <BR>
0981: The RowLocation object is own by the caller of rowLocation, in other
0982: words, the drainer of the RowSource. This is so that we don't need to
0983: new a row location for every row. If the Row Source wants to keep the
0984: row location, it needs to clone it (RowLocation is a ClonableObject).
0985: @exception StandardException on error
0986: */
0987: public void rowLocation(RowLocation rl) throws StandardException {
0988: }
0989:
0990: /**
0991: * @see NoPutResultSet#positionScanAtRowLocation
0992: *
0993: * This method is result sets used for scroll insensitive updatable
0994: * result sets for other result set it is a no-op.
0995: */
0996: public void positionScanAtRowLocation(RowLocation rl)
0997: throws StandardException {
0998: // Only used for Scrollable insensitive result sets otherwise no-op
0999: }
1000:
1001: // Class implementation
1002:
1003: /**
1004: * Is this ResultSet or it's source result set for update
1005: * This method will be overriden in the inherited Classes
1006: * if it is true
1007: * @return Whether or not the result set is for update.
1008: */
1009: public boolean isForUpdate() {
1010: return false;
1011: }
1012:
1013: /**
1014: * Shallow clone this result set. Used in trigger reference.
1015: * beetle 4373.
1016: */
1017: public Object clone() {
1018: Object clo = null;
1019: try {
1020: clo = super .clone();
1021: } catch (CloneNotSupportedException e) {
1022: }
1023: return clo;
1024: }
1025:
1026: public java.sql.SQLWarning getWarnings() {
1027: return null;
1028: }
1029:
1030: /**
1031: * @see NoPutResultSet#updateRow
1032: *
1033: * This method is result sets used for scroll insensitive updatable
1034: * result sets for other result set it is a no-op.
1035: */
1036: public void updateRow(ExecRow row) throws StandardException {
1037: // Only ResultSets of type Scroll Insensitive implement
1038: // detectability, so for other result sets this method
1039: // is a no-op
1040: }
1041:
1042: /**
1043: * @see NoPutResultSet#markRowAsDeleted
1044: *
1045: * This method is result sets used for scroll insensitive updatable
1046: * result sets for other result set it is a no-op.
1047: */
1048: public void markRowAsDeleted() throws StandardException {
1049: // Only ResultSets of type Scroll Insensitive implement
1050: // detectability, so for other result sets this method
1051: // is a no-op
1052: }
1053:
1054: /**
1055: * Return the <code>Activation</code> for this result set.
1056: *
1057: * @return activation
1058: */
1059: public final Activation getActivation() {
1060: return holder.activation;
1061: }
1062: }
|