Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vLpEw-00BT5F-1i for pgsql-hackers@arkaria.postgresql.org; Wed, 19 Nov 2025 20:57:22 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vLpEt-00FPT9-1B for pgsql-hackers@arkaria.postgresql.org; Wed, 19 Nov 2025 20:57:19 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vLpEs-00FPT0-2s for pgsql-hackers@lists.postgresql.org; Wed, 19 Nov 2025 20:57:19 +0000 Received: from mail-ed1-x529.google.com ([2a00:1450:4864:20::529]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1vLpEq-000Oyl-0v for pgsql-hackers@postgresql.org; Wed, 19 Nov 2025 20:57:18 +0000 Received: by mail-ed1-x529.google.com with SMTP id 4fb4d7f45d1cf-641677916b5so246865a12.0 for ; Wed, 19 Nov 2025 12:57:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cybertec.at; s=google; t=1763585834; x=1764190634; darn=postgresql.org; h=mime-version:user-agent:content-transfer-encoding:references :in-reply-to:date:cc:to:from:subject:message-id:from:to:cc:subject :date:message-id:reply-to; bh=BwRFXDLcgUcARR8LT30xsa2EwIf4ogZH5ONN9pOdKoU=; b=MTlgCV7+tYaxOtV8ZAe0OCf0FG9VeJOxd/IHQTV6ivCz2+XHQhlFiiLB3qHThu9HFw Ama98GTam0B2pLiWR1IYc85tX4tXiueqmVZuXDL2Mk8ywR8lyTf7V2NKAor8Yvm+aGmu NCLc+au9J4UGqxMkv8gARQMdknqqdG/K2b0XP6caZkHSpUW9pRXivOl1Zuj7GlfPdb6/ einc42y+EoYzk19FAo74jdZsv89oxQLwMVY6rpjODqGN292KV3nubHsq93ZRHVN8ESKk ANNyJla2DqmNYkVZ78dU2n7JBCKkHaAO+x+G8G0y/XXFz751z8LXdzs2FXvH+Jxjjnym lREA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763585834; x=1764190634; h=mime-version:user-agent:content-transfer-encoding:references :in-reply-to:date:cc:to:from:subject:message-id:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=BwRFXDLcgUcARR8LT30xsa2EwIf4ogZH5ONN9pOdKoU=; b=umyxnHPnnuaRNVDNiiBufePJ+EGrwpjHHHGd6Gc31usaOnFoULeIVwPFUD4hAmBrvq mxu97yTXOQ4Bkr7trlZX5P/JV6xUGl3/KkA8HDi73b4o+HohSN10FfYRXd77jMsZ0YzZ Ac0AWnKmOqZKM1QE6tFCTM5dURurGqRLlteFPsgkUCv0tE9R5HmgzlmV0QOgF/iLfGwe dY1Rr4/MOFDKl05fgFO3/U38hrvDykCBjuWzaWtLS5/6HzupChM+WRL/uB0uIV2E07ur 6rJLdqPhy+TzpNqoykxGF/8yrFHPhOWZoq0k8K0XFTCycbA6iNuJcCaYfarDQikrDK7C jIbQ== X-Forwarded-Encrypted: i=1; AJvYcCVZdQ+u9wvqO3fWwOPByI5OgMgnbHSj7hpybgMTup84wjh8R2ktec+eRVCZyEC3RsE5bEge07nZH28EmwCo@postgresql.org X-Gm-Message-State: AOJu0Yy+YD3tZMBF+CNXOe0tmKGN5LeGYO//o0SgKlUivjTsKDl4CqhJ DspI5Bf/wV0ZXUZ/scEe2vIrYZaGBfI8aaAJll4K74/Ahhs9VBl6ckkZATtFZ4jEzKQ= X-Gm-Gg: ASbGnctV2oiRAiayNqatCZ3O5AUS5Tqih6SZrtvaeigfSAw6fBSKvZ7uvzOX17anA9X KU3Z/nqLYR/T3Q5Mo7E1bl440Ot6CDpRPHLiLMgFnysXokaJVROw0PA9+OsXadwRIJbfqKUozqX FsGSUz2QTx2RgBEnG6lrZrb3Iw9sXg1ANcvOCkBq5NmMl+SUlxHa780zMjhAKGDN2x3S5zWKaGr SxRB50N1vbr8Wq2y6UcPX3zYBHnWfE+jgWQ4eRx1z45DpjV3MyQeK6G3nsxh16VSUo6T+1fDBP+ 8/meS3F6B1ZplW4nUdVGSmOKZMfGpC9td8lx4bNBwg/+UmhZQjZRC7DtVfxeBAYkYhCN279VRxf OR+z7/B+XDYaYvfhe4wftUBNW1PibqNzcKKiZ+mGGkaCzZyS6GW5mW3bEFtydqOOynO88cBZMm6 jfjEyzQ5PNVxdRux+98fW/fOIMAZ4o7QoBzvAn0XX+vrJq6pGOVvGCxSmZ7qIBFA== X-Google-Smtp-Source: AGHT+IE9xwpe4nBi4r6tSceWvDSs1VmyfVHxrrvqTJZBkx7wzvFdUhoriCNRsalljPH71CbgPwgvUg== X-Received: by 2002:a05:6402:2113:b0:640:976f:13b0 with SMTP id 4fb4d7f45d1cf-645381b58abmr96206a12.12.1763585833831; Wed, 19 Nov 2025 12:57:13 -0800 (PST) Received: from laurenz.albe-K4N0CV00F97414D ([213.83.186.126]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-6453645977dsm436672a12.30.2025.11.19.12.57.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Nov 2025 12:57:13 -0800 (PST) Message-ID: Subject: Re: System views for versions reporting From: Laurenz Albe To: Dmitry Dolgov <9erthalion6@gmail.com>, Tom Lane Cc: jian he , Joe Conway , pgsql-hackers@postgresql.org Date: Wed, 19 Nov 2025 21:57:12 +0100 In-Reply-To: References: <5jhyl6p3nwcaxczfxuh25q42q6bqlaxyqyfqtw4tldvmm24bw2@rfii5tkwn5rg> <866452.1742768493@sss.pgh.pa.us> Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable User-Agent: Evolution 3.56.2 (3.56.2-2.fc42) MIME-Version: 1.0 List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Sun, 2025-11-16 at 17:45 +0100, Dmitry Dolgov wrote: > Better late than never, rebased and dropped 0004. I think that having a system view like that would be quite useful. It would be even more useful if it included other libraries that are optionally linked with PostgreSQL, like OpenSSL, OpenLDAP, lz4, zstd, GSSAPI etc. Building the server worked fine on my Linux box (but see my comments about Glibc below), and the view behaves like it should. Building the documentation fails: element indexterm: validity error : IDREFS attribute zone references an unk= nown ID "view-pg-system-version" The problem is here: > --- a/doc/src/sgml/system-views.sgml > +++ b/doc/src/sgml/system-views.sgml > + > + <structname>pg_system_versions</structname> > + > + > + pg_system_versions > + "view-pg-system-version" is missing the "s" at the end. Comments on the code: =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Patch 0001: ----------- > --- a/doc/src/sgml/system-views.sgml > +++ b/doc/src/sgml/system-views.sgml > + > + pg_sy= stem_versions > + system versions > + > + > > > That list is alphabetically sorted by function name. You should add the fu= nction at the correct place, not at the end. The same applies to the next hunk. It gets rendered in its own page, so th= e order is not user-visible, but keeping these sections in the same alphabetical order= will ease maintenance. > + > + <structname>pg_system_versions</structname> > + > + > + pg_system_versions > + > + > + > + The view pg_system_versions provides descrip= tion > + about versions of various system components, e.g. PostgreSQL itself, > + compiler used to build it, dependencies, etc. > + > + > [...] > + > + > + type text > + > + > + Component type (compile time or Run time) > + > + I'm not happy with the English in "The view ... provides description about = ...", but all the other views use the same wording, so we should stick with it. But in "description about versions of various system components", there sho= uld be a "the" before "versions". It should also be "the compiler". Since you= start the list with "e.g.", I think the "etc." is superfluous. In "compile time or Run time", either use upper case everywhere (except in = "or") or lower case everywhere. I suggest to use upper case like in the actual v= iew output. > --- /dev/null > +++ b/src/backend/utils/misc/system_version.c > +void > +add_system_version(const char *name, SystemVersionCB cb, VersionType typ= e) > +{ > + SystemVersion *hentry; > + const char *key; > + bool found; > + > + if (!versions) > + { > + HASHCTL ctl; > + > + ctl.keysize =3D NAMEDATALEN; > + ctl.entrysize =3D sizeof(SystemVersion); > + ctl.hcxt =3D CurrentMemoryContext; That hashtable should stick around for the entire life time of the backend. Wouldn't it be better to explicitly name the correct memory context, rather that to rely on being called with "CurrentMemoryContext" set correctly? > + > + versions =3D hash_create("System versions table", > + MAX_SYSTEM_VERSIONS, > + &ctl, > + HASH_ELEM | HASH_STRINGS); > + } > + > + key =3D pstrdup(name); > + hentry =3D (SystemVersion *) hash_search(versions, key, > + HASH_ENTER, &found); I think you should at least add an Assert() that makes sure that the key is not longer than NAMEDATALEN. > + > + if (found) > + elog(ERROR, "duplicated system version"); Is that a problem? Why throw an error? > +Datum > +pg_get_system_versions(PG_FUNCTION_ARGS) > +{ > [...] > + while ((hentry =3D (SystemVersion *) hash_seq_search(&status)) !=3D N= ULL) > + { > + Datum values[PG_GET_SYS_VERSIONS_COLS] =3D {0}; > + bool nulls[PG_GET_SYS_VERSIONS_COLS] =3D {0}; > + bool available =3D false; > + const char *version =3D hentry->callback(&available); > + > + if (!available) > + continue; > + > + values[0] =3D CStringGetTextDatum(hentry->name); > + values[1] =3D CStringGetTextDatum(version); > + values[2] =3D hentry->type; > + > + tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, = nulls); > + } I think the assignment for the third column should be values[2] =3D Int32GetDatum((int32) hentry->type); since hentry->type is an enum type and hence an "int". Patch 0002: ----------- > --- a/src/backend/utils/misc/system_version.c > +++ b/src/backend/utils/misc/system_version.c > +/* > + * Register versions that describe core components and do not correspond= to any > + * individual component. > + */ > +void > +register_core_versions() > +{ > + add_system_version("Core", core_get_version, CompileTime); > + add_system_version("Arch", core_get_arch, CompileTime); > + add_system_version("Compiler", core_get_compiler, CompileTime); > + add_system_version("ICU", icu_get_version, RunTime); > + add_system_version("Glibc", glibc_get_version, RunTime); > +} > [...] > +const char * > +glibc_get_version(bool *available) > +{ > + *available =3D true; > + return (const char *) gnu_get_libc_version(); > +} Not all operating systems use Glibc, not even all Linux distributions. If you look at the commitfest entry, you'll see the the CI build fails on most platforms. At the very least, this calls for conditional compilation. Really, there should be an add_system_version() call for all types of C libraries that exist out there, but that might border on the impossible. > --- a/src/include/utils/system_version.h > +++ b/src/include/utils/system_version.h > @@ -11,6 +11,10 @@ > #ifndef SYSTEM_VERSION_H > #define SYSTEM_VERSION_H > =20 > +#ifdef __GLIBC__ > +#include > +#endif > + That should be included where glibc_get_version() is defined, not here. > #define MAX_SYSTEM_VERSIONS 100 > =20 > typedef enum VersionType > @@ -34,5 +38,13 @@ typedef struct SystemVersion > } SystemVersion; > =20 > void add_system_version(const char *name, SystemVersionCB cb, Vers= ionType type); > +extern void register_core_versions(void); > + > +const char *core_get_version(bool *available); > +const char *core_get_arch(bool *available); > +const char *core_get_compiler(bool *available); > + > +const char *icu_get_version(bool *available); > +const char *glibc_get_version(bool *available); > =20 > #endif /* SYSTEM_VERSION_H */ I think that these functions had better be "static". Do you expect a need = to call them from other parts of the code? > --- a/src/test/regress/sql/sysviews.sql > +++ b/src/test/regress/sql/sysviews.sql > @@ -101,3 +101,8 @@ select count(distinct utc_offset) >=3D 24 as ok from = pg_timezone_abbrevs; > -- One specific case we can check without much fear of breakage > -- is the historical local-mean-time value used for America/Los_Angeles. > select * from pg_timezone_abbrevs where abbrev =3D 'LMT'; > + > +-- 5 core versions should be present: architecture, ICU, core, compiler = and > +-- glibc. If built with JIT support, one more record will be displayed > +-- containing LLVM version. > +select count(*) >=3D 5 as ok FROM pg_system_versions; If you really think that a regression test for selecting from the view is useful, use "SELECT EXISTS (TABLE pg_system_versions)". =20 Are you sure that the regression tests will always run with ICU enabled? Patch 0003: ----------- > --- a/src/backend/jit/jit.c > +++ b/src/backend/jit/jit.c > + > +/* > + * Return JIT provider's version string for troubleshooting purposes. > + */ > +const char * > +jit_get_version(bool *available) > +{ > + if (provider_init()) > + return provider.get_version(available); > + > + *available =3D false; > + return ""; > +} I think it would be better to do do the "available" dance here rather than delegating it to get_version(). get_version() can simply return NULL if th= ere is no version available. A more meaningful function comment would be "Callback for add_system_versio= n()". > +void > +jit_register_version(void) > +{ > + add_system_version("LLVM", jit_get_version, RunTime); > +} I think that should be in utils/misc/system_version.c. Then you don't need to #include "utils/system_version.h" in the JIT code. > --- a/src/include/jit/jit.h > +++ b/src/include/jit/jit.h > +/* > + * Get the provider's version string. The flag indicating availability i= s > + * passed as an argument, and will be set accordingly if it's not possib= le to > + * get the version. > + */ > +extern const char *jit_get_version(bool *available); Again, I think "Callback for add_system_version()" would be a more useful comment. I have no trouble guessing that the function will return the JIT version, and if you know add_system_version(), you know what "available" is= . Yours, Laurenz Albe