The Apache Calcite PMC is pleased to announce Apache Calcite release 1.28.0.

This release comes four months after 1.27.0, contains contributions from 38 authors, and resolves 76 issues. New features include the UNIQUE sub-query predicate, the MODE aggregate function, PERCENTILE_CONT and PERCENTILE_DISC inverse distribution functions, an Exasol dialect for the JDBC adapter, and improvements to materialized view recognition.

This release contains some breaking changes (described below) due to the replacement of ImmutableBeans with Immutables. Two APIs are deprecated and will be removed in release 1.29.

Breaking changes to ImmutableBeans

In 1.28, Calcite converted the recently introduced configuration system from an internal system based on ImmutableBeans to instead use the Immutables annotation processor. This library brings a large number of additional features that should make value-type classes in Calcite easier to build and leverage. It also reduces reliance on dynamic proxies, which should improve performance and reduce memory footprint. Lastly, this change increases compatibility with ahead-of-time compilation technologies such as GraalVM. As part of this change, a number of minor changes have been made and key methods and classes have been deprecated. The change was designed to minimize disruption to existing consumers of Calcite but the following minor changes needed to be made:

  • The RelRule.Config.EMPTY field is now deprecated. To create a new configuration subclass, you can either use your preferred interface-implementation based construction or you can leverage Immutables. To do the latter, configure your project to use the Immutables annotation processor and annotate your subclass with the @Value.Immutable annotation.
  • Where RelRule.Config subclasses were nested 2+ classes deep, the interfaces have been marked deprecated and are superceded by new, uniquely named interfaces. The original Configs extend the new uniquely named interfaces. Subclassing these work as before and the existing rule signatures accept any previously implemented Config implementations. However, this is a breaking change if a user stored an instance of the DEFAULT object using the Config class name (as the DEFAULT instance now only implements the uniquely named interface).
  • The method should only be used for safe downcasts. Before, it could do arbitrary casts. The exception is that arbitrary as() will continue to work when using the deprecated RelRule.Config.EMPTY field. In most cases, this should be a non-breaking change. However, all Calcite-defined DEFAULT rule config instances use Immutables. As such, if one had previously subclassed a RelRule.Config subclass and then used the DEFAULT instance from that subclass, the as() call will no longer work to coerce the DEFAULT instance into a arbitrary subclass. In essence, outside the EMPTY use, as() is now only safe to do if a Java cast is also safe.
  • ExchangeRemoveConstantKeysRule.Config and ValuesReduceRule.Config now declare concrete bounds for their matchHandler configuration. This is a breaking change if one did not use the Rule as a bounding variable.
  • Collections used in Immutables value classes will be converted to Immutable collection types even if the passed in parameter is mutable (such as an ArrayList). As such, consumers of those configuration properties cannot mutate the returned collections.

See the release notes; download the release.