1 21 22 package org.apache.derby.impl.sql.compile; 23 24 import org.apache.derby.iapi.sql.dictionary.DataDictionary; 25 26 import org.apache.derby.iapi.types.TypeId; 27 import org.apache.derby.iapi.types.DataTypeDescriptor; 28 import org.apache.derby.iapi.reference.SQLState; 29 import org.apache.derby.iapi.error.StandardException; 30 31 import org.apache.derby.iapi.services.compiler.MethodBuilder; 32 import org.apache.derby.iapi.services.sanity.SanityManager; 33 import org.apache.derby.iapi.sql.compile.C_NodeTypes; 34 import org.apache.derby.impl.sql.compile.ExpressionClassBuilder; 35 36 import java.sql.Types ; 37 import java.util.Vector ; 38 39 44 45 public class UnaryArithmeticOperatorNode extends UnaryOperatorNode 46 { 47 private final static int UNARY_PLUS = 0; 48 private final static int UNARY_MINUS = 1; 49 private final static int SQRT = 2; 50 private final static int ABSOLUTE = 3; 51 private final static String [] UNARY_OPERATORS = {"+","-","SQRT", "ABS/ABSVAL"}; 52 private final static String [] UNARY_METHODS = {"plus","minus","sqrt", "absolute"}; 53 54 private int operatorType; 55 56 FromList localCopyFromList; 70 SubqueryList localCopySubqueryList; 71 Vector localAggregateVector; 72 73 78 public void init(Object operand) 79 { 80 switch(getNodeType()) 81 { 82 case C_NodeTypes.UNARY_PLUS_OPERATOR_NODE: 83 operatorType = UNARY_PLUS; 84 break; 85 case C_NodeTypes.UNARY_MINUS_OPERATOR_NODE: 86 operatorType = UNARY_MINUS; 87 break; 88 case C_NodeTypes.SQRT_OPERATOR_NODE: 89 operatorType = SQRT; 90 break; 91 case C_NodeTypes.ABSOLUTE_OPERATOR_NODE: 92 operatorType = ABSOLUTE; 93 break; 94 default: 95 if (SanityManager.DEBUG) 96 { 97 SanityManager.THROWASSERT("init for UnaryArithmeticOperator called with wrong nodeType = " + getNodeType()); 98 } 99 break; 100 } 101 init(operand, UNARY_OPERATORS[this.operatorType], 102 UNARY_METHODS[this.operatorType]); 103 } 104 105 116 117 void bindParameter() throws StandardException 118 { 119 if (operatorType == SQRT || operatorType == ABSOLUTE) 120 { 121 operand.setType( 122 new DataTypeDescriptor(TypeId.getBuiltInTypeId(Types.DOUBLE), true)); 123 } 124 else if (operatorType == UNARY_MINUS || operatorType == UNARY_PLUS) 126 return; 127 else if (operand.getTypeServices() == null) 128 { 129 throw StandardException.newException(SQLState.LANG_UNARY_OPERAND_PARM, operator); 130 } 131 } 132 143 144 public ValueNode bindExpression( 145 FromList fromList, SubqueryList subqueryList, 146 Vector aggregateVector) 147 throws StandardException 148 { 149 localCopyFromList = fromList; 150 localCopySubqueryList = subqueryList; 151 localAggregateVector = aggregateVector; 152 if (operand.requiresTypeFromContext() && ((operatorType == UNARY_PLUS || operatorType == UNARY_MINUS)) 154 && operand.getTypeServices() == null) 155 return this; 156 157 super.bindExpression(fromList, subqueryList, 158 aggregateVector); 159 160 if (operatorType == SQRT || operatorType == ABSOLUTE) 161 { 162 bindSQRTABS(); 163 } 164 else if (operatorType == UNARY_PLUS || operatorType == UNARY_MINUS) 165 { 166 TypeId operandType = operand.getTypeId(); 167 168 if ( ! operandType.isNumericTypeId()) 169 { 170 171 throw StandardException.newException(SQLState.LANG_UNARY_ARITHMETIC_BAD_TYPE, 172 (operatorType == UNARY_PLUS) ? "+" : "-", 173 operandType.getSQLTypeName()); 174 } 175 } 176 179 super.setType(operand.getTypeServices()); 180 return this; 181 } 182 183 191 192 public void generateExpression(ExpressionClassBuilder acb, 193 MethodBuilder mb) 194 throws StandardException 195 { 196 197 if (operatorType == UNARY_PLUS) 198 operand.generateExpression(acb, mb); 199 else 200 super.generateExpression(acb, mb); 201 } 202 207 private void bindSQRTABS() 208 throws StandardException 209 { 210 TypeId operandType; 211 int jdbcType; 212 213 216 operandType = operand.getTypeId(); 217 218 222 if (operandType.userType() ) 223 { 224 operand = operand.genSQLJavaSQLTree(); 225 } 226 227 228 jdbcType = operandType.getJDBCTypeId(); 229 230 231 if (!operandType.isNumericTypeId()) 232 throw StandardException.newException( 233 SQLState.LANG_UNARY_FUNCTION_BAD_TYPE, 234 getOperatorString(), operandType.getSQLTypeName()); 235 236 237 if (operatorType == SQRT && jdbcType != Types.DOUBLE) 238 { 239 operand = (ValueNode) getNodeFactory().getNode( 240 C_NodeTypes.CAST_NODE, 241 operand, 242 new DataTypeDescriptor(TypeId.getBuiltInTypeId(Types.DOUBLE), true), 243 getContextManager()); 244 ((CastNode) operand).bindCastNodeOnly(); 245 } 246 } 247 248 249 253 public void setType(DataTypeDescriptor descriptor) throws StandardException 254 { 255 operand.setType(descriptor); 256 super.setType(descriptor); 257 bindExpression(localCopyFromList, localCopySubqueryList, localAggregateVector); 261 } 262 } 263 | Popular Tags |