22.3. Trino Data Store Parameters¶
22.3.1. Data Store Parameters¶
The Trino data store takes the following parameters (required parameters are marked with *):
Parameter |
Type |
Description |
|---|---|---|
|
String |
Trino coordinator host |
|
Int |
Trino coordinator port |
|
String |
Trino schema (default |
|
String |
Trino session user |
|
String |
Shared secret presented to Trino as the ‘secret’ extra credential; must match the catalog’s secret |
|
||
|
String |
Specify the type of registry used to publish metrics. Must be one of |
|
String |
Override the default registry config. See Data Store Metrics for configuration details. |
22.3.2. Programmatic Access¶
An instance of the data store can be obtained through the normal GeoTools discovery methods, assuming that the GeoMesa code is on the classpath:
Map<String, Object> parameters = new HashMap<>();
parameters.put("trino.host", "trino-coordinator");
parameters.put("trino.port", 8080);
parameters.put("trino.schema", "spatial");
org.geotools.api.data.DataStore dataStore =
org.geotools.api.data.DataStoreFinder.getDataStore(parameters);
22.3.3. GeoMesa Filter Functions¶
The Trino datastore translates these functions from Filter Functions:
Function |
Translation |
|---|---|
|
Evaluated when each query is encoded, including ISO-8601 duration offsets such as |
|
Native SQL |
|
|
|
Positive 31-bit mask of |
|
|
The documented jsonPath and visibility functions are evaluated client-side, subject to the
client-side filtering policy. JSON path property expressions such as "$.props.color" can still be
pushed down through the datastore’s JSON support, and configured visibility enforcement is applied
independently of a CQL visibility predicate.
The geomesa_* SQL functions are supplied by the spatial-iceberg plugin.
Hashing supports strings, integers, longs, floats, doubles, dates, byte arrays and UUIDs. Unsupported
argument types become client-side residual filters, subject to the configured client-side filtering
policy. Other functions with feature-dependent arguments also become residual filters instead of being
sent to Trino under their GeoTools names. See Trino Runtime Configuration for the client-side filtering policy.
Before splitting a query into SQL and client-side predicates, GeoTools simplifies logical expressions
and evaluates constant functions. This includes functions outside the SQL translation list when their
arguments are feature-independent. Functions that implicitly read a feature, such as proxyId(),
remain feature-dependent. Functions outside the SQL translation list, including
z2, xz2 and convert2viewer, use client-side filtering when their arguments
depend on the feature.
Whole-world BBOX and INTERSECTS predicates on the default geometry are removed during
simplification, since indexed rows always have a geometry. Predicates on secondary geometries and
boundary-sensitive operators such as WITHIN and CONTAINS are retained.
currentDate is evaluated for every query, rather than when the datastore is created. This permits
merged stores to use rolling filters such as dtg < currentDate('-P1D') without freezing the cutoff.
22.3.4. SQL Patterns for Direct-SQL Consumers¶
Direct-SQL consumers can still make spatial queries using standard spatial ST_* functions. The
examples below run against a table whose geometry column is named geom - see Companion Columns and Naming Convention
for a description of the additional fields.
-- Standard intersects query
SELECT COUNT(*) FROM spatial_iceberg.spatial.observations
WHERE ST_Intersects(ST_GeomFromBinary(geom),
ST_GeometryFromText('POLYGON ((-80 37, -70 37, -70 45, -80 45, -80 37))'));
-- DWITHIN query
SELECT COUNT(*) FROM spatial_iceberg.spatial.observations
WHERE ST_Intersects(ST_GeomFromBinary(geom),
ST_GeometryFromText('POLYGON ((-77.94 37.91, -76.14 37.91, -76.14 39.91, -77.94 39.91, -77.94 37.91))'))
AND ST_Distance(
to_spherical_geography(ST_GeomFromBinary(geom)),
to_spherical_geography(ST_GeometryFromText('POINT (-77.04 38.91)'))
) <= 100000;
-- Bounding boxes can be queried directly, note that they are stored at float32 precision,
-- so may not provide 100% accurate results
SELECT COUNT(*) FROM spatial_iceberg.spatial.observations
WHERE "__geom_bbox__".xmax >= -80 AND "__geom_bbox__".xmin <= -70
AND "__geom_bbox__".ymax >= 37 AND "__geom_bbox__".ymin <= 45;
Note that geometry columns are defined as VARBINARY (encoded WKB), not Geometry types, thus every spatial function call
must wrap the column with ST_GeomFromBinary(geom), as shown above.
22.3.5. Verifying the Pruning Layers¶
From any Trino client (e.g. trino --server <coordinator>:8080 --catalog
spatial_iceberg --schema spatial):
SHOW TABLES;
SELECT COUNT(*) FROM observations;
-- Check the pruning layers are active. Layer 1 (truncate-string partition
-- projection) is NOT surfaced in `constraint on [...]` — use EXPLAIN ANALYZE and
-- confirm `Splits: N` and `Input: M rows` are much smaller than the table totals.
-- 1. EXPLAIN ANALYZE shows reduced scan-input rows/splits — Z2/XZ2 partition pushdown
-- 2. `geom_bbox_xmax >= ... AND geom_bbox_xmin <= ...` in filterPredicate — bbox-stat pushdown
-- 3. Layer 3 (page-source bbox filter) is not a plan node: for a rectangle
-- ST_Intersects on a point/Z2 column the `st_intersects` residual disappears
-- entirely (claimed enforced); otherwise it remains as the residual while rows
-- are pre-rejected in the page source — seen as EXPLAIN ANALYZE filter input
-- dropping below the scanned row count.
EXPLAIN
SELECT COUNT(*) FROM observations
WHERE ST_Intersects(ST_GeomFromBinary(geom),
ST_GeometryFromText('POLYGON ((-80 37, -70 37, -70 45, -80 45, -80 37))'));
-- Inspect Iceberg metadata tables (use single quotes around the SQL when running
-- through bash to avoid the shell eating $files / $manifests).
SELECT count(*) AS files,
avg(record_count) AS avg_rows,
avg(file_size_in_bytes) / 1048576.0 AS avg_mib
FROM iceberg.spatial."observations$files";
SELECT path,
added_data_files_count + existing_data_files_count AS files,
partition_summaries[1].lower_bound AS z2_prefix_min,
partition_summaries[1].upper_bound AS z2_prefix_max
FROM iceberg.spatial."observations$manifests"
ORDER BY partition_summaries[1].lower_bound;