KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2
3    Derby - Class org.apache.derby.impl.sql.compile.UnaryComparisonOperatorNode
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.compile.Optimizable;
25
26 import org.apache.derby.iapi.sql.dictionary.DataDictionary;
27 import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;
28
29 import org.apache.derby.iapi.types.TypeId;
30 import org.apache.derby.iapi.types.DataTypeDescriptor;
31
32 import org.apache.derby.iapi.store.access.ScanController;
33
34 import org.apache.derby.iapi.error.StandardException;
35
36 import org.apache.derby.iapi.services.loader.GeneratedMethod;
37
38 import org.apache.derby.iapi.services.compiler.MethodBuilder;
39
40 import org.apache.derby.iapi.services.sanity.SanityManager;
41
42 import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
43
44 import org.apache.derby.iapi.util.JBitSet;
45
46 import java.sql.Types JavaDoc;
47
48 import java.util.Vector JavaDoc;
49
50 /**
51  * This node is the superclass for all unary comparison operators, such as is null
52  * and is not null.
53  *
54  * @author Jerry Brenner
55  */

56
57 public class UnaryComparisonOperatorNode extends UnaryOperatorNode
58 {
59     /**
60      * Bind this comparison operator. All that has to be done for binding
61      * a comparison operator is to bind the operand and set the result type
62      * to SQLBoolean.
63      *
64      * @param fromList The query's FROM list
65      * @param subqueryList The subquery list being built as we find SubqueryNodes
66      * @param aggregateVector The aggregate vector being built as we find AggregateNodes
67      *
68      * @return The new top of the expression tree.
69      *
70      * @exception StandardException Thrown on error
71      */

72
73     public ValueNode bindExpression(
74         FromList fromList, SubqueryList subqueryList,
75         Vector JavaDoc aggregateVector)
76             throws StandardException
77     {
78         super.bindExpression(fromList, subqueryList,
79                              aggregateVector);
80
81         /* Set type info for this node */
82         bindComparisonOperator();
83
84         return this;
85     }
86
87     /**
88      * Set the type info for this node. This method is useful both during
89      * binding and when we generate nodes within the language module outside
90      * of the parser.
91      *
92      * @exception StandardException Thrown on error
93      */

94     public void bindComparisonOperator()
95             throws StandardException
96     {
97         /*
98         ** Set the result type of this comparison operator based on the
99         ** operand. The result type is always SQLBoolean and always
100         ** non-nullable.
101         */

102         setType(new DataTypeDescriptor(TypeId.BOOLEAN_ID, false));
103     }
104
105     /**
106      * Eliminate NotNodes in the current query block. We traverse the tree,
107      * inverting ANDs and ORs and eliminating NOTs as we go. We stop at
108      * ComparisonOperators and boolean expressions. We invert
109      * ComparisonOperators and replace boolean expressions with
110      * boolean expression = false.
111      * NOTE: Since we do not recurse under ComparisonOperators, there
112      * still could be NotNodes left in the tree.
113      *
114      * @param underNotNode Whether or not we are under a NotNode.
115      *
116      *
117      * @return The modified expression
118      *
119      * @exception StandardException Thrown on error
120      */

121     ValueNode eliminateNots(boolean underNotNode)
122                     throws StandardException
123     {
124         if (! underNotNode)
125         {
126             return this;
127         }
128
129         /* Convert the BinaryComparison operator to its negation */
130         return getNegation(operand);
131     }
132
133     /**
134      * Negate the comparison.
135      *
136      * @param operand The operand of the comparison operator
137      *
138      * @return BinaryOperatorNode The negated expression
139      *
140      * @exception StandardException Thrown on error
141      */

142     UnaryOperatorNode getNegation(ValueNode operand)
143                 throws StandardException
144     {
145         /* Keep the compiler happy - this method should never be called.
146          * We should always be calling the method in a sub-class.
147          */

148         if (SanityManager.DEBUG)
149         SanityManager.ASSERT(false,
150                     "expected to call getNegation() for subclass " +
151                     getClass().toString());
152         return this;
153     }
154
155     /* RelationalOperator interface */
156
157     /** @see RelationalOperator#getColumnOperand */
158     public ColumnReference getColumnOperand(
159                                 Optimizable optTable,
160                                 int columnPosition)
161     {
162         FromBaseTable ft;
163
164         if (SanityManager.DEBUG)
165         {
166             SanityManager.ASSERT(optTable instanceof FromBaseTable);
167         }
168
169         ft = (FromBaseTable) optTable;
170         ColumnReference cr;
171         if (operand instanceof ColumnReference)
172         {
173             /*
174             ** The operand is a column reference.
175             ** Is it the correct column?
176             */

177             cr = (ColumnReference) operand;
178             if (cr.getTableNumber() == ft.getTableNumber())
179             {
180                 /* The table is correct, how about the column position? */
181                 if (cr.getSource().getColumnPosition() == columnPosition)
182                 {
183                     /* We've found the correct column - return it */
184                     return cr;
185                 }
186             }
187         }
188
189         /* Neither side is the column we're looking for */
190         return null;
191     }
192
193     /** @see RelationalOperator#getColumnOperand */
194     public ColumnReference getColumnOperand(Optimizable optTable)
195     {
196         ColumnReference cr;
197
198         if (operand instanceof ColumnReference)
199         {
200             /*
201             ** The operand is a column reference.
202             ** Is it the correct column?
203             */

204             cr = (ColumnReference) operand;
205             if (cr.getTableNumber() == optTable.getTableNumber())
206             {
207                 /* We've found the correct column - return it */
208                 return cr;
209             }
210         }
211
212         /* Not the column we're looking for */
213         return null;
214     }
215
216     /** @see RelationalOperator#getOperand */
217     public ValueNode getOperand(ColumnReference cRef, int refSetSize,
218         boolean otherSide)
219     {
220         if (otherSide)
221         // there is no "other" side for Unary, so just return null.
222
return null;
223
224         ColumnReference cr;
225         if (operand instanceof ColumnReference)
226         {
227             /*
228             ** The operand is a column reference.
229             ** Is it the correct column?
230             */

231             JBitSet cRefTables = new JBitSet(refSetSize);
232             JBitSet crTables = new JBitSet(refSetSize);
233             BaseTableNumbersVisitor btnVis =
234                 new BaseTableNumbersVisitor(crTables);
235
236             cr = (ColumnReference) operand;
237             try {
238                 cr.accept(btnVis);
239                 btnVis.setTableMap(cRefTables);
240                 cRef.accept(btnVis);
241             } catch (StandardException se) {
242                 if (SanityManager.DEBUG)
243                 {
244                     SanityManager.THROWASSERT("Failed when trying to " +
245                         "find base table number for column reference check:\n" +
246                         se.getMessage());
247                 }
248             }
249             crTables.and(cRefTables);
250             if (crTables.getFirstSetBit() != -1)
251             {
252                 /*
253                 ** The table is correct, how about the column position?
254                 */

255                 if (cr.getSource().getColumnPosition() ==
256                     cRef.getColumnNumber())
257                 {
258                     /* We've found the correct column - return it. */
259                     return operand;
260                 }
261             }
262         }
263
264         /* Not the column we're looking for */
265         return null;
266     }
267
268     /** @see RelationalOperator#selfComparison */
269     public boolean selfComparison(ColumnReference cr)
270     {
271         ValueNode otherSide;
272         JBitSet tablesReferenced;
273
274         if (SanityManager.DEBUG)
275         {
276             SanityManager.ASSERT(cr == operand,
277                 "ColumnReference not found in IsNullNode.");
278         }
279
280         /* An IsNullNode is not a comparison with any other column */
281         return false;
282     }
283
284     /**
285      * @see RelationalOperator#getExpressionOperand
286      */

287     public ValueNode getExpressionOperand(int tableNumber,
288                                           int columnNumber,
289                                           FromTable ft)
290     {
291         return null;
292     }
293
294     /**
295      * @see RelationalOperator#generateExpressionOperand
296      *
297      * @exception StandardException Thrown on error
298      */

299     public void generateExpressionOperand(Optimizable optTable,
300                                                 int columnPosition,
301                                                 ExpressionClassBuilder acb,
302                                                 MethodBuilder mb)
303                         throws StandardException
304     {
305         acb.generateNull(mb, operand.getTypeCompiler());
306     }
307
308     /** @see RelationalOperator#getStartOperator */
309     public int getStartOperator(Optimizable optTable)
310     {
311         if (SanityManager.DEBUG)
312         {
313             SanityManager.THROWASSERT(
314                             "getStartOperator not expected to be called for " +
315                             this.getClass().getName());
316         }
317
318         return ScanController.GE;
319     }
320
321     /** @see RelationalOperator#getStopOperator */
322     public int getStopOperator(Optimizable optTable)
323     {
324         if (SanityManager.DEBUG)
325         {
326             SanityManager.THROWASSERT(
327                             "getStopOperator not expected to be called for " +
328                             this.getClass().getName());
329         }
330
331         return ScanController.GT;
332     }
333
334     /** @see RelationalOperator#generateOrderedNulls */
335     public void generateOrderedNulls(MethodBuilder mb)
336     {
337         mb.push(true);
338     }
339
340     /**
341      * @see RelationalOperator#generateQualMethod
342      *
343      * @exception StandardException Thrown on error
344      */

345     public void generateQualMethod(ExpressionClassBuilder acb,
346                                         MethodBuilder mb,
347                                         Optimizable optTable)
348                         throws StandardException
349     {
350         MethodBuilder qualMethod = acb.newUserExprFun();
351
352         /* Generate a method that returns that expression */
353         acb.generateNull(qualMethod, operand.getTypeCompiler());
354         qualMethod.methodReturn();
355         qualMethod.complete();
356
357         /* Return an expression that evaluates to the GeneratedMethod */
358         acb.pushMethodReference(mb, qualMethod);
359     }
360
361     /** @see RelationalOperator#generateAbsoluteColumnId */
362     public void generateAbsoluteColumnId(MethodBuilder mb,
363                                         Optimizable optTable)
364     {
365         // Get the absolute 0-based column position for the column
366
int columnPosition = getAbsoluteColumnPosition(optTable);
367
368         mb.push(columnPosition);
369     }
370
371     /** @see RelationalOperator#generateRelativeColumnId */
372     public void generateRelativeColumnId(MethodBuilder mb,
373                                                Optimizable optTable)
374     {
375         // Get the absolute 0-based column position for the column
376
int columnPosition = getAbsoluteColumnPosition(optTable);
377         // Convert the absolute to the relative 0-based column position
378
columnPosition = optTable.convertAbsoluteToRelativeColumnPosition(
379                                 columnPosition);
380
381         mb.push(columnPosition);
382     }
383
384     /**
385      * Get the absolute 0-based column position of the ColumnReference from
386      * the conglomerate for this Optimizable.
387      *
388      * @param optTable The Optimizable
389      *
390      * @return The absolute 0-based column position of the ColumnReference
391      */

392     private int getAbsoluteColumnPosition(Optimizable optTable)
393     {
394         ColumnReference cr = (ColumnReference) operand;
395         int columnPosition;
396         ConglomerateDescriptor bestCD;
397
398         /* Column positions are one-based, store is zero-based */
399         columnPosition = cr.getSource().getColumnPosition();
400
401         bestCD =
402             optTable.getTrulyTheBestAccessPath().getConglomerateDescriptor();
403
404         /*
405         ** If it's an index, find the base column position in the index
406         ** and translate it to an index column position.
407         */

408         if (bestCD.isIndex())
409         {
410             columnPosition = bestCD.getIndexDescriptor().
411               getKeyColumnPosition(new Integer JavaDoc(columnPosition)).intValue();
412
413             if (SanityManager.DEBUG)
414             {
415                 SanityManager.ASSERT(columnPosition > 0,
416                     "Base column not found in index");
417             }
418         }
419
420         // return the 0-based column position
421
return columnPosition - 1;
422     }
423
424     /** @see RelationalOperator#orderedNulls */
425     public boolean orderedNulls()
426     {
427         return true;
428     }
429
430     /** @see RelationalOperator#isQualifier */
431     public boolean isQualifier(Optimizable optTable, boolean forPush)
432     {
433         /*
434         ** It's a Qualifier if the operand is a ColumnReference referring
435         ** to a column in the given Optimizable table.
436         */

437         if ( ! (operand instanceof ColumnReference))
438             return false;
439
440         ColumnReference cr = (ColumnReference) operand;
441         FromTable ft = (FromTable) optTable;
442
443         if (cr.getTableNumber() != ft.getTableNumber())
444             return false;
445
446         return true;
447     }
448
449     /**
450      * @see RelationalOperator#getOrderableVariantType
451      *
452      * @exception StandardException thrown on error
453      */

454     public int getOrderableVariantType(Optimizable optTable)
455         throws StandardException
456     {
457         return operand.getOrderableVariantType();
458     }
459 }
460
Popular Tags