1 21 22 package org.apache.derby.impl.sql.execute; 23 24 import org.apache.derby.iapi.services.sanity.SanityManager; 25 import org.apache.derby.iapi.types.NumberDataValue; 26 import org.apache.derby.iapi.error.StandardException; 27 import org.apache.derby.iapi.sql.execute.ExecAggregator; 28 import org.apache.derby.iapi.types.DataValueDescriptor; 29 import org.apache.derby.iapi.types.TypeId; 30 31 import org.apache.derby.iapi.services.io.StoredFormatIds; 32 import org.apache.derby.iapi.reference.SQLState; 33 34 import java.io.ObjectOutput ; 35 import java.io.ObjectInput ; 36 import java.io.IOException ; 37 38 51 public final class AvgAggregator extends SumAggregator 52 { 53 private long count; 54 private int scale; 55 56 protected void accumulate(DataValueDescriptor addend) 57 throws StandardException 58 { 59 60 if (count == 0) { 61 62 String typeName = addend.getTypeName(); 63 if ( typeName.equals(TypeId.TINYINT_NAME) 64 || typeName.equals(TypeId.SMALLINT_NAME) 65 || typeName.equals(TypeId.INTEGER_NAME) 66 || typeName.equals(TypeId.LONGINT_NAME)) { 67 scale = 0; 68 } else if ( typeName.equals(TypeId.REAL_NAME) 69 || typeName.equals(TypeId.DOUBLE_NAME)) { 70 scale = TypeId.DECIMAL_SCALE; 71 } else { 72 scale = ((NumberDataValue) addend).getDecimalValueScale(); 74 if (scale < NumberDataValue.MIN_DECIMAL_DIVIDE_SCALE) 75 scale = NumberDataValue.MIN_DECIMAL_DIVIDE_SCALE; 76 } 77 } 78 79 try { 80 81 super.accumulate(addend); 82 count++; 83 return; 84 85 } catch (StandardException se) { 86 87 if (!se.getMessageId().equals(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE)) 88 throw se; 89 } 90 91 92 103 104 String typeName = value.getTypeName(); 107 108 DataValueDescriptor newValue; 109 110 if (typeName.equals(TypeId.INTEGER_NAME)) { 111 newValue = new org.apache.derby.iapi.types.SQLLongint(); 112 } else if (typeName.equals(TypeId.TINYINT_NAME) || 113 typeName.equals(TypeId.SMALLINT_NAME)) { 114 newValue = new org.apache.derby.iapi.types.SQLInteger(); 115 } else if (typeName.equals(TypeId.REAL_NAME)) { 116 newValue = new org.apache.derby.iapi.types.SQLDouble(); 117 } else { 118 TypeId decimalTypeId = TypeId.getBuiltInTypeId(java.sql.Types.DECIMAL); 119 newValue = decimalTypeId.getNull(); 120 } 121 122 newValue.setValue(value); 123 value = newValue; 124 125 accumulate(addend); 126 } 127 128 public void merge(ExecAggregator addend) 129 throws StandardException 130 { 131 AvgAggregator otherAvg = (AvgAggregator) addend; 132 133 if (count == 0) { 135 count = otherAvg.count; 136 value = otherAvg.value; 137 scale = otherAvg.scale; 138 return; 139 } 140 141 151 if(otherAvg.value != null) 152 { 153 count += (otherAvg.count - 1); 155 accumulate(otherAvg.value); 156 } 157 } 158 159 167 public DataValueDescriptor getResult() throws StandardException 168 { 169 if (count == 0) 170 { 171 return null; 172 } 173 174 NumberDataValue sum = (NumberDataValue) value; 175 NumberDataValue avg = (NumberDataValue) value.getNewNull(); 176 177 178 if (count > (long) Integer.MAX_VALUE) 179 { 180 String typeName = sum.getTypeName(); 187 188 if (typeName.equals(TypeId.INTEGER_NAME) || 189 typeName.equals(TypeId.TINYINT_NAME) || 190 typeName.equals(TypeId.SMALLINT_NAME)) 191 { 192 avg.setValue(0); 193 return avg; 194 } 195 } 196 197 NumberDataValue countv = new org.apache.derby.iapi.types.SQLLongint(count); 198 sum.divide(sum, countv, avg, scale); 199 200 return avg; 201 } 202 203 205 public ExecAggregator newAggregator() 206 { 207 return new AvgAggregator(); 208 } 209 210 219 public void writeExternal(ObjectOutput out) throws IOException 220 { 221 super.writeExternal(out); 222 out.writeLong(count); 223 out.writeInt(scale); 224 } 225 226 231 public void readExternal(ObjectInput in) 232 throws IOException , ClassNotFoundException 233 { 234 super.readExternal(in); 235 count = in.readLong(); 236 scale = in.readInt(); 237 } 238 239 249 public int getTypeFormatId() { return StoredFormatIds.AGG_AVG_V01_ID; } 250 } 251 | Popular Tags |