KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2
3    Derby - Class org.apache.derby.impl.sql.compile.JavaToSQLValueNode
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.sql.dictionary.DataDictionary;
25 import org.apache.derby.iapi.types.DataTypeDescriptor;
26 import org.apache.derby.iapi.types.TypeId;
27 import org.apache.derby.iapi.sql.compile.TypeCompiler;
28 import org.apache.derby.iapi.reference.SQLState;
29
30 import org.apache.derby.iapi.services.compiler.MethodBuilder;
31 import org.apache.derby.iapi.services.compiler.LocalField;
32
33 import org.apache.derby.iapi.error.StandardException;
34
35 import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
36
37 import org.apache.derby.iapi.sql.compile.Visitable;
38 import org.apache.derby.iapi.sql.compile.Visitor;
39
40 import org.apache.derby.iapi.services.sanity.SanityManager;
41
42 import java.lang.reflect.Modifier JavaDoc;
43
44 import org.apache.derby.iapi.util.JBitSet;
45
46 import java.util.Vector JavaDoc;
47
48 /**
49  * This node type converts a value from the Java domain to the SQL domain.
50  */

51
52 public class JavaToSQLValueNode extends ValueNode
53 {
54     JavaValueNode javaNode;
55
56     /**
57      * Initializer for a JavaToSQLValueNode
58      *
59      * @param value The Java value to convert to the SQL domain
60      */

61     public void init(Object JavaDoc value)
62     {
63         this.javaNode = (JavaValueNode) value;
64     }
65
66     /**
67      * Set the clause that this node appears in.
68      *
69      * @param clause The clause that this node appears in.
70      */

71     public void setClause(int clause)
72     {
73         super.setClause(clause);
74         javaNode.setClause(clause);
75     }
76
77     /**
78      * Preprocess an expression tree. We do a number of transformations
79      * here (including subqueries, IN lists, LIKE and BETWEEN) plus
80      * subquery flattening.
81      * NOTE: This is done before the outer ResultSetNode is preprocessed.
82      *
83      * @param numTables Number of tables in the DML Statement
84      * @param outerFromList FromList from outer query block
85      * @param outerSubqueryList SubqueryList from outer query block
86      * @param outerPredicateList PredicateList from outer query block
87      *
88      * @return The modified expression
89      *
90      * @exception StandardException Thrown on error
91      */

92     public ValueNode preprocess(int numTables,
93                                 FromList outerFromList,
94                                 SubqueryList outerSubqueryList,
95                                 PredicateList outerPredicateList)
96                         throws StandardException
97     {
98         javaNode.preprocess(numTables,
99                             outerFromList, outerSubqueryList,
100                             outerPredicateList);
101
102         return this;
103     }
104
105     /**
106      * Do code generation for this conversion of a value from the Java to
107      * the SQL domain.
108      *
109      * @param acb The ExpressionClassBuilder for the class we're generating
110      * @param mb the method the expression will go into
111      *
112      * @exception StandardException Thrown on error
113      */

114
115     public void generateExpression(ExpressionClassBuilder acb,
116                                             MethodBuilder mb)
117                                     throws StandardException
118     {
119         TypeId resultType;
120         String JavaDoc resultTypeName;
121
122         /*
123         ** Tell the Java node that it's value is being returned to the
124         ** SQL domain. This way, it knows whether the checking for a null
125         ** receiver is to be done at the Java level or the SQL level.
126         */

127         javaNode.returnValueToSQLDomain();
128
129         /* Generate the receiver, if any. */
130         boolean hasReceiver = javaNode.generateReceiver(acb, mb);
131
132         /*
133         ** If the java expression has a receiver, we want to check whether
134         ** it's null before evaluating the whole expression (to avoid
135         ** a NullPointerException.
136         */

137         if (hasReceiver)
138         {
139             /*
140             ** There is a receiver. Generate a null SQL value to return
141             ** in case the receiver is null. First, create a field to hold
142             ** the null SQL value.
143             */

144             String JavaDoc nullValueClass = getTypeCompiler().interfaceName();
145             LocalField nullValueField =
146                 acb.newFieldDeclaration(Modifier.PRIVATE, nullValueClass);
147             /*
148             ** There is a receiver. Generate the following to test
149             ** for null:
150             **
151             ** (receiverExpression == null) ?
152             */

153
154             mb.conditionalIfNull();
155             mb.getField(nullValueField);
156             acb.generateNullWithExpress(mb, getTypeCompiler());
157
158
159             /*
160             ** We have now generated the expression to test, and the
161             ** "true" side of the ?: operator. Finish the "true" side
162             ** so we can generate the "false" side.
163             */

164             mb.startElseCode();
165         }
166         
167         resultType = getTypeId();
168         TypeCompiler tc = getTypeCompiler();
169
170         resultTypeName = tc.interfaceName();
171
172         /* Allocate an object for re-use to hold the result of the conversion */
173         LocalField field = acb.newFieldDeclaration(Modifier.PRIVATE, resultTypeName);
174
175         /* Generate the expression for the Java value under us */
176         javaNode.generateExpression(acb, mb);
177
178         /* Generate the SQL value, which is always nullable */
179         acb.generateDataValue(mb, tc, field);
180
181         /*
182         ** If there was a receiver, the return value will be the result
183         ** of the ?: operator.
184         */

185         if (hasReceiver)
186         {
187             mb.completeConditional();
188         }
189     }
190
191     /**
192      * Prints the sub-nodes of this object. See QueryTreeNode for
193      * how tree printing is supposed to work.
194      *
195      * @param depth The depth of this node in the tree
196      */

197
198     public void printSubNodes(int depth)
199     {
200         if (SanityManager.DEBUG)
201         {
202             super.printSubNodes(depth);
203
204             printLabel(depth, "javaNode: ");
205             javaNode.treePrint(depth + 1);
206         }
207     }
208
209     /**
210      * Get the JavaValueNode that lives under this JavaToSQLValueNode.
211      *
212      * @return The JavaValueNode that lives under this node.
213      */

214
215     public JavaValueNode getJavaValueNode()
216     {
217         return javaNode;
218     }
219
220     /**
221      * @see QueryTreeNode#disablePrivilegeCollection
222      */

223     public void disablePrivilegeCollection()
224     {
225         super.disablePrivilegeCollection();
226         if (javaNode != null)
227             javaNode.disablePrivilegeCollection();
228     }
229
230     /**
231      * Bind this expression. This means binding the sub-expressions,
232      * as well as figuring out what the return type is for this expression.
233      *
234      * @param fromList The FROM list for the query this
235      * expression is in, for binding columns.
236      * @param subqueryList The subquery list being built as we find
237      * SubqueryNodes
238      * @param aggregateVector The aggregate vector being built as we find AggregateNodes
239      *
240      * @return The new top of the expression tree.
241      *
242      * @exception StandardException Thrown on error
243      */

244
245     public ValueNode bindExpression(FromList fromList, SubqueryList subqueryList,
246         Vector JavaDoc aggregateVector)
247             throws StandardException
248     {
249         // method invocations are not allowed in ADD TABLE clauses.
250
// And neither are field references.
251
javaNode.checkReliability(this);
252
253         /* Bind the expression under us */
254         javaNode = javaNode.bindExpression(fromList, subqueryList, aggregateVector);
255
256         DataTypeDescriptor dts = DataTypeDescriptor.getSQLDataTypeDescriptor(javaNode.getJavaTypeName());
257         if (dts == null)
258         {
259             throw StandardException.newException(SQLState.LANG_NO_CORRESPONDING_S_Q_L_TYPE,
260                 javaNode.getJavaTypeName());
261         }
262
263         setType(dts);
264
265         return this;
266     }
267
268     /**
269      * Remap all ColumnReferences in this tree to be clones of the
270      * underlying expression.
271      *
272      * @return ValueNode The remapped expression tree.
273      *
274      * @exception StandardException Thrown on error
275      */

276     public ValueNode remapColumnReferencesToExpressions()
277         throws StandardException
278     {
279         javaNode = javaNode.remapColumnReferencesToExpressions();
280         return this;
281     }
282
283     /**
284      * Categorize this predicate. Initially, this means
285      * building a bit map of the referenced tables for each predicate.
286      * If the source of this ColumnReference (at the next underlying level)
287      * is not a ColumnReference or a VirtualColumnNode then this predicate
288      * will not be pushed down.
289      *
290      * For example, in:
291      * select * from (select 1 from s) a (x) where x = 1
292      * we will not push down x = 1.
293      * NOTE: It would be easy to handle the case of a constant, but if the
294      * inner SELECT returns an arbitrary expression, then we would have to copy
295      * that tree into the pushed predicate, and that tree could contain
296      * subqueries and method calls.
297      *
298      * @param referencedTabs JBitSet with bit map of referenced FromTables
299      * @param simplePredsOnly Whether or not to consider method
300      * calls, field references and conditional nodes
301      * when building bit map
302      *
303      * @return boolean Whether or not source.expression is a ColumnReference
304      * or a VirtualColumnNode.
305      *
306      * @exception StandardException Thrown on error
307      */

308     public boolean categorize(JBitSet referencedTabs, boolean simplePredsOnly)
309         throws StandardException
310     {
311         return javaNode.categorize(referencedTabs, simplePredsOnly);
312     }
313
314     /**
315      * Return the variant type for the underlying expression.
316      * The variant type can be:
317      * VARIANT - variant within a scan
318      * (method calls and non-static field access)
319      * SCAN_INVARIANT - invariant within a scan
320      * (column references from outer tables)
321      * QUERY_INVARIANT - invariant within the life of a query
322      * (constant expressions)
323      *
324      * @return The variant type for the underlying expression.
325      * @exception StandardException thrown on error
326      */

327     protected int getOrderableVariantType() throws StandardException
328     {
329         return javaNode.getOrderableVariantType();
330     }
331
332     /**
333      * Accept a visitor, and call v.visit()
334      * on child nodes as necessary.
335      *
336      * @param v the visitor
337      *
338      * @exception StandardException on error
339      */

340     public Visitable accept(Visitor v)
341         throws StandardException
342     {
343         Visitable returnNode = v.visit(this);
344     
345         if (v.skipChildren(this))
346         {
347             return returnNode;
348         }
349
350         if (javaNode != null && !v.stopTraversal())
351         {
352             javaNode = (JavaValueNode)javaNode.accept(v);
353         }
354         
355         return returnNode;
356     }
357         
358     /**
359      * {@inheritDoc}
360      */

361     protected boolean isEquivalent(ValueNode o)
362     {
363         // anything in the java domain is not equiavlent.
364
return false;
365     }
366 }
367
Popular Tags