From c31f1594934b5386e2ec064be22960e2bb8828f5 Mon Sep 17 00:00:00 2001 From: Ehsan Nasiri Date: Tue, 16 Apr 2024 15:15:05 -0700 Subject: [PATCH 1/8] WIP: [internal] Query/AggregateQuery to proto representation. --- packages/firestore/src/api.ts | 4 +++ packages/firestore/src/remote/serializer.ts | 37 ++++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/packages/firestore/src/api.ts b/packages/firestore/src/api.ts index bcfa6dc5f34..1506e725888 100644 --- a/packages/firestore/src/api.ts +++ b/packages/firestore/src/api.ts @@ -219,6 +219,10 @@ export { */ export { isBase64Available as _isBase64Available } from './platform/base64'; export { DatabaseId as _DatabaseId } from './core/database_info'; +export { + queryToProtoQueryTarget as _queryToQueryTargetProto, + aggregationQueryToProtoRunAggregationQueryRequest as _aggregationQueryToProtoRunAggregationQueryRequest +} from './remote/serializer'; export { cast as _cast, validateIsNotUsedTogether as _validateIsNotUsedTogether diff --git a/packages/firestore/src/remote/serializer.ts b/packages/firestore/src/remote/serializer.ts index 63860a88972..ebd161a8921 100644 --- a/packages/firestore/src/remote/serializer.ts +++ b/packages/firestore/src/remote/serializer.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { Aggregate } from '../core/aggregate'; +import { Aggregate, AggregateImpl } from '../core/aggregate'; import { Bound } from '../core/bound'; import { DatabaseId } from '../core/database_info'; import { @@ -32,6 +32,7 @@ import { newQuery, newQueryForPath, Query, + queryToAggregateTarget, queryToTarget } from '../core/query'; import { SnapshotVersion } from '../core/snapshot_version'; @@ -104,6 +105,8 @@ import { WatchTargetChange, WatchTargetChangeState } from './watch_change'; +import { AggregateSpec } from '../lite-api/aggregate_types'; +import { mapToArray } from '../util/obj'; const DIRECTIONS = (() => { const dirs: { [dir: string]: ProtoOrderDirection } = {}; @@ -900,6 +903,38 @@ export function toQueryTarget( return { queryTarget, parent }; } +export function queryToProtoQueryTarget( + serializer: JsonProtoSerializer, + query: Query +): { queryTarget: ProtoQueryTarget; parent: ResourcePath } { + return toQueryTarget(serializer, queryToTarget(query)); +} + +export function aggregationQueryToProtoRunAggregationQueryRequest< + AggregateSpecType extends AggregateSpec +>( + serializer: JsonProtoSerializer, + query: Query, + aggregateSpec: AggregateSpecType +): { + request: ProtoRunAggregationQueryRequest; + aliasMap: Record; + parent: ResourcePath; +} { + const aggregates = mapToArray(aggregateSpec, (aggregate, alias) => { + return new AggregateImpl( + alias, + aggregate.aggregateType, + aggregate._internalFieldPath + ); + }); + return toRunAggregationQueryRequest( + serializer, + queryToAggregateTarget(query), + aggregates + ); +} + export function toRunAggregationQueryRequest( serializer: JsonProtoSerializer, target: Target, From bad3afccf17af3c6be60548377ff6fcc71a31e6a Mon Sep 17 00:00:00 2001 From: Ehsan Nasiri Date: Tue, 16 Apr 2024 16:57:50 -0700 Subject: [PATCH 2/8] using api classes. --- packages/firestore/src/remote/serializer.ts | 33 ++++++++++++++------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/packages/firestore/src/remote/serializer.ts b/packages/firestore/src/remote/serializer.ts index ebd161a8921..e29b9d3a31b 100644 --- a/packages/firestore/src/remote/serializer.ts +++ b/packages/firestore/src/remote/serializer.ts @@ -94,7 +94,7 @@ import { debugAssert, fail, hardAssert } from '../util/assert'; import { ByteString } from '../util/byte_string'; import { Code, FirestoreError } from '../util/error'; import { isNullOrUndefined } from '../util/types'; - +import { Query as ApiQuery } from '../lite-api/reference'; import { ExistenceFilter } from './existence_filter'; import { Serializer } from './number_serializer'; import { mapCodeFromRpcCode } from './rpc_error'; @@ -107,6 +107,8 @@ import { } from './watch_change'; import { AggregateSpec } from '../lite-api/aggregate_types'; import { mapToArray } from '../util/obj'; +import {ensureFirestoreConfigured, Firestore} from "../api/database"; +import {cast} from "../util/input_validation"; const DIRECTIONS = (() => { const dirs: { [dir: string]: ProtoOrderDirection } = {}; @@ -904,23 +906,27 @@ export function toQueryTarget( } export function queryToProtoQueryTarget( - serializer: JsonProtoSerializer, - query: Query -): { queryTarget: ProtoQueryTarget; parent: ResourcePath } { - return toQueryTarget(serializer, queryToTarget(query)); + query: ApiQuery +): { queryTarget: ProtoQueryTarget; parent: ResourcePath } | null { + const firestore = cast(query.firestore, Firestore); + const client = ensureFirestoreConfigured(firestore); + const serializer = client._onlineComponents?.datastore.serializer; + if (serializer === undefined) { + return null; + } + return toQueryTarget(serializer!, queryToTarget(query._query)); } export function aggregationQueryToProtoRunAggregationQueryRequest< AggregateSpecType extends AggregateSpec >( - serializer: JsonProtoSerializer, - query: Query, + query: ApiQuery, aggregateSpec: AggregateSpecType ): { request: ProtoRunAggregationQueryRequest; aliasMap: Record; parent: ResourcePath; -} { +} | null { const aggregates = mapToArray(aggregateSpec, (aggregate, alias) => { return new AggregateImpl( alias, @@ -928,9 +934,16 @@ export function aggregationQueryToProtoRunAggregationQueryRequest< aggregate._internalFieldPath ); }); + const firestore = cast(query.firestore, Firestore); + const client = ensureFirestoreConfigured(firestore); + const serializer = client._onlineComponents?.datastore.serializer; + if (serializer === undefined) { + return null; + } + return toRunAggregationQueryRequest( - serializer, - queryToAggregateTarget(query), + serializer!, + queryToAggregateTarget(query._query), aggregates ); } From 123f953c183ba5e1cd2f2b49eb6384ad48c6f4a9 Mon Sep 17 00:00:00 2001 From: Ehsan Nasiri Date: Wed, 17 Apr 2024 14:31:09 -0700 Subject: [PATCH 3/8] move to a separate file. --- packages/firestore/src/api.ts | 6 +- .../src/remote/internal_serializer.ts | 100 ++++++++++++++++++ packages/firestore/src/remote/serializer.ts | 52 +-------- 3 files changed, 105 insertions(+), 53 deletions(-) create mode 100644 packages/firestore/src/remote/internal_serializer.ts diff --git a/packages/firestore/src/api.ts b/packages/firestore/src/api.ts index 1506e725888..5f5b078fbd6 100644 --- a/packages/firestore/src/api.ts +++ b/packages/firestore/src/api.ts @@ -220,9 +220,9 @@ export { export { isBase64Available as _isBase64Available } from './platform/base64'; export { DatabaseId as _DatabaseId } from './core/database_info'; export { - queryToProtoQueryTarget as _queryToQueryTargetProto, - aggregationQueryToProtoRunAggregationQueryRequest as _aggregationQueryToProtoRunAggregationQueryRequest -} from './remote/serializer'; + _internalQueryToProtoQueryTarget, + _internalAggregationQueryToProtoRunAggregationQueryRequest +} from './remote/internal_serializer'; export { cast as _cast, validateIsNotUsedTogether as _validateIsNotUsedTogether diff --git a/packages/firestore/src/remote/internal_serializer.ts b/packages/firestore/src/remote/internal_serializer.ts new file mode 100644 index 00000000000..71c0019b3f7 --- /dev/null +++ b/packages/firestore/src/remote/internal_serializer.ts @@ -0,0 +1,100 @@ +/** + * @license + * Copyright 2017 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ensureFirestoreConfigured, Firestore } from '../api/database'; +import { AggregateImpl } from '../core/aggregate'; +import { queryToAggregateTarget, queryToTarget } from '../core/query'; +import { AggregateSpec } from '../lite-api/aggregate_types'; +import { Query } from '../lite-api/reference'; +import { cast } from '../util/input_validation'; +import { mapToArray } from '../util/obj'; + +import { toQueryTarget, toRunAggregationQueryRequest } from './serializer'; + +/** + * @internal + * @private + * + * This function is for internal use only. + * + * Returns + * ``` + * { + * queryTarget: QueryTarget; + * parent: ResourcePath + * } + * ``` + * which contains the proto representation of the given query. Returns `null` if + * the Firestore client associated with the given query has not been initialized + * or has been terminated. + * + * @param query - The Query to convert to proto representation. + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function _internalQueryToProtoQueryTarget(query: Query): any { + const firestore = cast(query.firestore, Firestore); + const client = ensureFirestoreConfigured(firestore); + const serializer = client._onlineComponents?.datastore.serializer; + if (serializer === undefined) { + return null; + } + return toQueryTarget(serializer!, queryToTarget(query._query)); +} + +/** + * @internal + * @private + * + * This function is for internal use only. + * + * Returns + * { + * request: RunAggregationQueryRequest; + * aliasMap: Record; + * parent: ResourcePath; + * } + * which contains the proto representation of the given aggregation query. + * Returns null if the Firestore client associated with the given query has not + * been initialized or has been terminated. + * + * @param query - The Query to convert to proto representation. + * @param aggregateSpec - The set of aggregations and their aliases. + */ +export function _internalAggregationQueryToProtoRunAggregationQueryRequest< + AggregateSpecType extends AggregateSpec + // eslint-disable-next-line @typescript-eslint/no-explicit-any +>(query: Query, aggregateSpec: AggregateSpecType): any { + const aggregates = mapToArray(aggregateSpec, (aggregate, alias) => { + return new AggregateImpl( + alias, + aggregate.aggregateType, + aggregate._internalFieldPath + ); + }); + const firestore = cast(query.firestore, Firestore); + const client = ensureFirestoreConfigured(firestore); + const serializer = client._onlineComponents?.datastore.serializer; + if (serializer === undefined) { + return null; + } + + return toRunAggregationQueryRequest( + serializer!, + queryToAggregateTarget(query._query), + aggregates + ); +} diff --git a/packages/firestore/src/remote/serializer.ts b/packages/firestore/src/remote/serializer.ts index e29b9d3a31b..63860a88972 100644 --- a/packages/firestore/src/remote/serializer.ts +++ b/packages/firestore/src/remote/serializer.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { Aggregate, AggregateImpl } from '../core/aggregate'; +import { Aggregate } from '../core/aggregate'; import { Bound } from '../core/bound'; import { DatabaseId } from '../core/database_info'; import { @@ -32,7 +32,6 @@ import { newQuery, newQueryForPath, Query, - queryToAggregateTarget, queryToTarget } from '../core/query'; import { SnapshotVersion } from '../core/snapshot_version'; @@ -94,7 +93,7 @@ import { debugAssert, fail, hardAssert } from '../util/assert'; import { ByteString } from '../util/byte_string'; import { Code, FirestoreError } from '../util/error'; import { isNullOrUndefined } from '../util/types'; -import { Query as ApiQuery } from '../lite-api/reference'; + import { ExistenceFilter } from './existence_filter'; import { Serializer } from './number_serializer'; import { mapCodeFromRpcCode } from './rpc_error'; @@ -105,10 +104,6 @@ import { WatchTargetChange, WatchTargetChangeState } from './watch_change'; -import { AggregateSpec } from '../lite-api/aggregate_types'; -import { mapToArray } from '../util/obj'; -import {ensureFirestoreConfigured, Firestore} from "../api/database"; -import {cast} from "../util/input_validation"; const DIRECTIONS = (() => { const dirs: { [dir: string]: ProtoOrderDirection } = {}; @@ -905,49 +900,6 @@ export function toQueryTarget( return { queryTarget, parent }; } -export function queryToProtoQueryTarget( - query: ApiQuery -): { queryTarget: ProtoQueryTarget; parent: ResourcePath } | null { - const firestore = cast(query.firestore, Firestore); - const client = ensureFirestoreConfigured(firestore); - const serializer = client._onlineComponents?.datastore.serializer; - if (serializer === undefined) { - return null; - } - return toQueryTarget(serializer!, queryToTarget(query._query)); -} - -export function aggregationQueryToProtoRunAggregationQueryRequest< - AggregateSpecType extends AggregateSpec ->( - query: ApiQuery, - aggregateSpec: AggregateSpecType -): { - request: ProtoRunAggregationQueryRequest; - aliasMap: Record; - parent: ResourcePath; -} | null { - const aggregates = mapToArray(aggregateSpec, (aggregate, alias) => { - return new AggregateImpl( - alias, - aggregate.aggregateType, - aggregate._internalFieldPath - ); - }); - const firestore = cast(query.firestore, Firestore); - const client = ensureFirestoreConfigured(firestore); - const serializer = client._onlineComponents?.datastore.serializer; - if (serializer === undefined) { - return null; - } - - return toRunAggregationQueryRequest( - serializer!, - queryToAggregateTarget(query._query), - aggregates - ); -} - export function toRunAggregationQueryRequest( serializer: JsonProtoSerializer, target: Target, From ad13216334796e8b83da191787609573a386b4a5 Mon Sep 17 00:00:00 2001 From: Ehsan Nasiri Date: Mon, 22 Apr 2024 13:12:43 -0700 Subject: [PATCH 4/8] Only return the QueryTarget object. --- .../firestore/src/remote/internal_serializer.ts | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/packages/firestore/src/remote/internal_serializer.ts b/packages/firestore/src/remote/internal_serializer.ts index 71c0019b3f7..2b8cd1dc375 100644 --- a/packages/firestore/src/remote/internal_serializer.ts +++ b/packages/firestore/src/remote/internal_serializer.ts @@ -31,16 +31,9 @@ import { toQueryTarget, toRunAggregationQueryRequest } from './serializer'; * * This function is for internal use only. * - * Returns - * ``` - * { - * queryTarget: QueryTarget; - * parent: ResourcePath - * } - * ``` - * which contains the proto representation of the given query. Returns `null` if - * the Firestore client associated with the given query has not been initialized - * or has been terminated. + * Returns the `QueryTarget` representation of the given query. Returns `null` + * if the Firestore client associated with the given query has not been + * initialized or has been terminated. * * @param query - The Query to convert to proto representation. */ @@ -52,7 +45,7 @@ export function _internalQueryToProtoQueryTarget(query: Query): any { if (serializer === undefined) { return null; } - return toQueryTarget(serializer!, queryToTarget(query._query)); + return toQueryTarget(serializer!, queryToTarget(query._query)).queryTarget; } /** From e695a33592afbd68a809afea78f1dfb3ae84e2fd Mon Sep 17 00:00:00 2001 From: Ehsan Nasiri Date: Mon, 22 Apr 2024 15:08:46 -0700 Subject: [PATCH 5/8] declare interface to avoid minification. --- .../firestore/src/remote/internal_serializer.ts | 1 - packages/firestore/src/remote/serializer.ts | 14 +++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/firestore/src/remote/internal_serializer.ts b/packages/firestore/src/remote/internal_serializer.ts index 2b8cd1dc375..123a1178bf0 100644 --- a/packages/firestore/src/remote/internal_serializer.ts +++ b/packages/firestore/src/remote/internal_serializer.ts @@ -22,7 +22,6 @@ import { AggregateSpec } from '../lite-api/aggregate_types'; import { Query } from '../lite-api/reference'; import { cast } from '../util/input_validation'; import { mapToArray } from '../util/obj'; - import { toQueryTarget, toRunAggregationQueryRequest } from './serializer'; /** diff --git a/packages/firestore/src/remote/serializer.ts b/packages/firestore/src/remote/serializer.ts index 63860a88972..d0f82bb9b69 100644 --- a/packages/firestore/src/remote/serializer.ts +++ b/packages/firestore/src/remote/serializer.ts @@ -900,15 +900,19 @@ export function toQueryTarget( return { queryTarget, parent }; } +// Note: keep this interface declaration in order to avoid its minification when +// used by _internalAggregationQueryToProtoRunAggregationQueryRequest. +declare interface toRunAggregationQueryRequestReturn { + request: ProtoRunAggregationQueryRequest; + aliasMap: Record; + parent: ResourcePath; +} + export function toRunAggregationQueryRequest( serializer: JsonProtoSerializer, target: Target, aggregates: Aggregate[] -): { - request: ProtoRunAggregationQueryRequest; - aliasMap: Record; - parent: ResourcePath; -} { +): toRunAggregationQueryRequestReturn { const { queryTarget, parent } = toQueryTarget(serializer, target); const aliasMap: Record = {}; From 406b62b9ced23e9922db29831e8948bfde9d002b Mon Sep 17 00:00:00 2001 From: Ehsan Nasiri Date: Mon, 22 Apr 2024 15:15:53 -0700 Subject: [PATCH 6/8] lint fix. --- packages/firestore/src/remote/internal_serializer.ts | 1 + packages/firestore/src/remote/serializer.ts | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/firestore/src/remote/internal_serializer.ts b/packages/firestore/src/remote/internal_serializer.ts index 123a1178bf0..2b8cd1dc375 100644 --- a/packages/firestore/src/remote/internal_serializer.ts +++ b/packages/firestore/src/remote/internal_serializer.ts @@ -22,6 +22,7 @@ import { AggregateSpec } from '../lite-api/aggregate_types'; import { Query } from '../lite-api/reference'; import { cast } from '../util/input_validation'; import { mapToArray } from '../util/obj'; + import { toQueryTarget, toRunAggregationQueryRequest } from './serializer'; /** diff --git a/packages/firestore/src/remote/serializer.ts b/packages/firestore/src/remote/serializer.ts index d0f82bb9b69..ee41ac785d5 100644 --- a/packages/firestore/src/remote/serializer.ts +++ b/packages/firestore/src/remote/serializer.ts @@ -902,7 +902,7 @@ export function toQueryTarget( // Note: keep this interface declaration in order to avoid its minification when // used by _internalAggregationQueryToProtoRunAggregationQueryRequest. -declare interface toRunAggregationQueryRequestReturn { +declare interface ToRunAggregationQueryRequestReturnType { request: ProtoRunAggregationQueryRequest; aliasMap: Record; parent: ResourcePath; @@ -912,7 +912,7 @@ export function toRunAggregationQueryRequest( serializer: JsonProtoSerializer, target: Target, aggregates: Aggregate[] -): toRunAggregationQueryRequestReturn { +): ToRunAggregationQueryRequestReturnType { const { queryTarget, parent } = toQueryTarget(serializer, target); const aliasMap: Record = {}; From b0bd0720da47edfa7987ca7674352bd42613a673 Mon Sep 17 00:00:00 2001 From: Ehsan Nasiri Date: Tue, 23 Apr 2024 15:33:59 -0700 Subject: [PATCH 7/8] attempt to avoid minification of ToRunAggregationQueryRequestReturnType. --- packages/firestore/rollup.shared.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/firestore/rollup.shared.js b/packages/firestore/rollup.shared.js index 92ec0e2ec9c..86517219641 100644 --- a/packages/firestore/rollup.shared.js +++ b/packages/firestore/rollup.shared.js @@ -108,6 +108,7 @@ const externsPaths = externs.map(p => path.resolve(__dirname, '../../', p)); const publicIdentifiers = extractPublicIdentifiers(externsPaths); // manually add `_delegate` because we don't have typings for the compat package publicIdentifiers.add('_delegate'); +publicIdentifiers.add('ToRunAggregationQueryRequestReturnType'); /** * Transformers that remove calls to `debugAssert` and messages for 'fail` and From 596dadb6d376d43a8a1861f9a868ff3eec9be02d Mon Sep 17 00:00:00 2001 From: Ehsan Nasiri Date: Wed, 1 May 2024 17:10:54 -0700 Subject: [PATCH 8/8] allow skipping aliasing. --- packages/firestore/rollup.shared.js | 1 - .../src/remote/internal_serializer.ts | 18 +++++++--------- packages/firestore/src/remote/serializer.ts | 21 +++++++++---------- 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/packages/firestore/rollup.shared.js b/packages/firestore/rollup.shared.js index 86517219641..92ec0e2ec9c 100644 --- a/packages/firestore/rollup.shared.js +++ b/packages/firestore/rollup.shared.js @@ -108,7 +108,6 @@ const externsPaths = externs.map(p => path.resolve(__dirname, '../../', p)); const publicIdentifiers = extractPublicIdentifiers(externsPaths); // manually add `_delegate` because we don't have typings for the compat package publicIdentifiers.add('_delegate'); -publicIdentifiers.add('ToRunAggregationQueryRequestReturnType'); /** * Transformers that remove calls to `debugAssert` and messages for 'fail` and diff --git a/packages/firestore/src/remote/internal_serializer.ts b/packages/firestore/src/remote/internal_serializer.ts index 2b8cd1dc375..8f278247581 100644 --- a/packages/firestore/src/remote/internal_serializer.ts +++ b/packages/firestore/src/remote/internal_serializer.ts @@ -54,15 +54,10 @@ export function _internalQueryToProtoQueryTarget(query: Query): any { * * This function is for internal use only. * - * Returns - * { - * request: RunAggregationQueryRequest; - * aliasMap: Record; - * parent: ResourcePath; - * } - * which contains the proto representation of the given aggregation query. - * Returns null if the Firestore client associated with the given query has not - * been initialized or has been terminated. + * Returns `RunAggregationQueryRequest` which contains the proto representation + * of the given aggregation query request. Returns null if the Firestore client + * associated with the given query has not been initialized or has been + * terminated. * * @param query - The Query to convert to proto representation. * @param aggregateSpec - The set of aggregations and their aliases. @@ -88,6 +83,7 @@ export function _internalAggregationQueryToProtoRunAggregationQueryRequest< return toRunAggregationQueryRequest( serializer!, queryToAggregateTarget(query._query), - aggregates - ); + aggregates, + /* skipAliasing= */ true + ).request; } diff --git a/packages/firestore/src/remote/serializer.ts b/packages/firestore/src/remote/serializer.ts index ee41ac785d5..811c2ac4df6 100644 --- a/packages/firestore/src/remote/serializer.ts +++ b/packages/firestore/src/remote/serializer.ts @@ -900,19 +900,16 @@ export function toQueryTarget( return { queryTarget, parent }; } -// Note: keep this interface declaration in order to avoid its minification when -// used by _internalAggregationQueryToProtoRunAggregationQueryRequest. -declare interface ToRunAggregationQueryRequestReturnType { - request: ProtoRunAggregationQueryRequest; - aliasMap: Record; - parent: ResourcePath; -} - export function toRunAggregationQueryRequest( serializer: JsonProtoSerializer, target: Target, - aggregates: Aggregate[] -): ToRunAggregationQueryRequestReturnType { + aggregates: Aggregate[], + skipAliasing?: boolean +): { + request: ProtoRunAggregationQueryRequest; + aliasMap: Record; + parent: ResourcePath; +} { const { queryTarget, parent } = toQueryTarget(serializer, target); const aliasMap: Record = {}; @@ -923,7 +920,9 @@ export function toRunAggregationQueryRequest( // Map all client-side aliases to a unique short-form // alias. This avoids issues with client-side aliases that // exceed the 1500-byte string size limit. - const serverAlias = `aggregate_${aggregationNum++}`; + const serverAlias = skipAliasing + ? aggregate.alias + : `aggregate_${aggregationNum++}`; aliasMap[serverAlias] = aggregate.alias; if (aggregate.aggregateType === 'count') {