{"record":{"id":"987febef2a221962","repo":"apache/druid","slug":"cannot-execute-query-with-orderby-s","errorCode":null,"errorMessage":"Cannot execute query with orderBy %s","messagePattern":"Cannot execute query with orderBy (.+?)","errorType":"exception","errorClass":"IllegalStateException (ISE)","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/query/scan/ScanQuery.java","lineNumber":203,"sourceCode":"          }\n        }\n      }\n    }\n\n    this.maxRowsQueuedForOrdering = validateAndGetMaxRowsQueuedForOrdering();\n    this.maxSegmentPartitionsOrderedInMemory = validateAndGetMaxSegmentPartitionsOrderedInMemory();\n  }\n\n  /**\n   * Verifies that the ordering of a query is solely determined by {@link #getTimeOrder()}. Required to actually\n   * execute queries, because {@link #getOrderBys()} is not yet understood by the query engines.\n   *\n   * @throws IllegalStateException if the ordering is not solely determined by {@link #getTimeOrder()}\n   */\n  public static void verifyOrderByForNativeExecution(final ScanQuery query)\n  {\n    if (query.getTimeOrder() == Order.NONE && !query.getOrderBys().isEmpty()) {\n      throw new ISE(\"Cannot execute query with orderBy %s\", query.getOrderBys());\n    }\n  }\n\n  private Integer validateAndGetMaxRowsQueuedForOrdering()\n  {\n    final Integer maxRowsQueuedForOrdering =\n        context().getInt(ScanQueryConfig.CTX_KEY_MAX_ROWS_QUEUED_FOR_ORDERING);\n    Preconditions.checkArgument(\n        maxRowsQueuedForOrdering == null || maxRowsQueuedForOrdering > 0,\n        \"maxRowsQueuedForOrdering must be greater than 0\"\n    );\n    return maxRowsQueuedForOrdering;\n  }\n\n  private Integer validateAndGetMaxSegmentPartitionsOrderedInMemory()\n  {\n    final Integer maxSegmentPartitionsOrderedInMemory =\n        context().getInt(ScanQueryConfig.CTX_KEY_MAX_SEGMENT_PARTITIONS_FOR_ORDERING);","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/query/scan/ScanQuery.java#L185-L221","documentation":"verifyOrderByForNativeExecution enforces that the native scan engine can only execute queries whose ordering is fully determined by getTimeOrder(). If the query has explicit orderBy columns but timeOrder resolves to NONE, the native engine cannot honor them and throws ISE. This guards callers like getResultOrdering that need a single deterministic ordering.","triggerScenarios":"Calling ScanQuery.verifyOrderByForNativeExecution (directly or via getResultOrdering) with a query that has non-empty getOrderBys() and getTimeOrder() == Order.NONE.","commonSituations":"Internal/extension code running native scan queries on user queries containing orderBy without setting the order property; custom query tooling building ScanQuery programmatically with orderBy but no order.","solutions":["Set the query 'order' property (ascending/descending/descending-by-time) consistent with orderBy","Remove the orderBy entries before native execution","Route the query through the SQL layer which handles orderBy natively"],"exampleFix":"// before\nScanQuery q = new ScanQuery(...).withOrderByColumns(Collections.singletonList(\"col\")); // no order set\nScanQuery.verifyOrderByForNativeExecution(q); // throws\n// after\nScanQuery q = new ScanQuery(...).withOrderByColumns(Collections.singletonList(\"col\")).withOrder(Order.ASCENDING);\nScanQuery.verifyOrderByForNativeExecution(q); // ok","handlingStrategy":"try-catch","validationCode":"if (q.getTimeOrder() == ScanQuery.Order.NONE && !q.getOrderBys().isEmpty()) {\n  q = q.withOrder(deduceOrder(q));\n}","typeGuard":null,"tryCatchPattern":"try {\n  ScanQuery.verifyOrderByForNativeExecution(query);\n} catch (IllegalStateException e) {\n  // fall back to SQL layer or strip orderBy\n}","preventionTips":["Never issue native scan queries with orderBy unless 'order' is also set","Use Calcite/SQL planner for orderBy-heavy scans","Centralize ScanQuery construction in one factory that sets ordering consistently"],"tags":["druid","scan-query","illegal-state","native-execution"],"backgroundTag":"invalid-state-transition","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}