{"record":{"id":"73f36363061b46ae","repo":"apache/druid","slug":"unable-to-compare-timestamp-for-rows-without-a-tim","errorCode":null,"errorMessage":"Unable to compare timestamp for rows without a time column","messagePattern":"Unable to compare timestamp for rows without a time column","errorType":"exception","errorClass":"IllegalStateException (ISE)","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/query/scan/ScanResultValue.java","lineNumber":103,"sourceCode":"  public Object getEvents()\n  {\n    return events;\n  }\n\n  @Nullable\n  @JsonProperty\n  public RowSignature getRowSignature()\n  {\n    return rowSignature;\n  }\n\n\n  public long getFirstEventTimestamp(ScanQuery.ResultFormat resultFormat)\n  {\n    if (resultFormat.equals(ScanQuery.ResultFormat.RESULT_FORMAT_LIST)) {\n      Object timestampObj = ((Map<String, Object>) ((List<Object>) this.getEvents()).get(0)).get(ColumnHolder.TIME_COLUMN_NAME);\n      if (timestampObj == null) {\n        throw new ISE(\"Unable to compare timestamp for rows without a time column\");\n      }\n      return DimensionHandlerUtils.convertObjectToLong(timestampObj);\n    } else if (resultFormat.equals(ScanQuery.ResultFormat.RESULT_FORMAT_COMPACTED_LIST)) {\n      int timeColumnIndex = this.getColumns().indexOf(ColumnHolder.TIME_COLUMN_NAME);\n      if (timeColumnIndex == -1) {\n        throw new ISE(\"Unable to compare timestamp for rows without a time column\");\n      }\n      List<Object> firstEvent = (List<Object>) ((List<Object>) this.getEvents()).get(0);\n      return DimensionHandlerUtils.convertObjectToLong(firstEvent.get(timeColumnIndex));\n    }\n    throw new UOE(\"Unable to get first event timestamp using result format of [%s]\", resultFormat.toString());\n  }\n\n  public List<ScanResultValue> toSingleEventScanResultValues()\n  {\n    List<ScanResultValue> singleEventScanResultValues = new ArrayList<>();\n    List<Object> events = (List<Object>) this.getEvents();\n    for (Object event : events) {","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/query/scan/ScanResultValue.java#L85-L121","documentation":"getFirstEventTimestamp reads the __time column of a ScanResultValue's first event (list format, where events are Maps). If the event map has no __time entry, rows cannot be time-compared for stable ordering, so Druid throws an IllegalStateException.","triggerScenarios":"stableLimitingSort comparing ScanResultValues whose first event (a Map) lacks ColumnHolder.TIME_COLUMN_NAME — e.g. scan queries that excluded __time from the columns list but requested descending time-ordering.","commonSituations":"SQL 'SELECT col1, col2 FROM t ORDER BY __time DESC' plans where __time is not projected; custom scans with explicit column lists omitting __time while ordering is enabled.","solutions":["Include __time in the query's columns list (in SQL, select __time or avoid excluding it) when using time-ordering.","Remove the time-ordering if the time column is intentionally not part of results.","If building ScanResultValues manually, always populate the __time key in each event map."],"exampleFix":"// before\nnew ScanQueryBuilder().columns(Arrays.asList(\"col1\")).order(Order.DESCENDING).build();\n// after\nnew ScanQueryBuilder().columns(Arrays.asList(ColumnHolder.TIME_COLUMN_NAME, \"col1\")).order(Order.DESCENDING).build();","handlingStrategy":"validation","validationCode":"if (query.getColumns() != null && !query.getColumns().contains(ColumnHolder.TIME_COLUMN_NAME) && query.getOrdering() != null) {\n  throw new IllegalArgumentException(\"time-ordered scans must include __time\");\n}","typeGuard":"boolean firstEventHasTime(ScanResultValue sv) {\n  Object ev = ((List<?>) sv.getEvents()).get(0);\n  return ev instanceof Map && ((Map<?, ?>) ev).containsKey(\"__time\");\n}","tryCatchPattern":"try {\n  long ts = sv.getFirstEventTimestamp(format);\n} catch (IllegalStateException e) {\n  if (e.getMessage().contains(\"without a time column\")) { /* add __time to columns and re-query */ }\n  else throw e;\n}","preventionTips":["Always include __time in columns for time-ordered scans.","In SQL, project __time or avoid excluding it.","Never strip __time from ScanResultValues used in sorting."],"tags":["druid","scan-query","missing-column"],"backgroundTag":"empty-required-field","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}