From d74e927adb6fa3083ec4a62db66ec9c3c8f71d69 Mon Sep 17 00:00:00 2001 From: Artem Gavrilov Date: Wed, 17 Sep 2025 19:56:56 +0200 Subject: [PATCH] PG-1931 Fix returned vaules from C function Latest version of extension stll may be installed with previous API verison. So we have to return appropriate data set from C code. This commit fixes bug that was introduced in PGSM version 2.1 when extension created with API version 2.0 crashes on data fetch. --- pg_stat_monitor.c | 32 ++++++++++++++++++---------- t/034_update.pl | 54 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 11 deletions(-) create mode 100644 t/034_update.pl diff --git a/pg_stat_monitor.c b/pg_stat_monitor.c index d0f0db7..4401d77 100644 --- a/pg_stat_monitor.c +++ b/pg_stat_monitor.c @@ -2300,7 +2300,7 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo, else nulls[i++] = true; - /* parentid at column number 9 */ + /* parentid at column number 11 */ if (tmpkey.parentid != UINT64CONST(0)) { values[i++] = UInt64GetDatum(tmpkey.parentid); @@ -2312,7 +2312,7 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo, nulls[i++] = true; } - /* application_name at column number 15 */ + /* application_name at column number 13 */ if (strlen(tmp.info.application_name) > 0) values[i++] = CStringGetTextDatum(tmp.info.application_name); else @@ -2445,8 +2445,11 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo, values[i++] = Int64GetDatumFast(tmp.blocks.temp_blks_written); values[i++] = Float8GetDatumFast(tmp.blocks.shared_blk_read_time); values[i++] = Float8GetDatumFast(tmp.blocks.shared_blk_write_time); - values[i++] = Float8GetDatumFast(tmp.blocks.local_blk_read_time); - values[i++] = Float8GetDatumFast(tmp.blocks.local_blk_write_time); + if (api_version >= PGSM_V2_1) + { + values[i++] = Float8GetDatumFast(tmp.blocks.local_blk_read_time); + values[i++] = Float8GetDatumFast(tmp.blocks.local_blk_write_time); + } values[i++] = Float8GetDatumFast(tmp.blocks.temp_blk_read_time); values[i++] = Float8GetDatumFast(tmp.blocks.temp_blk_write_time); @@ -2493,18 +2496,25 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo, values[i++] = Float8GetDatumFast(tmp.jitinfo.jit_optimization_time); values[i++] = Int64GetDatumFast(tmp.jitinfo.jit_emission_count); values[i++] = Float8GetDatumFast(tmp.jitinfo.jit_emission_time); - values[i++] = Int64GetDatumFast(tmp.jitinfo.jit_deform_count); - values[i++] = Float8GetDatumFast(tmp.jitinfo.jit_deform_time); + if (api_version >= PGSM_V2_1) + { + /* at column number 64 */ + values[i++] = Int64GetDatumFast(tmp.jitinfo.jit_deform_count); + values[i++] = Float8GetDatumFast(tmp.jitinfo.jit_deform_time); + } } - /* at column number 64 */ - values[i++] = TimestampTzGetDatum(entry->stats_since); - values[i++] = TimestampTzGetDatum(entry->minmax_stats_since); + if (api_version >= PGSM_V2_1) + { + /* at column number 66 */ + values[i++] = TimestampTzGetDatum(entry->stats_since); + values[i++] = TimestampTzGetDatum(entry->minmax_stats_since); + } - /* toplevel at column number 66 */ + /* toplevel at column number 68 */ values[i++] = BoolGetDatum(toplevel); - /* bucket_done at column number 67 */ + /* bucket_done at column number 69 */ values[i++] = BoolGetDatum(pg_atomic_read_u64(&pgsm->current_wbucket) != bucketid); /* clean up and return the tuplestore */ diff --git a/t/034_update.pl b/t/034_update.pl new file mode 100644 index 0000000..75a4208 --- /dev/null +++ b/t/034_update.pl @@ -0,0 +1,54 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use File::Basename; +use File::Compare; +use Test::More; +use lib 't'; +use pgsm; + +# Get filename and create out file name and dirs where requried +PGSM::setup_files_dir(basename($0)); + +# Create new PostgreSQL node and do initdb +my $node = PGSM->pgsm_init_pg(); +my $pgdata = $node->data_dir; + +# Update postgresql.conf to include/load pg_stat_monitor library +$node->append_conf('postgresql.conf', "shared_preload_libraries = 'pg_stat_monitor'"); + +# Start server +my $rt_value = $node->start; +ok($rt_value == 1, "Start Server"); + +# Create EXTENSION version 2.0 +my ($cmdret, $stdout, $stderr) = $node->psql('postgres', 'CREATE EXTENSION pg_stat_monitor VERSION "2.0";', extra_params => ['-a']); +ok($cmdret == 0, "Create PGSM EXTENSION"); +PGSM::append_to_debug_file($stdout); + +# Check that we have some results for version 2.0 +($cmdret, $stdout, $stderr) = $node->psql('postgres', "SELECT * FROM pg_stat_monitor;", extra_params => ['-a']); +ok($cmdret == 0, "Check PGSM returns some results for version 2.0"); +PGSM::append_to_debug_file($stdout); + +# Update EXTENSION to new version 2.1 +($cmdret, $stdout, $stderr) = $node->psql('postgres', 'ALTER EXTENSION pg_stat_monitor UPDATE TO "2.1";', extra_params => ['-a']); +ok($cmdret == 0, "Update PGSM EXTENSION to new version"); +PGSM::append_to_debug_file($stdout); + +# Check that we have some results for version 2.1 +($cmdret, $stdout, $stderr) = $node->psql('postgres', "SELECT * FROM pg_stat_monitor;", extra_params => ['-a']); +ok($cmdret == 0, "Check PGSM returns some results for version 2.1"); +PGSM::append_to_debug_file($stdout); + +# DROP EXTENSION +$stdout = $node->safe_psql('postgres', 'DROP EXTENSION pg_stat_monitor;', extra_params => ['-a']); +ok($cmdret == 0, "DROP PGSM EXTENSION"); +PGSM::append_to_debug_file($stdout); + +# Stop the server +$node->stop; + +# Done testing for this testcase file. +done_testing();