/* * 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; /** * A ColumnReference represents a column in the query tree. The parser generates a * ColumnReference for each column reference. A column refercence could be a column in * a base table, a column in a view (which could expand into a complex * expression), or a column in a subquery in the FROM clause. * */ public class ColumnReference extends ValueNode { private String columnName; /* ** This is the user-specified table name. It will be null if the ** user specifies a column without a table name. Leave it null even ** when the column is bound as it is only used in binding. */ private TableName tableName; /** * Initializer. * This one is called by the parser where we could * be dealing with delimited identifiers. * * @param columnName The name of the column being referenced * @param tableName The qualification for the column * @param tokBeginOffset begin position of token for the column name * identifier from parser. * @param tokEndOffsetend position of token for the column name * identifier from parser. */ public void init(Object columnName, Object tableName, Object tokBeginOffset, Object tokEndOffset) { this.columnName = (String)columnName; this.tableName = (TableName)tableName; this.setBeginOffset(((Integer)tokBeginOffset).intValue()); this.setEndOffset(((Integer)tokEndOffset).intValue()); } /** * Initializer. * * @param columnName The name of the column being referenced * @param tableName The qualification for the column */ public void init(Object columnName, Object tableName) { this.columnName = (String)columnName; this.tableName = (TableName)tableName; } /** * Fill this node with a deep copy of the given node. */ public void copyFrom(QueryTreeNode node) throws StandardException { super.copyFrom(node); ColumnReference other = (ColumnReference)node; this.columnName = other.columnName; this.tableName = (TableName) getNodeFactory().copyNode(other.tableName, getParserContext()); } /** * 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 */ public String toString() { return "columnName: " + columnName + "\n" + "tableName: " + ( ( tableName != null) ? tableName.toString() : "null") + "\n" + super.toString(); } /** * 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); } /** * Get the column name for purposes of error * messages or debugging. This returns the column * name as used in the SQL statement. Thus if it was qualified * with a table, alias name that will be included. * * @return The column name in the form [[schema.]table.]column */ public String getSQLColumnName() { if (tableName == null) return columnName; return tableName.toString() + "." + columnName; } /** * Get the name of this column * * @return The name of this column */ public String getColumnName() { return columnName; } /** * Get the user-supplied table name of this column. 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 The user-supplied name of this column. Null if no user- * supplied name. */ public String getTableName() { return ((tableName != null) ? tableName.getTableName() : null); } /** Return the table name as the node it is. @return the column's table name. */ public TableName getTableNameNode() { return tableName; } public void setTableNameNode(TableName tableName) { this.tableName = tableName; } /** * Get the user-supplied schema name of this column. This will be null * if the user did not supply a 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 * Code generation of aggregate functions relies on this method * * @return The user-supplied schema name of this column. Null if no user- * supplied name. */ public String getSchemaName() { return ((tableName != null) ? tableName.getSchemaName() : null); } protected boolean isEquivalent(ValueNode o) throws StandardException { if (!isSameNodeType(o)) { return false; } ColumnReference other = (ColumnReference)o; if (!columnName.equals(other.getColumnName())) { return false; } if (tableName == null) return other.tableName == null; else return tableName.equals(other.tableName); } }