📄 concatenationoperatornode.java
字号:
/* Derby - Class org.apache.derby.impl.sql.compile.ConcatenationOperatorNode Copyright 1997, 2004 The Apache Software Foundation or its licensors, as applicable. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */package org.apache.derby.impl.sql.compile;import org.apache.derby.iapi.sql.compile.C_NodeTypes;import org.apache.derby.iapi.services.sanity.SanityManager;import org.apache.derby.iapi.error.StandardException;import org.apache.derby.iapi.sql.dictionary.DataDictionary;import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;import org.apache.derby.iapi.types.TypeId;import org.apache.derby.iapi.types.ConcatableDataValue;import org.apache.derby.iapi.types.BitDataValue;import org.apache.derby.iapi.sql.compile.TypeCompiler;import org.apache.derby.iapi.types.DataTypeDescriptor;import org.apache.derby.iapi.services.compiler.MethodBuilder;import org.apache.derby.iapi.services.compiler.LocalField;import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;import org.apache.derby.iapi.reference.Limits;import org.apache.derby.iapi.reference.SQLState;import org.apache.derby.iapi.reference.ClassName;import java.sql.Types;import java.util.Vector;/** * This node represents a concatenation comparison operator * * @author Jerry Brenner -- modified by jamie for bit and bit * varying. */public class ConcatenationOperatorNode extends BinaryOperatorNode{ /** * Initializer for a ConcatenationOperatorNode * * @param leftOperand The left operand of the concatenation * @param rightOperand The right operand of the concatenation */ public void init(Object leftOperand, Object rightOperand) { super.init(leftOperand, rightOperand, "||", "concatenate", ClassName.ConcatableDataValue, ClassName.ConcatableDataValue); } /** * overrides BindOperatorNode.bindExpression because concatenation has special * requirements for parameter binding. * * @exception StandardException thrown on failure */ public ValueNode bindExpression( FromList fromList, SubqueryList subqueryList, Vector aggregateVector) throws StandardException { // deal with binding operands leftOperand = leftOperand.bindExpression(fromList, subqueryList, aggregateVector); rightOperand = rightOperand.bindExpression(fromList, subqueryList, aggregateVector); // deal with operand parameters /* Is there a ? parameter on the left? If so, it's type is the type of the other parameter, with maximum length for that type. */ if (leftOperand.isParameterNode()) { if (rightOperand.isParameterNode()) { throw StandardException.newException(SQLState.LANG_BINARY_OPERANDS_BOTH_PARMS, operator); } TypeId leftType; /* ** A ? on the left gets its type from the right. There are eight ** legal types for the concatenation operator: CHAR, VARCHAR, ** LONG VARCHAR, CLOB, BIT, BIT VARYING, LONG BIT VARYING, and BLOB. ** If the right type is BLOB, set the parameter type to BLOB with max length. ** If the right type is one of the other bit types, set the parameter type to ** BIT VARYING with maximum length. ** ** If the right type is CLOB, set parameter type to CLOB with max length. ** If the right type is anything else, set it to VARCHAR with ** maximum length. We count on the resolveConcatOperation method to ** catch an illegal type. ** ** NOTE: When I added the long types, I could have changed the ** resulting parameter types to LONG VARCHAR and LONG BIT VARYING, ** but they were already VARCHAR and BIT VARYING, and it wasn't ** clear to me what effect it would have to change it. - Jeff */ if (rightOperand.getTypeId().isBitTypeId()) { if (rightOperand.getTypeId().isBlobTypeId()) leftType = TypeId.getBuiltInTypeId(Types.BLOB); else leftType = TypeId.getBuiltInTypeId(Types.VARBINARY); } else { if (rightOperand.getTypeId().isClobTypeId()) leftType = TypeId.getBuiltInTypeId(Types.CLOB); else leftType = TypeId.getBuiltInTypeId(Types.VARCHAR); } ((ParameterNode) leftOperand).setDescriptor(new DataTypeDescriptor(leftType, true)); } /* Is there a ? parameter on the right? */ if (rightOperand.isParameterNode()) { TypeId rightType; /* ** A ? on the right gets its type from the left. There are eight ** legal types for the concatenation operator: CHAR, VARCHAR, ** LONG VARCHAR, CLOB, BIT, BIT VARYING, LONG BIT VARYING, and BLOB. ** If the left type is BLOB, set the parameter type to BLOB with max length. ** If the left type is one of the other bit types, set the parameter type to ** BIT VARYING with maximum length. ** ** If the left type is CLOB, set parameter type to CLOB with max length. ** If the left type is anything else, set it to VARCHAR with ** maximum length. We count on the resolveConcatOperation method to ** catch an illegal type. ** ** NOTE: When I added the long types, I could have changed the ** resulting parameter types to LONG VARCHAR and LONG BIT VARYING, ** but they were already VARCHAR and BIT VARYING, and it wasn't ** clear to me what effect it would have to change it. - Jeff */ if (leftOperand.getTypeId().isBitTypeId()) { if (leftOperand.getTypeId().isBlobTypeId()) rightType = TypeId.getBuiltInTypeId(Types.BLOB); else rightType = TypeId.getBuiltInTypeId(Types.VARBINARY); } else { if (leftOperand.getTypeId().isClobTypeId()) rightType = TypeId.getBuiltInTypeId(Types.CLOB); else rightType = TypeId.getBuiltInTypeId(Types.VARCHAR); } ((ParameterNode) rightOperand).setDescriptor( new DataTypeDescriptor( rightType, true)); } /* If the left operand is not a built-in type, then generate a bound conversion * tree to a built-in type. */ if (! leftOperand.getTypeId().systemBuiltIn()) { leftOperand = leftOperand.genSQLJavaSQLTree(); } /* If the right operand is not a built-in type, then generate a bound conversion * tree to a built-in type. */ if (! rightOperand.getTypeId().systemBuiltIn()) { rightOperand = rightOperand.genSQLJavaSQLTree(); } /* If either the left or right operands are non-string, non-bit types, * then we generate an implicit cast to VARCHAR. */ TypeCompiler tc = leftOperand.getTypeCompiler(); if (! (leftOperand.getTypeId().isStringTypeId() || leftOperand.getTypeId().isBitTypeId())) { leftOperand = (ValueNode) getNodeFactory().getNode( C_NodeTypes.CAST_NODE, leftOperand, DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, true, tc.getCastToCharWidth( leftOperand.getTypeServices())), getContextManager()); ((CastNode) leftOperand).bindCastNodeOnly(); } tc = rightOperand.getTypeCompiler(); if (! (rightOperand.getTypeId().isStringTypeId() || rightOperand.getTypeId().isBitTypeId())) { rightOperand = (ValueNode) getNodeFactory().getNode( C_NodeTypes.CAST_NODE, rightOperand, DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, true, tc.getCastToCharWidth( rightOperand.getTypeServices())), getContextManager()); ((CastNode) rightOperand).bindCastNodeOnly(); } /* ** Set the result type of this operator based on the operands. ** By convention, the left operand gets to decide the result type ** of a binary operator. */ tc = leftOperand.getTypeCompiler(); setType(resolveConcatOperation( leftOperand.getTypeServices(), rightOperand.getTypeServices())); /* ** Make sure the maximum width set for the result doesn't exceed the result type's maximum width */ if (SanityManager.DEBUG) { if (getTypeServices().getMaximumWidth() > getTypeId().getMaximumMaximumWidth()) { SanityManager.THROWASSERT("The maximum length " + getTypeServices().getMaximumWidth() + " for the result type " + getTypeId().getSQLTypeName() + " can't be greater than it's maximum width of result's typeid" + getTypeId().getMaximumMaximumWidth()); } } /* ** Now that we know the target interface type, set it. This assumes ** that both operands have the same interface type, which is a safe ** assumption for the concatenation operator. */ this.setLeftRightInterfaceType(tc.interfaceName()); return this;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -