KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > sql > compile > DB2LengthOperatorNode


1 /*
2
3    Derby - Class org.apache.derby.impl.sql.compile.DB2LengthOperatorNode
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.impl.sql.compile;
23
24 import org.apache.derby.iapi.services.sanity.SanityManager;
25
26 import org.apache.derby.iapi.types.TypeId;
27 import org.apache.derby.iapi.types.DataTypeDescriptor;
28 import org.apache.derby.iapi.error.StandardException;
29 import org.apache.derby.iapi.services.compiler.MethodBuilder;
30 import org.apache.derby.iapi.services.compiler.LocalField;
31 import org.apache.derby.iapi.types.DataValueDescriptor;
32 import org.apache.derby.iapi.types.DataValueFactory;
33 import org.apache.derby.iapi.types.DataTypeDescriptor;
34
35 import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
36
37 import org.apache.derby.iapi.reference.SQLState;
38 import org.apache.derby.iapi.reference.ClassName;
39
40 import org.apache.derby.iapi.services.classfile.VMOpcode;
41
42 import java.lang.reflect.Modifier JavaDoc;
43
44 import java.sql.Types JavaDoc;
45
46 import java.util.Vector JavaDoc;
47
48 /**
49  * This node represents a unary DB2 compatible length operator
50  *
51  * @author Jack Klebanoff
52  */

53
54 public final class DB2LengthOperatorNode extends UnaryOperatorNode
55 {
56     
57     /**
58      * Initializer for a DB2LengthOperatorNode
59      *
60      * @param operand The operand of the node
61      */

62     public void init(Object JavaDoc operand)
63     {
64         super.init( operand, "length", "getDB2Length");
65     }
66
67  
68     /**
69      * Bind this operator
70      *
71      * @param fromList The query's FROM list
72      * @param subqueryList The subquery list being built as we find SubqueryNodes
73      * @param aggregateVector The aggregate vector being built as we find AggregateNodes
74      *
75      * @return The new top of the expression tree.
76      *
77      * @exception StandardException Thrown on error
78      */

79
80     public ValueNode bindExpression(
81         FromList fromList, SubqueryList subqueryList,
82         Vector JavaDoc aggregateVector)
83             throws StandardException
84     {
85         ValueNode boundExpression = super.bindExpression( fromList, subqueryList, aggregateVector);
86
87         // This operator is not allowed on XML types.
88
TypeId operandType = operand.getTypeId();
89         if (operandType.isXMLTypeId()) {
90             throw StandardException.newException(SQLState.LANG_UNARY_FUNCTION_BAD_TYPE,
91                                     getOperatorString(),
92                                     operandType.getSQLTypeName());
93         }
94
95         setType( new DataTypeDescriptor( TypeId.getBuiltInTypeId( Types.INTEGER),
96                                          operand.getTypeServices().isNullable()));
97         return boundExpression;
98     }
99
100     /**
101      * This is a length operator node. Overrides this method
102      * in UnaryOperatorNode for code generation purposes.
103      */

104     public String JavaDoc getReceiverInterfaceName() {
105         return ClassName.ConcatableDataValue;
106     }
107
108     /**
109      * Do code generation for this unary operator.
110      *
111      * @param acb The ExpressionClassBuilder for the class we're generating
112      * @param mb The method the expression will go into
113      *
114      *
115      * @exception StandardException Thrown on error
116      */

117
118     public void generateExpression(ExpressionClassBuilder acb,
119                                             MethodBuilder mb)
120                                     throws StandardException
121     {
122         if (operand == null)
123             return;
124
125         int constantLength = getConstantLength();
126         // -1 if the length of a non-null operand depends on the data
127

128         String JavaDoc resultTypeName = getTypeCompiler().interfaceName();
129
130         mb.pushThis();
131         operand.generateExpression(acb, mb);
132         mb.upCast( ClassName.DataValueDescriptor);
133         mb.push( constantLength);
134
135         /* Allocate an object for re-use to hold the result of the operator */
136         LocalField field = acb.newFieldDeclaration(Modifier.PRIVATE, resultTypeName);
137         mb.getField(field);
138         mb.callMethod(VMOpcode.INVOKEVIRTUAL, ClassName.BaseActivation, methodName, resultTypeName, 3);
139
140         /*
141         ** Store the result of the method call in the field, so we can re-use
142         ** the object.
143         */

144         mb.putField(field);
145     } // end of generateExpression
146

147     private int getConstantLength( ) throws StandardException
148     {
149         DataTypeDescriptor typeDescriptor = operand.getTypeServices();
150         
151         switch( typeDescriptor.getJDBCTypeId())
152         {
153         case Types.BIGINT:
154             return 8;
155         case org.apache.derby.iapi.reference.JDBC30Translation.SQL_TYPES_BOOLEAN:
156         case Types.BIT:
157             return 1;
158         case Types.BINARY:
159         case Types.CHAR:
160             return typeDescriptor.getMaximumWidth();
161         case Types.DATE:
162             return 4;
163         case Types.DECIMAL:
164         case Types.NUMERIC:
165             return typeDescriptor.getPrecision()/2 + 1;
166         case Types.DOUBLE:
167             return 8;
168         case Types.FLOAT:
169         case Types.REAL:
170         case Types.INTEGER:
171             return 4;
172         case Types.SMALLINT:
173             return 2;
174         case Types.TIME:
175             return 3;
176         case Types.TIMESTAMP:
177             return 10;
178         case Types.TINYINT:
179             return 1;
180         case Types.LONGVARCHAR:
181         case Types.VARCHAR:
182         case Types.LONGVARBINARY:
183         case Types.VARBINARY:
184         case Types.BLOB:
185             return getConstantNodeLength();
186         default:
187             return -1;
188         }
189     } // end of getConstantLength
190

191     private int getConstantNodeLength() throws StandardException
192     {
193         if( operand instanceof ConstantNode)
194             return ((ConstantNode) operand).getValue().getLength();
195         return -1;
196     }
197 }
198
Popular Tags