/*
* 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;
import java.sql.Types;
/**
* An CastNode represents a cast expressionr.
*
*/
public class CastNode extends ValueNode
{
private ValueNode castOperand;
private int targetCharType;
private boolean forDataTypeFunction = false;
/** This variable gets set by the parser to indicate that this CAST node
* has been generated by the parser. This means that we should use the
* collation info of the current compilation schmea for this node's
* collation setting. If this variable does not get set to true, then it
* means that this CAST node has been an internally generated node and we
* should not touch the collation info set for this CAST node because it
* has been already set correctly by the class that generated this CAST
* node. Collation info is part of the DataTypeDescriptor that's defined
* on the ValueNode (the super class of this CastNode class)
*/
private boolean externallyGeneratedCastNode = false;
/**
* Initializer for a CastNode
*
* @param castOperand The operand of the node
* @param castTarget DataTypeDescriptor (target type of cast)
*
* @exception StandardException Thrown on error
*/
public void init(Object castOperand, Object castTarget) throws StandardException {
this.castOperand = (ValueNode)castOperand;
setType((DataTypeDescriptor)castTarget);
}
/**
* Initializer for a CastNode
*
* @param castOperand The operand of the node
* @param charType CHAR or VARCHAR JDBC type as target
* @param charLength target type length
*
* @exception StandardException Thrown on error
*/
public void init(Object castOperand, Object charType, Object charLength)
throws StandardException {
this.castOperand = (ValueNode)castOperand;
int charLen = ((Integer)charLength).intValue();
targetCharType = ((Integer)charType).intValue();
if (charLen < 0) // unknown, figure out later
return;
setType(DataTypeDescriptor.getBuiltInDataTypeDescriptor(targetCharType, charLen));
}
/**
* Fill this node with a deep copy of the given node.
*/
public void copyFrom(QueryTreeNode node) throws StandardException {
super.copyFrom(node);
CastNode other = (CastNode)node;
this.castOperand = (ValueNode)
getNodeFactory().copyNode(other.castOperand, getParserContext());
this.targetCharType = other.targetCharType;
this.forDataTypeFunction = other.forDataTypeFunction;
this.externallyGeneratedCastNode = other.externallyGeneratedCastNode;
}
public ValueNode getCastOperand() {
return castOperand;
}
/**
* 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 "castTarget: " + getType() + "\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);
if (castOperand != null) {
printLabel(depth, "castOperand: ");
castOperand.treePrint(depth + 1);
}
}
/**
* Return whether or not this expression tree represents a constant expression.
*
* @return Whether or not this expression tree represents a constant expression.
*/
public boolean isConstantExpression() {
return castOperand.isConstantExpression();
}
/**
* 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 (castOperand != null) {
castOperand = (ValueNode)castOperand.accept(v);
}
}
/** This method gets called by the parser to indiciate that this CAST node
* has been generated by the parser. This means that we should use the
* collation info of the current compilation schmea for this node's
* collation setting. If this method does not get called, then it means
* that this CAST node has been an internally generated node and we should
* not touch the collation of this CAST node because it has been already
* set correctly by the class that generated this CAST node.
*/
void setForExternallyGeneratedCASTnode() {
externallyGeneratedCastNode = true;
}
/** set this to be a dataTypeScalarFunction
*
* @param b true to use function conversion rules
*/
void setForDataTypeFunction(boolean b) {
forDataTypeFunction = b;
}
/**
* {@inheritDoc}
* @throws StandardException
*/
protected boolean isEquivalent(ValueNode o) throws StandardException {
if (isSameNodeType(o)) {
CastNode other = (CastNode)o;
return getType().equals(other.getType()) &&
castOperand.isEquivalent(other.castOperand);
}
return false;
}
}