001: /*
002:
003: Derby - Class org.apache.derby.impl.sql.execute.CountAggregator
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.impl.sql.execute;
023:
024: import org.apache.derby.iapi.types.DataValueDescriptor;
025: import org.apache.derby.iapi.services.sanity.SanityManager;
026: import org.apache.derby.iapi.error.StandardException;
027:
028: import org.apache.derby.iapi.sql.execute.ExecAggregator;
029: import org.apache.derby.iapi.services.io.StoredFormatIds;
030: import org.apache.derby.iapi.services.io.Formatable;
031: import java.io.ObjectOutput;
032: import java.io.ObjectInput;
033: import java.io.IOException;
034:
035: /**
036: * Aggregator for COUNT()/COUNT(*).
037: * @author jamie
038: */
039: public final class CountAggregator extends SystemAggregator {
040: private long value;
041: private boolean isCountStar;
042:
043: /**
044: */
045: public void setup(String aggregateName) {
046: isCountStar = aggregateName.equals("COUNT(*)");
047: }
048:
049: /**
050: * @see ExecAggregator#merge
051: *
052: * @exception StandardException on error
053: */
054: public void merge(ExecAggregator addend) throws StandardException {
055: if (SanityManager.DEBUG) {
056: SanityManager
057: .ASSERT(addend instanceof CountAggregator,
058: "addend is supposed to be the same type of aggregator for the merge operator");
059: }
060:
061: value += ((CountAggregator) addend).value;
062: }
063:
064: /**
065: * Return the result of the aggregation. Just
066: * spit out the running count.
067: *
068: * @return the value as a Long
069: */
070: public DataValueDescriptor getResult() {
071: return new org.apache.derby.iapi.types.SQLLongint(value);
072: }
073:
074: /**
075: * Accumulate for count(). Toss out all nulls in this kind of count.
076: * Increment the count for count(*). Count even the null values.
077: *
078: * @param addend value to be added in
079: * @param ga the generic aggregator that is calling me
080: *
081: * @see ExecAggregator#accumulate
082: */
083: public void accumulate(DataValueDescriptor addend, Object ga)
084: throws StandardException {
085: if (isCountStar)
086: value++;
087: else
088: super .accumulate(addend, ga);
089: }
090:
091: protected final void accumulate(DataValueDescriptor addend) {
092: value++;
093: }
094:
095: /**
096: * @return ExecAggregator the new aggregator
097: */
098: public ExecAggregator newAggregator() {
099: CountAggregator ca = new CountAggregator();
100: ca.isCountStar = isCountStar;
101: return ca;
102: }
103:
104: public boolean isCountStar() {
105: return isCountStar;
106: }
107:
108: /////////////////////////////////////////////////////////////
109: //
110: // EXTERNALIZABLE INTERFACE
111: //
112: /////////////////////////////////////////////////////////////
113: /**
114: * Although we are not expected to be persistent per se,
115: * we may be written out by the sorter temporarily. So
116: * we need to be able to write ourselves out and read
117: * ourselves back in.
118: *
119: * @exception IOException thrown on error
120: */
121: public final void writeExternal(ObjectOutput out)
122: throws IOException {
123: super .writeExternal(out);
124: out.writeBoolean(isCountStar);
125: out.writeLong(value);
126: }
127:
128: /**
129: * @see java.io.Externalizable#readExternal
130: *
131: * @exception IOException io exception
132: * @exception ClassNotFoundException on error
133: */
134: public final void readExternal(ObjectInput in) throws IOException,
135: ClassNotFoundException {
136: super .readExternal(in);
137: isCountStar = in.readBoolean();
138: value = in.readLong();
139: }
140:
141: /////////////////////////////////////////////////////////////
142: //
143: // FORMATABLE INTERFACE
144: //
145: /////////////////////////////////////////////////////////////
146: /**
147: * Get the formatID which corresponds to this class.
148: *
149: * @return the formatID of this class
150: */
151: public int getTypeFormatId() {
152: return StoredFormatIds.AGG_COUNT_V01_ID;
153: }
154: }
|