{"record":{"id":"e8c6466e90193e80","repo":"prestodb/presto","slug":"pinot-invalid-sql-generated","errorCode":"PINOT_INVALID_SQL_GENERATED","errorMessage":"Expected column handle %s to be present in the handles %s corresponding to the segment Pinot SQL","messagePattern":"Expected column handle (.+?) to be present in the handles (.+?) corresponding to the segment Pinot SQL","errorType":"error_code","errorClass":"PinotException","httpStatus":null,"severity":"error","filePath":"presto-pinot-toolkit/src/main/java/com/facebook/presto/pinot/PinotSegmentPageSource.java","lineNumber":166,"sourceCode":"        // This is the list of handles we came up with when generating the SQL\n        // This could be a superset/permutation of the handles being requested in this scan\n        List<PinotColumnHandle> expectedColumnHandles = split.getExpectedColumnHandles();\n        PageBuilder pageBuilder = new PageBuilder(columnTypes);\n        // Note that declared positions in the Page should be the same with number of rows in each Block\n        pageBuilder.declarePositions(currentDataTable.getDataTable().getNumberOfRows());\n        for (int columnHandleIndex = 0; columnHandleIndex < columnHandles.size(); columnHandleIndex++) {\n            BlockBuilder blockBuilder = pageBuilder.getBlockBuilder(columnHandleIndex);\n            Type columnType = columnTypes.get(columnHandleIndex);\n            // Write a block for each column in the original order.\n            PinotColumnHandle handle = columnHandles.get(columnHandleIndex);\n\n            // map the handle needed by the scan to its index corresponding to the generated SQL\n            // All handles requested by the scan should be a subset of the expected handles\n            // ie., the expected column handles (corresponding to the generated SQL) can contain\n            // extra columns that we drop.\n            int indexReturnedByPinot = expectedColumnHandles.indexOf(handle);\n            if (indexReturnedByPinot < 0) {\n                throw new PinotException(\n                        PINOT_INVALID_SQL_GENERATED,\n                        split.getSegmentPinotQuery(),\n                        String.format(\"Expected column handle %s to be present in the handles %s corresponding to the segment Pinot SQL\", handle, expectedColumnHandles));\n            }\n            writeBlock(blockBuilder, columnType, indexReturnedByPinot);\n        }\n\n        return pageBuilder.build();\n    }\n\n    /**\n     * @return constructed page for pinot data.\n     */\n    @Override\n    public Page getNextPage()\n    {\n        if (closed) {\n            return null;","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-pinot-toolkit/src/main/java/com/facebook/presto/pinot/PinotSegmentPageSource.java#L148-L184","documentation":"When filling a page, each column handle needed by the scan is looked up by index in the split's expected column handles (the columns the generated Pinot SQL returns). If a requested handle is absent, the generated SQL and the scan disagree, indicating a connector bug, so it throws PINOT_INVALID_SQL_GENERATED.","triggerScenarios":"fillNextPage calls expectedColumnHandles.indexOf(handle) and gets -1 for a scan's column handle — the SQL generator omitted a column that the scan expects.","commonSituations":"Connector bugs after schema changes or query shapes (e.g. predicates synthesizing columns not in the output); mixed plugin versions where split metadata was produced by a different build; stale cached plans.","solutions":["Retry after clearing Presto metadata/plan caches and resubmitting the query","Capture the full query and generated Pinot SQL (split.getSegmentPinotQuery()) and file a connector bug with the plan","Ensure all nodes run identical connector versions; restart the cluster after upgrades","Simplify or reshape the query (fewer projected columns, simpler predicates) as a workaround"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"catch (PinotException e) {\n    if (e.getErrorCode() == PINOT_INVALID_SQL_GENERATED.toErrorCode().getCode()) {\n        // clear caches, restart/upgrade connector, and file a bug with the plan + generated SQL\n    }\n}","preventionTips":["Run identical connector versions on all nodes","Reproduce with a minimal query and report the generated Pinot SQL upstream","Avoid unsupported query shapes known to confuse SQL generation; keep projections simple"],"tags":["pinot","sql-generation","connector-bug","column-handle"],"backgroundTag":"invalid-generated-sql","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}