apache/beam · error · UnsupportedOperationException

Analytics Function [ ] is not supported

Error message

Analytics Function [%s] is not supported

What it means

BeamBuiltinAnalyticFunctions.create(functionName, fieldType) looks up functionName in the BUILTIN_ANALYTIC_FACTORIES registry of supported analytic (window) function combiners. If the name is not registered (aggregatorFactory == null) it throws UnsupportedOperationException stating the analytic function is unsupported. This guards the closed set of built-in analytic functions Beam SQL can plan.

Solutions

  1. Check BUILTIN_ANALYTIC_FACTORIES in BeamBuiltinAnalyticFunctions for the exact supported function names and use one of those in the query.
  2. Upgrade the Beam version — newer releases add more analytic functions.
  3. Implement the window computation manually (e.g. with beam-sdks-java extensions or a custom CombineFn and windowing) and register it in the factory map if extending the SDK.
  4. Fix name casing/spelling — the registry lookup is exact-string.

Example fix

// before
CombineFn fn = BeamBuiltinAnalyticFunctions.create("NTILE", fieldType); // throws

// after
CombineFn fn = BeamBuiltinAnalyticFunctions.create("LAG", fieldType); // registered name
// or implement NTILE manually via GlobalWindows + custom combiner
Defensive patterns

Strategy: validation

Validate before calling

java.util.Set<String> supported = java.util.Set.of("LAG", "LEAD", "FIRST_VALUE", "LAST_VALUE", "NTH_VALUE"); // mirror BUILTIN_ANALYTIC_FACTORIES keys
if (!supported.contains(functionName)) {
  throw new IllegalArgumentException("Analytic function not supported: " + functionName);
}

Type guard

boolean analyticSupported(String fn, org.apache.beam.sdk.extensions.sql.impl.transform.BeamBuiltinAnalyticFunctions ignored) {
  // consult the registry directly if accessible
  return fn != null && BUILTIN_ANALYTIC_FACTORIES.containsKey(fn);
}

Try / catch

try {
  Combine.CombineFn<?, ?, ?> fn = BeamBuiltinAnalyticFunctions.create(functionName, fieldType);
} catch (UnsupportedOperationException e) {
  // fall back to manual window computation or a different supported function
}

Prevention

When it happens

Trigger: Calling BeamBuiltinAnalyticFunctions.create with a function name string that is not in the registry — e.g. an unsupported window function like NTILE or PERCENT_RANK in an OVER clause, or a misspelled function name passed programmatically.

Common situations: Using an analytic function available in other SQL engines (e.g. LISTAGG, MEDIAN as analytic) that Beam SQL has not implemented; case-sensitivity or spelling mismatch of the function name; version differences where a function was added only in newer Beam releases.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/5939c5d5ac5c7cc0. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/transform/BeamBuiltinAnalyticFunctions.java:56

              // Aggregate Analytic Functions
              .putAll(BeamBuiltinAggregations.BUILTIN_AGGREGATOR_FACTORIES)
              // Navigation Functions
              .put("FIRST_VALUE", typeName -> navigationFirstValue())
              .put("LAST_VALUE", typeName -> navigationLastValue())
              // Numbering Functions
              .put("ROW_NUMBER", typeName -> numberingRowNumber())
              .put("DENSE_RANK", typeName -> numberingDenseRank())
              .put("RANK", typeName -> numberingRank())
              .put("PERCENT_RANK", typeName -> numberingPercentRank())
              .build();

  public static Combine.CombineFn<?, ?, ?> create(String functionName, Schema.FieldType fieldType) {
    Function<Schema.FieldType, Combine.CombineFn<?, ?, ?>> aggregatorFactory =
        BUILTIN_ANALYTIC_FACTORIES.get(functionName);
    if (aggregatorFactory != null) {
      return aggregatorFactory.apply(fieldType);
    }
    throw new UnsupportedOperationException(
        String.format("Analytics Function [%s] is not supported", functionName));
  }

  // Navigation functions
  public static <T> Combine.CombineFn<T, ?, T> navigationFirstValue() {
    return new FirstValueCombineFn();
  }

  public static <T> Combine.CombineFn<T, ?, T> navigationLastValue() {
    return new LastValueCombineFn();
  }

  private static class FirstValueCombineFn<T> extends Combine.CombineFn<T, Optional<T>, T> {
    private FirstValueCombineFn() {}

    @Override
    public Optional<T> createAccumulator() {
      return Optional.empty();

View on GitHub (pinned to 12126d8942)