mirror of https://github.com/postgres/postgres
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.xyzpull/245/head
parent
1c05fe11ab
commit
cd0be131ba
@ -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; |
||||||
|
} |
||||||
|
} |
||||||
@ -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 */ |
||||||
Loading…
Reference in new issue