/* * 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 java.util.Properties; /** * A FromBaseTable represents a table in the FROM list of a DML statement, * as distinguished from a FromSubquery, which represents a subquery in the * FROM list. A FromBaseTable may actually represent a view. During parsing, * we can't distinguish views from base tables. During binding, when we * find FromBaseTables that represent views, we replace them with FromSubqueries. * By the time we get to code generation, all FromSubqueries have been eliminated, * and all FromBaseTables will represent only true base tables. * <p> * <B>Positioned Update</B>: Currently, all columns of an updatable cursor * are selected to deal with a positioned update. This is because we don't * know what columns will ultimately be needed from the UpdateNode above * us. For example, consider:<pre><i> * * get c as 'select cint from t for update of ctinyint' * update t set ctinyint = csmallint * * </pre></i> Ideally, the cursor only selects cint. Then, * something akin to an IndexRowToBaseRow is generated to * take the CursorResultSet and get the appropriate columns * out of the base table from the RowLocation retunrned by the * cursor. Then the update node can generate the appropriate * NormalizeResultSet (or whatever else it might need) to * get things into the correct format for the UpdateResultSet. * See CurrentOfNode for more information. * */ public class FromBaseTable extends FromTable { public static enum UpdateOrDelete { UPDATE, DELETE } private TableName tableName; private UpdateOrDelete updateOrDelete; private ResultColumnList templateColumns; private IndexHintList indexHints; /** * Initializer for a table in a FROM list. Parameters are as follows: * <ul> * <li>tableName The name of the table</li> * <li>correlationName The correlation name</li> * <li>derivedRCL The derived column list</li> * <li>tableProperties The Properties list associated with the table.</li> * </ul> */ public void init(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) { init(arg2, arg4); tableName = (TableName)arg1; resultColumns = (ResultColumnList)arg3; indexHints = (IndexHintList)arg5; setOrigTableName(this.tableName); templateColumns = resultColumns; } /** * Initializer for a table in a DELETE/ UPDATE. Parameters are as follows: * <ul> * <li>tableName The name of the table</li> * <li>correlationName The correlation name</li> * <li>updateOrDelete Table is being updated/deleted from. </li> * </ul> */ public void init(Object arg1, Object arg2, Object arg3) { init(arg2, null); tableName = (TableName)arg1; updateOrDelete = (UpdateOrDelete)arg3; setOrigTableName(this.tableName); } /** * Fill this node with a deep copy of the given node. */ public void copyFrom(QueryTreeNode node) throws StandardException { super.copyFrom(node); FromBaseTable other = (FromBaseTable)node; this.tableName = (TableName) getNodeFactory().copyNode(other.tableName, getParserContext()); this.updateOrDelete = other.updateOrDelete; this.templateColumns = (ResultColumnList) getNodeFactory().copyNode(other.templateColumns, getParserContext()); this.indexHints = (IndexHintList) getNodeFactory().copyNode(other.indexHints, 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 "tableName: " + (tableName != null ? tableName.toString() : "null") + "\n" + "updateOrDelete: " + updateOrDelete + "\n" + (tableProperties != null ? tableProperties.toString() : "null") + "\n" + super.toString(); } /** * Set the table properties for this table. * * @param tableProperties The new table properties. */ public void setTableProperties(Properties tableProperties) { this.tableProperties = tableProperties; } /** * Get the exposed name for this table, which is the name that can * be used to refer to it in the rest of the query. * * @return The exposed name of this table. * */ public String getExposedName() { if (correlationName != null) return correlationName; else return getOrigTableName().getFullTableName(); } /** * Get the exposed table name for this table, which is the name that can * be used to refer to it in the rest of the query. * * @return TableName The exposed name of this table. * * @exception StandardException Thrown on error */ public TableName getExposedTableName() throws StandardException { if (correlationName != null) return makeTableName(null, correlationName); else return getOrigTableName(); } /** * Return the table name for this table. * * @return The table name for this table. */ public TableName getTableName() throws StandardException { TableName tn = super.getTableName(); if (tn != null) return tn; else return tableName; } public IndexHintList getIndexHints() { return indexHints; } /** * 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); if (indexHints != null) { printLabel(depth, "indexHints: "); indexHints.treePrint(depth + 1); } } /** * Accept the visitor for all visitable children of this node. * * @param v the visitor * * @exception StandardException on error */ void acceptChildren(Visitor v) throws StandardException { super.acceptChildren(v); if (indexHints != null) { indexHints = (IndexHintList)indexHints.accept(v); } } }