From 8bb1a41abf0cfc6baf1bf272a7cf8989d1958dde Mon Sep 17 00:00:00 2001
From: Nicolas Rodriguez <nico@nicoladmin.fr>
Date: Thu, 20 Feb 2025 03:49:11 +0100
Subject: [PATCH] Skip pg_stat_checkpointer collector if pg<17 (#1112)

* fix: skip collector if pg<17

Signed-off-by: Michael Todorovic <michael.todorovic@outlook.com>

* fix: better condition

Signed-off-by: Michael Todorovic <michael.todorovic@outlook.com>

* fix: fix PGStatCheckpointerCollector tests

Signed-off-by: Nicolas Rodriguez <nico@nicoladmin.fr>

---------

Signed-off-by: Michael Todorovic <michael.todorovic@outlook.com>
Signed-off-by: Nicolas Rodriguez <nico@nicoladmin.fr>
Co-authored-by: Michael Todorovic <michael.todorovic@outlook.com>
---
 collector/pg_stat_checkpointer.go      | 16 +++++++++++++---
 collector/pg_stat_checkpointer_test.go |  5 +++--
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/collector/pg_stat_checkpointer.go b/collector/pg_stat_checkpointer.go
index 284cf650..31e9c5d6 100644
--- a/collector/pg_stat_checkpointer.go
+++ b/collector/pg_stat_checkpointer.go
@@ -16,7 +16,9 @@ package collector
 import (
 	"context"
 	"database/sql"
+	"log/slog"
 
+	"github.com/blang/semver/v4"
 	"github.com/prometheus/client_golang/prometheus"
 )
 
@@ -29,10 +31,11 @@ func init() {
 }
 
 type PGStatCheckpointerCollector struct {
+	log *slog.Logger
 }
 
-func NewPGStatCheckpointerCollector(collectorConfig) (Collector, error) {
-	return &PGStatCheckpointerCollector{}, nil
+func NewPGStatCheckpointerCollector(config collectorConfig) (Collector, error) {
+	return &PGStatCheckpointerCollector{log: config.logger}, nil
 }
 
 var (
@@ -104,8 +107,15 @@ var (
 	FROM pg_stat_checkpointer;`
 )
 
-func (PGStatCheckpointerCollector) Update(ctx context.Context, instance *instance, ch chan<- prometheus.Metric) error {
+func (c PGStatCheckpointerCollector) Update(ctx context.Context, instance *instance, ch chan<- prometheus.Metric) error {
 	db := instance.getDB()
+
+	before17 := instance.version.LT(semver.MustParse("17.0.0"))
+	if before17 {
+		c.log.Warn("pg_stat_checkpointer collector is not available on PostgreSQL < 17.0.0, skipping")
+		return nil
+	}
+
 	row := db.QueryRowContext(ctx, statCheckpointerQuery)
 
 	// num_timed           = nt  = bigint
diff --git a/collector/pg_stat_checkpointer_test.go b/collector/pg_stat_checkpointer_test.go
index 2f59343b..9a8dd7f2 100644
--- a/collector/pg_stat_checkpointer_test.go
+++ b/collector/pg_stat_checkpointer_test.go
@@ -18,6 +18,7 @@ import (
 	"time"
 
 	"github.com/DATA-DOG/go-sqlmock"
+	"github.com/blang/semver/v4"
 	"github.com/prometheus/client_golang/prometheus"
 	dto "github.com/prometheus/client_model/go"
 	"github.com/smartystreets/goconvey/convey"
@@ -30,7 +31,7 @@ func TestPGStatCheckpointerCollector(t *testing.T) {
 	}
 	defer db.Close()
 
-	inst := &instance{db: db}
+	inst := &instance{db: db, version: semver.MustParse("17.0.0")}
 
 	columns := []string{
 		"num_timed",
@@ -92,7 +93,7 @@ func TestPGStatCheckpointerCollectorNullValues(t *testing.T) {
 	}
 	defer db.Close()
 
-	inst := &instance{db: db}
+	inst := &instance{db: db, version: semver.MustParse("17.0.0")}
 
 	columns := []string{
 		"num_timed",