@@ -186,6 +186,12 @@ pub struct Catalog {
186186 /// Whether the database supports `int4_minmax_multi_ops` etc.
187187 /// See the [Postgres docs](https://www.postgresql.org/docs/15/brin-builtin-opclasses.html)
188188 has_minmax_multi_ops : bool ,
189+
190+ /// Whether the column `pg_stats.range_bounds_histogram` introduced in
191+ /// Postgres 17 exists. See the [Postgres
192+ /// docs](https://www.postgresql.org/docs/17/view-pg-stats.html)
193+ #[ allow( dead_code) ]
194+ pg_stats_has_range_bounds_histogram : bool ,
189195}
190196
191197impl Catalog {
@@ -199,6 +205,7 @@ impl Catalog {
199205 let text_columns = get_text_columns ( conn, & site. namespace ) ?;
200206 let use_poi = supports_proof_of_indexing ( conn, & site. namespace ) ?;
201207 let has_minmax_multi_ops = has_minmax_multi_ops ( conn) ?;
208+ let pg_stats_has_range_bounds_histogram = pg_stats_has_range_bounds_histogram ( conn) ?;
202209
203210 Ok ( Catalog {
204211 site,
@@ -207,6 +214,7 @@ impl Catalog {
207214 use_bytea_prefix,
208215 entities_with_causality_region : entities_with_causality_region. into_iter ( ) . collect ( ) ,
209216 has_minmax_multi_ops,
217+ pg_stats_has_range_bounds_histogram,
210218 } )
211219 }
212220
@@ -217,6 +225,7 @@ impl Catalog {
217225 entities_with_causality_region : BTreeSet < EntityType > ,
218226 ) -> Result < Self , StoreError > {
219227 let has_minmax_multi_ops = has_minmax_multi_ops ( conn) ?;
228+ let pg_stats_has_range_bounds_histogram = pg_stats_has_range_bounds_histogram ( conn) ?;
220229
221230 Ok ( Catalog {
222231 site,
@@ -228,6 +237,7 @@ impl Catalog {
228237 use_bytea_prefix : true ,
229238 entities_with_causality_region,
230239 has_minmax_multi_ops,
240+ pg_stats_has_range_bounds_histogram,
231241 } )
232242 }
233243
@@ -245,6 +255,7 @@ impl Catalog {
245255 use_bytea_prefix : true ,
246256 entities_with_causality_region,
247257 has_minmax_multi_ops : false ,
258+ pg_stats_has_range_bounds_histogram : false ,
248259 } )
249260 }
250261
@@ -975,6 +986,28 @@ fn has_minmax_multi_ops(conn: &mut PgConnection) -> Result<bool, StoreError> {
975986 Ok ( sql_query ( QUERY ) . get_result :: < Ops > ( conn) ?. has_ops )
976987}
977988
989+ /// Check whether the database for `conn` has the column
990+ /// `pg_stats.range_bounds_histogram` introduced in Postgres 17
991+ fn pg_stats_has_range_bounds_histogram ( conn : & mut PgConnection ) -> Result < bool , StoreError > {
992+ #[ derive( Queryable , QueryableByName ) ]
993+ struct HasIt {
994+ #[ diesel( sql_type = Bool ) ]
995+ has_it : bool ,
996+ }
997+
998+ let query = "
999+ select exists (\
1000+ select 1 \
1001+ from information_schema.columns \
1002+ where table_name = 'pg_stats' \
1003+ and table_schema = 'pg_catalog' \
1004+ and column_name = 'range_bounds_histogram') as has_it";
1005+ sql_query ( query)
1006+ . get_result :: < HasIt > ( conn)
1007+ . map ( |h| h. has_it )
1008+ . map_err ( StoreError :: from)
1009+ }
1010+
9781011pub ( crate ) fn histogram_bounds (
9791012 conn : & mut PgConnection ,
9801013 namespace : & Namespace ,
0 commit comments