prestodb/presto · error · PrestoException

INVALID_CAST_ARGUMENT

INVALID_CAST_ARGUMENT

Error message

Invalid bigint tile encoding: %s

What it means

castFromBigint implements the cast from BIGINT to BingTile. It validates the bigint by decoding it via BingTile.decode(tile), which enforces the quadkey/tile encoding invariants (zoom level 0-31, valid x/y bounds for the zoom). If decoding fails, Presto throws INVALID_CAST_ARGUMENT because the bigint does not represent a valid Bing tile. This is the library's way of rejecting malformed tile encodings during a SQL cast.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/geospatial/BingTileFunctions.java:109

    @Description("Encodes a Bing tile into a bigint")
    @ScalarOperator(CAST)
    @SqlType(StandardTypes.BIGINT)
    public static long castToBigint(@SqlType(BingTileType.NAME) long tile)
    {
        return tile;
    }

    @Description("Decodes a Bing tile from a bigint")
    @ScalarOperator(CAST)
    @SqlType(BingTileType.NAME)
    public static long castFromBigint(@SqlType(StandardTypes.BIGINT) long tile)
    {
        try {
            BingTile.decode(tile);
        }
        catch (IllegalArgumentException e) {
            throw new PrestoException(INVALID_CAST_ARGUMENT,
                    format("Invalid bigint tile encoding: %s", tile));
        }
        return tile;
    }

    @Description("Creates a Bing tile from XY coordinates and zoom level")
    @ScalarFunction("bing_tile")
    @SqlType(BingTileType.NAME)
    public static long toBingTile(@SqlType(StandardTypes.INTEGER) long tileX, @SqlType(StandardTypes.INTEGER) long tileY, @SqlType(StandardTypes.INTEGER) long zoomLevel)
    {
        checkZoomLevel(zoomLevel);
        checkCoordinate(tileX, zoomLevel);
        checkCoordinate(tileY, zoomLevel);

        return BingTile.fromCoordinates(toIntExact(tileX), toIntExact(tileY), toIntExact(zoomLevel)).encode();
    }

    @Description("Given a Bing tile, returns its QuadKey")

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Validate the tile value before casting: ensure it is non-negative and decodable, or build it with bing_tile(x, y, zoom_level) instead of a raw bigint cast.
  2. Check the zoom level encoded in the bigint (top bits) is between 0 and 31 and that x/y fit within 2^zoom.
  3. If data came from external tooling, re-encode tile IDs using the documented Bing tile quadkey/encoding scheme.
  4. Wrap the cast in a TRY clause in SQL to get NULL instead of a query failure for dirty data.

Example fix

// before (SQL)
SELECT CAST(tile_id AS BingTile) FROM raw_tiles;
// after
SELECT TRY(CAST(tile_id AS BingTile)) FROM raw_tiles;
-- or construct explicitly:
SELECT bing_tile(x, y, zoom_level) FROM raw_tiles;
Defensive patterns

Strategy: validation

Validate before calling

-- SQL: validate before casting
SELECT tile_id FROM raw_tiles
WHERE tile_id >= 0
  AND bing_tile_zoom_level(TRY(CAST(tile_id AS BingTile))) IS NOT NULL;

Try / catch

-- SQL
SELECT TRY(CAST(tile_id AS BingTile)) AS tile FROM raw_tiles;

Prevention

When it happens

Trigger: Executing CAST(bigint_value AS BingTile) or bing_tile(bigint) where the bigint is negative, exceeds the maximum encoding, has zoom level > 31, or has x/y coordinates out of range for the encoded zoom level, so BingTile.decode(tile) throws IllegalArgumentException.

Common situations: Hand-crafted or corrupted tile IDs passed to a cast; computing tile encodings in external code with wrong bit layouts; column data from another system where tile IDs were encoded differently; arithmetic on valid tile IDs producing invalid values.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/c08e91045033f576. Report an issue: GitHub.