PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
function.c File Reference
#include "postgres_fe.h"
#include "access/transam.h"
#include "catalog/pg_language_d.h"
#include "common/int.h"
#include "pg_upgrade.h"
Include dependency graph for function.c:

Go to the source code of this file.

Data Structures

struct  loadable_libraries_state
 

Functions

static int library_name_compare (const void *p1, const void *p2)
 
static void process_loadable_libraries (DbInfo *dbinfo, PGresult *res, void *arg)
 
void get_loadable_libraries (void)
 
void check_loadable_libraries (void)
 

Function Documentation

◆ check_loadable_libraries()

void check_loadable_libraries ( void  )

Definition at line 165 of file function.c.

166{
167 PGconn *conn = connectToServer(&new_cluster, "template1");
168 int libnum;
169 int was_load_failure = false;
170 FILE *script = NULL;
171 char output_path[MAXPGPATH];
172
173 prep_status("Checking for presence of required libraries");
174
175 snprintf(output_path, sizeof(output_path), "%s/%s",
176 log_opts.basedir, "loadable_libraries.txt");
177
178 /*
179 * Now we want to sort the library names into order. This avoids multiple
180 * probes of the same library, and ensures that libraries are probed in a
181 * consistent order, which is important for reproducible behavior if one
182 * library depends on another.
183 */
186
187 for (libnum = 0; libnum < os_info.num_libraries; libnum++)
188 {
189 char *lib = os_info.libraries[libnum].name;
190 int llen = strlen(lib);
191 char cmd[7 + 2 * MAXPGPATH + 1];
192 PGresult *res;
193
194 /* Did the library name change? Probe it. */
195 if (libnum == 0 || strcmp(lib, os_info.libraries[libnum - 1].name) != 0)
196 {
197 strcpy(cmd, "LOAD '");
198 PQescapeStringConn(conn, cmd + strlen(cmd), lib, llen, NULL);
199 strcat(cmd, "'");
200
201 res = PQexec(conn, cmd);
202
204 {
205 was_load_failure = true;
206
207 if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
208 pg_fatal("could not open file \"%s\": %m", output_path);
209 fprintf(script, _("could not load library \"%s\": %s"),
210 lib,
212 }
213 else
214 was_load_failure = false;
215
216 PQclear(res);
217 }
218
219 if (was_load_failure)
220 fprintf(script, _("In database: %s\n"),
222 }
223
224 PQfinish(conn);
225
226 if (script)
227 {
228 fclose(script);
229 pg_log(PG_REPORT, "fatal");
230 pg_fatal("Your installation references loadable libraries that are missing from the\n"
231 "new installation. You can add these libraries to the new installation,\n"
232 "or remove the functions using them from the old installation. A list of\n"
233 "problem libraries is in the file:\n"
234 " %s", output_path);
235 }
236 else
237 check_ok();
238}
#define fprintf(file, fmt, msg)
Definition: cubescan.l:21
#define _(x)
Definition: elog.c:90
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4939
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:7268
size_t PQescapeStringConn(PGconn *conn, char *to, const char *from, size_t length, int *error)
Definition: fe-exec.c:4145
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3411
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:2262
static int library_name_compare(const void *p1, const void *p2)
Definition: function.c:29
static void check_ok(void)
Definition: initdb.c:2119
@ PGRES_COMMAND_OK
Definition: libpq-fe.h:120
#define pg_fatal(...)
#define MAXPGPATH
OSInfo os_info
Definition: pg_upgrade.c:69
ClusterInfo new_cluster
Definition: pg_upgrade.c:68
ClusterInfo old_cluster
Definition: pg_upgrade.c:67
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:28
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
LogOpts log_opts
Definition: util.c:17
#define fopen_priv(path, mode)
Definition: pg_upgrade.h:419
@ PG_REPORT
Definition: pg_upgrade.h:269
void prep_status(const char *fmt,...) pg_attribute_printf(1
#define snprintf
Definition: port.h:238
#define qsort(a, b, c, d)
Definition: port.h:474
PGconn * conn
Definition: streamutil.c:53
DbInfoArr dbarr
Definition: pg_upgrade.h:284
DbInfo * dbs
Definition: pg_upgrade.h:215
char * db_name
Definition: pg_upgrade.h:194
char * name
Definition: pg_upgrade.h:334
char * basedir
Definition: pg_upgrade.h:311
LibraryInfo * libraries
Definition: pg_upgrade.h:348
int num_libraries
Definition: pg_upgrade.h:349

References _, LogOpts::basedir, check_ok(), conn, connectToServer(), DbInfo::db_name, ClusterInfo::dbarr, LibraryInfo::dbnum, DbInfoArr::dbs, fopen_priv, fprintf, OSInfo::libraries, library_name_compare(), log_opts, MAXPGPATH, LibraryInfo::name, new_cluster, OSInfo::num_libraries, old_cluster, os_info, pg_fatal, pg_log(), PG_REPORT, PGRES_COMMAND_OK, PQclear(), PQerrorMessage(), PQescapeStringConn(), PQexec(), PQfinish(), PQresultStatus(), prep_status(), qsort, res, and snprintf.

Referenced by check_new_cluster().

◆ get_loadable_libraries()

void get_loadable_libraries ( void  )

Definition at line 79 of file function.c.

80{
81 int totaltups;
82 int dbnum;
83 int n_libinfos;
86 char *query;
87
88 state.ress = (PGresult **) pg_malloc(old_cluster.dbarr.ndbs * sizeof(PGresult *));
89 state.totaltups = 0;
90
91 query = psprintf("SELECT DISTINCT probin "
92 "FROM pg_catalog.pg_proc "
93 "WHERE prolang = %u AND "
94 "probin IS NOT NULL AND "
95 "oid >= %u",
96 ClanguageId,
98
100 false, &state);
101
103 upgrade_task_free(task);
104
105 /*
106 * Allocate memory for required libraries and logical replication output
107 * plugins.
108 */
109 n_libinfos = state.totaltups + count_old_cluster_logical_slots();
110 os_info.libraries = (LibraryInfo *) pg_malloc(sizeof(LibraryInfo) * n_libinfos);
111 totaltups = 0;
112
113 for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
114 {
115 PGresult *res = state.ress[dbnum];
116 int ntups;
117 int rowno;
118 LogicalSlotInfoArr *slot_arr = &old_cluster.dbarr.dbs[dbnum].slot_arr;
119
120 ntups = PQntuples(res);
121 for (rowno = 0; rowno < ntups; rowno++)
122 {
123 char *lib = PQgetvalue(res, rowno, 0);
124
127
128 totaltups++;
129 }
130 PQclear(res);
131
132 /*
133 * Store the names of output plugins as well. There is a possibility
134 * that duplicated plugins are set, but the consumer function
135 * check_loadable_libraries() will avoid checking the same library, so
136 * we do not have to consider their uniqueness here.
137 */
138 for (int slotno = 0; slotno < slot_arr->nslots; slotno++)
139 {
140 if (slot_arr->slots[slotno].invalid)
141 continue;
142
143 os_info.libraries[totaltups].name = pg_strdup(slot_arr->slots[slotno].plugin);
145
146 totaltups++;
147 }
148 }
149
150 pg_free(state.ress);
151 pg_free(query);
152
154}
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3876
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3481
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
void pg_free(void *ptr)
Definition: fe_memutils.c:105
static void process_loadable_libraries(DbInfo *dbinfo, PGresult *res, void *arg)
Definition: function.c:60
int count_old_cluster_logical_slots(void)
Definition: info.c:742
UpgradeTask * upgrade_task_create(void)
Definition: task.c:117
void upgrade_task_run(const UpgradeTask *task, const ClusterInfo *cluster)
Definition: task.c:420
void upgrade_task_free(UpgradeTask *task)
Definition: task.c:133
void upgrade_task_add_step(UpgradeTask *task, const char *query, UpgradeTaskProcessCB process_cb, bool free_result, void *arg)
Definition: task.c:151
char * psprintf(const char *fmt,...)
Definition: psprintf.c:43
LogicalSlotInfoArr slot_arr
Definition: pg_upgrade.h:198
LogicalSlotInfo * slots
Definition: pg_upgrade.h:169
Definition: regguts.h:323
#define FirstNormalObjectId
Definition: transam.h:197

References count_old_cluster_logical_slots(), ClusterInfo::dbarr, LibraryInfo::dbnum, DbInfoArr::dbs, FirstNormalObjectId, LogicalSlotInfo::invalid, OSInfo::libraries, LibraryInfo::name, DbInfoArr::ndbs, LogicalSlotInfoArr::nslots, OSInfo::num_libraries, old_cluster, os_info, pg_free(), pg_malloc(), pg_strdup(), LogicalSlotInfo::plugin, PQclear(), PQgetvalue(), PQntuples(), process_loadable_libraries(), psprintf(), res, DbInfo::slot_arr, LogicalSlotInfoArr::slots, loadable_libraries_state::totaltups, upgrade_task_add_step(), upgrade_task_create(), upgrade_task_free(), and upgrade_task_run().

Referenced by check_and_dump_old_cluster().

◆ library_name_compare()

static int library_name_compare ( const void *  p1,
const void *  p2 
)
static

Definition at line 29 of file function.c.

30{
31 const char *str1 = ((const LibraryInfo *) p1)->name;
32 const char *str2 = ((const LibraryInfo *) p2)->name;
33 size_t slen1 = strlen(str1);
34 size_t slen2 = strlen(str2);
35 int cmp = strcmp(str1, str2);
36
37 if (slen1 != slen2)
38 return pg_cmp_size(slen1, slen2);
39 if (cmp != 0)
40 return cmp;
41 return pg_cmp_s32(((const LibraryInfo *) p1)->dbnum,
42 ((const LibraryInfo *) p2)->dbnum);
43}
static int pg_cmp_s32(int32 a, int32 b)
Definition: int.h:646
static int pg_cmp_size(size_t a, size_t b)
Definition: int.h:670
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:743

References cmp(), p2, pg_cmp_s32(), and pg_cmp_size().

Referenced by check_loadable_libraries().

◆ process_loadable_libraries()

static void process_loadable_libraries ( DbInfo dbinfo,
PGresult res,
void *  arg 
)
static

Definition at line 60 of file function.c.

61{
63
65
67 state->totaltups += PQntuples(res);
68}
#define AssertVariableIsOfType(varname, typename)
Definition: c.h:938
void * arg
static struct LogicalRepInfo * dbinfo
void(* UpgradeTaskProcessCB)(DbInfo *dbinfo, PGresult *res, void *arg)
Definition: pg_upgrade.h:500

References arg, AssertVariableIsOfType, ClusterInfo::dbarr, dbinfo, DbInfoArr::dbs, old_cluster, PQntuples(), process_loadable_libraries(), and res.

Referenced by get_loadable_libraries(), and process_loadable_libraries().