📄 fromlist.java
字号:
predicateList.categorize(); int size = size(); for (int index = 0; index < size; index++) { FromTable fromTable = (FromTable) elementAt(index); fromTable.pushExpressions(predicateList); } } /** * Prints the sub-nodes of this object. See QueryTreeNode.java for * how tree printing is supposed to work. * * @param depth The depth of this node in the tree * * @return Nothing */ public void printSubNodes(int depth) { if (SanityManager.DEBUG) { FromTable fromTable; super.printSubNodes(depth); int size = size(); for (int index = 0; index < size; index++) { fromTable = (FromTable) elementAt(index); fromTable.treePrint(depth + 1); } } } /** * Set the (query block) level (0-based) for the FromTables in this * FromList. * * @param level The query block level for this table. * * @return Nothing */ public void setLevel(int level) { int size = size(); for (int index = 0; index < size; index++) { FromTable fromTable = (FromTable) elementAt(index); fromTable.setLevel(level); } } /** Move the mark for result set being the statement's outermost result set down into the first table of the from list. Generally expect there is only one table at this point. */ void markStatementResultSet() { ((FromTable) elementAt(0)).markStatementResultSet(); } /** * Get the FromTable from this list which has the specified ResultColumn in * its RCL. * * @param rc The ResultColumn match on. * * @return FromTable The matching FromTable. */ public FromTable getFromTableByResultColumn(ResultColumn rc) { FromTable fromTable = null; int size = size(); for (int index = 0; index < size; index++) { fromTable = (FromTable) elementAt(index); if (fromTable.getResultColumns().indexOf(rc) != -1) { break; } } if (SanityManager.DEBUG) { SanityManager.ASSERT(fromTable != null, "No matching FromTable found"); } return fromTable; } /** * Set the Properties list for this FromList. * * @exception StandardException Thrown on error */ public void setProperties(Properties props) throws StandardException { properties = props; /* ** Validate the properties list now. This is possible because ** there is nothing in this properties list that relies on binding ** or optimization to validate. */ Enumeration e = properties.keys(); while (e.hasMoreElements()) { String key = (String) e.nextElement(); String value = (String) properties.get(key); if (key.equals("joinOrder")) { if (StringUtil.SQLEqualsIgnoreCase(value,"fixed")) { fixedJoinOrder = true; } else if (StringUtil.SQLEqualsIgnoreCase(value,"unfixed")) { fixedJoinOrder = false; } else { throw StandardException.newException(SQLState.LANG_INVALID_JOIN_ORDER_SPEC, value); } } else if (key.equals("useStatistics")) { if (StringUtil.SQLEqualsIgnoreCase(value,"true")) { useStatistics = true; } else if (StringUtil.SQLEqualsIgnoreCase(value,"false")) { useStatistics = false; } else { throw StandardException.newException(SQLState.LANG_INVALID_STATISTICS_SPEC, value); } } else { throw StandardException.newException(SQLState.LANG_INVALID_FROM_LIST_PROPERTY, key, value); } } } /** @see OptimizableList#reOrder */ public void reOrder(int[] joinOrder) { int posn; if (SanityManager.DEBUG) { if (joinOrder.length != size()) { SanityManager.THROWASSERT("In reOrder(), size of FromList is " + size() + " while size of joinOrder array is " + joinOrder.length); } /* ** Determine that the values in the list are unique and in range. ** The easiest way to determine that they are unique is to add ** them all up and see whether the result is what's expected ** for that array size. */ int sum = 0; for (int i = 0; i < joinOrder.length; i++) { if (joinOrder[i] < 0 || joinOrder[i] > (joinOrder.length - 1)) { SanityManager.THROWASSERT("joinOrder[" + i + "] == " + joinOrder[i] + " is out of range - must be between 0 and " + (joinOrder.length - 1) + " inclusive."); } sum += joinOrder[i]; } /* ** The sum of all integers from 0 through n is (n * (n - 1)) / 2. */ if (sum != ( ( joinOrder.length * (joinOrder.length - 1) ) / 2) ) { String arrayVals = ""; for (int i = 0; i < joinOrder.length; i++) arrayVals = arrayVals + joinOrder[i] + " "; SanityManager.THROWASSERT("joinOrder array has some duplicate value: " + arrayVals); } } /* Form a list that's in the order we want */ QueryTreeNode[] orderedFL = new FromTable[joinOrder.length]; for (posn = 0; posn < joinOrder.length; posn++) { /* ** Get the element at the i'th join order position from the ** current list and make it the next element of orderedList. */ orderedFL[posn] = elementAt(joinOrder[posn]); } /* Now orderedList has been built, so set this list to the same order */ for (posn = 0; posn < joinOrder.length; posn++) { setElementAt(orderedFL[posn], posn); } } /** @see OptimizableList#useStatistics */ public boolean useStatistics() { return useStatistics; } /** @see OptimizableList#optimizeJoinOrder */ public boolean optimizeJoinOrder() { return ! fixedJoinOrder; } /** @see OptimizableList#legalJoinOrder */ public boolean legalJoinOrder(int numTablesInQuery) { JBitSet assignedTableMap = new JBitSet(numTablesInQuery); int size = size(); for (int index = 0; index < size; index++) { FromTable ft = (FromTable) elementAt(index); assignedTableMap.or(ft.getReferencedTableMap()); if ( ! ft.legalJoinOrder(assignedTableMap)) { return false; } } return true; } /** @see OptimizableList#initAccessPaths */ public void initAccessPaths(Optimizer optimizer) { int size = size(); for (int index = 0; index < size; index++) { FromTable ft = (FromTable) elementAt(index); ft.initAccessPaths(optimizer); } } /** * Bind any untyped null nodes to the types in the given ResultColumnList. * * @param bindingRCL The ResultColumnList with the types to bind to. * * @exception StandardException Thrown on error */ public void bindUntypedNullsToResultColumns(ResultColumnList bindingRCL) throws StandardException { int size = size(); for (int index = 0; index < size; index++) { FromTable fromTable = (FromTable) elementAt(index); fromTable.bindUntypedNullsToResultColumns(bindingRCL); } } /** * Decrement (query block) level (0-based) for * all of the tables in this from list. * This is useful when flattening a subquery. * * @param decrement The amount to decrement by. * * @return Nothing; */ void decrementLevel(int decrement) { int size = size(); for (int index = 0; index < size; index++) { FromTable fromTable = (FromTable) elementAt(index); fromTable.decrementLevel(decrement); /* Decrement the level of any CRs in single table * predicates that are interesting to transitive * closure. */ ProjectRestrictNode prn = (ProjectRestrictNode) fromTable; PredicateList pl = prn.getRestrictionList(); if (pl != null) { pl.decrementLevel(this, decrement); } } } /** * This method is used for both subquery flattening and distinct * elimination based on a uniqueness condition. For subquery * flattening we want to make sure that the query block * will return at most 1 row. For distinct elimination we * want to make sure that the query block will not return * any duplicates. * This is true if every table in the from list is * (a base table and the set of columns from the table that * are in equality comparisons with expressions that do not include columns * from the same table is a superset of any unique index * on the table) or an EXISTS FBT. In addition, at least 1 of the tables * in the list has a set of columns in equality comparisons with expressions * that do not include column references from the same query block * is a superset of a unique index * on that table. (This ensures that the query block will onlyr * return a single row.) * This method is expected to be called after normalization and * after the from list has been preprocessed. * It can be called both before and after the predicates have * been pulled from the where clause. * The algorithm for this is as follows * * If any table in the query block is not a base table, give up. * For each table in the query * Ignore exists table since they can only produce one row * * create a matrix of tables and columns from the table (tableColMap) * (this is used to keep track of the join columns and constants * that can be used to figure out whether the rows from a join * or in a select list are distinct based on unique indexes) * * create an array of columns from the table(eqOuterCol) * (this is used to determine that only one row will be returned * from a join) * * if the current table is the table for the result columns * set the result columns in the eqOuterCol and tableColMap * (if these columns are a superset of a unique index and * all joining tables result in only one row, the * results will be distinct) * go through all the predicates and update tableColMap and * eqOuterCol with join columns and correlation variables, * parameters and constants * since setting constants, correlation variables and parameters, * reduces the number of columns required for uniqueness in a * multi-column index, they are set for all the tables (if the * table is not the result table, in this case only the column of the * result table is set) * join columns are just updated for the column in the row of the * joining table. * * check if the marked columns in tableColMap are a superset of a unique * index * (This means that the join will only produce 1 row when joined * with 1 row of another table) * check that there is a least one table for which the columns in * eqOuterCol(i.e. constant values) are a superset of a unique index * (This quarantees that there will be only one row selected * from this table). * * Once all tables have been evaluated, check that all the tables can be * joined by unique index or will have only one row * * * * @param rcl If non-null, the RCL from the query block. * If non-null for subqueries, then entry can * be considered as part of an = comparison. * @param whereClause The WHERE clause to consider. * @param wherePredicates The predicates that have already been * pulled from the WHERE clause. * @param dd The DataDictionary to use. * * @return Whether or not query block will return * at most 1 row for a subquery, no duplicates * for a distinct. * * @exception StandardException Thrown on error */ boolean returnsAtMostSingleRow(ResultColumnList rcl, ValueNode whereClause, PredicateList wherePredicates, DataDictionary dd) throws StandardException { boolean satisfiesOuter = false; int[] tableNumbers; ColumnReference additionalCR = null;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -