KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > quadcap > sql > MergeExpression


1 package com.quadcap.sql;
2
3 /* Copyright 1999 - 2003 Quadcap Software. All rights reserved.
4  *
5  * This software is distributed under the Quadcap Free Software License.
6  * This software may be used or modified for any purpose, personal or
7  * commercial. Open Source redistributions are permitted. Commercial
8  * redistribution of larger works derived from, or works which bundle
9  * this software requires a "Commercial Redistribution License"; see
10  * http://www.quadcap.com/purchase.
11  *
12  * Redistributions qualify as "Open Source" under one of the following terms:
13  *
14  * Redistributions are made at no charge beyond the reasonable cost of
15  * materials and delivery.
16  *
17  * Redistributions are accompanied by a copy of the Source Code or by an
18  * irrevocable offer to provide a copy of the Source Code for up to three
19  * years at the cost of materials and delivery. Such redistributions
20  * must allow further use, modification, and redistribution of the Source
21  * Code under substantially the same terms as this license.
22  *
23  * Redistributions of source code must retain the copyright notices as they
24  * appear in each source code file, these license terms, and the
25  * disclaimer/limitation of liability set forth as paragraph 6 below.
26  *
27  * Redistributions in binary form must reproduce this Copyright Notice,
28  * these license terms, and the disclaimer/limitation of liability set
29  * forth as paragraph 6 below, in the documentation and/or other materials
30  * provided with the distribution.
31  *
32  * The Software is provided on an "AS IS" basis. No warranty is
33  * provided that the Software is free of defects, or fit for a
34  * particular purpose.
35  *
36  * Limitation of Liability. Quadcap Software shall not be liable
37  * for any damages suffered by the Licensee or any third party resulting
38  * from use of the Software.
39  */

40
41 import java.io.ByteArrayOutputStream JavaDoc;
42 import java.io.Externalizable JavaDoc;
43 import java.io.IOException JavaDoc;
44 import java.io.ObjectInput JavaDoc;
45 import java.io.ObjectOutput JavaDoc;
46
47 import java.util.Vector JavaDoc;
48
49 import java.sql.SQLException JavaDoc;
50
51 import com.quadcap.sql.io.ObjectInputStream;
52 import com.quadcap.sql.io.ObjectOutputStream;
53
54 import com.quadcap.sql.file.BlockFile;
55
56 import com.quadcap.sql.types.Op;
57 import com.quadcap.sql.types.Type;
58 import com.quadcap.sql.types.Value;
59
60 import com.quadcap.util.Debug;
61 import com.quadcap.util.Util;
62
63 /**
64  * Table expression representing <b>UNION</b> or <b>INTERSECTION</b>
65  * operations.
66  *
67  * @author Stan Bailes
68  */

69 public class MergeExpression extends TableExpression
70     implements Externalizable JavaDoc
71 {
72     int op;
73     boolean all;
74     boolean corr;
75     TableExpression a;
76     TableExpression b;
77     Vector JavaDoc columns;
78     TempTableMerge tempTable;
79     MergeCursor mcursor = null;
80     int[] amap = null;
81     int[] bmap = null;
82     Type[] typeMap = null;
83     
84     public MergeExpression() {}
85
86     public MergeExpression(int op, boolean all, TableExpression a,
87                TableExpression b, Vector JavaDoc columns,
88                            boolean corr) {
89     this.op = op;
90     this.all = all;
91         this.a = a;
92         this.b = b;
93         this.columns = columns;
94         this.corr = corr;
95     }
96
97     public int rank() { return 2; }
98
99     public boolean isUpdatable() { return false; }
100
101     public void getBaseTables(Vector JavaDoc v) {
102     a.getBaseTables(v);
103     b.getBaseTables(v);
104     }
105
106     public void setWhere(Expression where) {
107         this.where = where;
108         a.setWhere(where);
109         b.setWhere(where);
110     }
111
112     public Cursor getCursor(Session session, Cursor c) throws SQLException JavaDoc {
113     try {
114         Cursor ca = a.getCursor(session, c);
115         Cursor cb = b.getCursor(session, c);
116
117         try {
118         checkCorresponding(ca, cb);
119         
120         Key compare = new Key(amap.length);
121
122         tempTable = new TempTableMerge(session, compare);
123         tempTable.addRows(session, ca, 0, amap);
124         tempTable.addRows(session, cb, 1, bmap);
125
126         mcursor = new MergeCursor(session, op, all, tempTable);
127
128         if (!corr) {
129             for (int i = 1; i <= ca.getColumnCount(); i++) {
130             Column col = ca.getColumn(i);
131             mcursor.addColumn(new Column(col.getName(), col));
132             }
133         } else {
134             for (int i = 0; i < amap.length; i++) {
135             Column col = ca.getColumn(amap[i]);
136             mcursor.addColumn(new Column(col.getName(), col));
137             }
138         }
139         mcursor.resolveColumns();
140         } finally {
141         ca.close();
142         cb.close();
143         }
144     } catch (IOException JavaDoc e) {
145         throw DbException.wrapThrowable(e);
146     }
147     return mcursor;
148     }
149
150     void checkCorresponding(Cursor ca, Cursor cb) throws SQLException JavaDoc {
151         if (!corr) {
152             if (ca.getColumnCount() != cb.getColumnCount()) {
153                 throw new SQLException JavaDoc(Op.toString(op) + " merge " +
154                                    "operation, tables must have the " +
155                                        "same number of columns", "42000");
156             }
157             amap = new int[ca.getColumnCount()];
158             bmap = new int[amap.length];
159             for (int i = 0; i < amap.length; i++) {
160                 amap[i] = bmap[i] = i+1;
161             }
162         } else if (columns == null) {
163             // find the common columns for eg EXCEPT CORRESPONDING
164
int cnt = 0;
165             for (int i = 1; i <= ca.getColumnCount(); i++) {
166                 Column cola = ca.getColumn(i);
167                 Column colb = cb.getColumn(cola.getShortName());
168                 if (colb != null) {
169                     cnt++;
170                 }
171             }
172             if (cnt == 0) {
173                 throw new SQLException JavaDoc(Op.toString(op) + " CORRESPONDING, " +
174                                        "no common columns found", "42000");
175             }
176             amap = new int[cnt];
177             bmap = new int[cnt];
178             int p = 0;
179             for (int i = 1; i <= ca.getColumnCount(); i++) {
180                 Column cola = ca.getColumn(i);
181                 Column colb = cb.getColumn(cola.getShortName());
182                 if (colb != null) {
183                     amap[p] = cola.getColumn();
184                     bmap[p] = colb.getColumn();
185                     p++;
186                 }
187             }
188     } else {
189         amap = new int[columns.size()];
190         bmap = new int[amap.length];
191             
192         for (int i = 0; i < columns.size(); i++) {
193         String JavaDoc name = (String JavaDoc)columns.elementAt(i);
194         Column cola = ca.getColumn(name);
195         if (cola == null) {
196             throw new SQLException JavaDoc("Not found: " + name, "42000");
197         }
198         amap[i] = cola.getColumn();
199
200         Column colb = cb.getColumn(name);
201         if (colb == null) {
202             throw new SQLException JavaDoc("Not found: " + name, "42000");
203         }
204         bmap[i] = colb.getColumn();
205         }
206     }
207     }
208
209     public void invert() {
210     throw new RuntimeException JavaDoc(
211         "invert not implemented for MergeExpression");
212     }
213
214     public void readExternal(ObjectInput JavaDoc in)
215     throws IOException JavaDoc, ClassNotFoundException JavaDoc
216     {
217     this.op = in.read();
218     this.all = in.read() == 1;
219     this.a = (TableExpression)in.readObject();
220     this.b = (TableExpression)in.readObject();
221     this.columns = (Vector JavaDoc)in.readObject();
222     this.corr = in.read() == 1;
223     }
224     
225     public void writeExternal(ObjectOutput JavaDoc out) throws IOException JavaDoc {
226     out.write(op);
227     out.write(all ? 1 : 0);
228     out.writeObject(a);
229     out.writeObject(b);
230     out.writeObject(columns);
231         out.write(corr ? 1 : 0);
232     }
233
234     public void visitSubExpressions(ExpressionVisitor ev) {
235     ev.visit(a);
236     ev.visit(b);
237     }
238
239     public String JavaDoc toString() {
240         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(a.toString());
241         sb.append(' ');
242         sb.append(Op.toString(op));
243         if (all) sb.append(" ALL");
244         if (corr) {
245             sb.append(" CORRESPONDING");
246             if (columns != null) {
247                 sb.append(" BY (");
248                 for (int i = 0; i < columns.size(); i++) {
249                     if (i > 0) sb.append(',');
250                     sb.append(columns.get(i).toString());
251                 }
252                 sb.append(")");
253             }
254         }
255         sb.append(' ');
256         sb.append(b.toString());
257         return sb.toString();
258     }
259
260     //#ifdef DEBUG
261
public String JavaDoc name() {
262         StringBuffer JavaDoc sb = new StringBuffer JavaDoc('(');
263         sb.append(a.name());
264         sb.append(' ');
265         sb.append(Op.toString(op));
266         sb.append(' ');
267         sb.append(b.name());
268         sb.append(')');
269         return sb.toString();
270     }
271     //#endif
272
}
273
Popular Tags