mirror of
https://github.com/postgres/postgres.git
synced 2025-10-16 17:07:43 +03:00
Introduce frontend API able to retrieve the contents of PG_VERSION
get_pg_version() is able to return a version number, that can be used for comparisons based on PG_VERSION_NUM. A macro is added to convert the result to a major version number, to work with PG_MAJORVERSION_NUM. It is possible to pass to the routine an optional argument, where the contents retrieved from PG_VERSION are saved. This requirement matters for some of the frontend code (one example: pg_upgrade wants that for tablespace paths with a version number strictly older than v10). This will be used by a set of follow-up patches, to be consumed in various frontend tools that duplicate a logic similar to do what this new routine does, like: - pg_resetwal - pg_combinebackup - pg_createsubscriber - pg_upgrade This routine supports both the post-v10 version number and the older flavor (aka 9.6), as required at least by pg_upgrade. Author: Michael Paquier <michael@paquier.xyz> Reviewed-by: Masahiko Sawada <sawada.mshk@gmail.com> Discussion: https://postgr.es/m/aOiirvWJzwdVCXph@paquier.xyz
This commit is contained in:
@@ -37,7 +37,8 @@ OBJS = \
|
||||
query_utils.o \
|
||||
recovery_gen.o \
|
||||
simple_list.o \
|
||||
string_utils.o
|
||||
string_utils.o \
|
||||
version.o
|
||||
|
||||
ifeq ($(PORTNAME), win32)
|
||||
override CPPFLAGS += -DFD_SETSIZE=1024
|
||||
|
@@ -18,6 +18,7 @@ fe_utils_sources = files(
|
||||
'recovery_gen.c',
|
||||
'simple_list.c',
|
||||
'string_utils.c',
|
||||
'version.c',
|
||||
)
|
||||
|
||||
psqlscan = custom_target('psqlscan',
|
||||
|
86
src/fe_utils/version.c
Normal file
86
src/fe_utils/version.c
Normal file
@@ -0,0 +1,86 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* version.c
|
||||
* Routine to retrieve information of PG_VERSION
|
||||
*
|
||||
* Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* src/fe_utils/version.c
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "postgres_fe.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "common/logging.h"
|
||||
#include "fe_utils/version.h"
|
||||
|
||||
/*
|
||||
* Assumed maximum size of PG_VERSION. This should be more than enough for
|
||||
* any version numbers that need to be handled.
|
||||
*/
|
||||
#define PG_VERSION_MAX_SIZE 64
|
||||
|
||||
/*
|
||||
* get_pg_version
|
||||
*
|
||||
* Retrieve the major version number of the given data folder, from
|
||||
* PG_VERSION. The result returned is a version number, that can be used
|
||||
* for comparisons based on PG_VERSION_NUM. For example, if PG_VERSION
|
||||
* contains "18\n", this function returns 180000.
|
||||
*
|
||||
* This supports both the pre-v10 and the post-v10 version numbering.
|
||||
*
|
||||
* Optionally, "version_str" can be specified to store the contents
|
||||
* retrieved from PG_VERSION. It is allocated by this routine; the
|
||||
* caller is responsible for pg_free()-ing it.
|
||||
*/
|
||||
uint32
|
||||
get_pg_version(const char *datadir, char **version_str)
|
||||
{
|
||||
FILE *version_fd;
|
||||
char ver_filename[MAXPGPATH];
|
||||
char buf[PG_VERSION_MAX_SIZE];
|
||||
int v1 = 0,
|
||||
v2 = 0;
|
||||
struct stat st;
|
||||
|
||||
snprintf(ver_filename, sizeof(ver_filename), "%s/PG_VERSION",
|
||||
datadir);
|
||||
|
||||
if ((version_fd = fopen(ver_filename, "r")) == NULL)
|
||||
pg_fatal("could not open version file \"%s\": %m", ver_filename);
|
||||
|
||||
if (fstat(fileno(version_fd), &st) != 0)
|
||||
pg_fatal("could not stat file \"%s\": %m", ver_filename);
|
||||
if (st.st_size > PG_VERSION_MAX_SIZE)
|
||||
pg_fatal("file \"%s\" is too large", ver_filename);
|
||||
|
||||
if (fscanf(version_fd, "%63s", buf) == 0 ||
|
||||
sscanf(buf, "%d.%d", &v1, &v2) < 1)
|
||||
pg_fatal("could not parse version file \"%s\"", ver_filename);
|
||||
|
||||
fclose(version_fd);
|
||||
|
||||
if (version_str)
|
||||
{
|
||||
*version_str = pg_malloc(PG_VERSION_MAX_SIZE);
|
||||
memcpy(*version_str, buf, st.st_size);
|
||||
}
|
||||
|
||||
if (v1 < 10)
|
||||
{
|
||||
/* pre-v10 style, e.g. 9.6.1 */
|
||||
return v1 * 10000 + v2 * 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* post-v10 style, e.g. 10.1 */
|
||||
return v1 * 10000;
|
||||
}
|
||||
}
|
23
src/include/fe_utils/version.h
Normal file
23
src/include/fe_utils/version.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* Routines to retrieve information of PG_VERSION
|
||||
*
|
||||
* Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* src/include/fe_utils/version.h
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef PG_VERSION_H
|
||||
#define PG_VERSION_H
|
||||
|
||||
/*
|
||||
* Retrieve the version major number, useful for major version checks
|
||||
* based on PG_MAJORVERSION_NUM.
|
||||
*/
|
||||
#define GET_PG_MAJORVERSION_NUM(v) ((v) / 10000)
|
||||
|
||||
extern uint32 get_pg_version(const char *datadir, char **version_str);
|
||||
|
||||
#endif /* PG_VERSION_H */
|
Reference in New Issue
Block a user