001: /*
002:
003: Derby - Class org.apache.derby.impl.sql.execute.rts.RealTableScanStatistics
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.rts;
023:
024: import org.apache.derby.iapi.services.io.StoredFormatIds;
025: import org.apache.derby.iapi.util.PropertyUtil;
026:
027: import org.apache.derby.iapi.services.i18n.MessageService;
028: import org.apache.derby.iapi.reference.SQLState;
029:
030: import org.apache.derby.iapi.services.io.FormatableHashtable;
031: import org.apache.derby.iapi.services.io.FormatableProperties;
032:
033: import java.io.ObjectOutput;
034: import java.io.ObjectInput;
035: import java.io.IOException;
036:
037: import java.util.Enumeration;
038: import java.util.Properties;
039:
040: /**
041: ResultSetStatistics implemenation for TableScanResultSet.
042:
043: @author jerry
044:
045: */
046: public class RealTableScanStatistics extends
047: RealNoPutResultSetStatistics {
048:
049: /* Leave these fields public for object inspectors */
050: public boolean isConstraint;
051: public boolean coarserLock;
052: public int fetchSize;
053: public String isolationLevel;
054: public String tableName;
055: public String userSuppliedOptimizerOverrides;
056: public String indexName;
057: public String lockString;
058: public String qualifiers;
059: public String startPosition;
060: public String stopPosition;
061: public FormatableProperties scanProperties;
062:
063: // CONSTRUCTORS
064:
065: /**
066: *
067: *
068: */
069: public RealTableScanStatistics(int numOpens, int rowsSeen,
070: int rowsFiltered, long constructorTime, long openTime,
071: long nextTime, long closeTime, int resultSetNumber,
072: String tableName, String userSuppliedOptimizerOverrides,
073: String indexName, boolean isConstraint, String qualifiers,
074: Properties scanProperties, String startPosition,
075: String stopPosition, String isolationLevel,
076: String lockString, int fetchSize, boolean coarserLock,
077: double optimizerEstimatedRowCount,
078: double optimizerEstimatedCost) {
079: super (numOpens, rowsSeen, rowsFiltered, constructorTime,
080: openTime, nextTime, closeTime, resultSetNumber,
081: optimizerEstimatedRowCount, optimizerEstimatedCost);
082: this .tableName = tableName;
083: this .userSuppliedOptimizerOverrides = userSuppliedOptimizerOverrides;
084: this .indexName = indexName;
085: this .isConstraint = isConstraint;
086: this .qualifiers = qualifiers;
087: this .scanProperties = new FormatableProperties();
088: for (Enumeration e = scanProperties.keys(); e.hasMoreElements();) {
089: String key = (String) e.nextElement();
090: this .scanProperties.put(key, scanProperties.get(key));
091: }
092: this .startPosition = startPosition;
093: this .stopPosition = stopPosition;
094: this .isolationLevel = isolationLevel;
095: this .lockString = lockString;
096: this .fetchSize = fetchSize;
097: this .coarserLock = coarserLock;
098: }
099:
100: // ResultSetStatistics methods
101:
102: /**
103: * Return the statement execution plan as a String.
104: *
105: * @param depth Indentation level
106: *
107: * @return String The statement executio plan as a String.
108: */
109: public String getStatementExecutionPlanText(int depth) {
110: String header = "";
111: String isolationString = null;
112:
113: initFormatInfo(depth);
114:
115: if (userSuppliedOptimizerOverrides != null) {
116: header = indent
117: + MessageService
118: .getTextMessage(
119: SQLState.RTS_USER_SUPPLIED_OPTIMIZER_OVERRIDES_FOR_TABLE,
120: tableName,
121: userSuppliedOptimizerOverrides);
122: header = header + "\n";
123: }
124: if (indexName != null) {
125: header = header
126: + indent
127: + MessageService
128: .getTextMessage(
129: SQLState.RTS_IS_RS_USING,
130: tableName,
131: MessageService
132: .getTextMessage((isConstraint) ? SQLState.RTS_CONSTRAINT
133: : SQLState.RTS_INDEX),
134: indexName);
135:
136: } else {
137: header = header
138: + indent
139: + MessageService.getTextMessage(
140: SQLState.RTS_TS_RS_FOR, tableName);
141: }
142:
143: header = header
144: + " "
145: + MessageService.getTextMessage(
146: SQLState.RTS_LOCKING_OPTIMIZER, isolationLevel,
147: lockString);
148:
149: /* Did we get (or already have) a coarser lock then requested
150: * due to a covering lock, lock escalation or configuration
151: * for table locking.
152: */
153: if (coarserLock) {
154: header = header
155: + " ("
156: + MessageService
157: .getTextMessage(SQLState.RTS_ACTUAL_TABLE)
158: + ")";
159: }
160:
161: header = header + "\n";
162:
163: String scanInfo = indent
164: + MessageService.getTextMessage(SQLState.RTS_SCAN_INFO)
165: + ": \n"
166: + PropertyUtil
167: .sortProperties(scanProperties, subIndent);
168:
169: return header
170: + indent
171: + MessageService.getTextMessage(SQLState.RTS_NUM_OPENS)
172: + " = "
173: + numOpens
174: + "\n"
175: + indent
176: + MessageService.getTextMessage(SQLState.RTS_ROWS_SEEN)
177: + " = "
178: + rowsSeen
179: + "\n"
180: + indent
181: + MessageService
182: .getTextMessage(SQLState.RTS_ROWS_FILTERED)
183: + " = "
184: + rowsFiltered
185: + "\n"
186: + indent
187: + MessageService
188: .getTextMessage(SQLState.RTS_FETCH_SIZE)
189: + " = "
190: + fetchSize
191: + "\n"
192: + dumpTimeStats(indent, subIndent)
193: + "\n"
194: + ((rowsSeen > 0) ? subIndent
195: + MessageService
196: .getTextMessage(SQLState.RTS_NEXT_TIME)
197: + " = " + (nextTime / rowsSeen) + "\n" : "")
198: + "\n"
199: + scanInfo
200: + subIndent
201: + MessageService
202: .getTextMessage(SQLState.RTS_START_POSITION)
203: + ": \n"
204: + startPosition
205: + subIndent
206: + MessageService
207: .getTextMessage(SQLState.RTS_STOP_POSITION)
208: + ": \n" + stopPosition + subIndent
209: + MessageService.getTextMessage(SQLState.RTS_QUALS)
210: + ":\n" + qualifiers + "\n" +
211: // RESOLVE - estimated row count and cost will eventually
212: // be displayed for all nodes
213: dumpEstimatedCosts(subIndent);
214: }
215:
216: /**
217: * Return information on the scan nodes from the statement execution
218: * plan as a String.
219: *
220: * @param depth Indentation level.
221: * @param tableName if not NULL then print information for this table only
222: *
223: * @return String The information on the scan nodes from the
224: * statement execution plan as a String.
225: */
226: public String getScanStatisticsText(String tableName, int depth) {
227: if ((tableName == null) || (tableName.equals(this .tableName)))
228: return getStatementExecutionPlanText(depth);
229: else
230: return "";
231: }
232:
233: // Class implementation
234:
235: public String toString() {
236: return getStatementExecutionPlanText(0);
237: }
238:
239: /**
240: * Format for display, a name for this node.
241: *
242: */
243: public String getNodeName() {
244: return MessageService
245: .getTextMessage(indexName == null ? SQLState.RTS_TABLE_SCAN
246: : SQLState.RTS_INDEX_SCAN);
247: }
248:
249: /**
250: * If this node is on a database item (like a table or an index), then provide a
251: * string that describes the on item.
252: *
253: */
254: public String getNodeOn() {
255: if (indexName == null)
256: return MessageService.getTextMessage(SQLState.RTS_ON,
257: tableName);
258: else
259: return MessageService.getTextMessage(SQLState.RTS_ON_USING,
260: tableName, indexName);
261: }
262: }
|