{"record":{"id":"8b348465b4e4a1fb","repo":"apache/druid","slug":"cannot-apply-virtual-columns-s-with-naive-apply","errorCode":null,"errorMessage":"Cannot apply virtual columns [%s] with naive apply.","messagePattern":"Cannot apply virtual columns \\[(.+?)\\] with naive apply\\.","errorType":"exception","errorClass":"QueryUnsupportedException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/query/rowsandcols/LazilyDecoratedRowsAndColumns.java","lineNumber":350,"sourceCode":"        rowsToSkip = new BitSet(numRows);\n      }\n\n      final ValueMatcher matcher = filter.makeMatcher(selectorFactory);\n\n      for (; rowId.get() < numRows; rowId.incrementAndGet()) {\n        final int theId = rowId.get();\n        if (rowsToSkip.get(theId)) {\n          continue;\n        }\n\n        if (!matcher.matches(false)) {\n          rowsToSkip.set(theId);\n        }\n      }\n    }\n\n    if (virtualColumns != null) {\n      throw new UOE(\"Cannot apply virtual columns [%s] with naive apply.\", virtualColumns);\n    }\n\n    ArrayList<String> columnsToGenerate = new ArrayList<>();\n    if (viewableColumns != null) {\n      columnsToGenerate.addAll(viewableColumns);\n    } else {\n      columnsToGenerate.addAll(rac.getColumnNames());\n      // When/if we support virtual columns from here, we should auto-add them to the list here as well as they expand\n      // the implicit project when no projection is defined\n    }\n\n    // There is all sorts of sub-optimal things in this code, but we just ignore them for now as it is difficult to\n    // optimally build frames for incremental data processing.  In order to build the frame object here, we must first\n    // materialize everything in memory so that we know how long things are, such that we can allocate a big byte[]\n    // so that the Frame.wrap() call can be given just a big byte[] to do its reading from.\n    //\n    // It would be a bit better if we could just build the per-column byte[] and somehow re-generate a Frame from\n    // that.  But it's also possible that this impedence mis-match is a function of using column-oriented frames and","sourceCodeStart":332,"sourceCodeEnd":368,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/query/rowsandcols/LazilyDecoratedRowsAndColumns.java#L332-L368","documentation":"The naive materialization path of LazilyDecoratedRowsAndColumns cannot apply virtual columns; it only handles skipping rows and selecting existing columns. When virtualColumns is set when the naive path is reached, Druid throws UOE. The fast cursor-based path must be used instead.","triggerScenarios":"materialize() falls back to naiveMaterialize() (because the base is not a CursorFactory) while virtual columns are configured on the decoration.","commonSituations":"Wrapping a data object that doesn't support cursors while also decorating with virtual column expressions; internal pipeline wiring that combines naive materialization with VCs.","solutions":["Ensure the base RowsAndColumns supports CursorFactory so the non-naive path is used","Apply virtual columns before wrapping in LazilyDecoratedRowsAndColumns","Remove virtual column decoration from this stage and compute derived columns elsewhere"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"if (decoration.getVirtualColumns() != null && !(base instanceof CursorFactory)) {\n  throw new IllegalStateException(\"virtual columns require a cursor-capable base\");\n}","typeGuard":"boolean supportsCursorPaths(RowsAndColumns rac) {\n  return rac.as(CursorFactory.class) != null;\n}","tryCatchPattern":"try {\n  rac = lazilyDecorated.materialize();\n} catch (UnsupportedOperationException e) {\n  if (e.getMessage().contains(\"virtual columns\") && e.getMessage().contains(\"naive\")) {\n    rac = applyVirtualColumnsManually(base, vcs);\n  } else throw e;\n}","preventionTips":["Only decorate cursor-capable RowsAndColumns with virtual columns","Apply virtual columns upstream of the decorated wrapper"],"tags":["virtual-columns","scan","unsupported-operation","rows-and-columns"],"backgroundTag":"unsupported-operation","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"}