KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > daffodilwoods > daffodildb > server > sql99 > dql > execution > AggregateAvgAll


1 package com.daffodilwoods.daffodildb.server.sql99.dql.execution;
2
3 import java.math.*;
4
5 import com.daffodilwoods.daffodildb.server.sql99.common.*;
6 import com.daffodilwoods.daffodildb.server.sql99.dql.iterator.*;
7 import com.daffodilwoods.daffodildb.server.sql99.expression.*;
8 import com.daffodilwoods.daffodildb.utils.*;
9 import com.daffodilwoods.daffodildb.utils.field.*;
10 import com.daffodilwoods.database.resource.*;
11 import com.daffodilwoods.database.utility.*;
12 import com.daffodilwoods.daffodildb.server.sql99.expression.valueexpression;
13 import com.daffodilwoods.daffodildb.server.sql99.common.GeneralPurposeStaticClass;
14 import com.daffodilwoods.daffodildb.server.sql99.utils._Reference;
15
16 /**
17  * <p>Title: AggregateAvgAll </p>
18  * <p>Description:
19  * This class is responsible for computing AVERAGE ALL aggregate
20  * function for a particular group of rows. NULL values are ignored
21  * in average function evaluation. </p>
22  * <p>Copyright: Copyright (c) 2004</p>
23  * <p>Company: </p>
24  * @author not attributable
25  * @version 1.0
26  */

27 public class AggregateAvgAll implements _Aggregate, Datatypes, IntegerPool {
28
29   /**
30    * Instance variable representing the sum of all the values
31    * belonging to one group.
32    */

33   protected Object JavaDoc result;
34   /**
35    * Variable representing the number of records involved in one group
36    */

37   protected long count = 0;
38   /**
39    * Instance variable representing the expression/column involed
40    * in the avg function argument.
41    */

42   protected valueexpression column;
43   /**
44    * data type of valueexpression involed in aggregate
45    * function computation.
46    */

47   protected int dataType;
48   /**
49    * flag denoting the sum of values/count of rows has been initialized or not.
50    */

51   protected boolean initialized = false;
52
53   private boolean forQuestion;
54   /**
55    * Initializes the value expression and its data type.
56    * @param column0 represents the value expression passed as argument to
57    * AVG ALL function
58    * @throws DException throws an exception when aggregate function is
59    * performed on column of data type character string, datetime, BLOB,
60    * CLOB and Boolean data type.
61    */

62   public AggregateAvgAll(valueexpression column0) throws DException {
63     column = column0;
64
65     try {
66        dataType=Datatypes.DOUBLE;
67
68        } catch (NullPointerException JavaDoc ex) {
69           throw ex;
70        }
71
72        if(column.getCardinality()==-1){
73           return;
74         }
75
76
77   GeneralPurposeStaticClass.checkForValidColumnsInAggregatesSumAndAvg(column0.getColumnDetails(),"AVG");
78     initialized = true;
79     forQuestion=true;
80  }
81
82
83    /**
84     * This method is required to initialize the variables used in aggregate
85     * function computation when a particular group of rows starts.
86     * @throws DException
87     */

88    public void initialize() throws DException {
89       count = 0;
90       result = FieldUtility.getField(dataType,FieldUtility.NULLBUFFERRANGE);
91       initialized = true;
92     }
93
94    /**
95     * This method is required to retrieve the result of AVG ALL function for a
96     * particular group.
97     * @return the average all of the records involved in the group.
98     * @throws DException
99     */

100    public Object JavaDoc getResult() throws DException {
101    if (result == null) {
102        return FieldUtility.NULLFIELDBASE;
103       }
104       return computeAverage();
105    }
106
107
108    /**
109     * This method performs the addition (sum) of value passed to the result i.e.
110     * sum of the values corresponding to one group. If the result value exceeds
111     * the maximum limit of result data type, data type of the result is promoted
112     * to next bigger datatype to retrive correct result.
113     * If there is numeric overflow after addition, an exception is thrown, which
114     * is catched, and value is added into sum after promoting data type.
115     * @param result0 previous sum of the values involved in the group
116     * @param newObject new value to be added into the sum
117     * @throws DException
118     */

119    protected void getSum(Object JavaDoc result0, FieldBase newObject) throws DException {
120       try {
121          result = GeneralPurposeStaticClass.computeSum(result0, newObject,
122              dataType);
123       } catch (DException ex) {
124          if (ex.getDseCode().equals("DSE8101")) {
125             promoteDatatype();
126             getSum(result0, newObject);
127          } else {
128             throw ex;
129          }
130       }
131    }
132
133    /**
134     * This method is used, when addtion of values causes numeric overflow, this
135     * method sets the data types to next bigger range data type.
136     * @throws DException
137     */

138    protected void promoteDatatype() throws DException {
139       switch (dataType) {
140          case BYTE:
141          case TINYINT:
142          case INTEGER:
143          case INT:
144          case SHORT:
145          case SMALLINT:
146             dataType = LONG;
147             break;
148          case LONG:
149          case BIGINT:
150          case REAL:
151             dataType = DOUBLE;
152             break;
153          case DOUBLE:
154          case FLOAT:
155          case DOUBLEPRECISION:
156             dataType = BIGDECIMAL;
157             break;
158       }
159    }
160
161
162    /**
163     * This method is used to initialize the sum of values involved in the group.
164     * It initializes the numeric values according to the result data type.
165     * @throws DException
166     */

167    protected void init() throws DException {
168      switch (dataType) {
169          case BYTE:
170          case TINYINT:
171          case INTEGER:
172          case INT:
173          case SHORT:
174          case SMALLINT:
175             result = new Integer JavaDoc(0);
176             break;
177          case LONG:
178          case BIGINT:
179             result = new Long JavaDoc(0);
180             break;
181          case REAL:
182             result = new Float JavaDoc(0.0);
183             break;
184          case DOUBLE:
185          case FLOAT:
186          case DOUBLEPRECISION:
187             result = new Double JavaDoc(0.0);
188             break;
189          case DEC:
190          case DECIMAL:
191          case NUMERIC:
192          case BIGDECIMAL:
193             result = new BigDecimal(0.0);
194             break;
195          case CHARACTER:
196          case CHAR:
197          case VARCHAR:
198          case CHARACTERVARYING:
199          case CHARVARYING:
200             throw new DException("DSE945", null);
201          default:
202             throw new DException("DSE416", new Object JavaDoc[] {new Integer JavaDoc(dataType)});
203       }
204    }
205
206    public void releaseResource() throws DException {
207    }
208
209    /**
210     * This method performs the actual computation of AVG ALL method according to
211     * result data type. The average of n values involved in the group is computed
212     * by dividing the sum of all the values by number of values involved in the
213     * average function computation.
214     * @return
215     * @throws DException
216     */

217    protected Object JavaDoc computeAverage() throws DException {
218      Object JavaDoc fb = null;
219      Number JavaDoc val = null;
220     try {
221       switch (dataType) {
222         case BYTE:
223         case TINYINT:
224         case INTEGER:
225         case INT:
226         case SHORT:
227         case SMALLINT:
228         double result1 = ( (Number JavaDoc) result).intValue();
229
230           result1 /= count;
231           return new FieldLiteral(new BigDecimal(result1), BIGDECIMAL);
232         case LONG:
233         case BIGINT:
234           double result0 = ( (Number JavaDoc) result).longValue();
235           result0 /= count;
236           return new FieldLiteral(new BigDecimal(result0), BIGDECIMAL);
237         case REAL:
238           double result3 = ( (Number JavaDoc) result).floatValue();
239           result3 /= count;
240           return new FieldLiteral(new BigDecimal(result3), BIGDECIMAL);
241         case DOUBLE:
242         case FLOAT:
243         case DOUBLEPRECISION:
244           double result4 = ( (Number JavaDoc) result).doubleValue();
245           result4 /= count;
246           return new FieldLiteral(new BigDecimal(result4), BIGDECIMAL);
247         case DEC:
248         case DECIMAL:
249         case NUMERIC:
250         case BIGDECIMAL:
251           BigDecimal bd = ( (BigDecimal) result).divide(new BigDecimal("" +
252               count), 2, 0);
253           return new FieldLiteral(bd, BIGDECIMAL);
254       }
255     }
256     catch (ClassCastException JavaDoc ex) {
257             return result;
258     }
259     return null;
260   }
261
262    public valueexpression getValueExpression() {
263       return column;
264    }
265
266    /**
267     * This method is responsible to add a new record in to a group and
268     * to correspondingly update the number of rows in the group and sum of the
269     * values. When the new value is added into the group, no of rows and the sum
270     * are updated. For first value in the group, sum of the values is initialized
271     * acc. to datatype. NULL values are ignored in aggregate function computation.
272     * @param iterator group by iterator retriving the values of columns
273     * involved in aggregate computation.
274     * @throws DException
275     */

276
277    public void addRecord(Object JavaDoc newObject) throws DException{
278        if (((FieldBase)newObject).isNull()) {
279           return;
280        }
281            if (initialized) {
282             if(forQuestion){
283            if (!GeneralPurposeStaticClass.checkForIntAndDouble( ( (FieldBase)
284                newObject).getDatatype()))
285              throw new DException("DSE773", null);
286             }
287            init();
288            initialized = false;
289
290        }
291      count++;
292      getSum(result, (FieldBase)newObject);
293
294
295  }}
296
Popular Tags