Class ResultColumn

All Implemented Interfaces:
Comparable<ResultColumn>, Visitable, ResultColumnDescriptor
Direct Known Subclasses:
AllResultColumn

class ResultColumn extends ValueNode implements ResultColumnDescriptor, Comparable<ResultColumn>
A ResultColumn represents a result column in a SELECT, INSERT, or UPDATE statement. In a SELECT statement, the result column just represents an expression in a row being returned to the client. For INSERT and UPDATE statements, the result column represents an column in a stored table. So, a ResultColumn has to be bound differently depending on the type of statement it appears in.

The type of the ResultColumn can differ from its underlying expression, for example in certain joins the ResultColumn can be nullable even if its underlying column is not. In an INSERT or UPDATE the ResultColumn will represent the type of the column in the table, the type of the underlying expression will be the type of the source of the value to be insert or updated. The method columnTypeAndLengthMatch() can be used to detect when normalization is required between the expression and the type of ResultColumn. This class does not implement any type normalization (conversion), this is typically handled by a NormalizeResultSetNode.

  • Field Details

    • _underlyingName

      private String _underlyingName
    • _derivedColumnName

      private String _derivedColumnName
    • _unqualifiedTableName

      private String _unqualifiedTableName
    • _unqualifiedSourceTableName

      private String _unqualifiedSourceTableName
    • _sourceSchemaName

      private String _sourceSchemaName
    • _expression

      private ValueNode _expression
    • _columnDescriptor

      private ColumnDescriptor _columnDescriptor
    • _isGenerated

      private boolean _isGenerated
    • _isGeneratedForUnmatchedColumnInInsert

      private boolean _isGeneratedForUnmatchedColumnInInsert
    • _isGroupingColumn

      private boolean _isGroupingColumn
    • _isReferenced

      private boolean _isReferenced
    • _isRedundant

      private boolean _isRedundant
    • _isNameGenerated

      private boolean _isNameGenerated
    • _updated

      private boolean _updated
    • _updatableByCursor

      private boolean _updatableByCursor
    • defaultColumn

      private boolean defaultColumn
    • wasDefault

      private boolean wasDefault
    • rightOuterJoinUsingClause

      private boolean rightOuterJoinUsingClause
    • joinResultSet

      private JoinNode joinResultSet
    • _autoincrementGenerated

      private boolean _autoincrementGenerated
    • _autoincrement

      private boolean _autoincrement
    • resultSetNumber

      private int resultSetNumber
    • _reference

      private ColumnReference _reference
    • virtualColumnId

      private int virtualColumnId
  • Constructor Details

  • Method Details

    • setTypeExpressionAndDefault

      private void setTypeExpressionAndDefault(ValueNode expression)
    • isRightOuterJoinUsingClause

      boolean isRightOuterJoinUsingClause()
      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.
    • setRightOuterJoinUsingClause

      void setRightOuterJoinUsingClause(boolean value)
      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).
      Parameters:
      value - True/False
    • getJoinResultSet

      JoinNode getJoinResultSet()
      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.
    • setJoinResultset

      void setJoinResultset(JoinNode 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"
      Parameters:
      resultSet - - The ResultColumn belongs to this JoinNode
    • isDefaultColumn

      boolean isDefaultColumn()
      Returns TRUE if the ResultColumn is standing in for a DEFAULT keyword in an insert/update statement.
    • setDefaultColumn

      void setDefaultColumn(boolean value)
    • wasDefaultColumn

      boolean wasDefaultColumn()
      Returns TRUE if the ResultColumn used to stand in for a DEFAULT keyword in an insert/update statement.
    • setWasDefaultColumn

      void setWasDefaultColumn(boolean value)
    • columnNameMatches

      boolean columnNameMatches(String columnName)
      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.
    • getUnderlyingOrAliasName

      String getUnderlyingOrAliasName()
      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);
    • isUpdatable

      boolean isUpdatable()
      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.
      Returns:
      true if this result column is updatable.
    • getSourceColumnName

      String getSourceColumnName()
      Returns the underlying source column name, if this ResultColumn is a simple direct reference to a table column, or NULL otherwise.
    • getName

      public String getName()
      The following methods implement the ResultColumnDescriptor interface. See the Language Module Interface for details.
      Specified by:
      getName in interface ResultColumnDescriptor
      Returns:
      A String containing the name of the column.
    • getSchemaName

      String getSchemaName() throws StandardException
      Description copied from class: ValueNode
      This returns the user-supplied schema name of the column. At this class level, it simply returns null. But, the subclasses of ValueNode will overwrite this method to return the user-supplied schema name. When the value node is in a result column of a select list, the user can request metadata information. The result column won't have a column descriptor, so we return some default information through the expression. This lets expressions that are simply columns return all of the info, and others use this supertype's default values.
      Overrides:
      getSchemaName in class ValueNode
      Returns:
      the default schema name for an expression -- null
      Throws:
      StandardException
    • getTableName

      String getTableName()
      Description copied from class: ValueNode
      This returns the user-supplied table name of the column. At this class level, it simply returns null. But, the subclasses of ValueNode will overwrite this method to return the user-supplied table name. When the value node is in a result column of a select list, the user can request metadata information. The result column won't have a column descriptor, so we return some default information through the expression. This lets expressions that are simply columns return all of the info, and others use this supertype's default values.
      Overrides:
      getTableName in class ValueNode
      Returns:
      the default table name for an expression -- null
    • getSourceTableName

      public String getSourceTableName()
      Description copied from interface: ResultColumnDescriptor
      Get the name of the underlying(base) table this column comes from, if any. Following example queries will all return T select a from t select b.a from t as b select t.a from t
      Specified by:
      getSourceTableName in interface ResultColumnDescriptor
      Returns:
      A String containing the name of the base table of the Column is in. If the column is not in a table (i.e. is a derived column), it returns NULL. The name of the Column's base table. If the column is not in a schema (i.e. is a derived column), it returns NULL.
      See Also:
    • getSourceSchemaName

      public String getSourceSchemaName()
      Description copied from interface: ResultColumnDescriptor
      Get the name of the schema for the Column's base table, if any. Following example queries will all return APP (assuming user is in schema APP) select t.a from t select b.a from t as b select app.t.a from t
      Specified by:
      getSourceSchemaName in interface ResultColumnDescriptor
      Returns:
      The name of the schema of the Column's base table. If the column is not in a schema (i.e. is a derived column), it returns NULL.
      See Also:
    • clearTableName

      void clearTableName()
      Clear the table name for the underlying ColumnReference. See UpdateNode.scrubResultColumns() for full explaination.
    • getType

      public DataTypeDescriptor getType()
      Description copied from interface: ResultColumnDescriptor
      Returns a DataTypeDescriptor for the column. This DataTypeDescriptor will not represent an actual value, it will only represent the type that all values in the column will have.
      Specified by:
      getType in interface ResultColumnDescriptor
      Returns:
      A DataTypeDescriptor describing the type of the column.
    • getColumnPosition

      public int getColumnPosition()
      Description copied from interface: ResultColumnDescriptor
      Get the position of the Column. NOTE - position is 1-based.
      Specified by:
      getColumnPosition in interface ResultColumnDescriptor
      Returns:
      An int containing the position of the Column within the table.
    • setExpression

      void setExpression(ValueNode expression)
      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.
      Parameters:
      expression - The expression to be set in this ResultColumn
    • getExpression

      ValueNode getExpression()
      Get the expression in this ResultColumn.
      Returns:
      ValueNode this.expression
    • setExpressionToNullNode

      void setExpressionToNullNode() throws StandardException
      Set the expression to a null node of the correct type.
      Throws:
      StandardException - Thrown on error
    • setName

      void setName(String name)
      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.
      Parameters:
      name - The name to set in this ResultColumn
    • isNameGenerated

      boolean isNameGenerated()
      Is the name for this ResultColumn generated?
    • setNameGenerated

      void setNameGenerated(boolean value)
      Set that this result column name is generated.
    • setResultSetNumber

      void setResultSetNumber(int resultSetNumber)
      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.
      Parameters:
      resultSetNumber - The resultSetNumber.
    • getResultSetNumber

      public int getResultSetNumber()
      Get the resultSetNumber for this ResultColumn.
      Returns:
      int The resultSetNumber.
    • adjustVirtualColumnId

      void adjustVirtualColumnId(int adjust)
      Adjust the virtualColumnId for this ResultColumn by the specified amount
      Parameters:
      adjust - The adjustment for the virtualColumnId
    • setVirtualColumnId

      void setVirtualColumnId(int id)
      Set the virtualColumnId for this ResultColumn
      Parameters:
      id - The virtualColumnId for this ResultColumn
    • getVirtualColumnId

      int getVirtualColumnId()
      Get the virtualColumnId for this ResultColumn
      Returns:
      virtualColumnId for this ResultColumn
    • collapseVirtualColumnIdGap

      void collapseVirtualColumnIdGap(int removedColumnId)
      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.
      Parameters:
      removedColumnId - id of the column being removed.
    • guaranteeColumnName

      void guaranteeColumnName() throws StandardException
      Generate a unique (across the entire statement) column name for unnamed ResultColumns
      Throws:
      StandardException - Thrown on error
    • toString

      public 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 ValueNode
      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 QueryTreeNode
      Parameters:
      depth - The depth of this node in the tree
    • bindExpression

      ResultColumn bindExpression(FromList fromList, SubqueryList subqueryList, List<AggregateNode> aggregates) throws StandardException
      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.
      Overrides:
      bindExpression in class ValueNode
      Parameters:
      fromList - The FROM list for the query this expression is in, for binding columns.
      subqueryList - The subquery list being built as we find SubqueryNodes
      aggregates - The aggregate list being built as we find AggregateNodes
      Returns:
      The new top of the expression tree.
      Throws:
      StandardException - Thrown on error
    • bindResultColumnByPosition

      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.
      Parameters:
      tableDescriptor - The descriptor for the table being inserted into
      columnId - The ordinal position of the column in the table, starting at 1.
      Throws:
      StandardException - Thrown on error
    • bindResultColumnByName

      void bindResultColumnByName(TableDescriptor tableDescriptor, int columnId) throws StandardException
      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.
      Parameters:
      tableDescriptor - The descriptor for the table being updated or inserted into
      columnId - The ordinal position of the column in the table, starting at 1. (Used to set the VirtualColumnId.)
      Throws:
      StandardException - Thrown on error
    • typeUntypedNullExpression

      void typeUntypedNullExpression(ResultColumn bindingRC) throws StandardException
      Change an untyped null to a typed null.
      Throws:
      StandardException - Thrown on error
    • setColumnDescriptor

      void setColumnDescriptor(TableDescriptor tableDescriptor, ColumnDescriptor columnDescriptor) throws StandardException
      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.
      Parameters:
      tableDescriptor - The TableDescriptor for the table being updated or inserted into. This parameter is used only for error reporting.
      columnDescriptor - The ColumnDescriptor to set in this ResultColumn.
      Throws:
      StandardException - tableNameMismatch
    • bindResultColumnToExpression

      void bindResultColumnToExpression() throws StandardException
      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.
      Throws:
      StandardException - Thrown on error
    • setSourceTableName

      void setSourceTableName(String t)
      Set the column source's table name
      Parameters:
      t - The source table name
    • setSourceSchemaName

      void setSourceSchemaName(String s)
      Set the column source's schema name
      Parameters:
      s - The source schema name
    • preprocess

      ResultColumn preprocess(int numTables, FromList outerFromList, SubqueryList outerSubqueryList, PredicateList outerPredicateList) throws StandardException
      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.
      Overrides:
      preprocess in class ValueNode
      Parameters:
      numTables - Number of tables in the DML Statement
      outerFromList - FromList from outer query block
      outerSubqueryList - SubqueryList from outer query block
      outerPredicateList - PredicateList from outer query block
      Returns:
      The modified expression
      Throws:
      StandardException - Thrown on error
    • checkStorableExpression

      void checkStorableExpression(ResultColumn toStore) throws StandardException
      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.
      Throws:
      StandardException - thrown if types not suitable.
    • checkStorableExpression

      private void checkStorableExpression(ValueNode source) throws StandardException
      Throws:
      StandardException
    • checkStorableExpression

      void checkStorableExpression() throws StandardException
      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.
      Throws:
      StandardException - thrown if types not suitable.
    • generateExpression

      void generateExpression(ExpressionClassBuilder ecb, MethodBuilder mb) throws StandardException
      Do code generation for a result column. This consists of doing the code generation for the underlying expression.
      Overrides:
      generateExpression in class ValueNode
      Parameters:
      ecb - The ExpressionClassBuilder for the class we're generating
      mb - The method the expression will go into
      Throws:
      StandardException - Thrown on error
    • columnTypeAndLengthMatch

      boolean columnTypeAndLengthMatch() throws StandardException
      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.
      Returns:
      true means the column matches its expressions, false means it doesn't match.
      Throws:
      StandardException
    • columnTypeAndLengthMatch

      boolean columnTypeAndLengthMatch(ResultColumn otherColumn) throws StandardException
      Throws:
      StandardException
    • isGenerated

      boolean isGenerated()
      Is this a generated column?
      Returns:
      Boolean - whether or not this column is a generated column.
    • isGeneratedForUnmatchedColumnInInsert

      boolean isGeneratedForUnmatchedColumnInInsert()
      Is this columm generated for an unmatched column in an insert?
      Returns:
      Boolean - whether or not this columm was generated for an unmatched column in an insert.
    • markGenerated

      void markGenerated()
      Mark this a columm as a generated column
    • markGeneratedForUnmatchedColumnInInsert

      void markGeneratedForUnmatchedColumnInInsert()
      Mark this a columm as generated for an unmatched column in an insert
    • isReferenced

      boolean isReferenced()
      Is this a referenced column?
      Returns:
      Boolean - whether or not this column is a referenced column.
    • setReferenced

      void setReferenced()
      Mark this column as a referenced column.
    • pullVirtualIsReferenced

      void pullVirtualIsReferenced()
      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.
    • setUnreferenced

      void setUnreferenced()
      Mark this column as an unreferenced column.
    • markAllRCsInChainReferenced

      void markAllRCsInChainReferenced()
      Mark this RC and all RCs in the underlying RC/VCN chain as referenced.
    • isRedundant

      boolean isRedundant()
      Is this a redundant ResultColumn?
      Returns:
      Boolean - whether or not this RC is redundant.
    • setRedundant

      void setRedundant()
      Mark this ResultColumn as redundant.
    • markAsGroupingColumn

      void markAsGroupingColumn()
      Mark this ResultColumn as a grouping column in the SELECT list
    • rejectParameter

      void rejectParameter() throws StandardException
      Look for and reject ?/-?/+? parameter under this ResultColumn. This is called for SELECT statements.
      Throws:
      StandardException - Thrown if a ?/-?/+? parameter was found directly under this ResultColumn.
    • compareTo

      public int compareTo(ResultColumn other)
      Specified by:
      compareTo in interface Comparable<ResultColumn>
    • markUpdated

      void markUpdated()
      Mark this column as being updated by an update statement.
    • markUpdatableByCursor

      void markUpdatableByCursor()
      Mark this column as being updatable, so we can make sure it is in the "for update" list of a positioned update.
    • updated

      boolean updated()
      Tell whether this column is being updated.
      Returns:
      true means this column is being updated.
    • updatableByCursor

      public boolean updatableByCursor()
      Tell whether this column is updatable by a positioned update.
      Specified by:
      updatableByCursor in interface ResultColumnDescriptor
      Overrides:
      updatableByCursor in class ValueNode
      Returns:
      true means this column is updatable
    • cloneMe

      Make a copy of this ResultColumn in a new ResultColumn
      Returns:
      A new ResultColumn with the same contents as this one
      Throws:
      StandardException - Thrown on error
    • getMaximumColumnSize

      int getMaximumColumnSize()
      Get the maximum size of the column
      Returns:
      the max size
    • getTypeServices

      public DataTypeDescriptor getTypeServices()
      Description copied from class: ValueNode
      Get the DataTypeServices from this ValueNode.
      Overrides:
      getTypeServices in class ValueNode
      Returns:
      The DataTypeServices from this ValueNode. This may be null if the node isn't bound yet.
    • getOrderableVariantType

      protected int getOrderableVariantType() throws StandardException
      Return the variant type for the underlying expression. The variant type can be: VARIANT - variant within a scan (method calls and non-static field access) SCAN_INVARIANT - invariant within a scan (column references from outer tables) QUERY_INVARIANT - invariant within the life of a query CONSTANT - constant
      Overrides:
      getOrderableVariantType in class ValueNode
      Returns:
      The variant type for the underlying expression.
      Throws:
      StandardException - thrown on error
    • acceptChildren

      void acceptChildren(Visitor v) throws StandardException
      Accept the visitor for all visitable children of this node.
      Overrides:
      acceptChildren in class QueryTreeNode
      Parameters:
      v - the visitor
      Throws:
      StandardException - on error
    • verifyOrderable

      void verifyOrderable() throws StandardException
      Verify that this RC is orderable.
      Throws:
      StandardException - Thrown on error
    • getTableColumnDescriptor

      ColumnDescriptor getTableColumnDescriptor()
      If this ResultColumn is bound to a column in a table get the column descriptor for the column in the table. Otherwise return null.
    • isAutoincrementGenerated

      boolean isAutoincrementGenerated()
      Returns true if this result column is a placeholder for a generated autoincrement value.
    • setAutoincrementGenerated

      void setAutoincrementGenerated()
    • resetAutoincrementGenerated

      void resetAutoincrementGenerated()
    • isAutoincrement

      public boolean isAutoincrement()
      Description copied from interface: ResultColumnDescriptor
      Tell us if the column is an autoincrement column or not.
      Specified by:
      isAutoincrement in interface ResultColumnDescriptor
      Returns:
      TRUE, if the column is a base column of a table and is an autoincrement column.
    • setAutoincrement

      void setAutoincrement()
    • isGroupingColumn

      public boolean isGroupingColumn()
    • convertConstant

      private DataValueDescriptor convertConstant(TypeId toTypeId, int maxWidth, DataValueDescriptor constantValue) throws StandardException
      Throws:
      StandardException - Thrown on error
    • getTableNameObject

      public TableName getTableNameObject()
    • getReference

      public ColumnReference getReference()
    • getColumnDescriptor

      ColumnDescriptor getColumnDescriptor()
      Get the column descriptor
    • getBaseColumnNode

      BaseColumnNode getBaseColumnNode()
      Get the source BaseColumnNode for this result column. The BaseColumnNode cannot be found unless the ResultColumn is bound and is a simple reference to a column in a BaseFromTable.
      Returns:
      a BaseColumnNode, or null if a BaseColumnNode cannot be found
    • getTableNumber

      int getTableNumber() throws StandardException
      Search the tree beneath this ResultColumn until we find the number of the table to which this RC points, and return that table number. If we can't determine which table this RC is for, then return -1. There are two places we can find the table number: 1) if our expression is a ColumnReference, then we can get the target table number from the ColumnReference and that's it; 2) if expression is a VirtualColumnNode, then if the VirtualColumnNode points to a FromBaseTable, we can get that FBT's table number; otherwise, we walk the VirtualColumnNode-ResultColumn chain and do a recursive search.
      Returns:
      The number of the table to which this ResultColumn points, or -1 if we can't determine that from where we are.
      Throws:
      StandardException
    • isEquivalent

      boolean isEquivalent(ValueNode o) throws StandardException
      Description copied from class: ValueNode
      Tests if this node is equivalent to the specified ValueNode. Two ValueNodes are considered equivalent if they will evaluate to the same value during query execution.

      This method provides basic expression matching facility for the derived class of ValueNode and it is used by the language layer to compare the node structural form of the two expressions for equivalence at bind phase.

      Note that it is not comparing the actual row values at runtime to produce a result; hence, when comparing SQL NULLs, they are considered to be equivalent and not unknown.

      One usage case of this method in this context is to compare the select column expression against the group by expression to check if they are equivalent. e.g.:

      SELECT c1+c2 FROM t1 GROUP BY c1+c2

      In general, node equivalence is determined by the derived class of ValueNode. But they generally abide to the rules below:

      • The two ValueNodes must be of the same node type to be considered equivalent. e.g.: CastNode vs. CastNode - equivalent (if their args also match), ColumnReference vs CastNode - not equivalent.
      • If node P contains other ValueNode(s) and so on, those node(s) must also be of the same node type to be considered equivalent.
      • If node P takes a parameter list, then the number of arguments and its arguments for the two nodes must also match to be considered equivalent. e.g.: CAST(c1 as INTEGER) vs CAST(c1 as SMALLINT), they are not equivalent.
      • When comparing SQL NULLs in this context, they are considered to be equivalent.
      • If this does not apply or it is determined that the two nodes are not equivalent then the derived class of this method should return false; otherwise, return true.
      Specified by:
      isEquivalent in class ValueNode
      Parameters:
      o - the node to compare this ValueNode against.
      Returns:
      true if the two nodes are equivalent, false otherwise.
      Throws:
      StandardException
    • hasGenerationClause

      public boolean hasGenerationClause()
      Return true if this result column represents a generated column.
      Specified by:
      hasGenerationClause in interface ResultColumnDescriptor