use of io.trino.spi.function.SqlType in project trino by trinodb.
the class TimestampWithTimeZoneToTimeWithTimeZoneCast method longToShort.
@LiteralParameters({ "sourcePrecision", "targetPrecision" })
@SqlType("time(targetPrecision) with time zone")
public static long longToShort(@LiteralParameter("targetPrecision") long targetPrecision, @SqlType("timestamp(sourcePrecision) with time zone") LongTimestampWithTimeZone timestamp) {
// source precision is > 3
// target precision is <= 9
TimeZoneKey zoneKey = getTimeZoneKey(timestamp.getTimeZoneKey());
long epochMillis = getChronology(zoneKey).getZone().convertUTCToLocal(timestamp.getEpochMillis());
// combine epochMillis with picosOfMilli from the timestamp. We compute modulo 24 to avoid overflow when rescaling epocMilli to picoseconds
long picos = rescale(floorMod(epochMillis, MILLISECONDS_PER_DAY), 3, 12) + timestamp.getPicosOfMilli();
picos = round(picos, (int) (12 - targetPrecision));
picos = floorMod(picos, PICOSECONDS_PER_DAY);
long nanos = rescale(picos, 12, 9);
return packTimeWithTimeZone(nanos, DateTimes.getOffsetMinutes(Instant.ofEpochMilli(epochMillis), zoneKey));
}
use of io.trino.spi.function.SqlType in project trino by trinodb.
the class TimestampWithTimeZoneToTimeWithTimeZoneCast method longToLong.
@LiteralParameters({ "sourcePrecision", "targetPrecision" })
@SqlType("time(targetPrecision) with time zone")
public static LongTimeWithTimeZone longToLong(@LiteralParameter("targetPrecision") long targetPrecision, @SqlType("timestamp(sourcePrecision) with time zone") LongTimestampWithTimeZone timestamp) {
// source precision is > 3
// target precision is > 9
TimeZoneKey zoneKey = getTimeZoneKey(timestamp.getTimeZoneKey());
long epochMillis = getChronology(zoneKey).getZone().convertUTCToLocal(timestamp.getEpochMillis());
// combine epochMillis with picosOfMilli from the timestamp. We compute modulo 24 to avoid overflow when rescaling epocMilli to picoseconds
long picos = rescale(floorMod(epochMillis, MILLISECONDS_PER_DAY), 3, 12) + timestamp.getPicosOfMilli();
picos = round(picos, (int) (12 - targetPrecision));
return new LongTimeWithTimeZone(floorMod(picos, PICOSECONDS_PER_DAY), DateTimes.getOffsetMinutes(Instant.ofEpochMilli(epochMillis), zoneKey));
}
use of io.trino.spi.function.SqlType in project trino by trinodb.
the class TimestampWithTimeZoneToTimeWithTimeZoneCast method shortToShort.
@LiteralParameters({ "sourcePrecision", "targetPrecision" })
@SqlType("time(targetPrecision) with time zone")
public static long shortToShort(@LiteralParameter("targetPrecision") long targetPrecision, @SqlType("timestamp(sourcePrecision) with time zone") long packedTimestamp) {
// source precision is <= 3
// target precision is <= 9
TimeZoneKey zoneKey = unpackZoneKey(packedTimestamp);
long epochMillis = getChronology(zoneKey).getZone().convertUTCToLocal(unpackMillisUtc(packedTimestamp));
if (targetPrecision <= 3) {
epochMillis = round(epochMillis, (int) (3 - targetPrecision));
}
long nanos = rescale(floorMod(epochMillis, MILLISECONDS_PER_DAY), 3, 9);
return packTimeWithTimeZone(nanos, DateTimes.getOffsetMinutes(Instant.ofEpochMilli(epochMillis), zoneKey));
}
use of io.trino.spi.function.SqlType in project trino by trinodb.
the class BingTileFunctions method geometryToBingTiles.
@Description("Given a geometry and a zoom level, returns the minimum set of Bing tiles that fully covers that geometry")
@ScalarFunction("geometry_to_bing_tiles")
@SqlType("array(" + BingTileType.NAME + ")")
public static Block geometryToBingTiles(@SqlType(GEOMETRY_TYPE_NAME) Slice input, @SqlType(StandardTypes.INTEGER) long zoomLevelInput) {
checkZoomLevel(zoomLevelInput);
int zoomLevel = toIntExact(zoomLevelInput);
OGCGeometry ogcGeometry = deserialize(input);
if (ogcGeometry.isEmpty()) {
return EMPTY_TILE_ARRAY;
}
Envelope envelope = getEnvelope(ogcGeometry);
checkLatitude(envelope.getYMin(), LATITUDE_SPAN_OUT_OF_RANGE);
checkLatitude(envelope.getYMax(), LATITUDE_SPAN_OUT_OF_RANGE);
checkLongitude(envelope.getXMin(), LONGITUDE_SPAN_OUT_OF_RANGE);
checkLongitude(envelope.getXMax(), LONGITUDE_SPAN_OUT_OF_RANGE);
boolean pointOrRectangle = isPointOrRectangle(ogcGeometry, envelope);
BingTile leftUpperTile = latitudeLongitudeToTile(envelope.getYMax(), envelope.getXMin(), zoomLevel);
BingTile rightLowerTile = getTileCoveringLowerRightCorner(envelope, zoomLevel);
// XY coordinates start at (0,0) in the left upper corner and increase left to right and top to bottom
long tileCount = (long) (rightLowerTile.getX() - leftUpperTile.getX() + 1) * (rightLowerTile.getY() - leftUpperTile.getY() + 1);
checkGeometryToBingTilesLimits(ogcGeometry, envelope, pointOrRectangle, tileCount, zoomLevel);
BlockBuilder blockBuilder = BIGINT.createBlockBuilder(null, toIntExact(tileCount));
if (pointOrRectangle || zoomLevel <= OPTIMIZED_TILING_MIN_ZOOM_LEVEL) {
// all tiles covering the bounding box intersect the geometry.
for (int x = leftUpperTile.getX(); x <= rightLowerTile.getX(); x++) {
for (int y = leftUpperTile.getY(); y <= rightLowerTile.getY(); y++) {
BingTile tile = BingTile.fromCoordinates(x, y, zoomLevel);
if (pointOrRectangle || !disjoint(tileToEnvelope(tile), ogcGeometry)) {
BIGINT.writeLong(blockBuilder, tile.encode());
}
}
}
} else {
// Intersection checks above are expensive. The logic below attempts to reduce the number
// of these checks. The idea is to identify large tiles which are fully covered by the
// geometry. For each such tile, we can cheaply compute all the containing tiles at
// the right zoom level and append them to results in bulk. This way we perform a single
// containment check instead of 2 to the power of level delta intersection checks, where
// level delta is the difference between the desired zoom level and level of the large
// tile covered by the geometry.
BingTile[] tiles = getTilesInBetween(leftUpperTile, rightLowerTile, OPTIMIZED_TILING_MIN_ZOOM_LEVEL);
for (BingTile tile : tiles) {
appendIntersectingSubtiles(ogcGeometry, zoomLevel, tile, blockBuilder);
}
}
return blockBuilder.build();
}
use of io.trino.spi.function.SqlType in project trino by trinodb.
the class GeoFunctions method toSphericalGeography.
@Description("Converts a Geometry object to a SphericalGeography object")
@ScalarFunction("to_spherical_geography")
@SqlType(SPHERICAL_GEOGRAPHY_TYPE_NAME)
public static Slice toSphericalGeography(@SqlType(GEOMETRY_TYPE_NAME) Slice input) {
// "every point in input is in range" <=> "the envelope of input is in range"
Envelope envelope = deserializeEnvelope(input);
if (!envelope.isEmpty()) {
checkLatitude(envelope.getYMin());
checkLatitude(envelope.getYMax());
checkLongitude(envelope.getXMin());
checkLongitude(envelope.getXMax());
}
OGCGeometry geometry = deserialize(input);
if (geometry.is3D()) {
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, "Cannot convert 3D geometry to a spherical geography");
}
GeometryCursor cursor = geometry.getEsriGeometryCursor();
while (true) {
com.esri.core.geometry.Geometry subGeometry = cursor.next();
if (subGeometry == null) {
break;
}
if (!GEOMETRY_TYPES_FOR_SPHERICAL_GEOGRAPHY.contains(subGeometry.getType())) {
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, "Cannot convert geometry of this type to spherical geography: " + subGeometry.getType());
}
}
return input;
}
Aggregations