--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.iapi.sql.compile.Optimizable\r
+\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to you under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.iapi.sql.compile;\r
+\r
+import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.TableDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+\r
+import org.apache.derby.iapi.util.JBitSet;\r
+\r
+import java.util.Properties;\r
+\r
+/**\r
+ * Optimizable provides services for optimizing a table in a query.\r
+ */\r
+\r
+public interface Optimizable {\r
+\r
+ /**\r
+ * Choose the next access path to evaluate for this Optimizable.\r
+ *\r
+ * @param optimizer Optimizer to use.\r
+ * @param predList The predicate list for this optimizable.\r
+ * The optimizer always passes null, and it is up\r
+ * to the optimizable object to pass along its\r
+ * own predicate list, if appropriate, when delegating\r
+ * this method.\r
+ * @param rowOrdering The row ordering for all the outer tables in\r
+ * the join order. This method will add the ordering\r
+ * of the next access path to the given RowOrdering.\r
+ *\r
+ * @return true means another access path was chosen, false means\r
+ * no more access paths to evaluate.\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+ boolean nextAccessPath(Optimizer optimizer,\r
+ OptimizablePredicateList predList,\r
+ RowOrdering rowOrdering)\r
+ throws StandardException;\r
+\r
+ /**\r
+ * Choose the best access path for this Optimizable.\r
+ *\r
+ * @param optimizer Optimizer to use.\r
+ * @param predList The predicate list to optimize against\r
+ * @param outerCost The CostEstimate for the outer tables in the join order,\r
+ * telling how many times this Optimizable will be scanned.\r
+ * @param rowOrdering The row ordering for all the tables in the\r
+ * join order, including this one.\r
+ *\r
+ * @return The optimizer's estimated cost of the best access path.\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+ CostEstimate optimizeIt(\r
+ Optimizer optimizer,\r
+ OptimizablePredicateList predList,\r
+ CostEstimate outerCost,\r
+ RowOrdering rowOrdering)\r
+ throws StandardException;\r
+\r
+ /**\r
+ * Get the current access path under consideration for this Optimizable\r
+ */\r
+ AccessPath getCurrentAccessPath();\r
+\r
+ /**\r
+ * Get the best access path for this Optimizable.\r
+ */\r
+ AccessPath getBestAccessPath();\r
+\r
+ /**\r
+ * Get the best sort-avoidance path for this Optimizable.\r
+ */\r
+ AccessPath getBestSortAvoidancePath();\r
+\r
+ /**\r
+ * Get the best access path overall for this Optimizable.\r
+ */\r
+ AccessPath getTrulyTheBestAccessPath();\r
+\r
+ /**\r
+ * Mark this optimizable so that its sort avoidance path will be\r
+ * considered.\r
+ */\r
+ void rememberSortAvoidancePath();\r
+\r
+ /**\r
+ * Check whether this optimizable's sort avoidance path should\r
+ * be considered.\r
+ */\r
+ boolean considerSortAvoidancePath();\r
+\r
+ /**\r
+ * Remember the current join strategy as the best one so far in this\r
+ * join order.\r
+ */\r
+ void rememberJoinStrategyAsBest(AccessPath ap);\r
+\r
+ /**\r
+ * Get the table descriptor for this table (if any). Only base tables\r
+ * have table descriptors - for the rest of the optimizables, this\r
+ * method returns null.\r
+ */\r
+ TableDescriptor getTableDescriptor();\r
+\r
+ /**\r
+ * Get the map of referenced tables for this Optimizable.\r
+ *\r
+ * @return JBitSet Referenced table map.\r
+ */\r
+ JBitSet getReferencedTableMap();\r
+\r
+ /**\r
+ * Push an OptimizablePredicate down, if this node accepts it.\r
+ *\r
+ * @param optimizablePredicate OptimizablePredicate to push down.\r
+ *\r
+ * @return Whether or not the predicate was pushed down.\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+ boolean pushOptPredicate(OptimizablePredicate optimizablePredicate)\r
+ throws StandardException;\r
+\r
+ /**\r
+ * Pull all the OptimizablePredicates from this Optimizable and put them\r
+ * in the given OptimizablePredicateList.\r
+ *\r
+ * @param optimizablePredicates The list to put the pulled predicates\r
+ * in.\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+ void pullOptPredicates(OptimizablePredicateList optimizablePredicates)\r
+ throws StandardException;\r
+\r
+ /**\r
+ * Modify the access path for this Optimizable, as necessary. This includes\r
+ * things like adding a result set to translate from index rows to base rows\r
+ *\r
+ * @param outerTables Bit map of the tables that are outer to this one\r
+ * in the join order.\r
+ * \r
+ * @return The (potentially new) Optimizable at the top of the tree.\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+ Optimizable modifyAccessPath(JBitSet outerTables) throws StandardException;\r
+\r
+ /**\r
+ * Return whether or not this is a covering index. We expect to call this\r
+ * during generation, after access path selection is complete.\r
+ *\r
+ * @param cd ConglomerateDesriptor for index to consider\r
+ *\r
+ * @return boolean Whether or not this is a covering index.\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+ public boolean isCoveringIndex(ConglomerateDescriptor cd) throws StandardException;\r
+\r
+ /**\r
+ * Get the Properties list, if any, associated with this optimizable.\r
+ *\r
+ * @return The Properties list, if any, associated with this optimizable.\r
+ */\r
+ public Properties getProperties();\r
+\r
+ /**\r
+ * Set the Properties list for this optimizalbe.\r
+ *\r
+ * @param tableProperties The Properties list for this optimizable.\r
+ */\r
+ public void setProperties(Properties tableProperties);\r
+\r
+ /** \r
+ * Verify that the Properties list with optimizer overrides, if specified, is valid\r
+ *\r
+ * @param dDictionary The DataDictionary to use.\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+ public void verifyProperties(DataDictionary dDictionary) throws StandardException;\r
+\r
+ /**\r
+ * Get the (exposed) name of this Optimizable\r
+ *\r
+ * @return The name of this Optimizable.\r
+ * @exception StandardException Thrown on error\r
+ */\r
+ public String getName() throws StandardException;\r
+\r
+ /**\r
+ * Get the table name of this Optimizable. Only base tables have\r
+ * table names (by the time we use this method, all views will have\r
+ * been resolved).\r
+ */\r
+ public String getBaseTableName();\r
+\r
+ /** \r
+ * Convert an absolute to a relative 0-based column position.\r
+ * This is useful when generating qualifiers for partial rows \r
+ * from the store.\r
+ *\r
+ * @param absolutePosition The absolute 0-based column position for the column.\r
+ *\r
+ * @return The relative 0-based column position for the column.\r
+ */\r
+ public int convertAbsoluteToRelativeColumnPosition(int absolutePosition);\r
+\r
+ /**\r
+ * When remembering "truly the best" access path for an Optimizable, we\r
+ * have to keep track of which OptimizerImpl the "truly the best" access\r
+ * is for. In most queries there will only be one OptimizerImpl in\r
+ * question, but in cases where there are nested subqueries, there will be\r
+ * one OptimizerImpl for every level of nesting, and each OptimizerImpl\r
+ * might have its own idea of what this Optimizable's "truly the best path"\r
+ * access path really is. In addition, there could be Optimizables\r
+ * above this Optimizable that might need to override the best path\r
+ * chosen during optimization. So whenever we save a "truly the best" path,\r
+ * we take note of which Optimizer/Optimizable told us to do so. Then\r
+ * as each level of subquery finishes optimization, the corresponding\r
+ * OptimizerImpl/Optimizable can load its preferred access path into this\r
+ * Optimizable's trulyTheBestAccessPath field and pass it up the tree, until\r
+ * eventually the outer-most OptimizerImpl can choose to either use the best\r
+ * path that it received from below (by calling "rememberAsBest()") or else\r
+ * use the path that it found to be "best" for itself.\r
+ *\r
+ * This method is what allows us to keep track of which OptimizerImpl or\r
+ * Optimizable saved which "best plan", and allows us to load the\r
+ * appropriate plans after each round of optimization.\r
+ * \r
+ * @param action Indicates whether we're adding, loading, or removing\r
+ * a best plan for the OptimizerImpl/Optimizable.\r
+ * @param planKey Object to use as the map key when adding/looking up\r
+ * a plan. If it is an instance of OptimizerImpl then it corresponds\r
+ * to an outer query; otherwise it's some Optimizable above this\r
+ * Optimizable that could potentially reject plans chosen by the\r
+ * OptimizerImpl to which this Optimizable belongs.\r
+ */\r
+ public void updateBestPlanMap(short action,\r
+ Object planKey) throws StandardException;\r
+\r
+ /**\r
+ * Remember the current access path as the best one (so far).\r
+ *\r
+ * @param planType The type of plan (one of Optimizer.NORMAL_PLAN\r
+ * or Optimizer.SORT_AVOIDANCE_PLAN)\r
+ * @param optimizer The OptimizerImpl that is telling this Optimizable\r
+ * to remember its current path as "truly the best".\r
+ *\r
+ * @exception StandardException thrown on error.\r
+ */\r
+ public void rememberAsBest(int planType, Optimizer optimizer)\r
+ throws StandardException;\r
+\r
+ /**\r
+ * Begin the optimization process for this Optimizable. This can be\r
+ * called many times for an Optimizable while optimizing a query -\r
+ * it will typically be called every time the Optimizable is placed\r
+ * in a potential join order.\r
+ */\r
+ public void startOptimizing(Optimizer optimizer, RowOrdering rowOrdering);\r
+\r
+ /**\r
+ * Estimate the cost of scanning this Optimizable using the given\r
+ * predicate list with the given conglomerate. It is assumed that the\r
+ * predicate list has already been classified. This cost estimate is\r
+ * just for one scan, not for the life of the query.\r
+ *\r
+ * @see OptimizablePredicateList#classify\r
+ *\r
+ * @param predList The predicate list to optimize against\r
+ * @param cd The conglomerate descriptor to get the cost of\r
+ * @param outerCost The estimated cost of the part of the plan outer\r
+ * to this optimizable.\r
+ * @param optimizer The optimizer to use to help estimate the cost\r
+ * @param rowOrdering The row ordering for all the tables in the\r
+ * join order, including this one.\r
+ *\r
+ * @return The estimated cost of doing the scan\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+ CostEstimate estimateCost(OptimizablePredicateList predList,\r
+ ConglomerateDescriptor cd,\r
+ CostEstimate outerCost,\r
+ Optimizer optimizer,\r
+ RowOrdering rowOrdering)\r
+ throws StandardException;\r
+\r
+ /** Tell whether this Optimizable represents a base table */\r
+ boolean isBaseTable();\r
+\r
+ /** Tell whether this Optimizable is materializable \r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+ boolean isMaterializable() throws StandardException;\r
+\r
+ /** Tell whether this Optimizable can be instantiated multiple times */\r
+ boolean supportsMultipleInstantiations();\r
+\r
+ /** Get this Optimizable's result set number */\r
+ int getResultSetNumber();\r
+\r
+ /** Get this Optimizable's table number */\r
+ int getTableNumber();\r
+\r
+ /** Return true if this Optimizable has a table number */\r
+ boolean hasTableNumber();\r
+\r
+ /** Return true if this is the target table of an update */\r
+ public boolean forUpdate();\r
+\r
+ /** Return the initial capacity of the hash table, for hash join strategy */\r
+ public int initialCapacity();\r
+\r
+ /** Return the load factor of the hash table, for hash join strategy */\r
+ public float loadFactor();\r
+\r
+ /** Return the hash key column numbers, for hash join strategy */\r
+ public int[] hashKeyColumns();\r
+\r
+ /** Set the hash key column numbers, for hash join strategy */\r
+ public void setHashKeyColumns(int[] columnNumbers);\r
+\r
+ /**\r
+ * Is the current proposed join strategy for this optimizable feasible\r
+ * given the predicate list?\r
+ *\r
+ * @param predList The predicate list that has been pushed down to\r
+ * this optimizable\r
+ * @param optimizer The optimizer to use.\r
+ *\r
+ * @return true means feasible\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+ public boolean feasibleJoinStrategy(OptimizablePredicateList predList,\r
+ Optimizer optimizer)\r
+ throws StandardException;\r
+\r
+ /**\r
+ * @param rowCount\r
+ * @param maxMemoryPerTable\r
+ * @return true if the memory usage of the proposed access path is OK, false if not.\r
+ *\r
+ * @exception StandardException standard error policy\r
+ */\r
+ public boolean memoryUsageOK( double rowCount, int maxMemoryPerTable)\r
+ throws StandardException;\r
+\r
+ /**\r
+ * Return the maximum capacity of the hash table, for hash join strategy\r
+ *\r
+ * @param maxMemoryPerTable The maximum number of bytes to be used. Ignored if the user has set a maximum\r
+ * number of rows for the Optimizable.\r
+ *\r
+ * @exception StandardException Standard error policy\r
+ */\r
+ public int maxCapacity( JoinStrategy joinStrategy, int maxMemoryPerTable) throws StandardException;\r
+\r
+ /**\r
+ * Can this Optimizable appear at the current location in the join order.\r
+ * In other words, have the Optimizable's dependencies been satisfied?\r
+ *\r
+ * @param assignedTableMap The tables that have been placed so far in the join order.\r
+ *\r
+ * @return Where or not this Optimizable can appear at the current location in the join order.\r
+ */\r
+ public boolean legalJoinOrder(JBitSet assignedTableMap);\r
+\r
+ /**\r
+ * Get the DataDictionary from this Optimizable. This is useful for code generation\r
+ * because we need to get the constraint name if scanning a back index so that\r
+ * RunTimeStatistics can display the correct info.\r
+ *\r
+ * @return The DataDictionary to use.\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+ public DataDictionary getDataDictionary() throws StandardException;\r
+\r
+ /**\r
+ * Is the optimizable the target table of an update or delete?\r
+ *\r
+ * @return Whether or not the optimizable the target table of an update or delete.\r
+ */\r
+ public boolean isTargetTable();\r
+\r
+ /**\r
+ * Get the number of the number of columns returned by this Optimizable.\r
+ *\r
+ * @return The number of the number of columns returned by this Optimizable.\r
+ */\r
+ public int getNumColumnsReturned();\r
+\r
+ /**\r
+ * Will the optimizable return at most 1 row per scan?\r
+ *\r
+ * @return Whether or not the optimizable will return at most 1 row per scan?\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+ public boolean isOneRowScan() throws StandardException;\r
+\r
+ /**\r
+ * Init the access paths for this optimizable.\r
+ *\r
+ * @param optimizer The optimizer being used.\r
+ */\r
+ public void initAccessPaths(Optimizer optimizer);\r
+\r
+ /**\r
+ * Does this optimizable have a uniqueness condition on the\r
+ * given predicate list, and if so, how many unique keys will be\r
+ * returned per scan.\r
+ *\r
+ * @param predList The predicate list to check\r
+ *\r
+ * @return <= 0 means there is no uniqueness condition\r
+ * > 0 means there is a uniqueness condition,\r
+ * and the return value is the number of rows per scan.\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+ public double uniqueJoin(OptimizablePredicateList predList)\r
+ throws StandardException;\r
+}\r