KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > smallsql > database > Join


1 /* =============================================================
2  * SmallSQL : a free Java DBMS library for the Java(tm) platform
3  * =============================================================
4  *
5  * (C) Copyright 2004-2006, by Volker Berlin.
6  *
7  * Project Info: http://www.smallsql.de/
8  *
9  * This library is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17  * License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22  * USA.
23  *
24  * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
25  * in the United States and other countries.]
26  *
27  * ---------------
28  * Join.java
29  * ---------------
30  * Author: Volker Berlin
31  *
32  */

33 package smallsql.database;
34
35
36 final class Join extends RowSource{
37
38     Expression condition; // the join condition, the part after the ON
39
private int type;
40     RowSource left; // the left table, view or rowsource of the join
41
RowSource right;
42     private boolean isBeforeFirst = true;
43     private boolean isAfterLast;
44     private boolean isOuterValid = true;
45     
46     // Variables for FULL JOIN
47
private boolean[] isFullNotValid;
48     private int fullRightRowCounter;
49     private int fullRowCount;
50     private int fullReturnCounter = -1;
51     
52     private LongLongList rowPositions; // needed for getRowPosition() and setRowPosition()
53
private int row; //current row number
54

55
56     Join( int type, RowSource left, RowSource right, Expression condition ){
57         this.type = type;
58         this.condition = condition;
59         this.left = left;
60         this.right = right;
61         if(type == FULL_JOIN){
62             isFullNotValid = new boolean[10];
63         }
64     }
65     
66     
67     final boolean isScrollable(){
68         return false; //TODO performance, if left and right are scrollable then this should also scrollable
69
}
70
71     
72     void beforeFirst() throws Exception JavaDoc{
73         left.beforeFirst();
74         right.beforeFirst();
75         isBeforeFirst = true;
76         isAfterLast = false;
77         fullRightRowCounter = 0;
78         fullRowCount = 0;
79         fullReturnCounter = -1;
80         row = 0;
81     }
82
83     boolean first() throws Exception JavaDoc{
84         boolean result = left.first() && right.first();
85         row = 1;
86         isBeforeFirst= false;
87         isAfterLast = false;
88         if(!result) noRow();
89         return result;
90     }
91     
92
93     boolean next() throws Exception JavaDoc{
94         if(isAfterLast) return false;
95         boolean result;
96         row++;
97         if(fullReturnCounter >=0){
98             do{
99                 if(fullReturnCounter >= fullRowCount){
100                     noRow();
101                     return false;
102                 }
103                 right.next();
104             }while(isFullNotValid[fullReturnCounter++]);
105             return true;
106         }
107         do{
108             if(isBeforeFirst){
109                 result = left.next();
110                 if(result){
111                     result = right.first();
112                     if(!result){
113                         switch(type){
114                             case LEFT_JOIN:
115                             case FULL_JOIN:
116                                 isOuterValid = false;
117                                 isBeforeFirst = false;
118                                 right.nullRow();
119                                 return true;
120                         }
121                     }else fullRightRowCounter++;
122                 }else{
123                     // left does not include any row
124
if(type == FULL_JOIN){
125                         while(right.next()){
126                             fullRightRowCounter++;
127                         }
128                         fullRowCount = fullRightRowCounter;
129                     }
130                 }
131             }else{
132                 result = right.next();
133                 if(!result){
134                     switch(type){
135                         case LEFT_JOIN:
136                         case FULL_JOIN:
137                             if(isOuterValid){
138                                 isOuterValid = false;
139                                 right.nullRow();
140                                 return true;
141                             }
142                             fullRowCount = Math.max( fullRowCount, fullRightRowCounter);
143                             fullRightRowCounter = 0;
144                     }
145                     isOuterValid = true;
146                     result = left.next();
147                     if(result){
148                         result = right.first();
149                         if(!result){
150                             switch(type){
151                                 case LEFT_JOIN:
152                                 case FULL_JOIN:
153                                     isOuterValid = false;
154                                     right.nullRow();
155                                     return true;
156                             }
157                         }else fullRightRowCounter++;
158                     }
159                     
160                 }else fullRightRowCounter++;
161             }
162             isBeforeFirst = false;
163         }while(result && !getBoolean());
164         isOuterValid = false;
165         if(type == FULL_JOIN){
166             if(fullRightRowCounter >= isFullNotValid.length){
167                 boolean[] temp = new boolean[fullRightRowCounter << 1];
168                 System.arraycopy( isFullNotValid, 0, temp, 0, fullRightRowCounter);
169                 isFullNotValid = temp;
170             }
171             if(!result){
172                 if(fullRowCount == 0){
173                     noRow();
174                     return false;
175                 }
176                 if(fullReturnCounter<0) {
177                     fullReturnCounter = 0;
178                     right.first();
179                     left.nullRow();
180                 }
181                 while(isFullNotValid[fullReturnCounter++]){
182                     if(fullReturnCounter >= fullRowCount){
183                         noRow();
184                         return false;
185                     }
186                     right.next();
187                 }
188                 return true;
189             }else
190                 isFullNotValid[fullRightRowCounter-1] = result;
191         }
192         if(!result){
193             noRow();
194         }
195         return result;
196     }
197     
198     
199     void afterLast(){
200         isAfterLast = true;
201         noRow();
202     }
203     
204     
205     int getRow(){
206         return row;
207     }
208     
209     
210     final long getRowPosition(){
211         if(rowPositions == null) rowPositions = new LongLongList();
212         rowPositions.add( left.getRowPosition(), right.getRowPosition());
213         return rowPositions.size()-1;
214     }
215     
216     final void setRowPosition(long rowPosition) throws Exception JavaDoc{
217         left .setRowPosition( rowPositions.get1((int)rowPosition));
218         right.setRowPosition( rowPositions.get2((int)rowPosition));
219     }
220     
221
222     final boolean rowInserted(){
223         return left.rowInserted() || right.rowInserted();
224     }
225     
226     
227     final boolean rowDeleted(){
228         return left.rowDeleted() || right.rowDeleted();
229     }
230     
231     
232     /**
233      * By OUTER or FULL JOIN must one rowsource set to null.
234      */

235     void nullRow(){
236         left.nullRow();
237         right.nullRow();
238         row = 0;
239     }
240     
241
242     void noRow(){
243         isAfterLast = true;
244         left.noRow();
245         right.noRow();
246         row = 0;
247     }
248
249     
250     void execute() throws Exception JavaDoc{
251         left.execute();
252         right.execute();
253     }
254     
255
256     private boolean getBoolean() throws Exception JavaDoc{
257         return type == CROSS_JOIN || condition.getBoolean();
258     }
259     
260
261     static final int CROSS_JOIN = 1;
262     static final int INNER_JOIN = 2;
263     static final int LEFT_JOIN = 3;
264     static final int FULL_JOIN = 4;
265     static final int RIGHT_JOIN = 5;
266 }
Popular Tags