Replace RowOperation.initialValue() and rowAggregator() by collect(Collector)

Lukas Eder lukas.eder at
Thu Oct 26 16:23:32 UTC 2017

That's really cool, thanks for adopting this!

I'm thinking maybe this should then be done in BatchCountOperation as well
(replacing initialValue() and countAggregator()) and perhaps in
OperationGroup (replacing initialValue() and memberAggregator())?

2017-10-25 23:16 GMT+03:00 Douglas Surber <douglas.surber at>:

> I’ve thought a bit more about your suggestion. It would add the following
> to RowOperation.
>     public <A> RowOperation<T> collect(Collector<? super Result.Row, A, ?
> extends T> c);

May I try my luck again regarding the generics involved here. I'm still
having a bit of a hard time understanding why the <T> type has to be bound
(and fixed!) at the moment when an Operation<T> subtype is created from the

>From how I understand the API, each Operation<T> has a type <T> which may
or may not be well defined at some point. Initially, it is not defined
because we may submit operations that do not wish to retrieve any results.
This might be the case when you return "null" in some of your examples. A
good type bound for <T> would then be Void or just "?".

Then, some operations have type-specifying methods, like the above
collect() method. From the moment when we call collect(), the type <T>
could be inferred from the Collector. So, after calling collect() on any
RowOperation<X>, we "change" or "specify" the returning type to

Something similar could be said of CountOperation.resultProcessor(), which
could infer its new <T> type from the argument function, rather than
requiring the function to adhere to some previously defined type.

I understand that this all originates from the OperationGroup<S, T> type,
which imposes the <T> type on its children, but perhaps I simply fail to
understand the intent of the OperationGroup.memberAggregator() method,
which is probably the target of these <S, T> types. Do you have an example
where that is put to action?

> I think it is better than initialValue, rowAggregator. You questioned the
> value of the combiner method. That is one of the things that makes this
> superior. While the implementation is, in general, constrained to produce
> the rows in the same order as the database, a Collector can be UNORDERED
> and/or CONCURRENT. The spec could allow an implementation to use that
> information to process the rows out of order and/or in multiple threads.
> This is a big win.

Yes, I've thought about this as well, afterwards. I could imagine databases
to open up several sockets to fetch data from a parallel query. That could
be super cool. I've just noticed CollectionGroup.parallel(). I guess that's
related, then?

More information about the jdbc-spec-discuss mailing list