001: /*
002:
003: Derby - Class org.apache.derby.impl.sql.compile.NumericConstantNode
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.impl.sql.compile;
023:
024: import org.apache.derby.iapi.sql.compile.C_NodeTypes;
025:
026: import org.apache.derby.iapi.services.sanity.SanityManager;
027:
028: import org.apache.derby.iapi.sql.compile.TypeCompiler;
029:
030: import org.apache.derby.iapi.error.StandardException;
031:
032: import org.apache.derby.iapi.services.compiler.MethodBuilder;
033: import org.apache.derby.iapi.services.info.JVMInfo;
034:
035: import org.apache.derby.iapi.types.TypeId;
036: import org.apache.derby.iapi.types.DataTypeUtilities;
037: import org.apache.derby.iapi.types.NumberDataValue;
038:
039: import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
040:
041: import org.apache.derby.iapi.util.ReuseFactory;
042:
043: import java.sql.Types;
044:
045: public final class NumericConstantNode extends ConstantNode {
046: /**
047: * Initializer for a typed null node
048: *
049: * @param arg1 The TypeId for the type of node OR An object containing the value of the constant.
050: *
051: * @exception StandardException
052: */
053: public void init(Object arg1) throws StandardException {
054: int precision = 0, scal = 0, maxwidth = 0;
055: Boolean isNullable;
056: boolean valueInP; // value in Predicate-- if TRUE a value was passed in
057: TypeId typeId = null;
058: int typeid = 0;
059:
060: if (arg1 instanceof TypeId) {
061: typeId = (TypeId) arg1;
062: isNullable = Boolean.TRUE;
063: valueInP = false;
064: maxwidth = 0;
065: }
066:
067: else {
068: isNullable = Boolean.FALSE;
069: valueInP = true;
070: }
071:
072: switch (getNodeType()) {
073: case C_NodeTypes.TINYINT_CONSTANT_NODE:
074: precision = TypeId.SMALLINT_PRECISION;
075: scal = TypeId.SMALLINT_SCALE;
076: if (valueInP) {
077: maxwidth = TypeId.SMALLINT_MAXWIDTH;
078: typeid = Types.TINYINT;
079: setValue(getDataValueFactory()
080: .getDataValue((Byte) arg1));
081: }
082: break;
083:
084: case C_NodeTypes.INT_CONSTANT_NODE:
085: precision = TypeId.INT_PRECISION;
086: scal = TypeId.INT_SCALE;
087: if (valueInP) {
088: maxwidth = TypeId.INT_MAXWIDTH;
089: typeid = Types.INTEGER;
090: setValue(getDataValueFactory().getDataValue(
091: (Integer) arg1));
092: }
093: break;
094:
095: case C_NodeTypes.SMALLINT_CONSTANT_NODE:
096: precision = TypeId.SMALLINT_PRECISION;
097: scal = TypeId.SMALLINT_SCALE;
098: if (valueInP) {
099: maxwidth = TypeId.SMALLINT_MAXWIDTH;
100: typeid = Types.SMALLINT;
101: setValue(getDataValueFactory().getDataValue(
102: (Short) arg1));
103: }
104: break;
105:
106: case C_NodeTypes.LONGINT_CONSTANT_NODE:
107: precision = TypeId.LONGINT_PRECISION;
108: scal = TypeId.LONGINT_SCALE;
109: if (valueInP) {
110: maxwidth = TypeId.LONGINT_MAXWIDTH;
111: typeid = Types.BIGINT;
112: setValue(getDataValueFactory()
113: .getDataValue((Long) arg1));
114: }
115: break;
116:
117: case C_NodeTypes.DECIMAL_CONSTANT_NODE:
118: if (valueInP) {
119:
120: NumberDataValue constantDecimal = getDataValueFactory()
121: .getDecimalDataValue((String) arg1);
122:
123: typeid = Types.DECIMAL;
124: precision = constantDecimal.getDecimalValuePrecision();
125: scal = constantDecimal.getDecimalValueScale();
126: /* be consistent with our convention on maxwidth, see also
127: * exactNumericType(), otherwise we get format problem, b 3923
128: */
129: maxwidth = DataTypeUtilities.computeMaxWidth(precision,
130: scal);
131: setValue(constantDecimal);
132: } else {
133: precision = TypeCompiler.DEFAULT_DECIMAL_PRECISION;
134: scal = TypeCompiler.DEFAULT_DECIMAL_SCALE;
135: maxwidth = TypeId.DECIMAL_MAXWIDTH;
136: }
137: break;
138:
139: case C_NodeTypes.DOUBLE_CONSTANT_NODE:
140: precision = TypeId.DOUBLE_PRECISION;
141: scal = TypeId.DOUBLE_SCALE;
142: if (valueInP) {
143: maxwidth = TypeId.DOUBLE_MAXWIDTH;
144: typeid = Types.DOUBLE;
145: setValue(getDataValueFactory().getDataValue(
146: (Double) arg1));
147: }
148: break;
149:
150: case C_NodeTypes.FLOAT_CONSTANT_NODE:
151: precision = TypeId.REAL_PRECISION;
152: scal = TypeId.REAL_SCALE;
153: if (valueInP) {
154: maxwidth = TypeId.REAL_MAXWIDTH;
155: typeid = Types.REAL;
156: setValue(getDataValueFactory().getDataValue(
157: (Float) arg1));
158: }
159: break;
160:
161: default:
162: if (SanityManager.DEBUG) {
163: // we should never really come here-- when the class is created
164: // it should have the correct nodeType set.
165: SanityManager.THROWASSERT("Unexpected nodeType = "
166: + getNodeType());
167: }
168: break;
169: }
170:
171: super .init((typeId != null) ? typeId : TypeId
172: .getBuiltInTypeId(typeid),
173:
174: ReuseFactory.getInteger(precision), ReuseFactory
175: .getInteger(scal), isNullable, ReuseFactory
176: .getInteger(maxwidth));
177: }
178:
179: /**
180: * Return an Object representing the bind time value of this
181: * expression tree. If the expression tree does not evaluate to
182: * a constant at bind time then we return null.
183: * This is useful for bind time resolution of VTIs.
184: * RESOLVE: What do we do for primitives?
185: *
186: * @return An Object representing the bind time value of this expression tree.
187: * (null if not a bind time constant.)
188: *
189: * @exception StandardException Thrown on error
190: */
191: Object getConstantValueAsObject() throws StandardException {
192: return value.getObject();
193: }
194:
195: /**
196: * This generates the proper constant. It is implemented
197: * by every specific constant node (e.g. IntConstantNode).
198: *
199: * @param acb The ExpressionClassBuilder for the class being built
200: * @param mb The method the expression will go into
201: *
202: * @exception StandardException Thrown on error
203: */
204: void generateConstant(ExpressionClassBuilder acb, MethodBuilder mb)
205: throws StandardException {
206: switch (getNodeType()) {
207: case C_NodeTypes.INT_CONSTANT_NODE:
208: mb.push(value.getInt());
209: break;
210: case C_NodeTypes.TINYINT_CONSTANT_NODE:
211: mb.push(value.getByte());
212: break;
213: case C_NodeTypes.SMALLINT_CONSTANT_NODE:
214: mb.push(value.getShort());
215: break;
216: case C_NodeTypes.DECIMAL_CONSTANT_NODE:
217: // No java.math.BigDecimal class in J2ME so the constant
218: // from the input SQL is handled directly as a String.
219: if (!JVMInfo.J2ME)
220: mb.pushNewStart("java.math.BigDecimal");
221: mb.push(value.getString());
222: if (!JVMInfo.J2ME)
223: mb.pushNewComplete(1);
224: break;
225: case C_NodeTypes.DOUBLE_CONSTANT_NODE:
226: mb.push(value.getDouble());
227: break;
228: case C_NodeTypes.FLOAT_CONSTANT_NODE:
229: mb.push(value.getFloat());
230: break;
231: case C_NodeTypes.LONGINT_CONSTANT_NODE:
232: mb.push(value.getLong());
233: break;
234: default:
235: if (SanityManager.DEBUG) {
236: // we should never really come here-- when the class is created
237: // it should have the correct nodeType set.
238: SanityManager.THROWASSERT("Unexpected nodeType = "
239: + getNodeType());
240: }
241: }
242: }
243: }
|