KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2
3    Derby - Class org.apache.derby.impl.sql.compile.RowOrderingImpl
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.RowOrdering;
25 import org.apache.derby.iapi.sql.compile.Optimizable;
26
27 import org.apache.derby.iapi.services.sanity.SanityManager;
28
29 import org.apache.derby.iapi.error.StandardException;
30
31 import java.util.Vector JavaDoc;
32
33 class RowOrderingImpl implements RowOrdering {
34
35     /* This vector contains ColumnOrderings */
36     Vector JavaDoc ordering;
37
38     /*
39     ** This ColumnOrdering represents the columns that can be considered
40     ** ordered no matter what. For example, columns that are compared to
41     ** constants with = are always ordered. Also, all columns in a one-row
42     ** result set are ordered.
43     */

44     ColumnOrdering columnsAlwaysOrdered;
45
46     /*
47     ** This vector contains table numbers for tables that are always ordered.
48     ** This happens for one-row tables.
49     */

50     Vector JavaDoc alwaysOrderedOptimizables;
51
52     ColumnOrdering currentColumnOrdering;
53
54     /* This vector contains unordered Optimizables */
55     Vector JavaDoc unorderedOptimizables;
56
57     RowOrderingImpl() {
58         ordering = new Vector JavaDoc();
59         unorderedOptimizables = new Vector JavaDoc();
60         columnsAlwaysOrdered = new ColumnOrdering(RowOrdering.DONTCARE);
61         alwaysOrderedOptimizables = new Vector JavaDoc();
62     }
63
64     /**
65      * @see RowOrdering#orderedOnColumn
66      *
67      * @exception StandardException Thrown on error
68      */

69     public boolean orderedOnColumn(int direction,
70                                     int orderPosition,
71                                     int tableNumber,
72                                     int columnNumber)
73                 throws StandardException {
74
75         /*
76         ** Return true if the table is always ordered.
77         */

78         if (vectorContainsOptimizable(tableNumber, alwaysOrderedOptimizables))
79         {
80             return true;
81         }
82
83         /*
84         ** Return true if the column is always ordered.
85         */

86         if (columnsAlwaysOrdered.contains(tableNumber, columnNumber)) {
87             return true;
88         }
89
90         /*
91         ** Return false if we're looking for an ordering position that isn't
92         ** in this ordering.
93         */

94         if (orderPosition >= ordering.size())
95             return false;
96
97         ColumnOrdering co = (ColumnOrdering) ordering.elementAt(orderPosition);
98
99         /*
100         ** Is the column in question ordered with the given direction at
101         ** this position?
102         */

103         return co.ordered(direction, tableNumber, columnNumber);
104     }
105
106     /**
107      * @see RowOrdering#orderedOnColumn
108      *
109      * @exception StandardException Thrown on error
110      */

111     public boolean orderedOnColumn(int direction,
112                                     int tableNumber,
113                                     int columnNumber)
114                 throws StandardException {
115
116         /*
117         ** Return true if the table is always ordered.
118         */

119         if (vectorContainsOptimizable(tableNumber, alwaysOrderedOptimizables))
120         {
121             return true;
122         }
123
124         /*
125         ** Return true if the column is always ordered.
126         */

127         if (columnsAlwaysOrdered.contains(tableNumber, columnNumber)) {
128             return true;
129         }
130
131         boolean ordered = false;
132
133         for (int i = 0; i < ordering.size(); i++) {
134             ColumnOrdering co = (ColumnOrdering) ordering.elementAt(i);
135
136             /*
137             ** Is the column in question ordered with the given direction at
138             ** this position?
139             */

140             boolean thisOrdered = co.ordered(direction,
141                                             tableNumber,
142                                             columnNumber);
143
144             if (thisOrdered) {
145                 ordered = true;
146                 break;
147             }
148         }
149
150         return ordered;
151     }
152
153     /**
154      * Return true if the given vector of Optimizables contains an Optimizable
155      * with the given table number.
156      */

157     private boolean vectorContainsOptimizable(int tableNumber, Vector JavaDoc vec)
158     {
159         int i;
160
161         for (i = vec.size() - 1; i >= 0; i--)
162         {
163             Optimizable optTable =
164                             (Optimizable) vec.elementAt(i);
165
166             if (optTable.hasTableNumber())
167             {
168                 if (optTable.getTableNumber() == tableNumber)
169                 {
170                     return true;
171                 }
172             }
173         }
174
175         return false;
176     }
177
178     /** @see RowOrdering#addOrderedColumn */
179     public void addOrderedColumn(int direction,
180                                 int tableNumber,
181                                 int columnNumber)
182     {
183         if (unorderedOptimizables.size() > 0)
184             return;
185
186         ColumnOrdering currentColumnOrdering;
187
188         if (ordering.size() == 0)
189         {
190             currentColumnOrdering = new ColumnOrdering(direction);
191             ordering.addElement(currentColumnOrdering);
192         }
193         else
194         {
195             currentColumnOrdering =
196                 (ColumnOrdering) ordering.elementAt(ordering.size() - 1);
197         }
198
199         if (SanityManager.DEBUG)
200         {
201             if (currentColumnOrdering.direction() != direction)
202             {
203                 SanityManager.THROWASSERT("direction == " + direction +
204                     ", currentColumnOrdering.direction() == " +
205                     currentColumnOrdering.direction());
206             }
207         }
208
209         currentColumnOrdering.addColumn(tableNumber, columnNumber);
210     }
211
212     /** @see RowOrdering#nextOrderPosition */
213     public void nextOrderPosition(int direction)
214     {
215         if (unorderedOptimizables.size() > 0)
216             return;
217
218         currentColumnOrdering = new ColumnOrdering(direction);
219         ordering.addElement(currentColumnOrdering);
220     }
221
222     public void optimizableAlwaysOrdered(Optimizable optimizable)
223     {
224         // A table can't be ordered if there is an outer unordered table
225
if (unorderedOptimizablesOtherThan(optimizable))
226         {
227             return;
228         }
229
230         /*
231         ** A table is not "always ordered" if any of the other ordered tables
232         ** in the join order are not also "always ordered". In other words,
233         ** if any outer table is not a one-row table, this table is not
234         ** always ordered.
235         **
236         ** The table that was passed in as a parameter may have already been
237         ** added as a table with ordered columns. If it is the first table
238         ** in the list of ordered columns, then there should be no other
239         ** tables in this list, so we remove it from the list and add it
240         ** to the list of always-ordered tables.
241         */

242         boolean hasTableNumber = optimizable.hasTableNumber();
243         int tableNumber = (hasTableNumber ? optimizable.getTableNumber() : 0);
244         if (
245             (
246                 (ordering.size() == 0) ||
247                 (
248                     hasTableNumber &&
249                     ((ColumnOrdering) ordering.elementAt(0)).hasTable(
250                                                                     tableNumber)
251                 )
252             )
253             &&
254             (
255                 hasTableNumber &&
256                 ! columnsAlwaysOrdered.hasAnyOtherTable(tableNumber)
257             )
258            )
259         {
260             if (optimizable.hasTableNumber())
261                 removeOptimizable(optimizable.getTableNumber());
262
263             alwaysOrderedOptimizables.addElement(optimizable);
264         }
265     }
266
267     /** @see RowOrdering#columnAlwaysOrdered */
268     public void columnAlwaysOrdered(Optimizable optimizable, int columnNumber)
269     {
270         columnsAlwaysOrdered.addColumn(optimizable.getTableNumber(),
271                                         columnNumber);
272     }
273
274     /** @see RowOrdering#alwaysOrdered */
275     public boolean alwaysOrdered(int tableNumber)
276     {
277         return vectorContainsOptimizable(
278                                         tableNumber,
279                                         alwaysOrderedOptimizables
280                                         );
281     }
282
283     /** @see RowOrdering#removeOptimizable */
284     public void removeOptimizable(int tableNumber)
285     {
286         int i;
287
288         /*
289         ** Walk the list backwards, so we can remove elements
290         ** by position.
291         */

292         for (i = ordering.size() - 1; i >= 0; i--)
293         {
294             /*
295             ** First, remove the table from all the ColumnOrderings
296             */

297             ColumnOrdering ord = (ColumnOrdering) ordering.elementAt(i);
298             ord.removeColumns(tableNumber);
299             if (ord.empty())
300                 ordering.removeElementAt(i);
301         }
302
303         /* Remove from list of always-ordered columns */
304         columnsAlwaysOrdered.removeColumns(tableNumber);
305
306         /* Also remove from list of unordered optimizables */
307         removeOptimizableFromVector(tableNumber, unorderedOptimizables);
308
309         /* Also remove from list of always ordered optimizables */
310         removeOptimizableFromVector(tableNumber, alwaysOrderedOptimizables);
311     }
312
313     /**
314      * Remove all optimizables with the given table number from the
315      * given vector of optimizables.
316      */

317     private void removeOptimizableFromVector(int tableNumber, Vector JavaDoc vec)
318     {
319         int i;
320
321         for (i = vec.size() - 1; i >= 0; i--)
322         {
323             Optimizable optTable =
324                             (Optimizable) vec.elementAt(i);
325
326             if (optTable.hasTableNumber())
327             {
328                 if (optTable.getTableNumber() == tableNumber)
329                 {
330                     vec.removeElementAt(i);
331                 }
332             }
333         }
334     }
335
336     /** @see RowOrdering#addUnorderedOptimizable */
337     public void addUnorderedOptimizable(Optimizable optimizable)
338     {
339         unorderedOptimizables.addElement(optimizable);
340     }
341
342     /** @see RowOrdering#copy */
343     public void copy(RowOrdering copyTo) {
344         if (SanityManager.DEBUG) {
345             if ( ! (copyTo instanceof RowOrderingImpl) ) {
346                 SanityManager.THROWASSERT(
347                     "copyTo should be a RowOrderingImpl, is a " +
348                     copyTo.getClass().getName());
349             }
350         }
351
352         RowOrderingImpl dest = (RowOrderingImpl) copyTo;
353
354         /* Clear the ordering of what we're copying to */
355         dest.ordering.removeAllElements();
356         dest.currentColumnOrdering = null;
357
358         dest.unorderedOptimizables.removeAllElements();
359         for (int i = 0; i < unorderedOptimizables.size(); i++) {
360             dest.unorderedOptimizables.addElement(
361                                             unorderedOptimizables.elementAt(i));
362         }
363
364         dest.alwaysOrderedOptimizables.removeAllElements();
365         for (int i = 0; i < alwaysOrderedOptimizables.size(); i++) {
366             dest.alwaysOrderedOptimizables.addElement(
367                                         alwaysOrderedOptimizables.elementAt(i));
368         }
369
370         for (int i = 0; i < ordering.size(); i++) {
371             ColumnOrdering co = (ColumnOrdering) ordering.elementAt(i);
372
373             dest.ordering.addElement(co.cloneMe());
374
375             if (co == currentColumnOrdering)
376                 dest.rememberCurrentColumnOrdering(i);
377         }
378
379         dest.columnsAlwaysOrdered = null;
380         if (columnsAlwaysOrdered != null)
381             dest.columnsAlwaysOrdered = columnsAlwaysOrdered.cloneMe();
382     }
383
384     private void rememberCurrentColumnOrdering(int posn) {
385         currentColumnOrdering = (ColumnOrdering) ordering.elementAt(posn);
386     }
387
388     public String JavaDoc toString() {
389         String JavaDoc retval = null;
390
391         if (SanityManager.DEBUG) {
392             int i;
393
394             retval = "Unordered optimizables: ";
395
396             for (i = 0; i < unorderedOptimizables.size(); i++)
397             {
398                 Optimizable opt = (Optimizable) unorderedOptimizables.elementAt(i);
399                 if (opt.getBaseTableName() != null)
400                 {
401                     retval += opt.getBaseTableName();
402                 }
403                 else
404                 {
405                     retval += unorderedOptimizables.elementAt(i).toString();
406                 }
407                 retval += " ";
408             }
409             retval += "\n";
410
411             retval += "\nAlways ordered optimizables: ";
412
413             for (i = 0; i < alwaysOrderedOptimizables.size(); i++)
414             {
415                 Optimizable opt = (Optimizable) alwaysOrderedOptimizables.elementAt(i);
416                 if (opt.getBaseTableName() != null)
417                 {
418                     retval += opt.getBaseTableName();
419                 }
420                 else
421                 {
422                     retval += alwaysOrderedOptimizables.elementAt(i).toString();
423                 }
424                 retval += " ";
425             }
426             retval += "\n";
427
428             for (i = 0; i < ordering.size(); i++) {
429                 retval += " ColumnOrdering " + i + ": " + ordering.elementAt(i);
430             }
431         }
432
433         return retval;
434     }
435
436     /**
437      * Returns true if there are unordered optimizables in the join order
438      * other than the given one.
439      */

440     private boolean unorderedOptimizablesOtherThan(Optimizable optimizable)
441     {
442         for (int i = 0; i < unorderedOptimizables.size(); i++)
443         {
444             Optimizable thisOpt =
445                 (Optimizable) unorderedOptimizables.elementAt(i);
446
447             if (thisOpt != optimizable)
448                 return true;
449         }
450
451         return false;
452     }
453 }
454
Popular Tags