/*
* Copyright (c) 2013, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software;Designed and Developed mainly by many Chinese
* opensource volunteers. you can redistribute it and/or modify it under the
* terms of the GNU General Public License version 2 only, as published by the
* Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Any questions about this component can be directed to it's project Web address
* https://code.google.com/p/opencloudb/.
*
*/
package com.akiban.sql.parser;
import com.akiban.sql.StandardException;
import com.akiban.sql.types.DataTypeDescriptor;
/**
* A VirtualColumnNode represents a virtual column reference to a column in
* a row returned by an underlying ResultSetNode. The underlying column could
* be in a base table, view (which could expand into a complex
* expression), subquery in the FROM clause, temp table, expression result, etc.
* By the time we get to code generation, all VirtualColumnNodes should stand only
* for references to columns in a base table within a FromBaseTable.
*
*/
public class VirtualColumnNode extends ValueNode
{
/* A VirtualColumnNode contains a pointer to the immediate child result
* that is materializing the virtual column and the ResultColumn
* that represents that materialization.
*/
private ResultSetNode sourceResultSet;
private ResultColumn sourceColumn;
/* columnId is redundant since a ResultColumn also has one, but
* we need it here for generate()
*/
int columnId;
/**
* Initializer for a VirtualColumnNode.
*
* @param sourceResultSet The ResultSetNode where the value is originating
* @param sourceColumn The ResultColumn where the value is originating
* @param columnId The columnId within the current Row
*/
public void init(Object sourceResultSet,
Object sourceColumn,
Object columnId)
throws StandardException {
ResultColumn source = (ResultColumn)sourceColumn;
this.sourceResultSet = (ResultSetNode)sourceResultSet;
this.sourceColumn = source;
this.columnId = ((Integer)columnId).intValue();
setType(source.getType());
}
/**
* Fill this node with a deep copy of the given node.
*/
public void copyFrom(QueryTreeNode node) throws StandardException {
super.copyFrom(node);
VirtualColumnNode other = (VirtualColumnNode)node;
this.sourceResultSet = (ResultSetNode)
getNodeFactory().copyNode(other.sourceResultSet, getParserContext());
this.sourceColumn = (ResultColumn)
getNodeFactory().copyNode(other.sourceColumn, getParserContext());
this.columnId = other.columnId;
}
/**
* 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 void printSubNodes(int depth) {
super.printSubNodes(depth);
printLabel(depth, "sourceColumn: ");
sourceColumn.treePrint(depth + 1);
printLabel(depth, "sourceResultSet: ");
sourceResultSet.treePrint(depth + 1);
}
/**
* Return the ResultSetNode that is the source of this VirtualColumnNode.
*
* @return ResultSetNode
*/
public ResultSetNode getSourceResultSet() {
return sourceResultSet;
}
/**
* Return the ResultColumn that is the source of this VirtualColumnNode.
*
* @return ResultColumn
*/
public ResultColumn getSourceColumn() {
return sourceColumn;
}
/**
* Get the name of the table the ResultColumn is in, if any. This will be null
* if the user did not supply a name (for example, select a from t).
* The method will return B for this example, select b.a from t as b
* The method will return T for this example, select t.a from t
*
* @return A String containing the name of the table the Column
* is in. If the column is not in a table (i.e. is a
* derived column), it returns NULL.
*/
public String getTableName() {
return sourceColumn.getTableName();
}
/**
* Get the name of the schema the ResultColumn's table is in, if any.
* The return value will be null if the user did not supply a schema name
* (for example, select t.a from t).
* Another example for null return value (for example, select b.a from t as b).
* But for following query select app.t.a from t, this will return APP
*
* @return A String containing the name of the schema for the Column's table.
* If the column is not in a schema (i.e. derived column), it returns NULL.
*/
public String getSchemaName() throws StandardException {
return sourceColumn.getSchemaName();
}
/**
* Get the DataTypeDesciptor from this Node.
*
* @return The DataTypeDescriptor from this Node. This
* may be null if the node isn't bound yet.
*/
public DataTypeDescriptor getType() {
return sourceColumn.getType();
}
public void setType(DataTypeDescriptor dtd) throws StandardException {
sourceColumn.setType(dtd);
}
protected boolean isEquivalent(ValueNode o) throws StandardException {
if (isSameNodeType(o)) {
VirtualColumnNode other = (VirtualColumnNode)o;
return sourceColumn.isEquivalent(other.sourceColumn);
}
return false;
}
}