Class UpdateNode

  • All Implemented Interfaces:
    Visitable

    public final class UpdateNode
    extends DMLModGeneratedColumnsStatementNode
    An UpdateNode represents an UPDATE statement. It is the top node of the query tree for that statement. For positioned update, there may be no from table specified. The from table will be derived from the cursor specification of the named cursor.
    • Field Detail

      • changedColumnIds

        int[] changedColumnIds
      • deferred

        boolean deferred
      • checkConstraints

        ValueNode checkConstraints
      • targetTable

        protected FromTable targetTable
      • positionedUpdate

        protected boolean positionedUpdate
    • Constructor Detail

      • UpdateNode

        UpdateNode​(TableName targetTableName,
                   ResultSetNode resultSet,
                   MatchingClauseNode matchingClause,
                   ContextManager cm)
        Constructor for an UpdateNode.
        Parameters:
        targetTableName - The name of the table to update
        resultSet - The ResultSet that we will generate
        matchingClause - Non-null if this DML is part of a MATCHED clause 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
      • 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 DMLModStatementNode
        Parameters:
        depth - The depth of this node in the tree
      • bindStatement

        public void bindStatement()
                           throws StandardException
        Bind this UpdateNode. 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.

        Binding an update will also massage the tree so that the ResultSetNode has a set of columns to contain the old row value, followed by a set of columns to contain the new row value, followed by a column to contain the RowLocation of the row to be updated.

        Overrides:
        bindStatement in class StatementNode
        Throws:
        StandardException - Thrown on error
      • getPrivType

        int getPrivType()
        Description copied from class: DMLStatementNode
        Return default privilege needed for this node. Other DML nodes can override this method to set their own default privilege.
        Overrides:
        getPrivType in class DMLStatementNode
        Returns:
        true if the statement is atomic
      • getExplicitlySetColumns

        private java.util.ArrayList<java.lang.String> getExplicitlySetColumns()
                                                                       throws StandardException
        Get the names of the explicitly set columns, that is, the columns on the left side of SET operators.
        Throws:
        StandardException
      • associateAddedColumns

        private void associateAddedColumns()
                                    throws StandardException
        Associate all added columns with the TARGET table of the enclosing MERGE statement.
        Throws:
        StandardException
      • tagOriginalResultSetColumns

        private void tagOriginalResultSetColumns()
                                          throws StandardException
        Tag the original columns mentioned in the result list.
        Throws:
        StandardException
      • collectAllCastNodes

        private java.util.List<CastNode> collectAllCastNodes()
                                                      throws StandardException
        Collect all of the CastNodes in the WHERE clause and on the right side of SET operators. Later on, we will need to add permissions for all UDTs mentioned by these nodes.
        Throws:
        StandardException
      • tagPrivilegedNodes

        private void tagPrivilegedNodes()
                                 throws StandardException
        Tag all of the nodes which may require privilege checks. These are various QueryTreeNodes in the WHERE clause and on the right side of SET operators.
        Throws:
        StandardException
      • addUpdatePriv

        private void addUpdatePriv​(java.util.ArrayList<java.lang.String> explicitlySetColumns)
                            throws StandardException
        Add UPDATE_PRIV on all columns on the left side of SET operators.
        Throws:
        StandardException
      • setDeferredForUpdateOfIndexColumn

        protected void setDeferredForUpdateOfIndexColumn()
        Updates are deferred if they update a column in the index used to scan the table being updated.
      • generate

        void generate​(ActivationClassBuilder acb,
                      MethodBuilder mb)
               throws StandardException
        Code generation for update. The generated code will contain: o A static member for the (xxx)ResultSet with the RowLocations and new update values o The static member will be assigned the appropriate ResultSet within the nested calls to get the ResultSets. (The appropriate cast to the (xxx)ResultSet will be generated.) o The CurrentRowLocation() in SelectNode's select list will generate a new method for returning the RowLocation as well as a call to that method when generating the (xxx)ResultSet.
        Overrides:
        generate in class QueryTreeNode
        Parameters:
        acb - The ActivationClassBuilder for the class being built
        mb - The method for the execute() method to be built
        Throws:
        StandardException - Thrown on error
      • getStatementType

        protected final int getStatementType()
        Return the type of statement, something from StatementType.
        Overrides:
        getStatementType in class QueryTreeNode
        Returns:
        the type of statement
      • getReadMap

        FormatableBitSet getReadMap​(DataDictionary dd,
                                    TableDescriptor baseTable,
                                    ResultColumnList updateColumnList,
                                    ColumnDescriptorList affectedGeneratedColumns)
                             throws StandardException
        Gets the map of all columns which must be read out of the base table. These are the columns needed to
          :
        • maintain indices
        • maintain foreign keys
        • maintain generated columns
        • support Replication's Delta Optimization

        The returned map is a FormatableBitSet with 1 bit for each column in the table plus an extra, unsued 0-bit. If a 1-based column id must be read from the base table, then the corresponding 1-based bit is turned ON in the returned FormatableBitSet.

        NOTE: this method is not expected to be called when all columns are being updated (i.e. updateColumnList is null).

        Parameters:
        dd - the data dictionary to look in
        baseTable - the base table descriptor
        updateColumnList - the rcl for the update. CANNOT BE NULL
        affectedGeneratedColumns - columns whose generation clauses mention columns being updated
        Returns:
        a FormatableBitSet of columns to be read out of the base table
        Throws:
        StandardException - Thrown on error
      • getChangedColumnIds

        private int[] getChangedColumnIds​(ResultColumnList rcl)
        Construct the changedColumnIds array. Note we sort its entries by columnId.
      • getUpdateReadMap

        static FormatableBitSet getUpdateReadMap​(DataDictionary dd,
                                                 TableDescriptor baseTable,
                                                 ResultColumnList updateColumnList,
                                                 java.util.List<ConglomerateDescriptor> conglomerates,
                                                 ConstraintDescriptorList relevantConstraints,
                                                 TriggerDescriptorList relevantTriggers,
                                                 boolean[] needsDeferredProcessing,
                                                 ColumnDescriptorList affectedGeneratedColumns)
                                          throws StandardException
        Builds a bitmap of all columns which should be read from the Store in order to satisfy an UPDATE statement. Is passed a list of updated columns. Does the following: 1) finds all indices which overlap the updated columns 2) adds the index columns to a bitmap of affected columns 3) adds the index descriptors to a list of conglomerate descriptors. 4) finds all constraints which overlap the updated columns and adds the constrained columns to the bitmap 5) finds all triggers which overlap the updated columns. 6) Go through all those triggers from step 5 and for each one of those triggers, follow the rules below to decide which columns should be read. Rule1)If trigger column information is null, then read all the columns from trigger table into memory irrespective of whether there is any trigger action column information. 2 egs of such triggers create trigger tr1 after update on t1 for each row values(1); create trigger tr1 after update on t1 referencing old as oldt for each row insert into t2 values(2,oldt.j,-2); Rule2)If trigger column information is available but no trigger action column information is found and no REFERENCES clause is used for the trigger, then read all the columns identified by the trigger column. eg create trigger tr1 after update of c1 on t1 for each row values(1); Rule3)If trigger column information and trigger action column information both are not null, then only those columns will be read into memory. This is possible only for triggers created in release 10.9 or higher(with the exception of 10.7.1.1 where we did collect that information but because of corruption caused by those changes, we do not use the information collected by 10.7). Starting 10.9, we are collecting trigger action column informatoin so we can be smart about what columns get read during trigger execution. eg create trigger tr1 after update of c1 on t1 referencing old as oldt for each row insert into t2 values(2,oldt.j,-2); Rule4)If trigger column information is available but no trigger action column information is found but REFERENCES clause is used for the trigger, then read all the columns from the trigger table. This will cover soft-upgrade scenario for triggers created pre-10.9. eg trigger created prior to 10.9 create trigger tr1 after update of c1 on t1 referencing old as oldt for each row insert into t2 values(2,oldt.j,-2); 7) adds the triggers to an evolving list of triggers 8) finds all generated columns whose generation clauses mention the updated columns and adds all of the mentioned columns
        Parameters:
        dd - Data Dictionary
        baseTable - Table on which update is issued
        updateColumnList - a list of updated columns
        conglomerates - OUT: list of affected indices
        relevantConstraints - IN/OUT. Empty list is passed in. We hang constraints on it as we go.
        relevantTriggers - IN/OUT. Passed in as an empty list. Filled in as we go.
        needsDeferredProcessing - IN/OUT. true if the statement already needs deferred processing. set while evaluating this routine if a trigger or constraint requires deferred processing
        affectedGeneratedColumns - columns whose generation clauses mention updated columns
        Returns:
        a FormatableBitSet of columns to be read out of the base table
        Throws:
        StandardException - Thrown on error
      • addGeneratedColumns

        private void addGeneratedColumns​(TableDescriptor baseTable,
                                         ResultSetNode updateSet,
                                         ColumnDescriptorList affectedGeneratedColumns,
                                         ColumnDescriptorList addedGeneratedColumns)
                                  throws StandardException
        Add generated columns to the update list as necessary. We add any column whose generation clause mentions columns already in the update list. We fill in a list of all generated columns affected by this update. We also fill in a list of all generated columns which we added to the update list.
        Throws:
        StandardException
      • checkTableNameAndScrubResultColumns

        private void checkTableNameAndScrubResultColumns​(ResultColumnList rcl)
                                                  throws StandardException
        Check table name and then clear it from the result set columns.
        Throws:
        StandardExcepion - if invalid column/table is specified.
        StandardException
      • normalizeSynonymColumns

        private void normalizeSynonymColumns​(ResultColumnList rcl,
                                             FromTable fromTable)
                                      throws StandardException
        Normalize synonym column references to have the name of the base table.
        Parameters:
        rcl - The result column list of the target table
        fromTable - The table name to set the column refs to
        Throws:
        StandardException - Thrown on error
      • forbidGenerationOverrides

        private void forbidGenerationOverrides​(ResultColumnList targetRCL,
                                               ColumnDescriptorList addedGeneratedColumns)
                                        throws StandardException
        Do not allow generation clauses to be overriden. Throws an exception if the user attempts to override the value of a generated column. The only value allowed in a generated column is DEFAULT. We will use addedGeneratedColumns list to pass through the generated columns which have already been added to the update list.
        Parameters:
        targetRCL - the row in the table being UPDATEd
        addedGeneratedColumns - generated columns which the compiler added earlier on
        Throws:
        StandardException - on error