Class CursorNode

  • All Implemented Interfaces:
    Visitable

    public class CursorNode
    extends DMLStatementNode
    A CursorNode represents a result set that can be returned to a client. A cursor can be a named cursor created by the DECLARE CURSOR statement, or it can be an unnamed cursor associated with a SELECT statement (more precisely, a table expression that returns rows to the client). In the latter case, the cursor does not have a name.
    • Field Detail

      • name

        private java.lang.String name
      • hasJDBClimitClause

        private boolean hasJDBClimitClause
      • statementType

        private java.lang.String statementType
      • updateMode

        private int updateMode
      • needTarget

        private boolean needTarget
      • updatableColumns

        private java.util.List<java.lang.String> updatableColumns
        There can only be a list of updatable columns when FOR UPDATE is specified as part of the cursor specification.
      • statsToUpdate

        private java.util.ArrayList<TableDescriptor> statsToUpdate
        List of TableDescriptors for base tables whose associated indexes should be checked for stale statistics.
      • checkIndexStats

        private boolean checkIndexStats
      • indexOfSessionTableNamesInSavedObjects

        private int indexOfSessionTableNamesInSavedObjects
      • forMergeStatement

        private boolean forMergeStatement
    • Constructor Detail

      • CursorNode

        CursorNode​(java.lang.String statementType,
                   ResultSetNode resultSet,
                   java.lang.String name,
                   OrderByList orderByList,
                   ValueNode offset,
                   ValueNode fetchFirst,
                   boolean hasJDBClimitClause,
                   int updateMode,
                   java.lang.String[] updatableColumns,
                   boolean forMergeStatement,
                   ContextManager cm)
        Constructor for a CursorNode
        Parameters:
        statementType - Type of statement (SELECT, UPDATE, INSERT)
        resultSet - A ResultSetNode specifying the result set for the cursor
        name - The name of the cursor, null if no name
        orderByList - The order by list for the cursor, null if no order by list
        offset - The value of a if present
        fetchFirst - The value of a if present
        hasJDBClimitClause - True if the offset/fetchFirst clauses come from JDBC limit/offset escape syntax
        updateMode - The user-specified update mode for the cursor, for example, CursorNode.READ_ONLY
        updatableColumns - The array of updatable columns specified by the user in the FOR UPDATE clause, null if no updatable columns specified. May only be provided if the updateMode parameter is CursorNode.UPDATE.
        forMergeStatement - True if this cursor is the driving left-join of a MERGE statement
        cm - The context manager
    • 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 StatementNode
        Returns:
        This object as a String
      • updateModeString

        private static java.lang.String updateModeString​(int updateMode)
        Support routine for translating an updateMode identifier to a String
        Parameters:
        updateMode - An updateMode identifier
        Returns:
        A String representing the update mode.
      • 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 DMLStatementNode
        Parameters:
        depth - The depth of this node in the tree
      • bindStatement

        public void bindStatement()
                           throws StandardException
        Bind this CursorNode. This means looking up tables and columns and getting their types, and figuring out the result types of all expressions, as well as doing view resolution, permissions checking, etc. It also includes determining whether an UNSPECIFIED cursor is updatable or not, and verifying that an UPDATE cursor actually is.
        Overrides:
        bindStatement in class StatementNode
        Throws:
        StandardException - Thrown on error
      • collectTablesWithPossiblyStaleStats

        private void collectTablesWithPossiblyStaleStats()
                                                  throws StandardException
        Collects table descriptors for base tables whose index statistics we want to check for staleness (or to create).
        Throws:
        StandardException
      • getSessionSchemaTableNamesForCursor

        protected java.util.ArrayList<java.lang.String> getSessionSchemaTableNamesForCursor()
                                                                                     throws StandardException
        Throws:
        StandardException
      • determineUpdateMode

        private int determineUpdateMode​(DataDictionary dataDictionary)
                                 throws StandardException
        Take a cursor and determine if it is UPDATE or READ_ONLY based on the shape of the cursor specification.

        The following conditions make a cursor read only:

        • if it says FOR READ ONLY
        • if it says ORDER BY
        • if its query specification is not read only. At present this is explicitly tested here, with these conditions. At some future point in time, this checking ought to be moved into the ResultSet nodes themselves. The conditions for a query spec. not to be read only include:
          • if it has a set operation such as UNION or INTERSECT, i.e. does not have a single outermost SELECT
          • if it does not have exactly 1 table in its FROM list; 0 tables would occur if we ever support a SELECT without a FROM e.g., for generating a row without an underlying table (like what we do for an INSERT of a VALUES list); >1 tables occurs when joins are in the tree.
          • if the table in its FROM list is not a base table (REMIND when views/from subqueries are added, this should be relaxed to be that the table is not updatable)
          • if it has a GROUP BY or HAVING (NOTE I am assuming that if and aggregate is detected in a SELECT w/o a GROUP BY, one has been added to show that the whole table is a group)
          • NOTE that cursors are updatable even if none of the columns in the select are updatable -- what they care about is the updatability of the columns of the target table.
        Returns:
        the known update mode for the cursor.
        Throws:
        StandardException - Thrown on error
      • optimizeStatement

        public void optimizeStatement()
                               throws StandardException
        Optimize a DML statement (which is the only type of statement that should need optimizing, I think). This method over-rides the one in QueryTreeNode. This method takes a bound tree, and returns an optimized tree. It annotates the bound tree rather than creating an entirely new tree. Throws an exception if the tree is not bound, or if the binding is out of date.
        Overrides:
        optimizeStatement in class DMLStatementNode
        Throws:
        StandardException - Thrown on error
      • getUpdateBaseTableName

        java.lang.String getUpdateBaseTableName()
      • getUpdateMode

        int getUpdateMode()
      • needsSavepoint

        public boolean needsSavepoint()
        Returns whether or not this Statement requires a set/clear savepoint around its execution. The following statement "types" do not require them: Cursor - unnecessary and won't work in a read only environment Xact - savepoint will get blown away underneath us during commit/rollback
        Overrides:
        needsSavepoint in class StatementNode
        Returns:
        boolean Whether or not this Statement requires a set/clear savepoint
      • getCursorInfo

        public java.lang.Object getCursorInfo()
                                       throws StandardException
        Get information about this cursor. For sps, this is info saved off of the original query tree (the one for the underlying query).
        Overrides:
        getCursorInfo in class StatementNode
        Returns:
        the cursor info
        Throws:
        StandardException - thrown if generation fails
      • bindUpdateColumns

        private void bindUpdateColumns​(FromTable targetTable)
                                throws StandardException
        Bind the update columns by their names to the target table of the cursor specification. Doesn't check for duplicates in the list, although it could... REVISIT: If the list is empty, should it expand it out? at present, it leaves it empty.
        Parameters:
        targetTable - The underlying target table
        Throws:
        StandardException - Thrown on error
      • getXML

        java.lang.String getXML()