@@ -127,22 +127,8 @@ public ByteBuffer read(TileCoord tileCoord) throws TileStoreException {
127127 * @param zoom the zoom level
128128 * @return the prepared query
129129 */
130- protected Query prepareQuery (int zoom ) {
131- if (postgresVersion >= 16 ) {
132- return prepareNewQuery (zoom );
133- } else {
134- return prepareLegacyQuery (zoom );
135- }
136- }
137-
138- /**
139- * Prepare the sql query for a given zoom level that uses the new version of postgresql (>= 16).
140- *
141- * @param zoom the zoom level
142- * @return the prepared query
143- */
144130 @ SuppressWarnings ("squid:S3776" )
145- private Query prepareNewQuery (int zoom ) {
131+ protected Query prepareQuery (int zoom ) {
146132 // Initialize a builder for the tile sql
147133 var tileSql = new StringBuilder ();
148134 tileSql .append ("SELECT " );
@@ -179,17 +165,10 @@ private Query prepareNewQuery(int zoom) {
179165 .replace (";" , "" )
180166 .replace ("?" , "??" )
181167 .replace ("$zoom" , String .valueOf (zoom ));
182- var querySqlWithParams = String .format (
183- """
184- SELECT
185- mvtData.id AS id,
186- mvtData.tags - 'id' AS tags,
187- ST_AsMVTGeom(mvtData.geom, ST_TileEnvelope(?, ?, ?)) AS geom
188- FROM (%s) AS mvtData
189- WHERE mvtData.geom IS NOT NULL
190- AND mvtData.geom && ST_TileEnvelope(?, ?, ?, margin => (64.0/4096))
191- """ ,
192- querySql );
168+
169+ var querySqlWithParams =
170+ postgresVersion >= 16 ? prepareNewQuery (querySql ) : prepareLegacyQuery (querySql );
171+
193172 layerSql .append (querySqlWithParams );
194173
195174 // Increase the parameter count (e.g. ?) and sql count
@@ -223,113 +202,68 @@ AND mvtData.geom && ST_TileEnvelope(?, ?, ?, margin => (64.0/4096))
223202 tileSql .append (tileQueryTail );
224203
225204 // Format the sql query
226- var sql = tileSql .toString ().replace ("\n " , " " );
205+ var sql = tileSql .toString ().replaceAll ("\\ s+ " , " " );
227206
228207 return new Query (sql , paramCount );
229208 }
230209
231210 /**
232- * Prepare the sql query for a given zoom level that uses the legacy versions of postgresql (<
233- * 16).
211+ * Prepare the sql query for the new versions of postgresql (>= 16).
212+ * <p>
213+ * Recent versions of the postgresql database better optimize subqueries. Using subqueries is more
214+ * robust and allows for more complex queries.
234215 *
235- * @param zoom the zoom level
216+ * @param sql the sql query
236217 * @return the prepared query
237218 */
238219 @ SuppressWarnings ("squid:S3776" )
239- private Query prepareLegacyQuery (int zoom ) {
240- // Initialize a builder for the tile sql
241- var tileSql = new StringBuilder ();
242- tileSql .append ("SELECT " );
243-
244- // Iterate over the layers and keep track of the number of layers and parameters included in the
245- // final sql
246- var layers = tileset .getVectorLayers ();
247- var layerCount = 0 ;
248- var paramCount = 0 ;
249- for (var layer : layers ) {
250-
251- // Initialize a builder for the layer sql
252- var layerSql = new StringBuilder ();
253- var layerHead = String .format ("(SELECT ST_AsMVT(mvtGeom.*, '%s') FROM (" , layer .getId ());
254- layerSql .append (layerHead );
255-
256- // Iterate over the queries and keep track of the number of queries included in the final
257- // sql
258- var queries = layer .getQueries ();
259- var queryCount = 0 ;
260- for (var query : queries ) {
261-
262- // Only include the sql if the zoom level is in the range
263- if (query .getMinzoom () <= zoom && zoom < query .getMaxzoom ()) {
264-
265- // Add a union between queries
266- if (queryCount > 0 ) {
267- layerSql .append ("UNION ALL " );
268- }
269-
270- // Add the sql to the layer sql
271- var querySql = query .getSql ().trim ()
272- .replaceAll ("\\ s+" , " " )
273- .replace (";" , "" )
274- .replace ("?" , "??" )
275- .replace ("$zoom" , String .valueOf (zoom ));
276-
277- // Append a new condition or a where clause
278- if (querySql .toLowerCase ().contains ("where" )) {
279- querySql += " AND " ;
280- } else {
281- querySql += " WHERE " ;
282- }
283-
284- // Append the condition to the query sql
285- querySql +=
286- "geom IS NOT NULL AND geom && ST_TileEnvelope(?, ?, ?, margin => (64.0/4096))" ;
287-
288- var querySqlWithParams = String .format (
289- """
290- SELECT
291- mvtData.id AS id,
292- mvtData.tags - 'id' AS tags,
293- ST_AsMVTGeom(mvtData.geom, ST_TileEnvelope(?, ?, ?)) AS geom
294- FROM (%s) as mvtData
295- """ ,
296- querySql );
297- layerSql .append (querySqlWithParams );
298-
299- // Increase the parameter count (e.g. ?) and sql count
300- paramCount += 6 ;
301- queryCount ++;
302- }
303- }
304-
305- // Add the tail of the layer sql
306- var layerQueryTail = ") AS mvtGeom)" ;
307- layerSql .append (layerQueryTail );
308-
309- // Only include the layer sql if queries were included for this layer
310- if (queryCount > 0 ) {
311-
312- // Add the concatenation between layer queries
313- if (layerCount > 0 ) {
314- tileSql .append (" || " );
315- }
220+ private String prepareNewQuery (final String sql ) {
221+ return String .format (
222+ """
223+ SELECT
224+ mvtData.id AS id,
225+ mvtData.tags - 'id' AS tags,
226+ ST_AsMVTGeom(mvtData.geom, ST_TileEnvelope(?, ?, ?)) AS geom
227+ FROM (%s) AS mvtData
228+ WHERE mvtData.geom IS NOT NULL
229+ AND mvtData.geom && ST_TileEnvelope(?, ?, ?, margin => (64.0/4096))
230+ """ ,
231+ sql );
232+ }
316233
317- // Add the layer sql to the mvt sql
318- tileSql .append (layerSql );
234+ /**
235+ * Prepare the sql query for the legacy versions of postgresql (< 16).
236+ * <p>
237+ * Older versions of the postgresql database do not optimize subqueries. Therefore, the conditions
238+ * are appended to the sql query, which is less robust and error-prone.
239+ *
240+ * @param sql the sql query
241+ * @return the prepared query
242+ */
243+ @ SuppressWarnings ("squid:S3776" )
244+ private String prepareLegacyQuery (final String sql ) {
245+ String query = sql ;
319246
320- // Increase the layer count
321- layerCount ++;
322- }
247+ // Append a new condition or a where clause
248+ if (sql .toLowerCase ().contains ("where" )) {
249+ query += " AND " ;
250+ } else {
251+ query += " WHERE " ;
323252 }
324253
325- // Add the tail of the tile sql
326- var tileQueryTail = " AS mvtTile" ;
327- tileSql .append (tileQueryTail );
328-
329- // Format the sql query
330- var sql = tileSql .toString ().replaceAll ("\\ s+" , " " );
331-
332- return new Query (sql , paramCount );
254+ // Append the condition to the query sql
255+ query +=
256+ "geom IS NOT NULL AND geom && ST_TileEnvelope(?, ?, ?, margin => (64.0/4096))" ;
257+
258+ return String .format (
259+ """
260+ SELECT
261+ mvtData.id AS id,
262+ mvtData.tags - 'id' AS tags,
263+ ST_AsMVTGeom(mvtData.geom, ST_TileEnvelope(?, ?, ?)) AS geom
264+ FROM (%s) as mvtData
265+ """ ,
266+ query );
333267 }
334268
335269 /**
0 commit comments