KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2
3    Derby - Class org.apache.derby.impl.sql.compile.RelationalOperator
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.compiler.MethodBuilder;
25
26 import org.apache.derby.iapi.error.StandardException;
27
28 import org.apache.derby.iapi.sql.compile.Optimizable;
29
30 import org.apache.derby.iapi.store.access.TransactionController;
31
32 import org.apache.derby.iapi.types.DataValueDescriptor;
33
34 import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
35
36 /**
37  * This interface is an abstraction of a relational operator. It was created
38  * for optimization, to allow binary comparison operators and IS NULL to
39  * be treated the same.
40  */

41 public interface RelationalOperator
42 {
43     public final int EQUALS_RELOP = 1;
44     public final int NOT_EQUALS_RELOP = 2;
45     public final int GREATER_THAN_RELOP = 3;
46     public final int GREATER_EQUALS_RELOP = 4;
47     public final int LESS_THAN_RELOP = 5;
48     public final int LESS_EQUALS_RELOP = 6;
49     public final int IS_NULL_RELOP = 7;
50     public final int IS_NOT_NULL_RELOP = 8;
51
52     /**
53      * Check whether this RelationalOperator is a comparison of the given
54      * column with an expression. If so, return the ColumnReference that
55      * corresponds to the given column, and that is on one side of this
56      * RelationalOperator or the other (this method copes with the
57      * column being on either side of the operator). If the given column
58      * does not appear by itself on one side of the comparison, the
59      * method returns null.
60      *
61      * @param optTable An Optimizable for the base table the column is in
62      * @param columnPosition The ordinal position of the column (one-based)
63      *
64      * @return The ColumnReference on one side of this RelationalOperator
65      * that represents the given columnPosition. Returns null
66      * if no such ColumnReference exists by itself on one side of
67      * this RelationalOperator.
68      */

69     ColumnReference getColumnOperand(Optimizable optTable, int columnPosition);
70
71     /**
72      * Get the ColumnReference for the given table on one side of this
73      * RelationalOperator. This presumes it will be found only on one
74      * side. If not found, it will return null.
75      */

76     ColumnReference getColumnOperand(Optimizable optTable);
77
78     /**
79      * Find the operand (left or right) that points to the same table
80      * as the received ColumnReference, and then return either that
81      * operand or the "other" operand, depending on the value of
82      * otherSide. This presumes it will be found only on one
83      * side. If not found, it will return null.
84      *
85      * @param cRef The ColumnReference for which we're searching.
86      * @param refSetSize Size of the referenced map for the predicate
87      * represented by this RelationalOperator node. This is used
88      * for storing base table numbers when searching for cRef.
89      * @param otherSide Assuming we find an operand that points to
90      * the same table as cRef, then we will return the *other*
91      * operand if otherSide is true; else we'll return the operand
92      * that matches cRef.
93      */

94     ValueNode getOperand(ColumnReference cRef, int refSetSize,
95         boolean otherSide);
96
97     /**
98      * Check whether this RelationalOperator is a comparison of the given
99      * column with an expression. If so, return the expression
100      * the column is being compared to.
101      *
102      * @param tableNumber The table number of the base table the column is in
103      * @param columnPosition The ordinal position of the column (one-based)
104      * @param ft We'll look for the column in all tables at and beneath ft.
105      * This is useful if ft is, say, a ProjectRestrictNode over a subquery--
106      * then we want to look at all of the FROM tables in the subquery to try
107      * to find the right column.
108      *
109      * @return The ValueNode for the expression the column is being compared
110      * to - null if the column is not being compared to anything.
111      */

112     ValueNode getExpressionOperand(int tableNumber,
113                                     int columnPosition,
114                                     FromTable ft);
115
116     /**
117      * Check whether this RelationalOperator is a comparison of the given
118      * column with an expression. If so, generate the Expression for
119      * the ValueNode that the column is being compared to.
120      *
121      * @param optTable An Optimizable for the base table the column is in
122      * @param columnPosition The ordinal position of the column (one-based)
123      * @param acb The ExpressionClassBuilder for the class we're building
124      * @param mb The method the expression will go into
125      *
126      *
127      * @exception StandardException Thrown on error
128      */

129     void generateExpressionOperand(Optimizable optTable,
130                                         int columnPosition,
131                                         ExpressionClassBuilder acb,
132                                         MethodBuilder mb)
133                         throws StandardException;
134
135     /**
136      * Check whether this RelationalOperator compares the given ColumnReference
137      * to any columns in the same table as the ColumnReference.
138      *
139      * @param cr The ColumnReference that is being compared to some
140      * expression.
141      *
142      * @return true if the given ColumnReference is being compared to any
143      * columns from the same table
144      *
145      * @exception StandardException Thrown on error
146      */

147     boolean selfComparison(ColumnReference cr)
148         throws StandardException;
149
150     /**
151      * Tell whether this relop is a useful start key for the given table.
152      * It has already been determined that the relop has a column from
153      * the given table on one side or the other.
154      *
155      * @param optTable The Optimizable table for which we want to know
156      * whether this is a useful start key.
157      *
158      * @return true if this is a useful start key
159      */

160     boolean usefulStartKey(Optimizable optTable);
161
162     /**
163      * Tell whether this relop is a useful stop key for the given table.
164      * It has already been determined that the relop has a column from
165      * the given table on one side or the other.
166      *
167      * @param optTable The Optimizable table for which we want to know
168      * whether this is a useful stop key.
169      *
170      * @return true if this is a useful stop key
171      */

172     boolean usefulStopKey(Optimizable optTable);
173
174     /**
175      * Get the start operator for a scan (at the store level) for this
176      * RelationalOperator.
177      *
178      * @param optTable The optimizable table we're doing the scan on.
179      * This parameter is so we can tell which side of
180      * the operator the table's column is on.
181      *
182      * @return Either ScanController.GT or ScanController.GE
183      *
184      * @see TransactionController#openScan
185      */

186     int getStartOperator(Optimizable optTable);
187
188     /**
189      * Get the stop operator for a scan (at the store level) for this
190      * RelationalOperator.
191      *
192      * @param optTable The optimizable table we're doing the scan on.
193      * This parameter is so we can tell which side of
194      * the operator the table's column is on.
195      *
196      * @return Either ScanController.GT or ScanController.GE
197      *
198      * @see TransactionController#openScan
199      */

200     int getStopOperator(Optimizable optTable);
201
202     /**
203      * Generate the absolute column id for the ColumnReference that appears on one
204      * side of this RelationalOperator or the other, and that refers to
205      * the given table. (Absolute column id means column id within the
206      * row stored on disk.)
207      *
208      * @param mb The method the generated code is to go into
209      * @param optTable The optimizable table we're doing the scan on.
210      *
211      */

212     void generateAbsoluteColumnId(MethodBuilder mb,
213                                         Optimizable optTable);
214
215     /**
216      * Generate the relative column id for the ColumnReference that appears on one
217      * side of this RelationalOperator or the other, and that refers to
218      * the given table. (Relative column id means column id within the
219      * partial row returned by the store.)
220      *
221      * @param mb The method the generated code is to go into
222      * @param optTable The optimizable table we're doing the scan on.
223      *
224      */

225     void generateRelativeColumnId(MethodBuilder mb,
226                                         Optimizable optTable);
227
228     /**
229      * Generate the comparison operator for this RelationalOperator.
230      * The operator can depend on which side of this operator the
231      * optimizable column is.
232      *
233      * @param mb The method the generated code is to go into
234      * @param optTable The optimizable table we're doing the scan on.
235      *
236      */

237     void generateOperator(MethodBuilder mb,
238                                 Optimizable optTable);
239
240     /**
241      * Generate the method to evaluate a Qualifier. The factory method for
242      * a Qualifier takes a GeneratedMethod that returns the Orderable
243      * that Qualifier.getOrderable() returns.
244      *
245      * @param acb The ExpressionClassBuilder for the class we're building
246      * @param mb The method the generated code is to go into
247      * @param optTable The Optimizable table the Qualifier will qualify
248      *
249      * @exception StandardException Thrown on error.
250      */

251     void generateQualMethod(ExpressionClassBuilder acb,
252                                 MethodBuilder mb,
253                                 Optimizable optTable)
254                         throws StandardException;
255
256     /**
257      * Generate an expression that evaluates to true if this RelationalOperator
258      * uses ordered null semantics, false if it doesn't.
259      *
260      * @param mb The method the generated code is to go into
261      *
262      */

263     void generateOrderedNulls(MethodBuilder mb);
264
265     /**
266      * Generate an expression that evaluates to true if the result of the
267      * comparison should be negated. For example, col > 1 generates
268      * a comparison operator of <= and a negation of true, while col < 1
269      * generates a comparison operator of < and a negation of false.
270      *
271      * @param mb The method the generated code is to go into
272      * @param optTable The Optimizable table the Qualifier will qualify
273      */

274     void generateNegate(MethodBuilder mb,
275                                 Optimizable optTable);
276
277     /** Return true if this operator uses ordered null semantics */
278     boolean orderedNulls();
279
280     /**
281      * Return true if this operator can be compiled into a Qualifier for
282      * the given Optimizable table. This means that there is a column
283      * from that table on one side of this relop, and an expression that
284      * does not refer to the table on the other side of the relop.
285      *
286      * Note that this method has two uses: 1) see if this operator (or
287      * more specifically, the predicate to which this operator belongs)
288      * can be used as a join predicate (esp. for a hash join), and 2)
289      * see if this operator can be pushed to the target optTable. We
290      * use the parameter "forPush" to distinguish between the two uses
291      * because in some cases (esp. situations where we have subqueries)
292      * the answer to "is this a qualifier?" can differ depending on
293      * whether or not we're pushing. In particular, for binary ops
294      * that are join predicates, if we're just trying to find an
295      * equijoin predicate then this op qualifies if it references either
296      * the target table OR any of the base tables in the table's subtree.
297      * But if we're planning to push the predicate down to the target
298      * table, this op only qualifies if it references the target table
299      * directly. This difference in behavior is required because in
300      * case 1 (searching for join predicates), the operator remains at
301      * its current level in the tree even if its operands reference
302      * nodes further down; in case 2, though, we'll end up pushing
303      * the operator down the tree to child node(s) and that requires
304      * additional logic, such as "scoping" consideration. Until
305      * that logic is in place, we don't search a subtree if the intent
306      * is to push the predicate to which this operator belongs further
307      * down that subtree. See BinaryRelationalOperatorNode for an
308      * example of where this comes into play.
309      *
310      * @param optTable The Optimizable table in question.
311      * @param forPush Are we asking because we're trying to push?
312      *
313      * @return true if this operator can be compiled into a Qualifier
314      * for the given Optimizable table.
315      *
316      * @exception StandardException Thrown on error
317      */

318     boolean isQualifier(Optimizable optTable, boolean forPush)
319         throws StandardException;
320
321     /**
322      * Return the operator (as an int) for this RelationalOperator.
323      *
324      * @return int The operator for this RelationalOperator.
325      */

326     public int getOperator();
327
328     /**
329      * Return the variant type for the Qualifier's Orderable.
330      * (Is the Orderable invariant within a scan or within a query?)
331      *
332      * @param optTable The Optimizable table the Qualifier will qualify
333      *
334      * @return int The variant type for the Qualifier's Orderable.
335      * @exception StandardException thrown on error
336      */

337     public int getOrderableVariantType(Optimizable optTable)
338         throws StandardException;
339
340     /**
341      * Return whether this operator compares the given Optimizable with
342      * a constant whose value is known at compile time.
343      */

344     public boolean compareWithKnownConstant(Optimizable optTable, boolean considerParameters);
345
346     /**
347      * Return an Object representing the known value that this relational
348      * operator is comparing to a column in the given Optimizable.
349      *
350      * @exception StandardException Thrown on error
351      */

352     public DataValueDescriptor getCompareValue(Optimizable optTable)
353                     throws StandardException;
354
355     /**
356      * Return whether this operator is an equality comparison of the given
357      * optimizable with a constant expression.
358      */

359     public boolean equalsComparisonWithConstantExpression(Optimizable optTable);
360
361     /**
362      * Return a relational operator which matches the current one
363      * but with the passed in ColumnReference as the (left) operand.
364      *
365      * @param otherCR The ColumnReference for the new (left) operand.
366      *
367      * @return A relational operator which matches the current one
368      * but with the passed in ColumnReference as the (left) operand.
369      *
370      * @exception StandardException Thrown on error
371      */

372     public RelationalOperator getTransitiveSearchClause(ColumnReference otherCR)
373         throws StandardException;
374 }
375
Popular Tags