{"record":{"id":"b476e3c14e4ec25a","repo":"prestodb/presto","slug":"invalid-function-argument-b476e3","errorCode":"INVALID_FUNCTION_ARGUMENT","errorMessage":"No rows supplied to spatial partition.","messagePattern":"No rows supplied to spatial partition\\.","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-main-base/src/main/java/com/facebook/presto/geospatial/SpatialPartitioningInternalAggregateFunction.java","lineNumber":87,"sourceCode":"            if (sampleIndex < MAX_SAMPLE_COUNT) {\n                samples.set(toIntExact(sampleIndex), extent);\n            }\n        }\n\n        state.setCount(state.getCount() + 1);\n    }\n\n    @CombineFunction\n    public static void combine(SpatialPartitioningState state, SpatialPartitioningState otherState)\n    {\n        throw new UnsupportedOperationException(\"spatial_partitioning must run on a single node\");\n    }\n\n    @OutputFunction(StandardTypes.VARCHAR)\n    public static void output(SpatialPartitioningState state, BlockBuilder out)\n    {\n        if (state.getCount() == 0) {\n            throw new PrestoException(INVALID_FUNCTION_ARGUMENT, \"No rows supplied to spatial partition.\");\n        }\n\n        List<Rectangle> samples = state.getSamples();\n\n        int partitionCount = state.getPartitionCount();\n        int maxItemsPerNode = (samples.size() + partitionCount - 1) / partitionCount;\n\n        VARCHAR.writeString(out, KdbTreeUtils.toJson(buildKdbTree(maxItemsPerNode, samples)));\n    }\n}\n","sourceCodeStart":69,"sourceCodeEnd":98,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-main-base/src/main/java/com/facebook/presto/geospatial/SpatialPartitioningInternalAggregateFunction.java#L69-L98","documentation":"spatial_partitioning is an aggregate function that builds a KDB tree from sampled geometry rows. If zero rows were supplied to the aggregation (state.getCount() == 0), there is no data to build a partitioning from, so the output step throws INVALID_FUNCTION_ARGUMENT instead of returning a meaningless tree.","triggerScenarios":"Calling spatial_partitioning(geometry, partition_count) over an empty table, a filtered-to-empty result set (WHERE clause matches nothing), or within a group where all rows were NULL geometry.","commonSituations":"Running a partitioning job before data is loaded, an over-restrictive WHERE filter, GROUP BY producing an empty group, upstream join eliminating all rows.","solutions":["Ensure the input query returns at least one non-null geometry row.","Guard with a COUNT(*) check or run the aggregation only when data exists.","Relax the WHERE filter or fix the join that eliminates all rows."],"exampleFix":"// before\nSELECT spatial_partitioning(geom, 100) FROM tiles WHERE partition_date = '2026-09-01'; -- empty\n// after\nSELECT spatial_partitioning(geom, 100) FROM tiles WHERE partition_date >= '2026-08-01'; -- non-empty range","handlingStrategy":"validation","validationCode":"-- check input non-empty before aggregating\nSELECT count(*) FROM tiles WHERE <your filter>; -- must be > 0\n// app code: if (count == 0) skip building the partitioning;","typeGuard":null,"tryCatchPattern":"try {\n    tree = query(\"SELECT spatial_partitioning(geom, ?)\", n);\n} catch (PrestoException e) {\n    if (e.getMessage().contains(\"No rows supplied to spatial partition\")) {\n        // fall back to a default partitioning or abort the job with a clear message\n    }\n}","preventionTips":["Verify the input SELECT returns rows before running the aggregation","Beware GROUP BY producing empty groups; coalesce empty groups to a default tree","Check joins/filters that can eliminate all rows"],"tags":["presto","geospatial","aggregate","empty-input"],"backgroundTag":"empty-aggregate-input","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"}