@@ -127,22 +127,8 @@ public ByteBuffer read(TileCoord tileCoord) throws TileStoreException {
127
127
* @param zoom the zoom level
128
128
* @return the prepared query
129
129
*/
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
- */
144
130
@ SuppressWarnings ("squid:S3776" )
145
- private Query prepareNewQuery (int zoom ) {
131
+ protected Query prepareQuery (int zoom ) {
146
132
// Initialize a builder for the tile sql
147
133
var tileSql = new StringBuilder ();
148
134
tileSql .append ("SELECT " );
@@ -179,17 +165,10 @@ private Query prepareNewQuery(int zoom) {
179
165
.replace (";" , "" )
180
166
.replace ("?" , "??" )
181
167
.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
+
193
172
layerSql .append (querySqlWithParams );
194
173
195
174
// Increase the parameter count (e.g. ?) and sql count
@@ -223,113 +202,68 @@ AND mvtData.geom && ST_TileEnvelope(?, ?, ?, margin => (64.0/4096))
223
202
tileSql .append (tileQueryTail );
224
203
225
204
// Format the sql query
226
- var sql = tileSql .toString ().replace ("\n " , " " );
205
+ var sql = tileSql .toString ().replaceAll ("\\ s+ " , " " );
227
206
228
207
return new Query (sql , paramCount );
229
208
}
230
209
231
210
/**
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.
234
215
*
235
- * @param zoom the zoom level
216
+ * @param sql the sql query
236
217
* @return the prepared query
237
218
*/
238
219
@ 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
+ }
316
233
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 ;
319
246
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 " ;
323
252
}
324
253
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 );
333
267
}
334
268
335
269
/**
0 commit comments