You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by rh...@apache.org on 2022/08/16 22:10:17 UTC

svn commit: r1903468 [2/5] - in /db/derby/code/trunk/java/org.apache.derby.engine/org/apache/derby/impl/sql: compile/ execute/

Modified: db/derby/code/trunk/java/org.apache.derby.engine/org/apache/derby/impl/sql/compile/ResultColumn.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/org.apache.derby.engine/org/apache/derby/impl/sql/compile/ResultColumn.java?rev=1903468&r1=1903467&r2=1903468&view=diff
==============================================================================
--- db/derby/code/trunk/java/org.apache.derby.engine/org/apache/derby/impl/sql/compile/ResultColumn.java (original)
+++ db/derby/code/trunk/java/org.apache.derby.engine/org/apache/derby/impl/sql/compile/ResultColumn.java Tue Aug 16 22:10:16 2022
@@ -62,29 +62,29 @@ import org.apache.derby.iapi.util.String
  */
 
 class ResultColumn extends ValueNode
-                implements ResultColumnDescriptor, Comparable<ResultColumn>
+    implements ResultColumnDescriptor, Comparable<ResultColumn>
 {
-	/* _underlyingName and _derivedColumnName should point to the same string, unless there is a
-	 * derived column list, in which case _underlyingName will point to the underlying name
-	 * and _derivedColumnName will point to the name from the derived column list.
-	 */
-	private String			_underlyingName; // name from the actual data source
-	private String			_derivedColumnName;
-	private String			_unqualifiedTableName;
-	private String			_unqualifiedSourceTableName;
-	//Used by metadata api ResultSetMetaData.getSchemaName to get a column's table's schema.
-	private String			_sourceSchemaName;
-	private ValueNode		_expression;
-	private ColumnDescriptor	_columnDescriptor;
-	private boolean			_isGenerated;
-	private boolean			_isGeneratedForUnmatchedColumnInInsert;
-	private boolean			_isGroupingColumn;
-	private boolean			_isReferenced;
-	private boolean			_isRedundant;
-	private boolean			_isNameGenerated;
-	private boolean			_updated;
-	private boolean			_updatableByCursor;
-	private boolean defaultColumn;
+    /* _underlyingName and _derivedColumnName should point to the same string, unless there is a
+     * derived column list, in which case _underlyingName will point to the underlying name
+     * and _derivedColumnName will point to the name from the derived column list.
+     */
+    private String			_underlyingName; // name from the actual data source
+    private String			_derivedColumnName;
+    private String			_unqualifiedTableName;
+    private String			_unqualifiedSourceTableName;
+    //Used by metadata api ResultSetMetaData.getSchemaName to get a column's table's schema.
+    private String			_sourceSchemaName;
+    private ValueNode		_expression;
+    private ColumnDescriptor	_columnDescriptor;
+    private boolean			_isGenerated;
+    private boolean			_isGeneratedForUnmatchedColumnInInsert;
+    private boolean			_isGroupingColumn;
+    private boolean			_isReferenced;
+    private boolean			_isRedundant;
+    private boolean			_isNameGenerated;
+    private boolean			_updated;
+    private boolean			_updatableByCursor;
+    private boolean defaultColumn;
     private boolean wasDefault;
     //Following 2 fields have been added for DERBY-4631. 
     //rightOuterJoinUsingClause will be set to true for following 2 cases
@@ -107,20 +107,20 @@ class ResultColumn extends ValueNode
     // time.
     private JoinNode joinResultSet = null;
 
-	// tells us if this ResultColumn is a placeholder for a generated
-	// autoincrement value for an insert statement.
-	private boolean			_autoincrementGenerated;
-
-	// tells us if this ResultColumn represents an autoincrement column in a
-	// base table.
-	private boolean 		_autoincrement;
-
-	/* ResultSetNumber for the ResultSet (at generate() time) that we belong to */
-	private int		resultSetNumber = -1;
-	private ColumnReference _reference; // used to verify quals at bind time, if given.
+    // tells us if this ResultColumn is a placeholder for a generated
+    // autoincrement value for an insert statement.
+    private boolean			_autoincrementGenerated;
+
+    // tells us if this ResultColumn represents an autoincrement column in a
+    // base table.
+    private boolean 		_autoincrement;
+
+    /* ResultSetNumber for the ResultSet (at generate() time) that we belong to */
+    private int		resultSetNumber = -1;
+    private ColumnReference _reference; // used to verify quals at bind time, if given.
 
-	/* virtualColumnId is the ResultColumn's position (1-based) within the ResultSet */
-	private int		virtualColumnId;
+    /* virtualColumnId is the ResultColumn's position (1-based) within the ResultSet */
+    private int		virtualColumnId;
 
     ResultColumn(ContextManager cm) {
         super(cm);
@@ -132,9 +132,9 @@ class ResultColumn extends ValueNode
      * @param cm context manager
      */
     ResultColumn(
-            String underlyingName,
-            ValueNode expression,
-            ContextManager cm) throws StandardException {
+        String underlyingName,
+        ValueNode expression,
+        ContextManager cm) throws StandardException {
         super(cm);
         setTypeExpressionAndDefault(expression);
         _underlyingName = underlyingName;
@@ -148,9 +148,9 @@ class ResultColumn extends ValueNode
      * @throws StandardException
      */
     ResultColumn(
-            ColumnReference cr,
-            ValueNode expression,
-            ContextManager cm) throws StandardException {
+        ColumnReference cr,
+        ValueNode expression,
+        ContextManager cm) throws StandardException {
         super(cm);
         setTypeExpressionAndDefault(expression);
         _underlyingName = cr.getColumnName();
@@ -168,9 +168,9 @@ class ResultColumn extends ValueNode
      * @throws StandardException
      */
     ResultColumn(
-            ColumnDescriptor cd,
-            ValueNode expression,
-            ContextManager cm) throws StandardException {
+        ColumnDescriptor cd,
+        ValueNode expression,
+        ContextManager cm) throws StandardException {
         super(cm);
         setTypeExpressionAndDefault(expression);
         _underlyingName = cd.getColumnName();
@@ -187,9 +187,9 @@ class ResultColumn extends ValueNode
      * @throws StandardException
      */
     ResultColumn(
-            DataTypeDescriptor dtd,
-            ValueNode expression,
-            ContextManager cm) throws StandardException {
+        DataTypeDescriptor dtd,
+        ValueNode expression,
+        ContextManager cm) throws StandardException {
         super(cm);
         setTypeExpressionAndDefault(expression);
         setType(dtd);
@@ -203,7 +203,7 @@ class ResultColumn extends ValueNode
         setExpression(expression);
 
         if (expression != null &&
-                expression instanceof DefaultNode) {
+            expression instanceof DefaultNode) {
             // This result column represents a <default> keyword in an insert or
             // update statement
             defaultColumn = true;
@@ -211,943 +211,897 @@ class ResultColumn extends ValueNode
     }
 
     /**
-	 * Returns TRUE if the ResultColumn is join column for a RIGHT OUTER 
-	 *  JOIN with USING/NATURAL. More comments at the top of this class
-	 *  where rightOuterJoinUsingClause is defined.
-	 */
-    boolean isRightOuterJoinUsingClause()
-	{
-		return rightOuterJoinUsingClause;
-	}
-
-	/**
-	 * Will be set to TRUE if this ResultColumn is join column for a 
-	 *  RIGHT OUTER JOIN with USING/NATURAL. More comments at the top of 
-	 *  this class where rightOuterJoinUsingClause is defined. 2 eg cases
-	 * 1)select c from t1 right join t2 using (c)
-	 *   This case is talking about column c as in "select c"
-	 * 2)select c from t1 right join t2 using (c)
-	 *   For "using(c)", a join predicate will be created as follows
-	 *     t1.c=t2.c
-	 *   This case is talking about column t2.c of the join predicate.
-	 *   
-	 * This method gets called for Case 1) during the bind phase of
-	 *  ResultColumn(ResultColumn.bindExpression).
-	 *   
-	 * This method gets called for Case 2) during the bind phase of
-	 *  JoinNode while we are going through the list of join columns
-	 *  for a NATURAL JOIN or user supplied list of join columns for
-	 *  USING clause(JoinNode.getMatchingColumn).
-	 *  
-	 * @param value True/False
-	 */
-    void setRightOuterJoinUsingClause(boolean value)
-	{
-		rightOuterJoinUsingClause = value;
-	}
-
-	/**
-	 * Returns a non-null value if the ResultColumn represents the join
-	 * column which is part of the SELECT list of a RIGHT OUTER JOIN with
-	 * USING/NATURAL. eg
-	 *      select c from t1 right join t2 using (c)
-	 * The join column we are talking about is column c as in "select c"
-	 * The return value of following method will show the association of this 
-	 * result column to the join resultset created for the RIGHT OUTER JOIN 
-	 * with USING/NATURAL. This information along with 
-	 * rightOuterJoinUsingClause will be used during the code generation 
-	 * time.
-	 */
+     * Returns TRUE if the ResultColumn is join column for a RIGHT OUTER 
+     *  JOIN with USING/NATURAL. More comments at the top of this class
+     *  where rightOuterJoinUsingClause is defined.
+     */
+    boolean isRightOuterJoinUsingClause() {
+        return rightOuterJoinUsingClause;
+    }
+
+    /**
+     * Will be set to TRUE if this ResultColumn is join column for a 
+     *  RIGHT OUTER JOIN with USING/NATURAL. More comments at the top of 
+     *  this class where rightOuterJoinUsingClause is defined. 2 eg cases
+     * 1)select c from t1 right join t2 using (c)
+     *   This case is talking about column c as in "select c"
+     * 2)select c from t1 right join t2 using (c)
+     *   For "using(c)", a join predicate will be created as follows
+     *     t1.c=t2.c
+     *   This case is talking about column t2.c of the join predicate.
+     *   
+     * This method gets called for Case 1) during the bind phase of
+     *  ResultColumn(ResultColumn.bindExpression).
+     *   
+     * This method gets called for Case 2) during the bind phase of
+     *  JoinNode while we are going through the list of join columns
+     *  for a NATURAL JOIN or user supplied list of join columns for
+     *  USING clause(JoinNode.getMatchingColumn).
+     *  
+     * @param value True/False
+     */
+    void setRightOuterJoinUsingClause(boolean value) {
+        rightOuterJoinUsingClause = value;
+    }
+
+    /**
+     * Returns a non-null value if the ResultColumn represents the join
+     * column which is part of the SELECT list of a RIGHT OUTER JOIN with
+     * USING/NATURAL. eg
+     *      select c from t1 right join t2 using (c)
+     * The join column we are talking about is column c as in "select c"
+     * The return value of following method will show the association of this 
+     * result column to the join resultset created for the RIGHT OUTER JOIN 
+     * with USING/NATURAL. This information along with 
+     * rightOuterJoinUsingClause will be used during the code generation 
+     * time.
+     */
     JoinNode getJoinResultSet() {
-		return joinResultSet;
-	}
+        return joinResultSet;
+    }
 
-	/**
-	 * This method gets called during the bind phase of a ResultColumn if it
-	 *  is determined that the ResultColumn represents the join column which
-	 *  is part of the SELECT list of a RIGHT OUTER JOIN with 
-	 *  USING/NATURAL. eg
-	 *      select c from t1 right join t2 using (c)
-	 *   This case is talking about column c as in "select c"
-	 * @param resultSet - The ResultColumn belongs to this JoinNode
-	 */
-    void setJoinResultset(JoinNode resultSet)
-	{
-		joinResultSet = resultSet;
-	}
+    /**
+     * This method gets called during the bind phase of a ResultColumn if it
+     *  is determined that the ResultColumn represents the join column which
+     *  is part of the SELECT list of a RIGHT OUTER JOIN with 
+     *  USING/NATURAL. eg
+     *      select c from t1 right join t2 using (c)
+     *   This case is talking about column c as in "select c"
+     * @param resultSet - The ResultColumn belongs to this JoinNode
+     */
+    void setJoinResultset(JoinNode resultSet) {
+        joinResultSet = resultSet;
+    }
 	
-	/**
-	 * Returns TRUE if the ResultColumn is standing in for a DEFAULT keyword in
-	 * an insert/update statement.
-	 */
-    boolean isDefaultColumn()
-	{
-		return defaultColumn;
-	}
-
-    void setDefaultColumn(boolean value)
-	{
-		defaultColumn = value;
-	}
-
-	/**
-	 * Returns TRUE if the ResultColumn used to stand in for a DEFAULT keyword in
-	 * an insert/update statement.
-	 */
-    boolean wasDefaultColumn()
-	{
-		return wasDefault;
-	}
-
-    void setWasDefaultColumn(boolean value)
-	{
-		wasDefault = value;
-	}
-
-	/**
-	 * Return TRUE if this result column matches the provided column name.
-	 *
-	 * This function is used by ORDER BY column resolution. For the
-	 * ORDER BY clause, Derby will prefer to match on the column's
-	 * alias (_derivedColumnName), but will also successfully match on the
-	 * underlying column name. Thus the following statements are
-	 * treated equally:
-	 *  select name from person order by name;
-	 *  select name as person_name from person order by name;
-	 *  select name as person_name from person order by person_name;
-	 * See DERBY-2351 for more discussion.
-	 */
-	boolean columnNameMatches(String columnName)
-	{
-		return columnName.equals(_derivedColumnName) ||
-			columnName.equals( _underlyingName ) ||
-			columnName.equals(getSourceColumnName());
-	}
+    /**
+     * Returns TRUE if the ResultColumn is standing in for a DEFAULT keyword in
+     * an insert/update statement.
+     */
+    boolean isDefaultColumn() {
+        return defaultColumn;
+    }
+
+    void setDefaultColumn(boolean value) {
+        defaultColumn = value;
+    }
+
+    /**
+     * Returns TRUE if the ResultColumn used to stand in for a DEFAULT keyword in
+     * an insert/update statement.
+     */
+    boolean wasDefaultColumn() {
+        return wasDefault;
+    }
+
+    void setWasDefaultColumn(boolean value) {
+        wasDefault = value;
+    }
+
+    /**
+     * Return TRUE if this result column matches the provided column name.
+     *
+     * This function is used by ORDER BY column resolution. For the
+     * ORDER BY clause, Derby will prefer to match on the column's
+     * alias (_derivedColumnName), but will also successfully match on the
+     * underlying column name. Thus the following statements are
+     * treated equally:
+     *  select name from person order by name;
+     *  select name as person_name from person order by name;
+     *  select name as person_name from person order by person_name;
+     * See DERBY-2351 for more discussion.
+     */
+    boolean columnNameMatches(String columnName) {
+        return columnName.equals(_derivedColumnName) ||
+            columnName.equals( _underlyingName ) ||
+            columnName.equals(getSourceColumnName());
+    }
 	
-	/**
-	 * Get non-null column name. This method is called during the bind phase
-	 *  to see if we are dealing with ResultColumn in the SELECT list that 
-	 *  belongs to a RIGHT OUTER JOIN(NATURAL OR USING)'s join column.
-	 * 					
-	 * For a query like following, we want to use column name x and not the
-	 *  alias x1 when looking in the JoinNode for join column
-	 *   SELECT x x1
-	 *   	 FROM derby4631_t2 NATURAL RIGHT OUTER JOIN derby4631_t1;
-	 * For a query like following, getSourceColumnName() will return null
-	 *  because we are dealing with a function for the column. For this
-	 *  case, "name" will return the alias name cx
-	 *   SELECT coalesce(derby4631_t2.x, derby4631_t1.x) cx
-	 *   	 FROM derby4631_t2 NATURAL RIGHT OUTER JOIN derby4631_t1;	
-	 * For a query like following, getSourceColumnName() and name will 
-	 *  return null and hence need to use the generated name
-	 *   SELECT ''dummy="'|| TRIM(CHAR(x))|| '"'
-	 *        FROM (derby4631_t2 NATURAL RIGHT OUTER JOIN derby4631_t1);
-	 */
-	String getUnderlyingOrAliasName() 
-	{
-		if (getSourceColumnName() != null)
-        {
-			return getSourceColumnName();
-        }
-		else if ( _underlyingName != null )
+    /**
+     * Get non-null column name. This method is called during the bind phase
+     *  to see if we are dealing with ResultColumn in the SELECT list that 
+     *  belongs to a RIGHT OUTER JOIN(NATURAL OR USING)'s join column.
+     * 					
+     * For a query like following, we want to use column name x and not the
+     *  alias x1 when looking in the JoinNode for join column
+     *   SELECT x x1
+     *   	 FROM derby4631_t2 NATURAL RIGHT OUTER JOIN derby4631_t1;
+     * For a query like following, getSourceColumnName() will return null
+     *  because we are dealing with a function for the column. For this
+     *  case, "name" will return the alias name cx
+     *   SELECT coalesce(derby4631_t2.x, derby4631_t1.x) cx
+     *   	 FROM derby4631_t2 NATURAL RIGHT OUTER JOIN derby4631_t1;	
+     * For a query like following, getSourceColumnName() and name will 
+     *  return null and hence need to use the generated name
+     *   SELECT ''dummy="'|| TRIM(CHAR(x))|| '"'
+     *        FROM (derby4631_t2 NATURAL RIGHT OUTER JOIN derby4631_t1);
+     */
+    String getUnderlyingOrAliasName() {
+        if (getSourceColumnName() != null)
         {
-			return _underlyingName;
+            return getSourceColumnName();
         }
-		else
+        else if ( _underlyingName != null )
         {
-			return _derivedColumnName;
+            return _underlyingName;
         }
-	}
+        else
+        {
+            return _derivedColumnName;
+        }
+    }
 	
- 	/**
-	 * Returns true if this column is updatable.
-	 *
-	 * This method is used for determining if updateRow and insertRow
-	 * are allowed for this cursor (DERBY-1773). Since the updateRow
-	 * and insertRow implementations dynamically build SQL statements
-	 * on the fly, the critical issue here is whether we have a
-	 * column that has been aliased, because if it has been
-	 * aliased, the dynamic SQL generation logic won't be able to
-	 * compute the proper true base column name when it needs to.
-	 *
-	 * @return true if this result column is updatable.
-	 */
-	boolean isUpdatable()
-	{
-		return _derivedColumnName == null ||
-			_underlyingName.equals(_derivedColumnName);
-	}
-
-	/**
-	 * Returns the underlying source column name, if this ResultColumn
-	 * is a simple direct reference to a table column, or NULL otherwise.
-	 */
-	String getSourceColumnName()
-	{
-		if (_expression instanceof ColumnReference)
-			return ((ColumnReference)_expression).getColumnName();
-		return null;
-	}
-	/**
-	 * The following methods implement the ResultColumnDescriptor
-	 * interface.  See the Language Module Interface for details.
-	 */
-
-	public String getName()
-	{
-		return _derivedColumnName;
-	}
+    /**
+     * Returns true if this column is updatable.
+     *
+     * This method is used for determining if updateRow and insertRow
+     * are allowed for this cursor (DERBY-1773). Since the updateRow
+     * and insertRow implementations dynamically build SQL statements
+     * on the fly, the critical issue here is whether we have a
+     * column that has been aliased, because if it has been
+     * aliased, the dynamic SQL generation logic won't be able to
+     * compute the proper true base column name when it needs to.
+     *
+     * @return true if this result column is updatable.
+     */
+    boolean isUpdatable() {
+        return _derivedColumnName == null ||
+            _underlyingName.equals(_derivedColumnName);
+    }
+
+    /**
+     * Returns the underlying source column name, if this ResultColumn
+     * is a simple direct reference to a table column, or NULL otherwise.
+     */
+    String getSourceColumnName() {
+        if (_expression instanceof ColumnReference)
+            return ((ColumnReference)_expression).getColumnName();
+        return null;
+    }
+    /**
+     * The following methods implement the ResultColumnDescriptor
+     * interface.  See the Language Module Interface for details.
+     */
+
+    public String getName() {
+        return _derivedColumnName;
+    }
 
     @Override
-    String getSchemaName() throws StandardException
-	{
-		if ((_columnDescriptor!=null) &&
-			(_columnDescriptor.getTableDescriptor() != null))
-			return _columnDescriptor.getTableDescriptor().getSchemaName();
-		else
-		{
-			if (_expression != null)
-			// REMIND: could look in reference, if set.
-				return _expression.getSchemaName();
-			else
-				return null;
-		}
-	}
+    String getSchemaName() throws StandardException {
+        if ((_columnDescriptor!=null) &&
+            (_columnDescriptor.getTableDescriptor() != null))
+            return _columnDescriptor.getTableDescriptor().getSchemaName();
+        else
+        {
+            if (_expression != null)
+                // REMIND: could look in reference, if set.
+                return _expression.getSchemaName();
+            else
+                return null;
+        }
+    }
 
     @Override
-    String getTableName()
-	{
-		if (_unqualifiedTableName != null)
-		{
-			return _unqualifiedTableName;
-		}
-		if ((_columnDescriptor!=null) &&
-			(_columnDescriptor.getTableDescriptor() != null))
-		{
-			return _columnDescriptor.getTableDescriptor().getName();
-		}
-		else
-		{
-			return _expression.getTableName();
-		}
-	}
-
-	/**
-	 * @see ResultColumnDescriptor#getSourceTableName
-	 */
-	public String getSourceTableName()
-	{
-		return _unqualifiedSourceTableName;
-	}
-
-	/**
-	 * @see ResultColumnDescriptor#getSourceSchemaName
-	 */
-	public String getSourceSchemaName()
-	{
-		return _sourceSchemaName;
-	}
-
-	/**
-	 * Clear the table name for the underlying ColumnReference.
-	 * See UpdateNode.scrubResultColumns() for full explaination.
-	 */
-    void clearTableName()
-	{
-		if (_expression instanceof ColumnReference)
-		{
-			((ColumnReference) _expression).setQualifiedTableName( (TableName) null );
-		}
-	}
-
-	public DataTypeDescriptor getType()
-	{
-		return getTypeServices();
-	}
-
-	public int getColumnPosition()
-	{
-		if (_columnDescriptor!=null)
-			return _columnDescriptor.getPosition();
-		else
-			return virtualColumnId;
-
-	}
-
-	/**
-	 * Set the expression in this ResultColumn.  This is useful in those
-	 * cases where you don't know the expression in advance, like for
-	 * INSERT statements with column lists, where the column list and
-	 * SELECT or VALUES clause are parsed separately, and then have to
-	 * be hooked up.
-	 *
-	 * @param expression	The expression to be set in this ResultColumn
-	 */
-
-    void setExpression(ValueNode expression)
-	{
-		_expression = expression;
-	}
-
-	/**
-	 * Get the expression in this ResultColumn.  
-	 *
-	 * @return ValueNode	this.expression
-	 */
-
-    ValueNode getExpression()
-	{
-		return _expression;
-	}
-
-	/**
-	 * Set the expression to a null node of the
-	 * correct type.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	void setExpressionToNullNode()
-		throws StandardException
-	{
-		setExpression( getNullNode(getTypeServices()) );
-	}
-
-	/**
-	 * Set the name in this ResultColumn.  This is useful when you don't
-	 * know the name at the time you create the ResultColumn, for example,
-	 * in an insert-select statement, where you want the names of the
-	 * result columns to match the table being inserted into, not the
-	 * table they came from.
-	 *
-	 * @param name	The name to set in this ResultColumn
-	 */
-
-    void setName(String name)
-	{
-		if ( _underlyingName == null )
-		{
-			_underlyingName = name;
-		}
-		else {
-			if (SanityManager.DEBUG)
-			SanityManager.ASSERT(_reference == null || 
-				name.equals(_reference.getColumnName()), 
-				"don't change name from reference name");
-		}
-
-		_derivedColumnName = name;
-	}
-
-	/**
-	 * Is the name for this ResultColumn generated?
-	 */
-    boolean isNameGenerated()
-	{
-		return _isNameGenerated;
-	}
-
-	/**
-	 * Set that this result column name is generated.
-	 */
-    void setNameGenerated(boolean value)
-	{
-		_isNameGenerated = value;
-	}
-
-	/**
-	 * Set the resultSetNumber for this ResultColumn.  This is the 
-	 * resultSetNumber for the ResultSet that we belong to.  This
-	 * is useful for generate() and necessary since we do not have a
-	 * back pointer to the RSN.
-	 *
-	 * @param resultSetNumber	The resultSetNumber.
-	 */
-    void setResultSetNumber(int resultSetNumber)
-	{
-		this.resultSetNumber = resultSetNumber;
-	}
-
-	/**
-	 * Get the resultSetNumber for this ResultColumn.
-	 *
-	 * @return int	The resultSetNumber.
-	 */
-	public int getResultSetNumber()
-	{
-		return resultSetNumber;
-	}
-
-	/** 
-	 * Adjust the virtualColumnId for this ResultColumn	by the specified amount
-	 * 
-	 * @param adjust	The adjustment for the virtualColumnId
-	 */
-
-    void adjustVirtualColumnId(int adjust)
-	{
-		virtualColumnId += adjust;
-	}
-
-	/** 
-	 * Set the virtualColumnId for this ResultColumn
-	 * 
-	 * @param id	The virtualColumnId for this ResultColumn
-	 */
-
-    void setVirtualColumnId(int id)
-	{
-		virtualColumnId = id;
-	}
-
-	/**
-	 * Get the virtualColumnId for this ResultColumn
-	 *
-	 * @return virtualColumnId for this ResultColumn
-	 */
-    int getVirtualColumnId()
-	{
-		return virtualColumnId;
-	}
-
-	/**
-	 * Adjust this virtualColumnId to account for the removal of a column
-	 *
-	 * This routine is called when bind processing finds and removes
-	 * duplicate columns in the result list which were pulled up due to their
-	 * presence in the ORDER BY clause, but were later found to be duplicate.
-	 * 
-	 * If this column is a virtual column, and if this column's virtual
-	 * column id is greater than the column id which is being removed, then
-	 * we must logically shift this column to the left by decrementing its
-	 * virtual column id.
-	 *
-	 * @param removedColumnId   id of the column being removed.
-	 */
-    void collapseVirtualColumnIdGap(int removedColumnId)
-	{
-		if (_columnDescriptor == null && virtualColumnId > removedColumnId)
-			virtualColumnId--;
-	}
-
-	/**
-	 * Generate a unique (across the entire statement) column name for unnamed
-	 * ResultColumns
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-    void guaranteeColumnName() throws StandardException
-	{
-		if (_derivedColumnName == null)
-		{
-			/* Unions may also need generated names, if both sides name don't match */
-			_derivedColumnName ="SQLCol" + getCompilerContext().getNextColumnNumber();
-			_isNameGenerated = true;
-		}
-	}
-
-	/**
-	 * 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
-	 */
+    String getTableName() {
+        if (_unqualifiedTableName != null)
+        {
+            return _unqualifiedTableName;
+        }
+        if ((_columnDescriptor!=null) &&
+            (_columnDescriptor.getTableDescriptor() != null))
+        {
+            return _columnDescriptor.getTableDescriptor().getName();
+        }
+        else
+        {
+            return _expression.getTableName();
+        }
+    }
+
+    /**
+     * @see ResultColumnDescriptor#getSourceTableName
+     */
+    public String getSourceTableName() {
+        return _unqualifiedSourceTableName;
+    }
+
+    /**
+     * @see ResultColumnDescriptor#getSourceSchemaName
+     */
+    public String getSourceSchemaName() {
+        return _sourceSchemaName;
+    }
+
+    /**
+     * Clear the table name for the underlying ColumnReference.
+     * See UpdateNode.scrubResultColumns() for full explaination.
+     */
+    void clearTableName() {
+        if (_expression instanceof ColumnReference)
+        {
+            ((ColumnReference) _expression).setQualifiedTableName( (TableName) null );
+        }
+    }
+
+    public DataTypeDescriptor getType() {
+        return getTypeServices();
+    }
+
+    public int getColumnPosition() {
+        if (_columnDescriptor!=null)
+            return _columnDescriptor.getPosition();
+        else
+            return virtualColumnId;
+
+    }
+
+    /**
+     * Set the expression in this ResultColumn.  This is useful in those
+     * cases where you don't know the expression in advance, like for
+     * INSERT statements with column lists, where the column list and
+     * SELECT or VALUES clause are parsed separately, and then have to
+     * be hooked up.
+     *
+     * @param expression	The expression to be set in this ResultColumn
+     */
+
+    void setExpression(ValueNode expression) {
+        _expression = expression;
+    }
+
+    /**
+     * Get the expression in this ResultColumn.  
+     *
+     * @return ValueNode	this.expression
+     */
+
+    ValueNode getExpression() {
+        return _expression;
+    }
+
+    /**
+     * Set the expression to a null node of the
+     * correct type.
+     *
+     * @exception StandardException		Thrown on error
+     */
+    void setExpressionToNullNode()
+        throws StandardException {
+        setExpression( getNullNode(getTypeServices()) );
+    }
+
+    /**
+     * Set the name in this ResultColumn.  This is useful when you don't
+     * know the name at the time you create the ResultColumn, for example,
+     * in an insert-select statement, where you want the names of the
+     * result columns to match the table being inserted into, not the
+     * table they came from.
+     *
+     * @param name	The name to set in this ResultColumn
+     */
+
+    void setName(String name) {
+        if ( _underlyingName == null )
+        {
+            _underlyingName = name;
+        }
+        else {
+            if (SanityManager.DEBUG)
+                SanityManager.ASSERT(_reference == null || 
+                                     name.equals(_reference.getColumnName()), 
+                                     "don't change name from reference name");
+        }
+
+        _derivedColumnName = name;
+    }
+
+    /**
+     * Is the name for this ResultColumn generated?
+     */
+    boolean isNameGenerated() {
+        return _isNameGenerated;
+    }
+
+    /**
+     * Set that this result column name is generated.
+     */
+    void setNameGenerated(boolean value) {
+        _isNameGenerated = value;
+    }
+
+    /**
+     * Set the resultSetNumber for this ResultColumn.  This is the 
+     * resultSetNumber for the ResultSet that we belong to.  This
+     * is useful for generate() and necessary since we do not have a
+     * back pointer to the RSN.
+     *
+     * @param resultSetNumber	The resultSetNumber.
+     */
+    void setResultSetNumber(int resultSetNumber) {
+        this.resultSetNumber = resultSetNumber;
+    }
+
+    /**
+     * Get the resultSetNumber for this ResultColumn.
+     *
+     * @return int	The resultSetNumber.
+     */
+    public int getResultSetNumber() {
+        return resultSetNumber;
+    }
+
+    /** 
+     * Adjust the virtualColumnId for this ResultColumn	by the specified amount
+     * 
+     * @param adjust	The adjustment for the virtualColumnId
+     */
+
+    void adjustVirtualColumnId(int adjust) {
+        virtualColumnId += adjust;
+    }
+
+    /** 
+     * Set the virtualColumnId for this ResultColumn
+     * 
+     * @param id	The virtualColumnId for this ResultColumn
+     */
+
+    void setVirtualColumnId(int id) {
+        virtualColumnId = id;
+    }
+
+    /**
+     * Get the virtualColumnId for this ResultColumn
+     *
+     * @return virtualColumnId for this ResultColumn
+     */
+    int getVirtualColumnId() {
+        return virtualColumnId;
+    }
+
+    /**
+     * Adjust this virtualColumnId to account for the removal of a column
+     *
+     * This routine is called when bind processing finds and removes
+     * duplicate columns in the result list which were pulled up due to their
+     * presence in the ORDER BY clause, but were later found to be duplicate.
+     * 
+     * If this column is a virtual column, and if this column's virtual
+     * column id is greater than the column id which is being removed, then
+     * we must logically shift this column to the left by decrementing its
+     * virtual column id.
+     *
+     * @param removedColumnId   id of the column being removed.
+     */
+    void collapseVirtualColumnIdGap(int removedColumnId) {
+        if (_columnDescriptor == null && virtualColumnId > removedColumnId)
+            virtualColumnId--;
+    }
+
+    /**
+     * Generate a unique (across the entire statement) column name for unnamed
+     * ResultColumns
+     *
+     * @exception StandardException		Thrown on error
+     */
+    void guaranteeColumnName() throws StandardException {
+        if (_derivedColumnName == null)
+        {
+            /* Unions may also need generated names, if both sides name don't match */
+            _derivedColumnName ="SQLCol" + getCompilerContext().getNextColumnNumber();
+            _isNameGenerated = true;
+        }
+    }
+
+    /**
+     * 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
+     */
     @Override
-	public String toString()
-	{
-		if (SanityManager.DEBUG)
-		{
-			return "derivedColumnName: " + _derivedColumnName + "\n" +
-				"underlyingName: " + _underlyingName + "\n" +
-				"tableName: " + _unqualifiedTableName + "\n" +
-				"isDefaultColumn: " + defaultColumn + "\n" +
-				"wasDefaultColumn: " + wasDefault + "\n" +
-				"isNameGenerated: " + _isNameGenerated + "\n" +
-				"sourceTableName: " + _unqualifiedSourceTableName + "\n" +
-				"type: " + getTypeServices() + "\n" +
-				"columnDescriptor: " + _columnDescriptor + "\n" +
-				"isGenerated: " + _isGenerated + "\n" +
-				"isGeneratedForUnmatchedColumnInInsert: " + _isGeneratedForUnmatchedColumnInInsert + "\n" +
-				"isGroupingColumn: " + _isGroupingColumn + "\n" +
-				"isReferenced: " + _isReferenced + "\n" +
-				"isRedundant: " + _isRedundant + "\n" +
-				"rightOuterJoinUsingClause: " + rightOuterJoinUsingClause + "\n" +
-				"joinResultSet: " + joinResultSet + "\n" +
-				"virtualColumnId: " + virtualColumnId + "\n" +
-				"resultSetNumber: " + resultSetNumber + "\n" +
-				super.toString();
-		}
-		else
-		{
-			return "";
-		}
-	}
-
-	/**
-	 * 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
-	 */
+    public String toString() {
+        if (SanityManager.DEBUG)
+        {
+            return "derivedColumnName: " + _derivedColumnName + "\n" +
+                "underlyingName: " + _underlyingName + "\n" +
+                "tableName: " + _unqualifiedTableName + "\n" +
+                "isDefaultColumn: " + defaultColumn + "\n" +
+                "wasDefaultColumn: " + wasDefault + "\n" +
+                "isNameGenerated: " + _isNameGenerated + "\n" +
+                "sourceTableName: " + _unqualifiedSourceTableName + "\n" +
+                "type: " + getTypeServices() + "\n" +
+                "columnDescriptor: " + _columnDescriptor + "\n" +
+                "isGenerated: " + _isGenerated + "\n" +
+                "isGeneratedForUnmatchedColumnInInsert: " + _isGeneratedForUnmatchedColumnInInsert + "\n" +
+                "isGroupingColumn: " + _isGroupingColumn + "\n" +
+                "isReferenced: " + _isReferenced + "\n" +
+                "isRedundant: " + _isRedundant + "\n" +
+                "rightOuterJoinUsingClause: " + rightOuterJoinUsingClause + "\n" +
+                "joinResultSet: " + joinResultSet + "\n" +
+                "virtualColumnId: " + virtualColumnId + "\n" +
+                "resultSetNumber: " + resultSetNumber + "\n" +
+                super.toString();
+        }
+        else
+        {
+            return "";
+        }
+    }
+
+    /**
+     * 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
+     */
     @Override
-    void printSubNodes(int depth)
-	{
-		if (SanityManager.DEBUG)
-		{
-			super.printSubNodes(depth);
-			if (_expression != null)
-			{
-				printLabel(depth, "expression: ");
-				_expression.treePrint(depth + 1);
-			}
-			if (_reference != null)
-			{
-				printLabel(depth, "reference: ");
-				_reference.treePrint(depth + 1);
-			}
-		}
-	}
-
-	/**
-	 * Bind this expression.  This means binding the sub-expressions.
-	 * In this case, we figure out what the result type of this result
-	 * column is when we call one of the bindResultColumn*() methods.
-	 * The reason is that there are different ways of binding the
-	 * result columns depending on the statement type, and this is
-	 * a standard interface that does not take the statement type as
-	 * a parameter.
-	 *
-	 * @param fromList		The FROM list for the query this
-	 *				expression is in, for binding columns.
-	 * @param subqueryList		The subquery list being built as we find SubqueryNodes
+    void printSubNodes(int depth) {
+        if (SanityManager.DEBUG)
+        {
+            super.printSubNodes(depth);
+            if (_expression != null)
+            {
+                printLabel(depth, "expression: ");
+                _expression.treePrint(depth + 1);
+            }
+            if (_reference != null)
+            {
+                printLabel(depth, "reference: ");
+                _reference.treePrint(depth + 1);
+            }
+        }
+    }
+
+    /**
+     * Bind this expression.  This means binding the sub-expressions.
+     * In this case, we figure out what the result type of this result
+     * column is when we call one of the bindResultColumn*() methods.
+     * The reason is that there are different ways of binding the
+     * result columns depending on the statement type, and this is
+     * a standard interface that does not take the statement type as
+     * a parameter.
+     *
+     * @param fromList		The FROM list for the query this
+     *				expression is in, for binding columns.
+     * @param subqueryList		The subquery list being built as we find SubqueryNodes
      * @param aggregates        The aggregate list being built as we find AggregateNodes
-	 *
-	 * @return	The new top of the expression tree.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
+     *
+     * @return	The new top of the expression tree.
+     *
+     * @exception StandardException		Thrown on error
+     */
     @Override
     ResultColumn bindExpression(FromList fromList, SubqueryList subqueryList, List<AggregateNode> aggregates)
-				throws StandardException
-	{
-		/*
-		** Set the type of a parameter to the type of the result column.
-		** Don't do it if this result column doesn't have a type yet.
-		** This can happen if the parameter is part of a table constructor.
-		*/
-		if (_expression.requiresTypeFromContext())
-		{
-			if (getTypeServices() != null)
-			{
-				_expression.setType(getTypeServices());
-			}
-		}
-
-		//DERBY-4631
-		//Following code is for a join column(which obviously will not be 
-		// qualified with a table name because join columns are not
-		// associated with left or right table) of RIGHT OUTER JOIN  
-		// with USING/NATURAL join. For such columns, 
-		// isJoinColumnForRightOuterJoin() call will set 
-		// rightOuterJoinUsingClause to true and associate the  
-		// JoinResultSet with it. eg
-		//      select c from t1 right join t2 using (c)
-		// Here, we are talking about column c as in "select c"
-		if (_expression.getTableName() == null) {
-			fromList.isJoinColumnForRightOuterJoin(this);
-		}
-
-		setExpression( _expression.bindExpression(fromList, subqueryList,
-                                                 aggregates) );
-
-		if (_expression instanceof ColumnReference)
-		{
-			_autoincrement = ((ColumnReference)_expression).getSource().isAutoincrement();
-		}
+        throws StandardException {
+        /*
+        ** Set the type of a parameter to the type of the result column.
+        ** Don't do it if this result column doesn't have a type yet.
+        ** This can happen if the parameter is part of a table constructor.
+        */
+        if (_expression.requiresTypeFromContext())
+        {
+            if (getTypeServices() != null)
+            {
+                _expression.setType(getTypeServices());
+            }
+        }
+
+        //DERBY-4631
+        //Following code is for a join column(which obviously will not be 
+        // qualified with a table name because join columns are not
+        // associated with left or right table) of RIGHT OUTER JOIN  
+        // with USING/NATURAL join. For such columns, 
+        // isJoinColumnForRightOuterJoin() call will set 
+        // rightOuterJoinUsingClause to true and associate the  
+        // JoinResultSet with it. eg
+        //      select c from t1 right join t2 using (c)
+        // Here, we are talking about column c as in "select c"
+        if (_expression.getTableName() == null) {
+            fromList.isJoinColumnForRightOuterJoin(this);
+        }
+
+        setExpression( _expression.bindExpression(fromList, subqueryList,
+                                                  aggregates) );
+
+        if (_expression instanceof ColumnReference)
+        {
+            _autoincrement = ((ColumnReference)_expression).getSource().isAutoincrement();
+        }
 			
 
 		
-		return this;
-	}
+        return this;
+    }
 
-	/**
-	 * Bind this result column by ordinal position and set the VirtualColumnId.  
-	 * This is useful for INSERT statements like "insert into t values (1, 2, 3)", 
-	 * where the user did not specify a column list.
-	 * If a columnDescriptor is not found for a given position, then
-	 * the user has specified more values than the # of columns in
-	 * the table and an exception is thrown.
-	 *
-	 * NOTE: We must set the VirtualColumnId here because INSERT does not
-	 * construct the ResultColumnList in the usual way.
-	 *
-	 * @param tableDescriptor	The descriptor for the table being
-	 *				inserted into
-	 * @param columnId		The ordinal position of the column
-	 *						in the table, starting at 1.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-
-	void bindResultColumnByPosition(TableDescriptor tableDescriptor,
-					int columnId)
-				throws StandardException
-	{
+    /**
+     * Bind this result column by ordinal position and set the VirtualColumnId.  
+     * This is useful for INSERT statements like "insert into t values (1, 2, 3)", 
+     * where the user did not specify a column list.
+     * If a columnDescriptor is not found for a given position, then
+     * the user has specified more values than the # of columns in
+     * the table and an exception is thrown.
+     *
+     * NOTE: We must set the VirtualColumnId here because INSERT does not
+     * construct the ResultColumnList in the usual way.
+     *
+     * @param tableDescriptor	The descriptor for the table being
+     *				inserted into
+     * @param columnId		The ordinal position of the column
+     *						in the table, starting at 1.
+     *
+     * @exception StandardException		Thrown on error
+     */
+
+    void bindResultColumnByPosition(TableDescriptor tableDescriptor,
+                                    int columnId)
+        throws StandardException {
         ColumnDescriptor    colDesc;
 
         colDesc = tableDescriptor.getColumnDescriptor(columnId);
 
         if (colDesc == null)
-		{
-			String		errorString;
-			String		schemaName;
-
-			errorString = "";
-			schemaName = tableDescriptor.getSchemaName();
-			if (schemaName != null)
-				errorString += schemaName + ".";
-			errorString += tableDescriptor.getName();
+        {
+            String		errorString;
+            String		schemaName;
 
-			throw StandardException.newException(SQLState.LANG_TOO_MANY_RESULT_COLUMNS, errorString);
-		}
+            errorString = "";
+            schemaName = tableDescriptor.getSchemaName();
+            if (schemaName != null)
+                errorString += schemaName + ".";
+            errorString += tableDescriptor.getName();
+
+            throw StandardException.newException(SQLState.LANG_TOO_MANY_RESULT_COLUMNS, errorString);
+        }
 
         setColumnDescriptor(tableDescriptor, colDesc);
-		setVirtualColumnId(columnId);
-	}
+        setVirtualColumnId(columnId);
+    }
 
-	/**
-	 * Bind this result column by its name and set the VirtualColumnId.  
-	 * This is useful for update statements, and for INSERT statements 
-	 * like "insert into t (a, b, c) values (1, 2, 3)" where the user 
-	 * specified a column list.
-	 * An exception is thrown when a columnDescriptor cannot be found for a
-	 * given name.  (There is no column with that name.)
-	 *
-	 * NOTE: We must set the VirtualColumnId here because INSERT does not
-	 * construct the ResultColumnList in the usual way.
-	 *
-	 * @param tableDescriptor	The descriptor for the table being
-	 *				updated or inserted into
-	 * @param columnId		The ordinal position of the column
-	 *						in the table, starting at 1. (Used to
-	 *						set the VirtualColumnId.)
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
+    /**
+     * Bind this result column by its name and set the VirtualColumnId.  
+     * This is useful for update statements, and for INSERT statements 
+     * like "insert into t (a, b, c) values (1, 2, 3)" where the user 
+     * specified a column list.
+     * An exception is thrown when a columnDescriptor cannot be found for a
+     * given name.  (There is no column with that name.)
+     *
+     * NOTE: We must set the VirtualColumnId here because INSERT does not
+     * construct the ResultColumnList in the usual way.
+     *
+     * @param tableDescriptor	The descriptor for the table being
+     *				updated or inserted into
+     * @param columnId		The ordinal position of the column
+     *						in the table, starting at 1. (Used to
+     *						set the VirtualColumnId.)
+     *
+     * @exception StandardException		Thrown on error
+     */
 
     void bindResultColumnByName(TableDescriptor tableDescriptor,
-					int columnId)
-				throws StandardException
-	{
+                                int columnId)
+        throws StandardException {
         ColumnDescriptor    colDesc;
 
         colDesc = tableDescriptor.getColumnDescriptor(_derivedColumnName);
 
         if (colDesc == null)
-		{
-			String		errorString;
-			String		schemaName;
-
-			errorString = "";
-			schemaName = tableDescriptor.getSchemaName();
-			if (schemaName != null)
-				errorString += schemaName + ".";
-			errorString += tableDescriptor.getName();
+        {
+            String		errorString;
+            String		schemaName;
 
-			throw StandardException.newException(SQLState.LANG_COLUMN_NOT_FOUND_IN_TABLE, _derivedColumnName, errorString);
-		}
+            errorString = "";
+            schemaName = tableDescriptor.getSchemaName();
+            if (schemaName != null)
+                errorString += schemaName + ".";
+            errorString += tableDescriptor.getName();
+
+            throw StandardException.newException(SQLState.LANG_COLUMN_NOT_FOUND_IN_TABLE, _derivedColumnName, errorString);
+        }
 
         setColumnDescriptor(tableDescriptor, colDesc);
-		setVirtualColumnId(columnId);
-		if (isPrivilegeCollectionRequired())
+        setVirtualColumnId(columnId);
+        if (isPrivilegeCollectionRequired())
             getCompilerContext().addRequiredColumnPriv( colDesc);
-	}
+    }
 
-	/**
-	 * Change an untyped null to a typed null.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
+    /**
+     * Change an untyped null to a typed null.
+     *
+     * @exception StandardException		Thrown on error
+     */
     void typeUntypedNullExpression( ResultColumn bindingRC)
-			throws StandardException
-	{
+        throws StandardException {
         TypeId typeId = bindingRC.getTypeId();
-		/* This is where we catch null in a VALUES clause outside
-		 * of INSERT VALUES()
-		 */
-		if (typeId == null)
-		{
-			throw StandardException.newException(SQLState.LANG_NULL_IN_VALUES_CLAUSE);
-		}
+        /* This is where we catch null in a VALUES clause outside
+         * of INSERT VALUES()
+         */
+        if (typeId == null)
+        {
+            throw StandardException.newException(SQLState.LANG_NULL_IN_VALUES_CLAUSE);
+        }
 
         if( _expression instanceof UntypedNullConstantNode)
-        	//since we don't know the type of such a constant node, we just
-        	//use the default values for collation type and derivation.
-        	//eg insert into table1 values(1,null)
-        	//When this method is executed for the sql above, we don't know
-        	//the type of the null at this point.
+            //since we don't know the type of such a constant node, we just
+            //use the default values for collation type and derivation.
+            //eg insert into table1 values(1,null)
+            //When this method is executed for the sql above, we don't know
+            //the type of the null at this point.
             setExpression( getNullNode(bindingRC.getTypeServices()) );
         else if( ( _expression instanceof ColumnReference) && _expression.getTypeServices() == null)
         {
             // The expression must be a reference to a null column in a values table.
             _expression.setType( bindingRC.getType());
         }
-	}
+    }
 
-	/**
-	 * Set the column descriptor for this result column.  It also gets
-	 * the data type services from the column descriptor and stores it in
-	 * this result column: this is redundant, but we have to store the result
-	 * type here for SELECT statements, and it is more orthogonal if the type
-	 * can be found here regardless of what type of statement it is.
-	 *
-	 * @param tableDescriptor	The TableDescriptor for the table
-	 *				being updated or inserted into.
-	 *				This parameter is used only for
-	 *				error reporting.
-	 * @param columnDescriptor	The ColumnDescriptor to set in
-	 *				this ResultColumn.
-	 *
-	 * @exception StandardException tableNameMismatch
-	 */
-	void setColumnDescriptor(TableDescriptor tableDescriptor,
-				ColumnDescriptor columnDescriptor) throws StandardException
-	{
-		if ( columnDescriptor != null ) { setType(columnDescriptor.getType()); }
-		_columnDescriptor = columnDescriptor;
-
-		/*
-			If the node was created using a reference, the table name
-			of the reference must agree with that of the tabledescriptor.
-		 */
-		if (
+    /**
+     * Set the column descriptor for this result column.  It also gets
+     * the data type services from the column descriptor and stores it in
+     * this result column: this is redundant, but we have to store the result
+     * type here for SELECT statements, and it is more orthogonal if the type
+     * can be found here regardless of what type of statement it is.
+     *
+     * @param tableDescriptor	The TableDescriptor for the table
+     *				being updated or inserted into.
+     *				This parameter is used only for
+     *				error reporting.
+     * @param columnDescriptor	The ColumnDescriptor to set in
+     *				this ResultColumn.
+     *
+     * @exception StandardException tableNameMismatch
+     */
+    void setColumnDescriptor(TableDescriptor tableDescriptor,
+                             ColumnDescriptor columnDescriptor) throws StandardException {
+        if ( columnDescriptor != null ) { setType(columnDescriptor.getType()); }
+        _columnDescriptor = columnDescriptor;
+
+        /*
+          If the node was created using a reference, the table name
+          of the reference must agree with that of the tabledescriptor.
+        */
+        if (
             _reference != null &&
             _reference.getTableName() != null &&
             (_reference.getMergeTableID() == ColumnReference.MERGE_UNKNOWN)
             ) 
-		{
-			if ( (tableDescriptor != null) && ! tableDescriptor.getName().equals(
-					_reference.getTableName()) ) 
-			{
-				/* REMIND: need to have schema name comparison someday as well...
-				** left out for now, lots of null checking needed...
-				** || ! tableDescriptor.getSchemaName().equals(
-				**	reference.getQualifiedTableName().getSchemaName())) {
-				*/
-				String realName = tableDescriptor.getName();
-				String refName = _reference.getTableName();
-
-				throw StandardException.newException(SQLState.LANG_TABLE_NAME_MISMATCH, 
-					realName, refName);
-			}
-		}
-	}
-
-	/**
-	 * Bind the result column to the expression that lives under it.
-	 * All this does is copy the datatype information to this node.
-	 * This is useful for SELECT statements, where the result type
-	 * of each column is the type of the column's expression.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
+        {
+            if ( (tableDescriptor != null) && ! tableDescriptor.getName().equals(
+                     _reference.getTableName()) ) 
+            {
+                /* REMIND: need to have schema name comparison someday as well...
+                ** left out for now, lots of null checking needed...
+                ** || ! tableDescriptor.getSchemaName().equals(
+                **	reference.getQualifiedTableName().getSchemaName())) {
+                */
+                String realName = tableDescriptor.getName();
+                String refName = _reference.getTableName();
+
+                throw StandardException.newException(SQLState.LANG_TABLE_NAME_MISMATCH, 
+                                                     realName, refName);
+            }
+        }
+    }
+
+    /**
+     * Bind the result column to the expression that lives under it.
+     * All this does is copy the datatype information to this node.
+     * This is useful for SELECT statements, where the result type
+     * of each column is the type of the column's expression.
+     *
+     * @exception StandardException		Thrown on error
+     */
     void bindResultColumnToExpression()
-				throws StandardException
-	{
-		/*
-		** This gets the same DataTypeServices object as
-		** is used in the expression.  It is probably not
-		** necessary to clone the object here.
-		*/
-		setType(_expression.getTypeServices());
-
-		if (_expression instanceof ColumnReference)
-		{
-			ColumnReference cr = (ColumnReference) _expression;
-			_unqualifiedTableName = cr.getTableName();
-			_unqualifiedSourceTableName = cr.getSourceTableName();
-			_sourceSchemaName = cr.getSourceSchemaName();
-		}
-	}
-
-
-	/**
-	 * Set the column source's table name
-	 * @param t The source table name
-	 */
+        throws StandardException {
+        /*
+        ** This gets the same DataTypeServices object as
+        ** is used in the expression.  It is probably not
+        ** necessary to clone the object here.
+        */
+        setType(_expression.getTypeServices());
+
+        if (_expression instanceof ColumnReference)
+        {
+            ColumnReference cr = (ColumnReference) _expression;
+            _unqualifiedTableName = cr.getTableName();
+            _unqualifiedSourceTableName = cr.getSourceTableName();
+            _sourceSchemaName = cr.getSourceSchemaName();
+        }
+    }
+
+
+    /**
+     * Set the column source's table name
+     * @param t The source table name
+     */
     void setSourceTableName(String t) {
-		_unqualifiedSourceTableName = t;
-	}
+        _unqualifiedSourceTableName = t;
+    }
 
-	/**
-	 * Set the column source's schema name
-	 * @param s The source schema name
-	 */
+    /**
+     * Set the column source's schema name
+     * @param s The source schema name
+     */
     void setSourceSchemaName(String s) {
-		_sourceSchemaName = s;
-	}
+        _sourceSchemaName = s;
+    }
 
-	/**
-	 * Preprocess an expression tree.  We do a number of transformations
-	 * here (including subqueries, IN lists, LIKE and BETWEEN) plus
-	 * subquery flattening.
-	 * NOTE: This is done before the outer ResultSetNode is preprocessed.
-	 *
-	 * @param	numTables			Number of tables in the DML Statement
-	 * @param	outerFromList		FromList from outer query block
-	 * @param	outerSubqueryList	SubqueryList from outer query block
-	 * @param	outerPredicateList	PredicateList from outer query block
-	 *
-	 * @return		The modified expression
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
+    /**
+     * Preprocess an expression tree.  We do a number of transformations
+     * here (including subqueries, IN lists, LIKE and BETWEEN) plus
+     * subquery flattening.
+     * NOTE: This is done before the outer ResultSetNode is preprocessed.
+     *
+     * @param	numTables			Number of tables in the DML Statement
+     * @param	outerFromList		FromList from outer query block
+     * @param	outerSubqueryList	SubqueryList from outer query block
+     * @param	outerPredicateList	PredicateList from outer query block
+     *
+     * @return		The modified expression
+     *
+     * @exception StandardException		Thrown on error
+     */
     @Override
     ResultColumn preprocess(int numTables,
-								FromList outerFromList,
-								SubqueryList outerSubqueryList,
-								PredicateList outerPredicateList) 
-					throws StandardException
-	{
-		if (_expression == null)
-			return this;
-		setExpression( _expression.preprocess(numTables, outerFromList,
-										   outerSubqueryList,
-                                           outerPredicateList) );
-		return this;
-	}
-
-	/**
-		This verifies that the expression is storable into the result column.
-		It checks versus the given ResultColumn.
-
-		This method should not be called until the result column and
-		expression both have a valid type, i.e. after they are bound
-		appropriately. Its use is for statements like insert, that need to
-		verify if a given value can be stored into a column.
+                            FromList outerFromList,
+                            SubqueryList outerSubqueryList,
+                            PredicateList outerPredicateList) 
+        throws StandardException {
+        if (_expression == null)
+            return this;
+        setExpression( _expression.preprocess(numTables, outerFromList,
+                                              outerSubqueryList,
+                                              outerPredicateList) );
+        return this;
+    }
+
+    /**
+       This verifies that the expression is storable into the result column.
+       It checks versus the given ResultColumn.
 
-		@exception StandardException thrown if types not suitable.
-	 */
+       This method should not be called until the result column and
+       expression both have a valid type, i.e. after they are bound
+       appropriately. Its use is for statements like insert, that need to
+       verify if a given value can be stored into a column.
+
+       @exception StandardException thrown if types not suitable.
+    */
     void checkStorableExpression(ResultColumn toStore)
-					throws StandardException
-	{
+        throws StandardException {
         checkStorableExpression((ValueNode) toStore);
-	}
+    }
     
     private void checkStorableExpression(ValueNode source)
-        throws StandardException
-    {
+        throws StandardException {
         TypeId toStoreTypeId = source.getTypeId();
         
         if (!getTypeCompiler().storable(toStoreTypeId, getClassFactory()))
         {
-           throw StandardException.newException(SQLState.LANG_NOT_STORABLE, 
-                    getTypeId().getSQLTypeName(),
-                    toStoreTypeId.getSQLTypeName() );
+            throw StandardException.newException(SQLState.LANG_NOT_STORABLE, 
+                                                 getTypeId().getSQLTypeName(),
+                                                 toStoreTypeId.getSQLTypeName() );
         }   
     }
 
-	/**
-		This verifies that the expression is storable into the result column.
-		It checks versus the expression under this ResultColumn.
-
-		This method should not be called until the result column and
-		expression both have a valid type, i.e. after they are bound
-		appropriately. Its use is for statements like update, that need to
-		verify if a given value can be stored into a column.
+    /**
+       This verifies that the expression is storable into the result column.
+       It checks versus the expression under this ResultColumn.
+
+       This method should not be called until the result column and
+       expression both have a valid type, i.e. after they are bound
+       appropriately. Its use is for statements like update, that need to
+       verify if a given value can be stored into a column.
 
-		@exception StandardException thrown if types not suitable.
-	 */
+       @exception StandardException thrown if types not suitable.
+    */
     void checkStorableExpression()
-					throws StandardException
-	{
+        throws StandardException {
         checkStorableExpression(getExpression());
-	}
+    }
 
-	/**
-	 * Do code generation for a result column.  This consists of doing the code
-	 * generation for the underlying expression.
-	 *
-	 * @param ecb	The ExpressionClassBuilder for the class we're generating
-	 * @param mb	The method the expression will go into
-	 *
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
+    /**
+     * Do code generation for a result column.  This consists of doing the code
+     * generation for the underlying expression.
+     *
+     * @param ecb	The ExpressionClassBuilder for the class we're generating
+     * @param mb	The method the expression will go into
+     *
+     *
+     * @exception StandardException		Thrown on error
+     */
     @Override
     void generateExpression(ExpressionClassBuilder ecb, MethodBuilder mb)
-									throws StandardException
-	{
+        throws StandardException {
         _expression.generateExpression(ecb, mb);
-	}
+    }
 
-	/**
-	 * Do code generation to return a Null of the appropriate type
-	 * for the result column.  
-	   Requires the getCOlumnExpress value pushed onto the stack
-	 *
-	 * @param acb		The ActivationClassBuilder for the class we're generating
-	 * @param eb		The ExpressionBlock that the generate code is to go into
-	 * @param getColumnExpression "fieldx.getColumn(y)"
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
+    /**
+     * Do code generation to return a Null of the appropriate type
+     * for the result column.  
+     Requires the getCOlumnExpress value pushed onto the stack
+     *
+     * @param acb		The ActivationClassBuilder for the class we're generating
+     * @param eb		The ExpressionBlock that the generate code is to go into
+     * @param getColumnExpression "fieldx.getColumn(y)"
+     *
+     * @exception StandardException		Thrown on error
+     */
 /*PUSHCOMPILE
-    void generateNulls(ExpressionClassBuilder acb,
-									MethodBuilder mb,
-									Expression getColumnExpress) 
-			throws StandardException
-	{
+  void generateNulls(ExpressionClassBuilder acb,
+  MethodBuilder mb,
+  Expression getColumnExpress) 
+  throws StandardException
+  {
 
-		acb.pushDataValueFactory(mb);
-		getTypeCompiler().generateNull(mb, acb.getBaseClassName());
+  acb.pushDataValueFactory(mb);
+  getTypeCompiler().generateNull(mb, acb.getBaseClassName());
 
 		
-		mb.cast(ClassName.DataValueDescriptor);
+  mb.cast(ClassName.DataValueDescriptor);
 
 
-		return eb.newCastExpression(
-					ClassName.DataValueDescriptor, 
-					getTypeCompiler().
-						generateNull(
-									eb,
-									acb.getBaseClassName(),
-									acb.getDataValueFactory(eb),
-									getColumnExpress));
-	}
+  return eb.newCastExpression(
+  ClassName.DataValueDescriptor, 
+  getTypeCompiler().
+  generateNull(
+  eb,
+  acb.getBaseClassName(),
+  acb.getDataValueFactory(eb),
+  getColumnExpress));
+  }
 */
 
-	/**
-	** Check whether the column length and type of this result column
-	** match the expression under the columns.  This is useful for
-	** INSERT and UPDATE statements.  For SELECT statements this method
-	** should always return true.  There is no need to call this for a
-	** DELETE statement.
-	**
-	** @return	true means the column matches its expressions,
-	**			false means it doesn't match.
-	*/
-	boolean columnTypeAndLengthMatch()
-		throws StandardException
-	{
-
-		/*
-		** We can never make any assumptions about
-		** parameters.  So don't even bother in this
-		** case.
-		*/
-		if (getExpression().requiresTypeFromContext())
-		{
-			return false;
-		}
-
-		// Are we inserting/updating an XML column?  If so, we always
-		// return false so that normalization will occur.  We have to
-		// do this because there are different "kinds" of XML values
-		// and we need to make sure they match--but we don't know
-		// the "kind" until execution time.  See the "normalize"
-		// method in org.apache.derby.iapi.types.XML for more.
-		if (getTypeId().isXMLTypeId())
-			return false;
+    /**
+     ** Check whether the column length and type of this result column
+     ** match the expression under the columns.  This is useful for
+     ** INSERT and UPDATE statements.  For SELECT statements this method
+     ** should always return true.  There is no need to call this for a
+     ** DELETE statement.
+     **
+     ** @return	true means the column matches its expressions,
+     **			false means it doesn't match.
+     */
+    boolean columnTypeAndLengthMatch()
+        throws StandardException {
+
+        /*
+        ** We can never make any assumptions about
+        ** parameters.  So don't even bother in this
+        ** case.
+        */
+        if (getExpression().requiresTypeFromContext())
+        {
+            return false;
+        }
+
+        // Are we inserting/updating an XML column?  If so, we always
+        // return false so that normalization will occur.  We have to
+        // do this because there are different "kinds" of XML values
+        // and we need to make sure they match--but we don't know
+        // the "kind" until execution time.  See the "normalize"
+        // method in org.apache.derby.iapi.types.XML for more.
+        if (getTypeId().isXMLTypeId())
+            return false;
         
         
         DataTypeDescriptor  expressionType = getExpression().getTypeServices();
@@ -1155,217 +1109,209 @@ class ResultColumn extends ValueNode
         if (!getTypeServices().isExactTypeAndLengthMatch(expressionType))
             return false;
 
-		/* Is the source nullable and the target non-nullable? */
-		if ((! getTypeServices().isNullable()) && expressionType.isNullable())
-		{
-			return false;
-		}
-
-		return true;
-	}
-
-	boolean columnTypeAndLengthMatch(ResultColumn otherColumn)
-		throws StandardException
-	{
-		ValueNode otherExpression = otherColumn.getExpression();
+        /* Is the source nullable and the target non-nullable? */
+        if ((! getTypeServices().isNullable()) && expressionType.isNullable())
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+    boolean columnTypeAndLengthMatch(ResultColumn otherColumn)
+        throws StandardException {
+        ValueNode otherExpression = otherColumn.getExpression();
 
         DataTypeDescriptor resultColumnType = getTypeServices();
         DataTypeDescriptor otherResultColumnType = otherColumn.getTypeServices();
 
-		if (SanityManager.DEBUG)
-		{
-			SanityManager.ASSERT(resultColumnType != null,
-					"Type is null for column " + this);
-			SanityManager.ASSERT(otherResultColumnType != null,
-					"Type is null for column " + otherColumn);
-		}
-
-		/*
-		** We can never make any assumptions about
-		** parameters.  So don't even bother in this
-		** case.
-		*/
-		if ((otherExpression != null) && (otherExpression.requiresTypeFromContext()) ||
-			(_expression.requiresTypeFromContext()))
-		{
-			return false;
-		}
-
-		// Are we inserting/updating an XML column?  If so, we always
-		// return false so that normalization will occur.  We have to
-		// do this because there are different "kinds" of XML values
-		// and we need to make sure they match--but we don't know
-		// the "kind" until execution time.  See the "normalize"
-		// method in org.apache.derby.iapi.types.XML for more.
-		if (resultColumnType.getTypeId().isXMLTypeId())
-			return false;
-
-		/* Are they the same type? */
-		if ( ! resultColumnType.getTypeId().equals(
-			otherResultColumnType.getTypeId()
-				)
-			)
-		{
-			/* If the source is a constant of a different type then
-			 * we try to convert that constant to a constant of our
-			 * type. (The initial implementation only does the conversion
-			 * to string types because the most common problem is a char
-			 * constant with a varchar column.)  
-			 * NOTE: We do not attempt any conversion here if the source
-			 * is a string type and the target is not or vice versa in 
-			 * order to avoid problems with implicit varchar conversions.
-			 * Anyway, we will check if the "converted" constant has the
-			 * same type as the original constant.  If not, then the conversion
-			 * happened.  In that case, we will reuse the ConstantNode, for simplicity,
-			 * and reset the type to match the desired type.
-			 */
-			if (otherExpression instanceof ConstantNode)
-			{
-				ConstantNode constant = (ConstantNode)otherColumn.getExpression();
-				DataValueDescriptor oldValue = constant.getValue();
-
-				DataValueDescriptor newValue = convertConstant(
-					resultColumnType.getTypeId(),
-					resultColumnType.getMaximumWidth(), 
-					oldValue);
-
-				if ((oldValue != newValue) &&
-					(oldValue instanceof StringDataValue ==
-					 newValue instanceof StringDataValue))
-				{
-					constant.setValue(newValue);
-					constant.setType(getTypeServices());
-					otherColumn.bindResultColumnToExpression();
-					otherResultColumnType = otherColumn.getType();
-				}
-				//If we are dealing with StringDataValue, then make sure we 
-				//have correct collation type and derivaiton set and the value
-				//represented by collation is either SQLxxx or CollatorSQLxxx
-				//depending on the collation type.
-				if (newValue instanceof StringDataValue)
-				{
+        if (SanityManager.DEBUG)
+        {
+            SanityManager.ASSERT(resultColumnType != null,
+                                 "Type is null for column " + this);
+            SanityManager.ASSERT(otherResultColumnType != null,
+                                 "Type is null for column " + otherColumn);
+        }
+
+        /*
+        ** We can never make any assumptions about
+        ** parameters.  So don't even bother in this
+        ** case.
+        */
+        if ((otherExpression != null) && (otherExpression.requiresTypeFromContext()) ||
+            (_expression.requiresTypeFromContext()))
+        {
+            return false;
+        }
+
+        // Are we inserting/updating an XML column?  If so, we always
+        // return false so that normalization will occur.  We have to
+        // do this because there are different "kinds" of XML values
+        // and we need to make sure they match--but we don't know
+        // the "kind" until execution time.  See the "normalize"
+        // method in org.apache.derby.iapi.types.XML for more.
+        if (resultColumnType.getTypeId().isXMLTypeId())
+            return false;
+
+        /* Are they the same type? */
+        if ( ! resultColumnType.getTypeId().equals(
+                 otherResultColumnType.getTypeId()
+                 )
+            )
+        {
+            /* If the source is a constant of a different type then
+             * we try to convert that constant to a constant of our
+             * type. (The initial implementation only does the conversion
+             * to string types because the most common problem is a char
+             * constant with a varchar column.)  
+             * NOTE: We do not attempt any conversion here if the source
+             * is a string type and the target is not or vice versa in 
+             * order to avoid problems with implicit varchar conversions.
+             * Anyway, we will check if the "converted" constant has the
+             * same type as the original constant.  If not, then the conversion
+             * happened.  In that case, we will reuse the ConstantNode, for simplicity,
+             * and reset the type to match the desired type.
+             */
+            if (otherExpression instanceof ConstantNode)
+            {
+                ConstantNode constant = (ConstantNode)otherColumn.getExpression();
+                DataValueDescriptor oldValue = constant.getValue();
+
+                DataValueDescriptor newValue = convertConstant(
+                    resultColumnType.getTypeId(),
+                    resultColumnType.getMaximumWidth(), 
+                    oldValue);
+
+                if ((oldValue != newValue) &&
+                    (oldValue instanceof StringDataValue ==
+                     newValue instanceof StringDataValue))
+                {
+                    constant.setValue(newValue);
+                    constant.setType(getTypeServices());
+                    otherColumn.bindResultColumnToExpression();
+                    otherResultColumnType = otherColumn.getType();
+                }
+                //If we are dealing with StringDataValue, then make sure we 
+                //have correct collation type and derivaiton set and the value
+                //represented by collation is either SQLxxx or CollatorSQLxxx
+                //depending on the collation type.
+                if (newValue instanceof StringDataValue)
+                {
                     constant.setCollationInfo(resultColumnType);
                     
-					DataValueFactory dvf = getDataValueFactory();
-					newValue = ((StringDataValue)newValue).getValue(dvf.getCharacterCollator(
-							constant.getTypeServices().getCollationType()));
-					constant.setValue(newValue);
-				}
-			}
-			if ( ! resultColumnType.getTypeId().equals(
-				otherResultColumnType.getTypeId()
-					)
-				)
-			{
-				return false;
-			}
-		}
-
-		/* Are they the same precision? */
-		if (resultColumnType.getPrecision() !=
-										otherResultColumnType.getPrecision())
-		{
-			return false;
-		}
-
-		/* Are they the same scale? */
-		if (resultColumnType.getScale() != otherResultColumnType.getScale())
-		{
-			return false;
-		}
-
-		/* Are they the same width? */
-		if (resultColumnType.getMaximumWidth() !=
-										otherResultColumnType.getMaximumWidth())
-		{
-			return false;
-		}
-
-		/* Is the source nullable and the target non-nullable? 
-		 * The source is nullable if it is nullable or if the target is generated
-		 * for an unmatched column in an insert with a column list.
-		 * This additional check is needed because when we generate any additional
-		 * source RCs for an insert with a column list the generated RCs for any 
-		 * non-specified columns get the type info from the column.  Thus, 
-		 * for t1(non_nullable, nullable)
-		 *	insert into t2 (nullable) values 1;
-		 * RCType.isNullable() returns false for the generated source RC for 
-		 * non_nullable.  In this case, we want to see it as
-		 */
-		if ((! resultColumnType.isNullable()) &&
-					(otherResultColumnType.isNullable() || 
-					 otherColumn.isGeneratedForUnmatchedColumnInInsert()))
-		{
-			return false;
-		}
-
-		return true;
-	}
-
-	/**
-	 * Is this a generated column?
-	 *
-	 * @return Boolean - whether or not this column is a generated column.
-	 */
-    boolean isGenerated()
-	{
-		return (_isGenerated == true);
-	}
-
-	/**
-	 * Is this columm generated for an unmatched column in an insert?
-	 *
-	 * @return Boolean - whether or not this columm was generated for an unmatched column in an insert.
-	 */
-    boolean isGeneratedForUnmatchedColumnInInsert()
-	{
-		return (_isGeneratedForUnmatchedColumnInInsert == true);
-	}
-
-	/**
-	 * Mark this a columm as a generated column
-	 */
-    void markGenerated()
-	{
-		_isGenerated = true;
-		/* A generated column is a referenced column */
-		_isReferenced = true;
-	}
-
-	/**
-	 * Mark this a columm as generated for an unmatched column in an insert
-	 */
-    void markGeneratedForUnmatchedColumnInInsert()
-	{
-		_isGeneratedForUnmatchedColumnInInsert = true;
-		/* A generated column is a referenced column */
-		_isReferenced = true;
-	}
-
-	/**
-	 * Is this a referenced column?
-	 *
-	 * @return Boolean - whether or not this column is a referenced column.
-	 */
-    boolean isReferenced()
-	{
-		return _isReferenced;
-	}
-
-	/**
-	 * Mark this column as a referenced column.
-	 */
-    void setReferenced()
-	{
-		_isReferenced = true;
-	}
+                    DataValueFactory dvf = getDataValueFactory();
+                    newValue = ((StringDataValue)newValue).getValue(dvf.getCharacterCollator(
+                                                                        constant.getTypeServices().getCollationType()));
+                    constant.setValue(newValue);
+                }
+            }
+            if ( ! resultColumnType.getTypeId().equals(
+                     otherResultColumnType.getTypeId()
+                     )
+                )
+            {
+                return false;
+            }
+        }
+
+        /* Are they the same precision? */
+        if (resultColumnType.getPrecision() !=
+            otherResultColumnType.getPrecision())
+        {
+            return false;
+        }
+
+        /* Are they the same scale? */
+        if (resultColumnType.getScale() != otherResultColumnType.getScale())
+        {
+            return false;
+        }
+
+        /* Are they the same width? */
+        if (resultColumnType.getMaximumWidth() !=
+            otherResultColumnType.getMaximumWidth())
+        {
+            return false;
+        }
+
+        /* Is the source nullable and the target non-nullable? 
+         * The source is nullable if it is nullable or if the target is generated
+         * for an unmatched column in an insert with a column list.
+         * This additional check is needed because when we generate any additional
+         * source RCs for an insert with a column list the generated RCs for any 
+         * non-specified columns get the type info from the column.  Thus, 
+         * for t1(non_nullable, nullable)
+         *	insert into t2 (nullable) values 1;
+         * RCType.isNullable() returns false for the generated source RC for 
+         * non_nullable.  In this case, we want to see it as
+         */
+        if ((! resultColumnType.isNullable()) &&
+            (otherResultColumnType.isNullable() || 
+             otherColumn.isGeneratedForUnmatchedColumnInInsert()))
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Is this a generated column?
+     *
+     * @return Boolean - whether or not this column is a generated column.
+     */
+    boolean isGenerated() {
+        return (_isGenerated == true);
+    }
+
+    /**
+     * Is this columm generated for an unmatched column in an insert?
+     *
+     * @return Boolean - whether or not this columm was generated for an unmatched column in an insert.
+     */
+    boolean isGeneratedForUnmatchedColumnInInsert() {
+        return (_isGeneratedForUnmatchedColumnInInsert == true);
+    }
+
+    /**
+     * Mark this a columm as a generated column
+     */
+    void markGenerated() {
+        _isGenerated = true;
+        /* A generated column is a referenced column */
+        _isReferenced = true;
+    }
+
+    /**
+     * Mark this a columm as generated for an unmatched column in an insert
+     */
+    void markGeneratedForUnmatchedColumnInInsert() {
+        _isGeneratedForUnmatchedColumnInInsert = true;
+        /* A generated column is a referenced column */
+        _isReferenced = true;
+    }
+
+    /**
+     * Is this a referenced column?
+     *
+     * @return Boolean - whether or not this column is a referenced column.
+     */
+    boolean isReferenced() {
+        return _isReferenced;
+    }
+
+    /**
+     * Mark this column as a referenced column.
+     */
+    void setReferenced() {
+        _isReferenced = true;
+    }
 
     /**
      * Mark this column as a referenced column if it is already marked as referenced or if any result column in
      * its chain of virtual columns is marked as referenced.
      */
-    void pullVirtualIsReferenced()
-    {
+    void pullVirtualIsReferenced() {
         if( isReferenced())
             return;
         
@@ -1382,232 +1328,218 @@ class ResultColumn extends ValueNode
         }
     } // end of pullVirtualIsReferenced
 
-	/**
-	 * Mark this column as an unreferenced column.
-	 */
-    void setUnreferenced()
-	{
-		_isReferenced = false;
-	}
-
-	/**
- 	 * Mark this RC and all RCs in the underlying
-	 * RC/VCN chain as referenced.
-	 */
-	void markAllRCsInChainReferenced()
-	{
-		setReferenced();
-
-		ValueNode vn = _expression;
-
-		while (vn instanceof VirtualColumnNode)
-		{
-			VirtualColumnNode vcn = (VirtualColumnNode) vn;
-			ResultColumn rc = vcn.getSourceColumn();
-			rc.setReferenced();
-			vn = rc.getExpression();
-		}
-	}
-
-	/**
-	 * Is this a redundant ResultColumn?
-	 *
-	 * @return Boolean - whether or not this RC is redundant.
-	 */
-    boolean isRedundant()
-	{
-		return _isRedundant;
-	}
-
-	/**
-	 * Mark this ResultColumn as redundant.
-	 */
-    void setRedundant()
-	{
-		_isRedundant = true;
-	}
-
-	/**
-	 * Mark this ResultColumn as a grouping column in the SELECT list
-	 */
-    void markAsGroupingColumn()
-	{
-		_isGroupingColumn = true;
-	}
-
-	/**
-	 * Look for and reject ?/-?/+? parameter under this ResultColumn.  This is
-	 * called for SELECT statements.
-	 *
-	 * @exception StandardException		Thrown if a ?/-?/+? parameter was found
-	 *									directly under this ResultColumn.
-	 */
-
-	void rejectParameter() throws StandardException
-	{
-		if ((_expression != null) && (_expression.isParameterNode()))
-			throw StandardException.newException(SQLState.LANG_PARAM_IN_SELECT_LIST);
-	}
-
-	/*
-	** The following methods implement the Comparable interface.
-	*/
-    public int compareTo(ResultColumn other)
-	{
+    /**
+     * Mark this column as an unreferenced column.
+     */
+    void setUnreferenced() {
+        _isReferenced = false;
+    }
+
+    /**
+     * Mark this RC and all RCs in the underlying
+     * RC/VCN chain as referenced.
+     */
+    void markAllRCsInChainReferenced() {
+        setReferenced();
+
+        ValueNode vn = _expression;
+
+        while (vn instanceof VirtualColumnNode)
+        {
+            VirtualColumnNode vcn = (VirtualColumnNode) vn;
+            ResultColumn rc = vcn.getSourceColumn();
+            rc.setReferenced();
+            vn = rc.getExpression();
+        }
+    }
+
+    /**
+     * Is this a redundant ResultColumn?
+     *
+     * @return Boolean - whether or not this RC is redundant.
+     */
+    boolean isRedundant() {
+        return _isRedundant;
+    }
+
+    /**
+     * Mark this ResultColumn as redundant.
+     */
+    void setRedundant() {
+        _isRedundant = true;
+    }
+
+    /**
+     * Mark this ResultColumn as a grouping column in the SELECT list
+     */
+    void markAsGroupingColumn() {
+        _isGroupingColumn = true;
+    }
+
+    /**
+     * Look for and reject ?/-?/+? parameter under this ResultColumn.  This is
+     * called for SELECT statements.
+     *
+     * @exception StandardException		Thrown if a ?/-?/+? parameter was found
+     *									directly under this ResultColumn.
+     */
+
+    void rejectParameter() throws StandardException {
+        if ((_expression != null) && (_expression.isParameterNode()))
+            throw StandardException.newException(SQLState.LANG_PARAM_IN_SELECT_LIST);
+    }
+
+    /*
+    ** The following methods implement the Comparable interface.
+    */
+    public int compareTo(ResultColumn other) {
         ResultColumn otherResultColumn = other;
 
-		return this.getColumnPosition() - otherResultColumn.getColumnPosition();
-	}
+        return this.getColumnPosition() - otherResultColumn.getColumnPosition();
+    }
 
-	/**
+    /**
      * Mark this column as being updated by an update statement.
-	 */
-	void markUpdated()
-	{
-		_updated = true;
-	}
-
-	/**
-	 * Mark this column as being updatable, so we can make sure it is in the
-	 * "for update" list of a positioned update.
-	 */
-	void markUpdatableByCursor()
-	{
-		_updatableByCursor = true;
-	}
-
-	/**
-	 * Tell whether this column is being updated.
-	 *
-	 * @return	true means this column is being updated.
-	 */
-	boolean updated()
-	{
-		return _updated;
-	}
-
-	/**
-	 * Tell whether this column is updatable by a positioned update.
-	 *
-	 * @return	true means this column is updatable
-	 */
+     */
+    void markUpdated() {
+        _updated = true;
+    }
+
+    /**
+     * Mark this column as being updatable, so we can make sure it is in the
+     * "for update" list of a positioned update.
+     */
+    void markUpdatableByCursor() {
+        _updatableByCursor = true;
+    }
+
+    /**
+     * Tell whether this column is being updated.
+     *
+     * @return	true means this column is being updated.
+     */
+    boolean updated() {
+        return _updated;
+    }
+
+    /**
+     * Tell whether this column is updatable by a positioned update.
+     *
+     * @return	true means this column is updatable
+     */
     @Override
-	public boolean updatableByCursor()
-	{
-		return _updatableByCursor;
-	}
-
-	/**
-	 * Make a copy of this ResultColumn in a new ResultColumn
-	 *
-	 * @return	A new ResultColumn with the same contents as this one
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	ResultColumn cloneMe() throws StandardException
-	{
-		ResultColumn	newResultColumn;
-		ValueNode		cloneExpr;
-
-		/* If expression is a ColumnReference, then we want to 
-		 * have the RC's clone have a clone of the ColumnReference
-		 * for it's expression.  This is for the special case of
-		 * cloning the SELECT list for the HAVING clause in the parser.
-		 * The SELECT generated for the HAVING needs its own copy
-		 * of the ColumnReferences.
-		 */
-		if (_expression instanceof ColumnReference)
-		{
-			cloneExpr = ((ColumnReference) _expression).getClone();
-		}
-		else
-		{
-			cloneExpr = _expression;
-		}
-
-		/* If a columnDescriptor exists, then we must propagate it */
-		if (_columnDescriptor != null)
-		{
+    public boolean updatableByCursor() {
+        return _updatableByCursor;
+    }
+
+    /**
+     * Make a copy of this ResultColumn in a new ResultColumn
+     *
+     * @return	A new ResultColumn with the same contents as this one
+     *
+     * @exception StandardException		Thrown on error
+     */
+    ResultColumn cloneMe() throws StandardException {
+        ResultColumn	newResultColumn;
+        ValueNode		cloneExpr;
+
+        /* If expression is a ColumnReference, then we want to 
+         * have the RC's clone have a clone of the ColumnReference
+         * for it's expression.  This is for the special case of
+         * cloning the SELECT list for the HAVING clause in the parser.
+         * The SELECT generated for the HAVING needs its own copy
+         * of the ColumnReferences.
+         */
+        if (_expression instanceof ColumnReference)
+        {
+            cloneExpr = ((ColumnReference) _expression).getClone();
+        }
+        else
+        {
+            cloneExpr = _expression;
+        }
+
+        /* If a columnDescriptor exists, then we must propagate it */
+        if (_columnDescriptor != null)
+        {
             newResultColumn = new ResultColumn(
-                    _columnDescriptor, _expression, getContextManager());
-			newResultColumn.setExpression(cloneExpr);
-		}
-		else
-		{
+                _columnDescriptor, _expression, getContextManager());
+            newResultColumn.setExpression(cloneExpr);
+        }
+        else
+        {
             newResultColumn = new ResultColumn(
-                    getName(), cloneExpr, getContextManager());
-		}
+                getName(), cloneExpr, getContextManager());
+        }
 
-		/* Set the VirtualColumnId and name in the new node */
-		newResultColumn.setVirtualColumnId(getVirtualColumnId());
+        /* Set the VirtualColumnId and name in the new node */
+        newResultColumn.setVirtualColumnId(getVirtualColumnId());
 
-		/* Set the type and name information in the new node */
-		newResultColumn.setName(getName());
-		newResultColumn.setType(getTypeServices());
-		newResultColumn.setNameGenerated(isNameGenerated());
-
-		// For OFFSET/FETCH we need the also clone table name to avoid failing
-		// check #2 in EmbedResultSet#checksBeforeUpdateXXX. Clone schema for
-		// good measure...
-		newResultColumn.setSourceTableName(getSourceTableName());
-		newResultColumn.setSourceSchemaName(getSourceSchemaName());
-
-		/* Set the "is generated for unmatched column in insert" status in the new node
-		This if for bug 4194*/
-		if (isGeneratedForUnmatchedColumnInInsert())
-			newResultColumn.markGeneratedForUnmatchedColumnInInsert();
-
-		/* Set the "is referenced" status in the new node */
-		if (isReferenced())
-			newResultColumn.setReferenced();
-
-		/* Set the "updated" status in the new node */
-		if (updated())
-			newResultColumn.markUpdated();
-
-		/* Setthe "updatable by cursor" status in the new node */
-		if (updatableByCursor())
-			newResultColumn.markUpdatableByCursor();
-
-		if (isAutoincrementGenerated())
-			newResultColumn.setAutoincrementGenerated();
-
-  		if (isAutoincrement())
-  			newResultColumn.setAutoincrement();
-  		if (isGroupingColumn()) 
-  			newResultColumn.markAsGroupingColumn();
+        /* Set the type and name information in the new node */
+        newResultColumn.setName(getName());
+        newResultColumn.setType(getTypeServices());

[... 620 lines stripped ...]