📄 selectnode.java
字号:
/* Derby - Class org.apache.derby.impl.sql.compile.SelectNode Copyright 1997, 2004 The Apache Software Foundation or its licensors, as applicable. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package org.apache.derby.impl.sql.compile;import org.apache.derby.iapi.sql.compile.CostEstimate;import org.apache.derby.iapi.sql.compile.Optimizer;import org.apache.derby.iapi.sql.compile.Visitable;import org.apache.derby.iapi.sql.compile.Visitor;import org.apache.derby.iapi.sql.compile.C_NodeTypes;import org.apache.derby.iapi.sql.dictionary.DataDictionary;import org.apache.derby.iapi.sql.dictionary.TableDescriptor;import org.apache.derby.iapi.types.TypeId;import org.apache.derby.iapi.types.DataTypeDescriptor;import org.apache.derby.iapi.reference.Limits;import org.apache.derby.iapi.reference.SQLState;import org.apache.derby.iapi.error.StandardException;import org.apache.derby.iapi.store.access.TransactionController;import org.apache.derby.iapi.services.sanity.SanityManager;import org.apache.derby.iapi.util.JBitSet;import java.util.Vector;import java.util.HashSet;/** * A SelectNode represents the result set for any of the basic DML * operations: SELECT, INSERT, UPDATE, and DELETE. (A RowResultSetNode * will be used for an INSERT with a VALUES clause.) For INSERT - SELECT, * any of the fields in a SelectNode can be used (the SelectNode represents * the SELECT statement in the INSERT - SELECT). For UPDATE and * DELETE, there will be one table in the fromList, and the groupByList * fields will be null. For both INSERT and UPDATE, * the resultColumns in the selectList will contain the names of the columns * being inserted into or updated. * * @author Jeff Lichtman */public class SelectNode extends ResultSetNode{ /** * List of tables in the FROM clause of this SELECT */ FromList fromList; FromTable targetTable; /* Aggregate Vectors for select and where clauses */ Vector selectAggregates ; Vector whereAggregates; /** * The ValueNode for the WHERE clause must represent a boolean * expression. The binding phase will enforce this - the parser * does not have enough information to enforce it in all cases * (for example, user methods that return boolean). */ ValueNode whereClause; ValueNode originalWhereClause; /** * List of result columns in GROUP BY clause */ GroupByList groupByList; /* List of columns in ORDER BY list */ OrderByList orderByList; boolean orderByQuery ; /* PredicateLists for where clause */ PredicateList wherePredicates; /* SubqueryLists for select and where clauses */ SubqueryList selectSubquerys; SubqueryList whereSubquerys; /* Whether or not we are only binding the target list */ private boolean bindTargetListOnly; private boolean isDistinct; private boolean orderByAndDistinctMerged; private boolean generatedForGroupByClause; private boolean generatedForHavingClause; /* Copy of fromList prior to generating join tree */ private FromList preJoinFL; /** * Initializer for a SelectNode. * * @param selectList The result column list for the SELECT statement * @param aggregateVector The aggregate vector for this SELECT * @param fromList The FROM list for the SELECT statement * @param whereClause An expression representing the WHERE clause. * It must be a boolean expression, but this is * not checked until binding. * @param groupByList The GROUP BY list, if any. * @exception StandardException Thrown on error */ public void init(Object selectList, Object aggregateVector, Object fromList, Object whereClause, Object groupByList) throws StandardException { /* RESOLVE - remove aggregateList from constructor. * Consider adding selectAggregates and whereAggregates */ resultColumns = (ResultColumnList) selectList; if (resultColumns != null) resultColumns.markInitialSize(); this.fromList = (FromList) fromList; this.whereClause = (ValueNode) whereClause; this.originalWhereClause = (ValueNode) whereClause; this.groupByList = (GroupByList) groupByList; bindTargetListOnly = false; } /** * Convert this object to a String. See comments in QueryTreeNode.java * for how this should be done for tree printing. * * @return This object as a String */ public String toString() { if (SanityManager.DEBUG) { return "isDistinct: "+ isDistinct + "\n"+ "groupByList: " + (groupByList != null ? groupByList.toString() : "null") + "\n" + "orderByList: " + (orderByList != null ? orderByList.toString() : "null") + "\n" + "generatedForGroupByClause: " +generatedForGroupByClause +"\n" + "generatedForHavingClause: " + generatedForHavingClause + "\n" + super.toString(); } else { return ""; } } public String statementToString() { return "SELECT"; } public void makeDistinct() { isDistinct = true; } public void clearDistinct() { isDistinct = false; } boolean hasDistinct() { return isDistinct; } /** * Mark this SelectNode as being generated for a GROUP BY clause. * * @return Nothing. */ public void markAsForGroupByClause() { generatedForGroupByClause = true; } /** * Return whether or not this SelectNode was generated for a GROUP BY clause. * * @return boolean Whether or not this SelectNode was generated for a GROUP BY clause. */ public boolean getGeneratedForGroupbyClause() { return generatedForGroupByClause; } /** * Mark this SelectNode as being generated for a HAVING clause. * * @return Nothing. */ public void markAsForHavingClause() { generatedForHavingClause = true; } /** * 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) { super.printSubNodes(depth); if (selectSubquerys != null) { printLabel(depth, "selectSubquerys: "); selectSubquerys.treePrint(depth + 1); } printLabel(depth, "fromList: "); if (fromList != null) { fromList.treePrint(depth + 1); } if (whereClause != null) { printLabel(depth, "whereClause: "); whereClause.treePrint(depth + 1); } if ((wherePredicates != null) &&wherePredicates.size() > 0) { printLabel(depth, "wherePredicates: "); wherePredicates.treePrint(depth + 1); } if (whereSubquerys != null) { printLabel(depth, "whereSubquerys: "); whereSubquerys.treePrint(depth + 1); } printLabel(depth, "preJoinFL: "); if (preJoinFL != null) { preJoinFL.treePrint(depth + 1); } } } /** * Return the fromList for this SelectNode. * * @return FromList The fromList for this SelectNode. */ public FromList getFromList() { return fromList; } /** * Return the groupByList for this SelectNode. * * @return GroupByList The groupByList for this SelectNode. */ public GroupByList getGroupByList() { return groupByList; } /** * Find colName in the result columns and return underlying columnReference. * Note that this function returns null if there are more than one FromTable * for this SelectNode and the columnReference needs to be directly under * the resultColumn. So having an expression under the resultSet would cause * returning null. * * @param colName Name of the column * * @return ColumnReference ColumnReference to the column, if found */ public ColumnReference findColumnReferenceInResult(String colName) throws StandardException { if (fromList.size() != 1) return null; // This logic is similar to SubQueryNode.singleFromBaseTable(). Refactor FromTable ft = (FromTable) fromList.elementAt(0); if (! ((ft instanceof ProjectRestrictNode) && ((ProjectRestrictNode) ft).getChildResult() instanceof FromBaseTable) && !(ft instanceof FromBaseTable)) return null; // Loop through the result columns looking for a match int rclSize = resultColumns.size(); for (int index = 0; index < rclSize; index++) { ResultColumn rc = (ResultColumn) resultColumns.elementAt(index); if (! (rc.getExpression() instanceof ColumnReference)) return null; ColumnReference crNode = (ColumnReference) rc.getExpression(); if (crNode.columnName.equals(colName)) return (ColumnReference) crNode.getClone(); } return null; } /** * Return the whereClause for this SelectNode. * * @return ValueNode The whereClause for this SelectNode. */ public ValueNode getWhereClause() { return whereClause; } /** * Return the wherePredicates for this SelectNode. * * @return PredicateList The wherePredicates for this SelectNode. */ public PredicateList getWherePredicates() { return wherePredicates; } /** * Return the selectSubquerys for this SelectNode. * * @return SubqueryList The selectSubquerys for this SelectNode. */ public SubqueryList getSelectSubquerys() { return selectSubquerys; } /** * Return the specified aggregate vector for this SelectNode. * * @param clause Which clause to get the aggregate list for * * @return aggregateVector The specified aggregate vector for this SelectNode. */ public Vector getAggregateVector(int clause) { switch (clause) { case ValueNode.IN_SELECT_LIST: return selectAggregates; case ValueNode.IN_WHERE_CLAUSE: if (generatedForHavingClause) { return null; } else { return whereAggregates; } case ValueNode.IN_HAVING_CLAUSE: if (generatedForHavingClause) { return whereAggregates; } else { return null; } default: if (SanityManager.DEBUG) { SanityManager.ASSERT(false, "Unexpected value for clause"); } return null; } } /** * Return the whereSubquerys for this SelectNode. * * @return SubqueryList The whereSubquerys for this SelectNode. */ public SubqueryList getWhereSubquerys() { return whereSubquerys; } /**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -