📄 frombasetable.java
字号:
/* ** Tell the rowOrdering that what the ordering of this conglomerate is */ if (currentConglomerateDescriptor != null) { if ( ! currentConglomerateDescriptor.isIndex()) { /* If we are scanning the heap, but there * is a full match on a unique key, then * we can say that the table IS NOT unordered. * (We can't currently say what the ordering is * though.) */ if (! isOneRowResultSet(predList)) { optimizer.trace(Optimizer.ADDING_UNORDERED_OPTIMIZABLE, ((predList == null) ? 0 : predList.size()), 0, 0.0, null); rowOrdering.addUnorderedOptimizable(this); } else { optimizer.trace(Optimizer.SCANNING_HEAP_FULL_MATCH_ON_UNIQUE_KEY, 0, 0, 0.0, null); } } else { IndexRowGenerator irg = currentConglomerateDescriptor.getIndexDescriptor(); int[] baseColumnPositions = irg.baseColumnPositions(); boolean[] isAscending = irg.isAscending(); for (int i = 0; i < baseColumnPositions.length; i++) { /* ** Don't add the column to the ordering if it's already ** an ordered column. This can happen in the following ** case: ** ** create index ti on t(x, y); ** select * from t where x = 1 order by y; ** ** Column x is always ordered, so we want to avoid the ** sort when using index ti. This is accomplished by ** making column y appear as the first ordered column ** in the list. */ if ( ! rowOrdering.orderedOnColumn(isAscending[i] ? RowOrdering.ASCENDING : RowOrdering.DESCENDING, getTableNumber(), baseColumnPositions[i])) { rowOrdering.nextOrderPosition(isAscending[i] ? RowOrdering.ASCENDING : RowOrdering.DESCENDING); rowOrdering.addOrderedColumn(isAscending[i] ? RowOrdering.ASCENDING : RowOrdering.DESCENDING, getTableNumber(), baseColumnPositions[i]); } } } } ap.setConglomerateDescriptor(currentConglomerateDescriptor); return currentConglomerateDescriptor != null; } /** Tell super-class that this Optimizable can be ordered */ protected boolean canBeOrdered() { return true; } /** * @see org.apache.derby.iapi.sql.compile.Optimizable#optimizeIt * * @exception StandardException Thrown on error */ public CostEstimate optimizeIt( Optimizer optimizer, OptimizablePredicateList predList, CostEstimate outerCost, RowOrdering rowOrdering) throws StandardException { optimizer.costOptimizable( this, tableDescriptor, getCurrentAccessPath().getConglomerateDescriptor(), predList, outerCost); // The cost that we found from the above call is now stored in the // cost field of this FBT's current access path. So that's the // cost we want to return here. return getCurrentAccessPath().getCostEstimate(); } /** @see Optimizable#getTableDescriptor */ public TableDescriptor getTableDescriptor() { return tableDescriptor; } /** @see Optimizable#isMaterializable * * @exception StandardException Thrown on error */ public boolean isMaterializable() throws StandardException { /* base tables are always materializable */ return true; } /** * @see Optimizable#pushOptPredicate * * @exception StandardException Thrown on error */ public boolean pushOptPredicate(OptimizablePredicate optimizablePredicate) throws StandardException { if (SanityManager.DEBUG) { SanityManager.ASSERT(optimizablePredicate instanceof Predicate, "optimizablePredicate expected to be instanceof Predicate"); } /* Add the matching predicate to the restrictionList */ restrictionList.addPredicate((Predicate) optimizablePredicate); return true; } /** * @see Optimizable#pullOptPredicates * * @exception StandardException Thrown on error */ public void pullOptPredicates( OptimizablePredicateList optimizablePredicates) throws StandardException { for (int i = restrictionList.size() - 1; i >= 0; i--) { optimizablePredicates.addOptPredicate( restrictionList.getOptPredicate(i)); restrictionList.removeOptPredicate(i); } } /** * @see Optimizable#isCoveringIndex * @exception StandardException Thrown on error */ public boolean isCoveringIndex(ConglomerateDescriptor cd) throws StandardException { boolean coveringIndex = true; IndexRowGenerator irg; int[] baseCols; int colPos; /* You can only be a covering index if you're an index */ if ( ! cd.isIndex()) return false; irg = cd.getIndexDescriptor(); baseCols = irg.baseColumnPositions(); /* First we check to see if this is a covering index */ int rclSize = resultColumns.size(); for (int index = 0; index < rclSize; index++) { ResultColumn rc = (ResultColumn) resultColumns.elementAt(index); /* Ignore unreferenced columns */ if (! rc.isReferenced()) { continue; } /* Ignore constants - this can happen if all of the columns * were projected out and we ended up just generating * a "1" in RCL.doProject(). */ if (rc.getExpression() instanceof ConstantNode) { continue; } coveringIndex = false; colPos = rc.getColumnPosition(); /* Is this column in the index? */ for (int i = 0; i < baseCols.length; i++) { if (colPos == baseCols[i]) { coveringIndex = true; break; } } /* No need to continue if the column was not in the index */ if (! coveringIndex) { break; } } return coveringIndex; } /** @see Optimizable#verifyProperties * @exception StandardException Thrown on error */ public void verifyProperties(DataDictionary dDictionary) throws StandardException { if (tableProperties == null) { return; } /* Check here for: * invalid properties key * index and constraint properties * non-existent index * non-existent constraint * invalid joinStrategy * invalid value for hashInitialCapacity * invalid value for hashLoadFactor * invalid value for hashMaxCapacity */ boolean indexSpecified = false; boolean constraintSpecified = false; ConstraintDescriptor consDesc = null; Enumeration e = tableProperties.keys(); StringUtil.SQLEqualsIgnoreCase(tableDescriptor.getSchemaName(), "SYS"); while (e.hasMoreElements()) { String key = (String) e.nextElement(); String value = (String) tableProperties.get(key); if (key.equals("index")) { // User only allowed to specify 1 of index and constraint, not both if (constraintSpecified) { throw StandardException.newException(SQLState.LANG_BOTH_FORCE_INDEX_AND_CONSTRAINT_SPECIFIED, getBaseTableName()); } indexSpecified = true; /* Validate index name - NULL means table scan */ if (! StringUtil.SQLToUpperCase(value).equals("NULL")) { ConglomerateDescriptor cd = null; ConglomerateDescriptor[] cds = tableDescriptor.getConglomerateDescriptors(); for (int index = 0; index < cds.length; index++) { cd = cds[index]; String conglomerateName = cd.getConglomerateName(); if (conglomerateName != null) { if (conglomerateName.equals(value)) { break; } } // Not a match, clear cd cd = null; } // Throw exception if user specified index not found if (cd == null) { throw StandardException.newException(SQLState.LANG_INVALID_FORCED_INDEX1, value, getBaseTableName()); } /* Query is dependent on the ConglomerateDescriptor */ getCompilerContext().createDependency(cd); } } else if (key.equals("constraint")) { // User only allowed to specify 1 of index and constraint, not both if (indexSpecified) { throw StandardException.newException(SQLState.LANG_BOTH_FORCE_INDEX_AND_CONSTRAINT_SPECIFIED, getBaseTableName()); } constraintSpecified = true; /* Validate constraint name - NULL means table scan */ if (! StringUtil.SQLToUpperCase(value).equals("NULL")) { consDesc = dDictionary.getConstraintDescriptorByName( tableDescriptor, (SchemaDescriptor)null, value, false); /* Throw exception if user specified constraint not found * or if it does not have a backing index. */ if ((consDesc == null) || ! consDesc.hasBackingIndex()) { throw StandardException.newException(SQLState.LANG_INVALID_FORCED_INDEX2, value, getBaseTableName()); } /* Query is dependent on the ConstraintDescriptor */ getCompilerContext().createDependency(consDesc); } } else if (key.equals("joinStrategy")) { userSpecifiedJoinStrategy = StringUtil.SQLToUpperCase(value); } else if (key.equals("hashInitialCapacity")) { initialCapacity = getIntProperty(value, key); // verify that the specified value is valid if (initialCapacity <= 0) { throw StandardException.newException(SQLState.LANG_INVALID_HASH_INITIAL_CAPACITY, String.valueOf(initialCapacity)); } } else if (key.equals("hashLoadFactor")) { try { loadFactor = Float.valueOf(value).floatValue(); } catch (NumberFormatException nfe) { throw StandardException.newException(SQLState.LANG_INVALID_NUMBER_FORMAT_FOR_OVERRIDE, value, key); } // verify that the specified value is valid if (loadFactor <= 0.0 || loadFactor > 1.0) { throw StandardException.newException(SQLState.LANG_INVALID_HASH_LOAD_FACTOR, value); } } else if (key.equals("hashMaxCapacity")) { maxCapacity = getIntProperty(value, key); // verify that the specified value is valid if (maxCapacity <= 0) { throw StandardException.newException(SQLState.LANG_INVALID_HASH_MAX_CAPACITY, String.valueOf(maxCapacity)); } } else if (key.equals("bulkFetch")) { bulkFetch = getIntProperty(value, key); // verify that the specified value is valid if (bulkFetch <= 0) { throw StandardException.newException(SQLState.LANG_INVALID_BULK_FETCH_VALUE, String.valueOf(bulkFetch)); } // no bulk fetch on updatable scans if (forUpdate()) { throw StandardException.newException(SQLState.LANG_INVALID_BULK_FETCH_UPDATEABLE); } } else { // No other "legal" values at this time throw StandardException.newException(SQLState.LANG_INVALID_FROM_TABLE_PROPERTY, key, "index, constraint, joinStrategy"); } } /* If user specified a constraint name, then replace it in the * properties list with the underlying index name to simplify * the code in the optimizer. * NOTE: The code to get from the constraint name, for a constraint * with a backing index, to the index name is convoluted. Given * the constraint name, we can get the conglomerate id from the * ConstraintDescriptor. We then use the conglomerate id to get * the ConglomerateDescriptor from the DataDictionary and, finally, * we get the index name (conglomerate name) from the ConglomerateDescriptor. */ if (constraintSpecified) { ConglomerateDescriptor cd = dDictionary.getConglomerateDescriptor( consDesc.getConglomerateId()); String indexName = cd.getConglomerateName(); tableProperties.remove("constraint"); tableProperties.put("index", indexName); } } /** @see Optimizable#getBaseTableName */ public String getBaseTableName() { return tableName.getTableName(); } /** @see Optimizable#startOptimizing */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -