00001
package com.quadcap.sql;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
import java.io.ByteArrayInputStream;
00042
import java.io.ByteArrayOutputStream;
00043
import java.io.IOException;
00044
00045
import java.util.Vector;
00046
00047
import java.sql.SQLException;
00048
00049
import com.quadcap.sql.io.ObjectInputStream;
00050
import com.quadcap.sql.io.ObjectOutputStream;
00051
00052
import com.quadcap.sql.index.BCursor;
00053
import com.quadcap.sql.index.Btree;
00054
00055
import com.quadcap.sql.file.BlockFile;
00056
import com.quadcap.sql.file.PageManager;
00057
00058
import com.quadcap.sql.types.Op;
00059
import com.quadcap.sql.types.Value;
00060
00061
import com.quadcap.util.Debug;
00062
import com.quadcap.util.Util;
00063
00064
00065
00066
00067
00068
00069
00070 public class GroupByCursor extends FilterCursor {
00071 Vector
groupBy = null;
00072 int currentRowNum = 0;
00073 byte[]
prevKey =
new byte[32];
00074 int prevKeyLen = -1;
00075 int[]
gMap = null;
00076 BCursor
bc = null;
00077 LazyRow prevRow = null;
00078 LazyRow currRow = null;
00079 boolean sameGroup =
false;
00080 boolean prev =
false;
00081 Key compare = null;
00082 TempTable tempTable = null;
00083
00084 public GroupByCursor(
Session session,
Cursor cursor, Vector groupBy)
00085
throws SQLException
00086 {
00087 super(session, cursor);
00088
00089
this.currRow =
new LazyRow(cursor.
getColumnCount());
00090
this.prevRow =
new LazyRow(cursor.
getColumnCount());
00091
this.groupBy =
groupBy;
00092
this.gMap =
new int[
groupBy.size()];
00093
this.compare =
new Key(
gMap.length);
00094
for (
int i = 0; i <
gMap.length; i++) {
00095
Column c = cursor.
getColumn((String)
groupBy.elementAt(i));
00096
gMap[i] = c.
getColumn();
00097 }
00098
try {
00099
this.tempTable =
new TempTable(session,
new Key(
gMap.length+1),
00100
gMap);
00101
tempTable.
addRows(cursor);
00102
this.bc =
tempTable.
getCursor();
00103
beforeFirst();
00104 }
catch (IOException e) {
00105
throw DbException.wrapThrowable(e);
00106 }
00107 }
00108
00109 public Row getRow() throws SQLException {
00110
00111
return prevRow;
00112 }
00113
00114 public void updateRow(
Row row)
throws SQLException {
00115
throw new SQLException(
"GroupBy expressions aren't updateable",
00116
"42000");
00117 }
00118
00119 public void deleteRow() throws SQLException {
00120
throw new SQLException(
"GroupBy expressions aren't updateable",
00121
"42000");
00122 }
00123
00124 public void beforeFirst() throws SQLException {
00125
try {
00126
bc.beforeFirst();
00127
prev =
nextRow();
00128 }
catch (IOException e) {
00129
throw DbException.wrapThrowable(e);
00130 }
catch (ClassNotFoundException e) {
00131
throw DbException.wrapThrowable(e);
00132 }
00133 }
00134
00135 public boolean lastRowOfGroup() {
00136
00137
return !
sameGroup;
00138 }
00139
00140 public boolean next() throws SQLException {
00141
try {
00142
boolean ret =
prev;
00143 prev =
nextRow();
00144
return ret;
00145 }
catch (IOException e) {
00146
throw DbException.wrapThrowable(e);
00147 }
catch (ClassNotFoundException e) {
00148
throw DbException.wrapThrowable(e);
00149 }
00150 }
00151
00152 public boolean nextRow()
00153 throws SQLException, IOException, ClassNotFoundException
00154 {
00155
swapRows();
00156
sameGroup =
false;
00157
if (!
bc.next()) {
00158
return false;
00159 }
00160
final byte[] key =
bc.getKeyBuf();
00161
final int len =
bc.getKeyLen();
00162
00163
if (
prevKeyLen != -1) {
00164
sameGroup =
compare.
compare(key, 0, len,
00165
prevKey, 0,
prevKeyLen) == 0;
00166 }
00167
prevKey = (byte[])
Util.checkCapacity(
prevKey, len);
00168
prevKeyLen = len;
00169
00170 System.arraycopy(key, 0,
prevKey, 0, len);
00171
00172
tempTable.
getRow(
bc.getValBuf(),
currRow);
00173
return true;
00174 }
00175
00176 final void swapRows() {
00177
LazyRow temp =
prevRow;
00178 prevRow =
currRow;
00179 currRow = temp;
00180
00181 }
00182
00183 public boolean isWritable(
int col)
throws SQLException {
00184
return false;
00185 }
00186
00187
00188
00189
00190 public long size() {
return -1; }
00191
00192 public void close() throws SQLException {
00193
try {
00194 super.close();
00195 } finally {
00196
try {
00197
if (
bc != null)
bc.release();
00198 } finally {
00199
bc = null;
00200
try {
00201
if (
tempTable != null)
tempTable.
release();
00202 }
catch (IOException e2) {
00203
throw DbException.wrapThrowable(e2);
00204 } finally {
00205
tempTable = null;
00206 }
00207 }
00208 }
00209 }
00210 }