Class SelectNode

  • All Implemented Interfaces:
    Visitable

    class SelectNode
    extends ResultSetNode
    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.
    • Field Detail

      • fromList

        FromList fromList
        List of tables in the FROM clause of this SELECT
      • selectAggregates

        private java.util.List<AggregateNode> selectAggregates
        Aggregates in the SELECT list.
      • whereAggregates

        private java.util.List<AggregateNode> whereAggregates
        Aggregates in the WHERE clause.
      • havingAggregates

        private java.util.List<AggregateNode> havingAggregates
        Aggregates in the HAVING clause.
      • whereClause

        ValueNode whereClause
        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).
      • originalWhereClause

        ValueNode originalWhereClause
      • groupByList

        GroupByList groupByList
        List of result columns in GROUP BY clause
      • overridingPlan

        OptimizerPlan overridingPlan
        Full plan for this SELECT as specified in an optimizer override
      • windowFuncCalls

        java.util.List<WindowFunctionNode> windowFuncCalls
        List of window function calls (e.g. ROW_NUMBER, AVG(i), DENSE_RANK).
      • wasGroupBy

        private boolean wasGroupBy
        User specified a group by without aggregates and we turned it into a select distinct
      • orderByQuery

        boolean orderByQuery
      • bindTargetListOnly

        private boolean bindTargetListOnly
      • isDistinct

        private boolean isDistinct
      • orderByAndDistinctMerged

        private boolean orderByAndDistinctMerged
      • originalWhereClauseHadSubqueries

        boolean originalWhereClauseHadSubqueries
      • nestingLevel

        private int nestingLevel
    • Method Detail

      • toString

        public java.lang.String toString()
        Convert this object to a String. See comments in QueryTreeNode.java for how this should be done for tree printing.
        Overrides:
        toString in class ResultSetNode
        Returns:
        This object as a String
      • statementToString

        java.lang.String statementToString()
      • makeDistinct

        void makeDistinct()
      • clearDistinct

        void clearDistinct()
      • hasDistinct

        boolean hasDistinct()
      • printSubNodes

        void printSubNodes​(int depth)
        Prints the sub-nodes of this object. See QueryTreeNode.java for how tree printing is supposed to work.
        Overrides:
        printSubNodes in class ResultSetNode
        Parameters:
        depth - The depth of this node in the tree
      • getFromList

        FromList getFromList()
        Return the fromList for this SelectNode.
        Overrides:
        getFromList in class ResultSetNode
        Returns:
        FromList The fromList for this SelectNode.
      • findColumnReferenceInResult

        ColumnReference findColumnReferenceInResult​(java.lang.String colName)
                                             throws StandardException
        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.
        Parameters:
        colName - Name of the column
        Returns:
        ColumnReference ColumnReference to the column, if found
        Throws:
        StandardException
      • getWhereClause

        ValueNode getWhereClause()
        Return the whereClause for this SelectNode.
        Returns:
        ValueNode The whereClause for this SelectNode.
      • getWherePredicates

        PredicateList getWherePredicates()
        Return the wherePredicates for this SelectNode.
        Returns:
        PredicateList The wherePredicates for this SelectNode.
      • getSelectSubquerys

        SubqueryList getSelectSubquerys()
        Return the selectSubquerys for this SelectNode.
        Returns:
        SubqueryList The selectSubquerys for this SelectNode.
      • getWhereSubquerys

        SubqueryList getWhereSubquerys()
        Return the whereSubquerys for this SelectNode.
        Returns:
        SubqueryList The whereSubquerys for this SelectNode.
      • bindNonVTITables

        ResultSetNode bindNonVTITables​(DataDictionary dataDictionary,
                                       FromList fromListParam)
                                throws StandardException
        Bind the tables in this SelectNode. This includes getting their TableDescriptors from the DataDictionary and numbering the FromTables. NOTE: Because this node represents the top of a new query block, we bind both the non VTI and VTI tables under this node in this method call.
        Overrides:
        bindNonVTITables in class ResultSetNode
        Parameters:
        dataDictionary - The DataDictionary to use for binding
        fromListParam - FromList to use/append to.
        Returns:
        ResultSetNode
        Throws:
        StandardException - Thrown on error
      • bindExpressions

        void bindExpressions​(FromList fromListParam)
                      throws StandardException
        Bind the expressions in this SelectNode. This means binding the sub-expressions, as well as figuring out what the return type is for each expression.
        Overrides:
        bindExpressions in class ResultSetNode
        Parameters:
        fromListParam - FromList to use/append to.
        Throws:
        StandardException - Thrown on error
      • bindExpressionsWithTables

        void bindExpressionsWithTables​(FromList fromListParam)
                                throws StandardException
        Bind the expressions in this ResultSetNode if it has tables. This means binding the sub-expressions, as well as figuring out what the return type is for each expression.
        Overrides:
        bindExpressionsWithTables in class ResultSetNode
        Parameters:
        fromListParam - FromList to use/append to.
        Throws:
        StandardException - Thrown on error
      • bindTargetExpressions

        void bindTargetExpressions​(FromList fromListParam)
                            throws StandardException
        Bind the expressions in the target list. This means binding the sub-expressions, as well as figuring out what the return type is for each expression. This is useful for EXISTS subqueries, where we need to validate the target list before blowing it away and replacing it with a SELECT true.
        Overrides:
        bindTargetExpressions in class ResultSetNode
        Throws:
        StandardException - Thrown on error
      • bindResultColumns

        void bindResultColumns​(FromList fromListParam)
                        throws StandardException
        Bind the result columns of this ResultSetNode when there is no base table to bind them to. This is useful for SELECT statements, where the result columns get their types from the expressions that live under them.
        Overrides:
        bindResultColumns in class ResultSetNode
        Parameters:
        fromListParam - FromList to use/append to.
        Throws:
        StandardException - Thrown on error
      • bindResultColumns

        void bindResultColumns​(TableDescriptor targetTableDescriptor,
                               FromVTI targetVTI,
                               ResultColumnList targetColumnList,
                               DMLStatementNode statement,
                               FromList fromListParam)
                        throws StandardException
        Bind the result columns for this ResultSetNode to a base table. This is useful for INSERT and UPDATE statements, where the result columns get their types from the table being updated or inserted into. If a result column list is specified, then the verification that the result column list does not contain any duplicates will be done when binding them by name.
        Overrides:
        bindResultColumns in class ResultSetNode
        Parameters:
        targetTableDescriptor - The TableDescriptor for the table being updated or inserted into
        targetColumnList - For INSERT statements, the user does not have to supply column names (for example, "insert into t values (1,2,3)". When this parameter is null, it means that the user did not supply column names, and so the binding should be done based on order. When it is not null, it means do the binding by name, not position.
        statement - Calling DMLStatementNode (Insert or Update)
        fromListParam - FromList to use/append to.
        Throws:
        StandardException - Thrown on error
      • pushExpressionsIntoSelect

        void pushExpressionsIntoSelect​(Predicate predicate)
                                throws StandardException
        Push an expression into this SELECT (and possibly down into one of the tables in the FROM list). This is useful when trying to push predicates into unflattened views or derived tables.
        Parameters:
        predicate - The predicate that we attempt to push
        Throws:
        StandardException - Thrown on error
      • verifySelectStarSubquery

        void verifySelectStarSubquery​(FromList outerFromList,
                                      int subqueryType)
                               throws StandardException
        Verify that a SELECT * is valid for this type of subquery.
        Overrides:
        verifySelectStarSubquery in class ResultSetNode
        Parameters:
        outerFromList - The FromList from the outer query block(s)
        subqueryType - The subquery type
        Throws:
        StandardException - Thrown on error
      • getFromTableByName

        FromTable getFromTableByName​(java.lang.String name,
                                     java.lang.String schemaName,
                                     boolean exactMatch)
                              throws StandardException
        Determine whether or not the specified name is an exposed name in the current query block.
        Overrides:
        getFromTableByName in class ResultSetNode
        Parameters:
        name - The specified name to search for as an exposed name.
        schemaName - Schema name, if non-null.
        exactMatch - Whether or not we need an exact match on specified schema and table names or match on table id.
        Returns:
        The FromTable, if any, with the exposed name.
        Throws:
        StandardException - Thrown on error
      • rejectParameters

        void rejectParameters()
                       throws StandardException
        Check for (and reject) ? parameters directly under the ResultColumns. This is done for SELECT statements.
        Overrides:
        rejectParameters in class ResultSetNode
        Throws:
        StandardException - Thrown if a ? parameter found directly under a ResultColumn
      • pushOrderByList

        void pushOrderByList​(OrderByList orderByList)
        Push the order by list down from the cursor node into its child result set so that the optimizer has all of the information that it needs to consider sort avoidance.
        Overrides:
        pushOrderByList in class ResultSetNode
        Parameters:
        orderByList - The order by list
      • pushOffsetFetchFirst

        void pushOffsetFetchFirst​(ValueNode offset,
                                  ValueNode fetchFirst,
                                  boolean hasJDBClimitClause)
        Push down the offset and fetch first parameters to this node.
        Overrides:
        pushOffsetFetchFirst in class ResultSetNode
        Parameters:
        offset - the OFFSET, if any
        fetchFirst - the OFFSET FIRST, if any
        hasJDBClimitClause - true if the clauses were added by (and have the semantics of) a JDBC limit clause
      • preprocess

        ResultSetNode preprocess​(int numTables,
                                 GroupByList gbl,
                                 FromList fl)
                          throws StandardException
        Put a ProjectRestrictNode on top of each FromTable in the FromList. ColumnReferences must continue to point to the same ResultColumn, so that ResultColumn must percolate up to the new PRN. However, that ResultColumn will point to a new expression, a VirtualColumnNode, which points to the FromTable and the ResultColumn that is the source for the ColumnReference. (The new PRN will have the original of the ResultColumnList and the ResultColumns from that list. The FromTable will get shallow copies of the ResultColumnList and its ResultColumns. ResultColumn.expression will remain at the FromTable, with the PRN getting a new VirtualColumnNode for each ResultColumn.expression.) We then project out the non-referenced columns. If there are no referenced columns, then the PRN's ResultColumnList will consist of a single ResultColumn whose expression is 1.
        Overrides:
        preprocess in class ResultSetNode
        Parameters:
        numTables - The number of tables in the DML Statement
        gbl - The outer group by list, if any
        fl - The from list, if any
        Returns:
        The generated ProjectRestrictNode atop the original FromTable.
        Throws:
        StandardException - Thrown on error
      • performTransitiveClosure

        private void performTransitiveClosure​(int numTables)
                                       throws StandardException
        Peform the various types of transitive closure on the where clause. The 2 types are transitive closure on join clauses and on search clauses. Join clauses will be processed first to maximize benefit for search clauses.
        Parameters:
        numTables - The number of tables in the query
        Throws:
        StandardException - Thrown on error
      • addNewPredicate

        ResultSetNode addNewPredicate​(Predicate predicate)
                               throws StandardException
        Add a new predicate to the list. This is useful when doing subquery transformations, when we build a new predicate with the left side of the subquery operator and the subquery's result column.
        Overrides:
        addNewPredicate in class ResultSetNode
        Parameters:
        predicate - The predicate to add
        Returns:
        ResultSetNode The new top of the tree.
        Throws:
        StandardException - Thrown on error
      • flattenableInFromSubquery

        boolean flattenableInFromSubquery​(FromList fromList)
        Evaluate whether or not the subquery in a FromSubquery is flattenable. Currently, a FSqry is flattenable if all of the following are true: o Subquery is a SelectNode. (ie, not a RowResultSetNode or a UnionNode) o It contains a single table in its FROM list. o It contains no subqueries in the SELECT list. o It does not contain a group by or having clause o It does not contain aggregates. o It is not a DISTINCT. o It does not have an ORDER BY clause (pushed from FromSubquery).
        Overrides:
        flattenableInFromSubquery in class ResultSetNode
        Parameters:
        fromList - The outer from list
        Returns:
        boolean Whether or not the FromSubquery is flattenable.
      • genProjectRestrict

        ResultSetNode genProjectRestrict​(int origFromListSize)
                                  throws StandardException
        Replace this SelectNode with a ProjectRestrictNode, since it has served its purpose.
        Overrides:
        genProjectRestrict in class ResultSetNode
        Parameters:
        origFromListSize - The size of the original FROM list, before generation of join tree.
        Returns:
        ResultSetNode new ResultSetNode atop the query tree.
        Throws:
        StandardException - Thrown on error
      • isOrderedResult

        private boolean isOrderedResult​(ResultColumnList resultColumns,
                                        ResultSetNode newTopRSN,
                                        boolean permuteOrdering)
                                 throws StandardException
        Is the result of this node an ordered result set. An ordered result set means that the results from this node will come in a known sorted order. This means that the data is ordered according to the order of the elements in the RCL. Today, the data is considered ordered if: o The RCL is composed entirely of CRs or ConstantNodes o The underlying tree is ordered on the CRs in the order in which they appear in the RCL, taking equality predicates into account. Future Enhancements: o The prefix will not be required to be in order. (We will need to reorder the RCL and generate a PRN with an RCL in the expected order.)
        Returns:
        boolean Whether or not this node returns an ordered result set.
        Throws:
        StandardException - Thrown on error
      • ensurePredicateList

        ResultSetNode ensurePredicateList​(int numTables)
                                   throws StandardException
        Ensure that the top of the RSN tree has a PredicateList.
        Overrides:
        ensurePredicateList in class ResultSetNode
        Parameters:
        numTables - The number of tables in the query.
        Returns:
        ResultSetNode A RSN tree with a node which has a PredicateList on top.
        Throws:
        StandardException - Thrown on error
      • optimize

        ResultSetNode optimize​(DataDictionary dataDictionary,
                               PredicateList predicateList,
                               double outerRows)
                        throws StandardException
        Optimize this SelectNode. This means choosing the best access path for each table, among other things.
        Overrides:
        optimize in class ResultSetNode
        Parameters:
        dataDictionary - The DataDictionary to use for optimization
        predicateList - The predicate list to optimize against
        outerRows - The number of outer joining rows
        Returns:
        ResultSetNode The top of the optimized tree
        Throws:
        StandardException - Thrown on error
      • modifyAccessPaths

        ResultSetNode modifyAccessPaths​(PredicateList predList)
                                 throws StandardException
        Modify the access paths according to the decisions the optimizer made. This can include adding project/restrict nodes, index-to-base-row nodes, etc.
        Overrides:
        modifyAccessPaths in class ResultSetNode
        Parameters:
        predList - A list of optimizable predicates that should be pushed to this ResultSetNode, as determined by optimizer.
        Returns:
        The modified query tree
        Throws:
        StandardException - Thrown on error
      • getCursorTargetTable

        FromTable getCursorTargetTable()
        Assumes that isCursorUpdatable has been called, and that it is only called for updatable cursors.
        Overrides:
        getCursorTargetTable in class ResultSetNode
      • referencesTarget

        boolean referencesTarget​(java.lang.String name,
                                 boolean baseTable)
                          throws StandardException
        Search to see if a query references the specifed table name.
        Overrides:
        referencesTarget in class ResultSetNode
        Parameters:
        name - Table name (String) to search for.
        baseTable - Whether or not name is for a base table
        Returns:
        true if found, else false
        Throws:
        StandardException - Thrown on error
      • subqueryReferencesTarget

        boolean subqueryReferencesTarget​(java.lang.String name,
                                         boolean baseTable)
                                  throws StandardException
        Return whether or not this ResultSetNode contains a subquery with a reference to the specified target table.
        Overrides:
        subqueryReferencesTarget in class ResultSetNode
        Parameters:
        name - The table name.
        baseTable - Whether or not table is a base table.
        Returns:
        boolean Whether or not a reference to the table was found.
        Throws:
        StandardException - Thrown on error
      • decrementLevel

        void decrementLevel​(int decrement)
        Decrement (query block) level (0-based) for all of the tables in this ResultSet tree. This is useful when flattening a subquery.
        Specified by:
        decrementLevel in class ResultSetNode
        Parameters:
        decrement - The amount to decrement by.
      • uniqueSubquery

        boolean uniqueSubquery​(boolean additionalEQ)
                        throws StandardException
        Determine whether or not this subquery, the SelectNode is in a subquery, can be flattened into the outer query block based on a uniqueness condition. A uniqueness condition exists when we can guarantee that at most 1 row will qualify in each table in the subquery. 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 a column from the same table is a superset of any unique index on the table) or an ExistsBaseTable.
        Parameters:
        additionalEQ - Whether or not the column returned by this select, if it is a ColumnReference, is in an equality comparison.
        Returns:
        Whether or not this subquery can be flattened based on a uniqueness condition.
        Throws:
        StandardException - Thrown on error
      • updateTargetLockMode

        int updateTargetLockMode()
        Get the lock mode for the target of an update statement (a delete or update). The update mode will always be row for CurrentOfNodes. It will be table if there is no where clause.
        Overrides:
        updateTargetLockMode in class ResultSetNode
        Returns:
        The lock mode
        See Also:
        TransactionController
      • returnsAtMostOneRow

        boolean returnsAtMostOneRow()
        Return whether or not this ResultSet tree is guaranteed to return at most 1 row based on heuristics. (A RowResultSetNode and a SELECT with a non-grouped aggregate will return at most 1 row.)
        Overrides:
        returnsAtMostOneRow in class ResultSetNode
        Returns:
        Whether or not this ResultSet tree is guaranteed to return at most 1 row based on heuristics.
      • hasAggregatesInSelectList

        boolean hasAggregatesInSelectList()
        Returns:
        true if there are aggregates in the select list.
      • hasWindows

        boolean hasWindows()
        Used by SubqueryNode to avoid flattening of a subquery if a window is defined on it. Note that any inline window definitions should have been collected from both the selectList and orderByList at the time this method is called, so the windows list is complete. This is true after preprocess is completed.
        Returns:
        true if this select node has any windows on it
      • replaceOrForbidDefaults

        void replaceOrForbidDefaults​(TableDescriptor ttd,
                                     ResultColumnList tcl,
                                     boolean allowDefaults)
                              throws StandardException
        Replace any DEFAULTs with the associated tree for the default if allowed, or flag (when inside top level set operator nodes). Subqueries are checked for illegal DEFAULTs elsewhere. A no-op for SelectNode.
        Overrides:
        replaceOrForbidDefaults in class ResultSetNode
        Parameters:
        ttd - The TableDescriptor for the target table.
        tcl - The RCL for the target table.
        allowDefaults - true if allowed
        Throws:
        StandardException - Thrown on error
      • hasOffsetFetchFirst

        boolean hasOffsetFetchFirst()