{"record":{"id":"ceab0f266aa5d3af","repo":"prestodb/presto","slug":"bigquery-failed-to-execute-query","errorCode":"BIGQUERY_FAILED_TO_EXECUTE_QUERY","errorMessage":"Failed to compute empty projection","messagePattern":"Failed to compute empty projection","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-bigquery/src/main/java/com/facebook/presto/plugin/bigquery/BigQuerySplitManager.java","lineNumber":133,"sourceCode":"                String sql = bigQueryClient.createFormatSql(tableId, \"COUNT(*)\", new String[] {filter.get()});\n                TableResult result = bigQueryClient.query(sql);\n                numberOfRows = result.iterateAll().iterator().next().get(0).getLongValue();\n            }\n            else {\n                // no filters, so we can take the value from the table info\n                numberOfRows = bigQueryClient.getTable(tableId).getNumRows().longValue();\n            }\n\n            long rowsPerSplit = numberOfRows / actualParallelism;\n            long remainingRows = numberOfRows - (rowsPerSplit * actualParallelism); // need to be added to one of the split due to integer division\n            List<BigQuerySplit> splits = range(0, actualParallelism)\n                    .mapToObj(ignored -> BigQuerySplit.emptyProjection(rowsPerSplit))\n                    .collect(toList());\n            splits.set(0, BigQuerySplit.emptyProjection(rowsPerSplit + remainingRows));\n            return splits;\n        }\n        catch (BigQueryException e) {\n            throw new PrestoException(BIGQUERY_FAILED_TO_EXECUTE_QUERY, \"Failed to compute empty projection\", e);\n        }\n    }\n}\n","sourceCodeStart":115,"sourceCodeEnd":137,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-bigquery/src/main/java/com/facebook/presto/plugin/bigquery/BigQuerySplitManager.java#L115-L137","documentation":"BigQuerySplitManager.createEmptyProjection builds splits for queries with no columns (e.g. SELECT count(*)) by generating empty-projection splits; any BigQueryException during that computation is rethrown as BIGQUERY_FAILED_TO_EXECUTE_QUERY with this message. It means the connector failed while planning/sizing the empty-projection splits.","triggerScenarios":"Running a query with an empty projection (e.g. SELECT COUNT(*) FROM table) when the split computation against BigQuery metadata throws a BigQueryException (API errors, missing table, quota).","commonSituations":"Table dropped/renamed between metadata fetch and split computation; BigQuery API quota/rate limits; permission revocations; transient API outages.","solutions":["Look at the wrapped BigQueryException cause for the root reason and address it (permissions, quota, table existence)","Verify the table still exists and the service account has access","Retry the query if the cause was transient","Check BigQuery API quotas and error details in Google Cloud logs"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// before empty-projection queries, verify table access\nTable table = bigQueryClient.getTable(tableId);\nif (table == null) {\n    throw new IllegalStateException(\"Table not found or not accessible: \" + tableId);\n}","typeGuard":null,"tryCatchPattern":"try {\n    return splitManager.getSplits(...);\n} catch (PrestoException e) {\n    if (BIGQUERY_FAILED_TO_EXECUTE_QUERY.getCode() == e.getErrorCode().getCode()) {\n        log.error(\"Empty projection failed; cause: %s\", e.getCause());\n        // address cause (permissions/quota/table existence) then retry\n    }\n    throw e;\n}","preventionTips":["Grant the service account stable access to all queried tables","Monitor BigQuery quotas for rate-limit errors","Avoid rapid metadata re-checks on dropping/renaming tables","Always log the wrapped cause to identify the root BigQuery error"],"tags":["bigquery","split-planning","query-execution"],"backgroundTag":"bigquery-query-execution-failed","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"}