{"record":{"id":"f16a515afc3599a7","repo":"apache/beam","slug":"please-explicitly-specify-windowing-in-sql-query-using-hop","errorCode":null,"errorMessage":"Please explicitly specify windowing in SQL query using HOP/TUMBLE/SESSION functions (default trigger will be used in this case). Unbounded input with global windowing and default trigger is not supported in Beam SQL aggregations. See GroupByKey section in Beam Programming Guide","messagePattern":"Please explicitly specify windowing in SQL query using HOP/TUMBLE/SESSION functions \\(default trigger will be used in this case\\)\\. Unbounded input with global windowing and default trigger is not supported in Beam SQL aggregations\\. See GroupByKey section in Beam Programming Guide","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/rel/BeamAggregationRel.java","lineNumber":343,"sourceCode":"              .apply(Window.into(windowFn));\n      return windowedStream;\n    }\n\n    /**\n     * Performs the same check as {@link GroupByKey}, provides more context in exception.\n     *\n     * <p>Verifies that the input PCollection is bounded, or that there is windowing/triggering\n     * being used. Without this, the watermark (at end of global window) will never be reached.\n     *\n     * <p>Throws {@link UnsupportedOperationException} if validation fails.\n     */\n    private void validateWindowIsSupported(PCollection<Row> upstream) {\n      WindowingStrategy<?, ?> windowingStrategy = upstream.getWindowingStrategy();\n      if (windowingStrategy.getWindowFn() instanceof GlobalWindows\n          && windowingStrategy.getTrigger() instanceof DefaultTrigger\n          && upstream.isBounded() != BOUNDED) {\n\n        throw new UnsupportedOperationException(\n            \"Please explicitly specify windowing in SQL query using HOP/TUMBLE/SESSION functions \"\n                + \"(default trigger will be used in this case). \"\n                + \"Unbounded input with global windowing and default trigger is not supported \"\n                + \"in Beam SQL aggregations. \"\n                + \"See GroupByKey section in Beam Programming Guide\");\n      }\n    }\n\n    static DoFn<Row, Row> mergeRecord(\n        Schema outputSchema,\n        int windowStartFieldIndex,\n        boolean ignoreValues,\n        boolean verifyRowValues) {\n      return new DoFn<Row, Row>() {\n        @ProcessElement\n        public void processElement(\n            @Element Row kvRow, BoundedWindow window, OutputReceiver<Row> o) {\n          int capacity =","sourceCodeStart":325,"sourceCodeEnd":361,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/rel/BeamAggregationRel.java#L325-L361","documentation":"Beam SQL aggregations (GROUP BY) on unbounded (streaming) input require explicit windowing via HOP/TUMBLE/SESSION. Global windowing combined with the default trigger on an unbounded PCollection would be an invalid GroupByKey scenario per the Beam model, so validateWindowIsSupported throws UnsupportedOperationException before the pipeline even runs.","triggerScenarios":"Executing a Beam SQL aggregation over an unbounded PCollection whose windowing strategy is GlobalWindows with DefaultTrigger and no HOP/TUMBLE/SESSION in the query.","commonSituations":"Streaming data (Kafka/Flink source) fed into a Beam SQL query that forgot the window function; queries written against bounded input then reused on streaming input; Beam 2.x default-trigger streaming semantics.","solutions":["Add an explicit window function to the aggregation: GROUP BY TUMBLE(eventTime, INTERVAL ...), HOP(...), or SESSION(...)","Ensure the input PCollection has non-default windowing/trigger if you must keep global windows (e.g. set a non-default trigger)","Make the input bounded if batch semantics are intended","See the GroupByKey section of the Beam Programming Guide for why this combination is invalid"],"exampleFix":"// before\nSELECT f1, COUNT(*) FROM t GROUP BY f1 -- streaming, no windowing\n// after\nSELECT f1, COUNT(*) FROM t GROUP BY f1, TUMBLE(eventTime, INTERVAL '1' MINUTE)","handlingStrategy":"validation","validationCode":"import org.apache.beam.sdk.transforms.windowing.*;\nWindowingStrategy<?, ?> ws = upstream.getWindowingStrategy();\nboolean ok = !(ws.getWindowFn() instanceof GlobalWindows\n    && ws.getTrigger() instanceof DefaultTrigger\n    && !pc.isBounded().equals(PCollection.IsBounded.BOUNDED));\nif (!ok) throw new IllegalStateException(\"Specify HOP/TUMBLE/SESSION for streaming aggregation\");","typeGuard":"boolean supportsSqlAggregation(PCollection<?> pc) {\n  WindowingStrategy<?, ?> ws = pc.getWindowingStrategy();\n  return pc.isBounded() == PCollection.IsBounded.BOUNDED\n      || !(ws.getWindowFn() instanceof GlobalWindows\n           && ws.getTrigger() instanceof DefaultTrigger);\n}","tryCatchPattern":"try {\n  result = stmt.executeSql(query);\n} catch (UnsupportedOperationException e) {\n  if (e.getMessage().contains(\"explicitly specify windowing\")) {\n    // rewrite query with TUMBLE/HOP/SESSION and re-run\n  } else throw e;\n}","preventionTips":["Always include TUMBLE/HOP/SESSION in GROUP BY queries over streaming input","Verify the input PCollection's windowing strategy before SQL aggregation","Do not rely on default triggers for streaming aggregations; read the Beam GroupByKey programming guide"],"tags":["sql","streaming","windowing","group-by","beam"],"backgroundTag":"feature-not-enabled","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}