📄 fromtable.java
字号:
public String getName() throws StandardException { return getExposedName(); } /** @see Optimizable#getBaseTableName */ public String getBaseTableName() { return ""; } /** @see Optimizable#convertAbsoluteToRelativeColumnPosition */ public int convertAbsoluteToRelativeColumnPosition(int absolutePosition) { return absolutePosition; } /** @see Optimizable#addOrLoadBestPlanMapping */ public void addOrLoadBestPlanMapping(boolean doAdd, Object planKey) throws StandardException { AccessPath bestPath = getTrulyTheBestAccessPath(); AccessPathImpl ap = null; if (doAdd) { // If we get to this method before ever optimizing this node, then // there will be no best path--so there's nothing to do. if (bestPath == null) return; // If the optimizerToBestPlanMap already exists, search for an // AccessPath for the received key and use that if we can. if (optimizerToBestPlanMap == null) optimizerToBestPlanMap = new HashMap(); else ap = (AccessPathImpl)optimizerToBestPlanMap.get(planKey); // If we don't already have an AccessPath for the key, // create a new one. If the key is an OptimizerImpl then // we might as well pass it in to the AccessPath constructor; // otherwise just pass null. if (ap == null) { if (planKey instanceof Optimizer) ap = new AccessPathImpl((Optimizer)planKey); else ap = new AccessPathImpl((Optimizer)null); } ap.copy(bestPath); optimizerToBestPlanMap.put(planKey, ap); return; } // If we get here, we want to load the best plan from our map // into this Optimizable's trulyTheBestAccessPath field. // If we don't have any plans saved, then there's nothing to load. // This can happen if the key is an OptimizerImpl that tried some // join order for which there was no valid plan. if (optimizerToBestPlanMap == null) return; ap = (AccessPathImpl)optimizerToBestPlanMap.get(planKey); // It might be the case that there is no plan stored for // the key, in which case there's nothing to load. if ((ap == null) || (ap.getCostEstimate() == null)) return; // We found a best plan in our map, so load it into this Optimizable's // trulyTheBestAccessPath field. bestPath.copy(ap); return; } /** @see Optimizable#rememberAsBest */ public void rememberAsBest(int planType, Optimizer optimizer) throws StandardException { AccessPath bestPath = null; switch (planType) { case Optimizer.NORMAL_PLAN: bestPath = getBestAccessPath(); break; case Optimizer.SORT_AVOIDANCE_PLAN: bestPath = getBestSortAvoidancePath(); break; default: if (SanityManager.DEBUG) { SanityManager.THROWASSERT( "Invalid plan type " + planType); } } getTrulyTheBestAccessPath().copy(bestPath); // Since we just set trulyTheBestAccessPath for the current // join order of the received optimizer, take note of what // that path is, in case we need to "revert" back to this // path later. See Optimizable.addOrLoadBestPlanMapping(). // Note: Since this call descends all the way down to base // tables, it can be relatively expensive when we have deeply // nested subqueries. So in an attempt to save some work, we // skip the call if this node is a ProjectRestrictNode whose // child is an Optimizable--in that case the ProjectRestrictNode // will in turn call "rememberAsBest" on its child and so // the required call to addOrLoadBestPlanMapping() will be // made at that time. If we did it here, too, then we would // just end up duplicating the work. if (!(this instanceof ProjectRestrictNode)) addOrLoadBestPlanMapping(true, optimizer); else { ProjectRestrictNode prn = (ProjectRestrictNode)this; if (!(prn.getChildResult() instanceof Optimizable)) addOrLoadBestPlanMapping(true, optimizer); } /* also store the name of the access path; i.e index name/constraint * name if we're using an index to access the base table. */ ConglomerateDescriptor cd = bestPath.getConglomerateDescriptor(); if (isBaseTable()) { DataDictionary dd = getDataDictionary(); TableDescriptor td = getTableDescriptor(); getTrulyTheBestAccessPath().initializeAccessPathName(dd, td); } setCostEstimate(bestPath.getCostEstimate()); bestPath.getOptimizer().trace(Optimizer.REMEMBERING_BEST_ACCESS_PATH, tableNumber, planType, 0.0, bestPath); } /** @see Optimizable#startOptimizing */ public void startOptimizing(Optimizer optimizer, RowOrdering rowOrdering) { resetJoinStrategies(optimizer); considerSortAvoidancePath = false; /* ** If there are costs associated with the best and sort access ** paths, set them to their maximum values, so that any legitimate ** access path will look cheaper. */ CostEstimate ce = getBestAccessPath().getCostEstimate(); if (ce != null) ce.setCost(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE); ce = getBestSortAvoidancePath().getCostEstimate(); if (ce != null) ce.setCost(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE); if (! canBeOrdered()) rowOrdering.addUnorderedOptimizable(this); } /** * This method is called when this table is placed in a potential * join order, or when a new conglomerate is being considered. * Set this join strategy number to 0 to indicate that * no join strategy has been considered for this table yet. */ protected void resetJoinStrategies(Optimizer optimizer) { joinStrategyNumber = 0; getCurrentAccessPath().setJoinStrategy((JoinStrategy) null); } /** * @see Optimizable#estimateCost * * @exception StandardException Thrown on error */ public CostEstimate estimateCost(OptimizablePredicateList predList, ConglomerateDescriptor cd, CostEstimate outerCost, Optimizer optimizer, RowOrdering rowOrdering) throws StandardException { if (SanityManager.DEBUG) { SanityManager.THROWASSERT( "estimateCost() not expected to be called for " + getClass().toString()); } return null; } /** * Get the final CostEstimate for this FromTable. * * @return The final CostEstimate for this FromTable, which is * the costEstimate of trulyTheBestAccessPath if there is one. * If there's no trulyTheBestAccessPath for this node, then * we just return the value stored in costEstimate as a default. */ public CostEstimate getFinalCostEstimate() throws StandardException { // If we already found it, just return it. if (finalCostEstimate != null) return finalCostEstimate; if (getTrulyTheBestAccessPath() == null) finalCostEstimate = costEstimate; else finalCostEstimate = getTrulyTheBestAccessPath().getCostEstimate(); return finalCostEstimate; } /** @see Optimizable#isBaseTable */ public boolean isBaseTable() { return false; } /** @see Optimizable#isMaterializable * * @exception StandardException Thrown on error */ public boolean isMaterializable() throws StandardException { /* Derived tables are materializable * iff they are not correlated with an outer query block. */ HasCorrelatedCRsVisitor visitor = new HasCorrelatedCRsVisitor(); accept(visitor); return !(visitor.hasCorrelatedCRs()); } /** @see Optimizable#supportsMultipleInstantiations */ public boolean supportsMultipleInstantiations() { return true; } /** @see Optimizable#getTableNumber */ public int getTableNumber() { return tableNumber; } /** @see Optimizable#hasTableNumber */ public boolean hasTableNumber() { return tableNumber >= 0; } /** @see Optimizable#forUpdate */ public boolean forUpdate() { return false; } /** @see Optimizable#initialCapacity */ public int initialCapacity() { if (SanityManager.DEBUG) { SanityManager.THROWASSERT("Not expected to be called"); } return 0; } /** @see Optimizable#loadFactor */ public float loadFactor() { if (SanityManager.DEBUG) { SanityManager.THROWASSERT("Not expected to be called"); } return 0.0F; } /** @see Optimizable#maxCapacity */ public int maxCapacity( JoinStrategy joinStrategy, int maxMemoryPerTable) throws StandardException { return joinStrategy.maxCapacity( maxCapacity, maxMemoryPerTable, getPerRowUsage()); } private double getPerRowUsage() throws StandardException { if( perRowUsage < 0) { // Do not use getRefCols() because the cached refCols may no longer be valid. FormatableBitSet refCols = resultColumns.getReferencedFormatableBitSet(cursorTargetTable(), true, false); perRowUsage = 0.0; /* Add up the memory usage for each referenced column */ for (int i = 0; i < refCols.size(); i++) { if (refCols.isSet(i)) { ResultColumn rc = (ResultColumn) resultColumns.elementAt(i); DataTypeDescriptor expressionType = rc.getExpressionType(); if( expressionType != null) perRowUsage += expressionType.estimatedMemoryUsage(); } } /* ** If the proposed conglomerate is a non-covering index, add the ** size of the RowLocation column to the total. ** ** NOTE: We don't have a DataTypeDescriptor representing a ** REF column here, so just add a constant here. */ ConglomerateDescriptor cd = getCurrentAccessPath().getConglomerateDescriptor(); if (cd != null) { if (cd.isIndex() && ( ! isCoveringIndex(cd) ) ) { // workaround for a jikes bug. Can't directly reference a // double with a value of 12.0 in this classfile. double baseIndexUsage = 1.0; perRowUsage += ( baseIndexUsage + 11 ); } } } return perRowUsage ; } // end of getPerRowUsage /** @see Optimizable#hashKeyColumns */ public int[] hashKeyColumns() { if (SanityManager.DEBUG) { SanityManager.ASSERT(hashKeyColumns != null, "hashKeyColumns expected to be non-null"); } return hashKeyColumns; } /** @see Optimizable#setHashKeyColumns */ public void setHashKeyColumns(int[] columnNumbers) { hashKeyColumns = columnNumbers; } /** * @see Optimizable#feasibleJoinStrategy * * @exception StandardException Thrown on error */ public boolean feasibleJoinStrategy(OptimizablePredicateList predList, Optimizer optimizer) throws StandardException { return getCurrentAccessPath().getJoinStrategy(). feasible(this, predList, optimizer); } /** @see Optimizable#memoryUsageOK */ public boolean memoryUsageOK( double rowCount, int maxMemoryPerTable) throws StandardException { /* ** Don't enforce maximum memory usage for a user-specified join ** strategy. */ if( userSpecifiedJoinStrategy != null) return true; int intRowCount = (rowCount > Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int) rowCount; return intRowCount <= maxCapacity( getCurrentAccessPath().getJoinStrategy(), maxMemoryPerTable); } /** * @see Optimizable#legalJoinOrder */ public boolean legalJoinOrder(JBitSet assignedTableMap) { // Only those subclasses with dependencies need to override this. return true; } /** * @see Optimizable#getNumColumnsReturned */ public int getNumColumnsReturned() { return resultColumns.size(); } /** * @see Optimizable#isTargetTable */ public boolean isTargetTable() { return false; } /** * @see Optimizable#isOneRowScan * * @exception StandardException Thrown on error */ public boolean isOneRowScan() throws StandardException { /* We simply return isOneRowResultSet() for all * subclasses except for EXISTS FBT where * the semantics differ between 1 row per probe * and whether or not there can be more than 1 * rows that qualify on a scan. */ return isOneRowResultSet(); } /** * @see Optimizable#initAccessPaths */ public void initAccessPaths(Optimizer optimizer) { if (currentAccessPath == null) { currentAccessPath = new AccessPathImpl(optimizer); } if (bestAccessPath == null) { bestAccessPath = new AccessPathImpl(optimizer); } if (bestSortAvoidancePath == null) { bestSortAvoidancePath = new AccessPathImpl(optimizer); } if (trulyTheBestAccessPath == null) { trulyTheBestAccessPath = new AccessPathImpl(optimizer); } } /** * @see Optimizable#uniqueJoin * * @exception StandardException Thrown on error */ public double uniqueJoin(OptimizablePredicateList predList) throws StandardException { return -1.0; } private FormatableBitSet getRefCols() { if (refCols == null) refCols = resultColumns.getReferencedFormatableBitSet(cursorTargetTable(), true, false); return refCols; } /** * Return the user specified join strategy, if any for this table. * * @return The user specified join strategy, if any for this table. */ String getUserSpecifiedJoinStrategy() { if (tableProperties == null) { return null; } return tableProperties.getProperty("joinStrategy"); } /** * Is this a table that has a FOR UPDATE * clause. Overridden by FromBaseTable. * * @return true/false */ protected boolean cursorTargetTable() { return false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -