Mark all GUC variable as PGDLLIMPORT
Hi,
I've been pinged many time over the years to either fix Windows compatibility
or provide DLL for multiple extensions I'm maintaining. I've finally taken
some time to setup a Windows build environment so I could take care of most of
the problem, but not all (at least not in a satisfactory way).
I've also been looking a bit around other extensions and I see that the #1
problem with compiling extensions on Windows is the lack of PGDLLIMPORT
annotations, which is 99% of the time for a GUC.
This topic has been raised multiple time over the years, and I don't see any
objection to add such an annotation at least for all GUC variables (either the
direct variables or the indirect variables set during the hook execution), so
PFA a patch that takes care of all the GUC.
I don't now if that's still an option at that point, but backporting to at
least pg14 if that patch is accepted would be quite helpful.
Attachments:
v1-0001-Add-PGDLLIMPORT-to-all-direct-or-indirect-GUC-var.patchtext/x-diff; charset=us-asciiDownload
From 10af6e965ace671aad13cae47ee1b475ac24f15a Mon Sep 17 00:00:00 2001
From: Julien Rouhaud <julien.rouhaud@free.fr>
Date: Sun, 22 Aug 2021 15:40:47 +0800
Subject: [PATCH v1] Add PGDLLIMPORT to all direct or indirect GUC variables
---
src/backend/utils/misc/guc.c | 18 +++---
src/include/access/gin.h | 2 +-
src/include/access/tableam.h | 4 +-
src/include/access/toast_compression.h | 2 +-
src/include/access/xact.h | 12 ++--
src/include/access/xlog.h | 78 +++++++++++------------
src/include/catalog/namespace.h | 2 +-
src/include/catalog/storage.h | 2 +-
src/include/commands/async.h | 2 +-
src/include/commands/user.h | 2 +-
src/include/commands/vacuum.h | 12 ++--
src/include/fmgr.h | 2 +-
src/include/jit/jit.h | 20 +++---
src/include/libpq/auth.h | 4 +-
src/include/libpq/libpq.h | 24 +++----
src/include/libpq/pqcomm.h | 2 +-
src/include/miscadmin.h | 22 +++----
src/include/optimizer/geqo.h | 10 +--
src/include/optimizer/optimizer.h | 4 +-
src/include/optimizer/planmain.h | 6 +-
src/include/parser/parse_expr.h | 2 +-
src/include/parser/parser.h | 4 +-
src/include/pgstat.h | 6 +-
src/include/pgtime.h | 2 +-
src/include/postmaster/autovacuum.h | 30 ++++-----
src/include/postmaster/bgwriter.h | 8 +--
src/include/postmaster/postmaster.h | 28 ++++----
src/include/postmaster/syslogger.h | 10 +--
src/include/postmaster/walwriter.h | 4 +-
src/include/replication/logicallauncher.h | 4 +-
src/include/replication/syncrep.h | 2 +-
src/include/replication/walreceiver.h | 6 +-
src/include/replication/walsender.h | 6 +-
src/include/storage/bufmgr.h | 20 +++---
src/include/storage/dsm_impl.h | 4 +-
src/include/storage/fd.h | 2 +-
src/include/storage/large_object.h | 2 +-
src/include/storage/lock.h | 12 ++--
src/include/storage/lwlock.h | 2 +-
src/include/storage/pg_shmem.h | 6 +-
src/include/storage/predicate.h | 6 +-
src/include/storage/proc.h | 2 +-
src/include/storage/standby.h | 8 +--
src/include/tcop/tcopprot.h | 6 +-
src/include/tsearch/ts_cache.h | 2 +-
src/include/utils/array.h | 2 +-
src/include/utils/builtins.h | 2 +-
src/include/utils/bytea.h | 2 +-
src/include/utils/elog.h | 10 +--
src/include/utils/guc.h | 62 +++++++++---------
src/include/utils/pg_locale.h | 8 +--
src/include/utils/plancache.h | 2 +-
src/include/utils/ps_status.h | 2 +-
src/include/utils/queryjumble.h | 2 +-
src/include/utils/rls.h | 2 +-
src/include/utils/xml.h | 4 +-
56 files changed, 256 insertions(+), 256 deletions(-)
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index a2e0f8de7e..145aeed94b 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -129,20 +129,20 @@
#define REALTYPE_PRECISION 17
/* XXX these should appear in other modules' header files */
-extern bool Log_disconnections;
-extern int CommitDelay;
-extern int CommitSiblings;
-extern char *default_tablespace;
-extern char *temp_tablespaces;
-extern bool ignore_checksum_failure;
-extern bool ignore_invalid_pages;
+extern PGDLLIMPORT bool Log_disconnections;
+extern PGDLLIMPORT int CommitDelay;
+extern PGDLLIMPORT int CommitSiblings;
+extern PGDLLIMPORT char *default_tablespace;
+extern PGDLLIMPORT char *temp_tablespaces;
+extern PGDLLIMPORT bool ignore_checksum_failure;
+extern PGDLLIMPORT bool ignore_invalid_pages;
extern bool synchronize_seqscans;
#ifdef TRACE_SYNCSCAN
-extern bool trace_syncscan;
+extern PGDLLIMPORT bool trace_syncscan;
#endif
#ifdef DEBUG_BOUNDED_SORT
-extern bool optimize_bounded_sort;
+extern PGDLLIMPORT bool optimize_bounded_sort;
#endif
static int GUC_check_errcode_value;
diff --git a/src/include/access/gin.h b/src/include/access/gin.h
index 266cb07236..893cf57bc1 100644
--- a/src/include/access/gin.h
+++ b/src/include/access/gin.h
@@ -68,7 +68,7 @@ typedef char GinTernaryValue;
/* GUC parameters */
extern PGDLLIMPORT int GinFuzzySearchLimit;
-extern int gin_pending_list_limit;
+extern PGDLLIMPORT int gin_pending_list_limit;
/* ginutil.c */
extern void ginGetStats(Relation index, GinStatsData *stats);
diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h
index 9f1e4a1ac9..1d8646b080 100644
--- a/src/include/access/tableam.h
+++ b/src/include/access/tableam.h
@@ -28,8 +28,8 @@
#define DEFAULT_TABLE_ACCESS_METHOD "heap"
/* GUCs */
-extern char *default_table_access_method;
-extern bool synchronize_seqscans;
+extern PGDLLIMPORT char *default_table_access_method;
+extern PGDLLIMPORT bool synchronize_seqscans;
struct BulkInsertStateData;
diff --git a/src/include/access/toast_compression.h b/src/include/access/toast_compression.h
index c992ece4c4..efc218087b 100644
--- a/src/include/access/toast_compression.h
+++ b/src/include/access/toast_compression.h
@@ -20,7 +20,7 @@
* but the value is one of the char values defined below, as they appear in
* pg_attribute.attcompression, e.g. TOAST_PGLZ_COMPRESSION.
*/
-extern int default_toast_compression;
+extern PGDLLIMPORT int default_toast_compression;
/*
* Built-in compression method ID. The toast compression header will store
diff --git a/src/include/access/xact.h b/src/include/access/xact.h
index 134f6862da..00511dcb63 100644
--- a/src/include/access/xact.h
+++ b/src/include/access/xact.h
@@ -38,7 +38,7 @@
#define XACT_REPEATABLE_READ 2
#define XACT_SERIALIZABLE 3
-extern int DefaultXactIsoLevel;
+extern PGDLLIMPORT int DefaultXactIsoLevel;
extern PGDLLIMPORT int XactIsoLevel;
/*
@@ -52,8 +52,8 @@ extern PGDLLIMPORT int XactIsoLevel;
#define IsolationIsSerializable() (XactIsoLevel == XACT_SERIALIZABLE)
/* Xact read-only state */
-extern bool DefaultXactReadOnly;
-extern bool XactReadOnly;
+extern PGDLLIMPORT bool DefaultXactReadOnly;
+extern PGDLLIMPORT bool XactReadOnly;
/* flag for logging statements in this transaction */
extern bool xact_is_sampled;
@@ -62,8 +62,8 @@ extern bool xact_is_sampled;
* Xact is deferrable -- only meaningful (currently) for read only
* SERIALIZABLE transactions
*/
-extern bool DefaultXactDeferrable;
-extern bool XactDeferrable;
+extern PGDLLIMPORT bool DefaultXactDeferrable;
+extern PGDLLIMPORT bool XactDeferrable;
typedef enum
{
@@ -80,7 +80,7 @@ typedef enum
#define SYNCHRONOUS_COMMIT_ON SYNCHRONOUS_COMMIT_REMOTE_FLUSH
/* Synchronous commit level */
-extern int synchronous_commit;
+extern PGDLLIMPORT int synchronous_commit;
/* used during logical streaming of a transaction */
extern PGDLLIMPORT TransactionId CheckXidAlive;
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index 0a8ede700d..d2ee540b08 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -27,7 +27,7 @@
#define SYNC_METHOD_OPEN 2 /* for O_SYNC */
#define SYNC_METHOD_FSYNC_WRITETHROUGH 3
#define SYNC_METHOD_OPEN_DSYNC 4 /* for O_DSYNC */
-extern int sync_method;
+extern PGDLLIMPORT int sync_method;
extern PGDLLIMPORT TimeLineID ThisTimeLineID; /* current TLI */
@@ -62,45 +62,45 @@ extern PGDLLIMPORT XLogRecPtr XactLastCommitEnd;
extern bool reachedConsistency;
/* these variables are GUC parameters related to XLOG */
-extern int wal_segment_size;
-extern int min_wal_size_mb;
-extern int max_wal_size_mb;
-extern int wal_keep_size_mb;
-extern int max_slot_wal_keep_size_mb;
-extern int XLOGbuffers;
-extern int XLogArchiveTimeout;
-extern int wal_retrieve_retry_interval;
-extern char *XLogArchiveCommand;
-extern bool EnableHotStandby;
-extern bool fullPageWrites;
-extern bool wal_log_hints;
-extern int wal_compression;
-extern bool wal_init_zero;
-extern bool wal_recycle;
+extern PGDLLIMPORT int wal_segment_size;
+extern PGDLLIMPORT int min_wal_size_mb;
+extern PGDLLIMPORT int max_wal_size_mb;
+extern PGDLLIMPORT int wal_keep_size_mb;
+extern PGDLLIMPORT int max_slot_wal_keep_size_mb;
+extern PGDLLIMPORT int XLOGbuffers;
+extern PGDLLIMPORT int XLogArchiveTimeout;
+extern PGDLLIMPORT int wal_retrieve_retry_interval;
+extern PGDLLIMPORT char *XLogArchiveCommand;
+extern PGDLLIMPORT bool EnableHotStandby;
+extern PGDLLIMPORT bool fullPageWrites;
+extern PGDLLIMPORT bool wal_log_hints;
+extern PGDLLIMPORT int wal_compression;
+extern PGDLLIMPORT bool wal_init_zero;
+extern PGDLLIMPORT bool wal_recycle;
extern bool *wal_consistency_checking;
-extern char *wal_consistency_checking_string;
-extern bool log_checkpoints;
-extern char *recoveryRestoreCommand;
-extern char *recoveryEndCommand;
-extern char *archiveCleanupCommand;
-extern bool recoveryTargetInclusive;
-extern int recoveryTargetAction;
-extern int recovery_min_apply_delay;
-extern char *PrimaryConnInfo;
-extern char *PrimarySlotName;
-extern bool wal_receiver_create_temp_slot;
-extern bool track_wal_io_timing;
+extern PGDLLIMPORT char *wal_consistency_checking_string;
+extern PGDLLIMPORT bool log_checkpoints;
+extern PGDLLIMPORT char *recoveryRestoreCommand;
+extern PGDLLIMPORT char *recoveryEndCommand;
+extern PGDLLIMPORT char *archiveCleanupCommand;
+extern PGDLLIMPORT bool recoveryTargetInclusive;
+extern PGDLLIMPORT int recoveryTargetAction;
+extern PGDLLIMPORT int recovery_min_apply_delay;
+extern PGDLLIMPORT char *PrimaryConnInfo;
+extern PGDLLIMPORT char *PrimarySlotName;
+extern PGDLLIMPORT bool wal_receiver_create_temp_slot;
+extern PGDLLIMPORT bool track_wal_io_timing;
/* indirectly set via GUC system */
-extern TransactionId recoveryTargetXid;
-extern char *recovery_target_time_string;
-extern const char *recoveryTargetName;
-extern XLogRecPtr recoveryTargetLSN;
-extern RecoveryTargetType recoveryTarget;
-extern char *PromoteTriggerFile;
-extern RecoveryTargetTimeLineGoal recoveryTargetTimeLineGoal;
-extern TimeLineID recoveryTargetTLIRequested;
-extern TimeLineID recoveryTargetTLI;
+extern PGDLLIMPORT TransactionId recoveryTargetXid;
+extern PGDLLIMPORT char *recovery_target_time_string;
+extern PGDLLIMPORT const char *recoveryTargetName;
+extern PGDLLIMPORT XLogRecPtr recoveryTargetLSN;
+extern PGDLLIMPORT RecoveryTargetType recoveryTarget;
+extern PGDLLIMPORT char *PromoteTriggerFile;
+extern PGDLLIMPORT RecoveryTargetTimeLineGoal recoveryTargetTimeLineGoal;
+extern PGDLLIMPORT TimeLineID recoveryTargetTLIRequested;
+extern PGDLLIMPORT TimeLineID recoveryTargetTLI;
extern int CheckPointSegments;
@@ -115,7 +115,7 @@ typedef enum ArchiveMode
ARCHIVE_MODE_ON, /* enabled while server is running normally */
ARCHIVE_MODE_ALWAYS /* enabled always (even during recovery) */
} ArchiveMode;
-extern int XLogArchiveMode;
+extern PGDLLIMPORT int XLogArchiveMode;
/* WAL levels */
typedef enum WalLevel
@@ -183,7 +183,7 @@ extern PGDLLIMPORT int wal_level;
#define XLogLogicalInfoActive() (wal_level >= WAL_LEVEL_LOGICAL)
#ifdef WAL_DEBUG
-extern bool XLOG_DEBUG;
+extern PGDLLIMPORT bool XLOG_DEBUG;
#endif
/*
diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h
index b98f284356..f72956dfa9 100644
--- a/src/include/catalog/namespace.h
+++ b/src/include/catalog/namespace.h
@@ -182,7 +182,7 @@ extern void AtEOSubXact_Namespace(bool isCommit, SubTransactionId mySubid,
SubTransactionId parentSubid);
/* stuff for search_path GUC variable */
-extern char *namespace_search_path;
+extern PGDLLIMPORT char *namespace_search_path;
extern List *fetch_search_path(bool includeImplicit);
extern int fetch_search_path_array(Oid *sarray, int sarray_len);
diff --git a/src/include/catalog/storage.h b/src/include/catalog/storage.h
index 0ab32b44e9..b6dbdbc8a5 100644
--- a/src/include/catalog/storage.h
+++ b/src/include/catalog/storage.h
@@ -20,7 +20,7 @@
#include "utils/relcache.h"
/* GUC variables */
-extern int wal_skip_threshold;
+extern PGDLLIMPORT int wal_skip_threshold;
extern SMgrRelation RelationCreateStorage(RelFileNode rnode, char relpersistence);
extern void RelationDropStorage(Relation rel);
diff --git a/src/include/commands/async.h b/src/include/commands/async.h
index 9217f66b91..88f2d206d2 100644
--- a/src/include/commands/async.h
+++ b/src/include/commands/async.h
@@ -20,7 +20,7 @@
*/
#define NUM_NOTIFY_BUFFERS 8
-extern bool Trace_notify;
+extern PGDLLIMPORT bool Trace_notify;
extern volatile sig_atomic_t notifyInterruptPending;
extern Size AsyncShmemSize(void);
diff --git a/src/include/commands/user.h b/src/include/commands/user.h
index 0b7a3cd65f..d5159f3fe5 100644
--- a/src/include/commands/user.h
+++ b/src/include/commands/user.h
@@ -17,7 +17,7 @@
#include "parser/parse_node.h"
/* GUC. Is actually of type PasswordType. */
-extern int Password_encryption;
+extern PGDLLIMPORT int Password_encryption;
/* Hook to check passwords in CreateRole() and AlterRole() */
typedef void (*check_password_hook_type) (const char *username, const char *shadow_pass, PasswordType password_type, Datum validuntil_time, bool validuntil_null);
diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h
index bf3126aa9b..4f682afbb1 100644
--- a/src/include/commands/vacuum.h
+++ b/src/include/commands/vacuum.h
@@ -232,12 +232,12 @@ typedef struct VacuumParams
/* GUC parameters */
extern PGDLLIMPORT int default_statistics_target; /* PGDLLIMPORT for PostGIS */
-extern int vacuum_freeze_min_age;
-extern int vacuum_freeze_table_age;
-extern int vacuum_multixact_freeze_min_age;
-extern int vacuum_multixact_freeze_table_age;
-extern int vacuum_failsafe_age;
-extern int vacuum_multixact_failsafe_age;
+extern PGDLLIMPORT int vacuum_freeze_min_age;
+extern PGDLLIMPORT int vacuum_freeze_table_age;
+extern PGDLLIMPORT int vacuum_multixact_freeze_min_age;
+extern PGDLLIMPORT int vacuum_multixact_freeze_table_age;
+extern PGDLLIMPORT int vacuum_failsafe_age;
+extern PGDLLIMPORT int vacuum_multixact_failsafe_age;
/* Variables for cost-based parallel vacuum */
extern pg_atomic_uint32 *VacuumSharedCostBalance;
diff --git a/src/include/fmgr.h b/src/include/fmgr.h
index ab7b85c86e..d394c4afa2 100644
--- a/src/include/fmgr.h
+++ b/src/include/fmgr.h
@@ -716,7 +716,7 @@ extern bool CheckFunctionValidatorAccess(Oid validatorOid, Oid functionOid);
/*
* Routines in dfmgr.c
*/
-extern char *Dynamic_library_path;
+extern PGDLLIMPORT char *Dynamic_library_path;
extern void *load_external_function(const char *filename, const char *funcname,
bool signalNotFound, void **filehandle);
diff --git a/src/include/jit/jit.h b/src/include/jit/jit.h
index b634df30b9..7730a77aef 100644
--- a/src/include/jit/jit.h
+++ b/src/include/jit/jit.h
@@ -79,16 +79,16 @@ struct JitProviderCallbacks
/* GUCs */
-extern bool jit_enabled;
-extern char *jit_provider;
-extern bool jit_debugging_support;
-extern bool jit_dump_bitcode;
-extern bool jit_expressions;
-extern bool jit_profiling_support;
-extern bool jit_tuple_deforming;
-extern double jit_above_cost;
-extern double jit_inline_above_cost;
-extern double jit_optimize_above_cost;
+extern PGDLLIMPORT bool jit_enabled;
+extern PGDLLIMPORT char *jit_provider;
+extern PGDLLIMPORT bool jit_debugging_support;
+extern PGDLLIMPORT bool jit_dump_bitcode;
+extern PGDLLIMPORT bool jit_expressions;
+extern PGDLLIMPORT bool jit_profiling_support;
+extern PGDLLIMPORT bool jit_tuple_deforming;
+extern PGDLLIMPORT double jit_above_cost;
+extern PGDLLIMPORT double jit_inline_above_cost;
+extern PGDLLIMPORT double jit_optimize_above_cost;
extern void jit_reset_after_error(void);
diff --git a/src/include/libpq/auth.h b/src/include/libpq/auth.h
index 3d6734f253..34bec0c91a 100644
--- a/src/include/libpq/auth.h
+++ b/src/include/libpq/auth.h
@@ -16,8 +16,8 @@
#include "libpq/libpq-be.h"
-extern char *pg_krb_server_keyfile;
-extern bool pg_krb_caseins_users;
+extern PGDLLIMPORT char *pg_krb_server_keyfile;
+extern PGDLLIMPORT bool pg_krb_caseins_users;
extern char *pg_krb_realm;
extern void ClientAuthentication(Port *port);
diff --git a/src/include/libpq/libpq.h b/src/include/libpq/libpq.h
index 6c51b2f20f..b4dbd909f5 100644
--- a/src/include/libpq/libpq.h
+++ b/src/include/libpq/libpq.h
@@ -85,13 +85,13 @@ extern bool pq_check_connection(void);
/*
* prototypes for functions in be-secure.c
*/
-extern char *ssl_library;
-extern char *ssl_cert_file;
-extern char *ssl_key_file;
-extern char *ssl_ca_file;
-extern char *ssl_crl_file;
-extern char *ssl_crl_dir;
-extern char *ssl_dh_params_file;
+extern PGDLLIMPORT char *ssl_library;
+extern PGDLLIMPORT char *ssl_cert_file;
+extern PGDLLIMPORT char *ssl_key_file;
+extern PGDLLIMPORT char *ssl_ca_file;
+extern PGDLLIMPORT char *ssl_crl_file;
+extern PGDLLIMPORT char *ssl_crl_dir;
+extern PGDLLIMPORT char *ssl_dh_params_file;
extern PGDLLIMPORT char *ssl_passphrase_command;
extern PGDLLIMPORT bool ssl_passphrase_command_supports_reload;
#ifdef USE_SSL
@@ -116,11 +116,11 @@ extern ssize_t secure_open_gssapi(Port *port);
#endif
/* GUCs */
-extern char *SSLCipherSuites;
-extern char *SSLECDHCurve;
-extern bool SSLPreferServerCiphers;
-extern int ssl_min_protocol_version;
-extern int ssl_max_protocol_version;
+extern PGDLLIMPORT char *SSLCipherSuites;
+extern PGDLLIMPORT char *SSLECDHCurve;
+extern PGDLLIMPORT bool SSLPreferServerCiphers;
+extern PGDLLIMPORT int ssl_min_protocol_version;
+extern PGDLLIMPORT int ssl_max_protocol_version;
enum ssl_protocol_versions
{
diff --git a/src/include/libpq/pqcomm.h b/src/include/libpq/pqcomm.h
index be9d970574..64687c37b0 100644
--- a/src/include/libpq/pqcomm.h
+++ b/src/include/libpq/pqcomm.h
@@ -135,7 +135,7 @@ typedef ProtocolVersion MsgType;
typedef uint32 PacketLen;
-extern bool Db_user_namespace;
+extern PGDLLIMPORT bool Db_user_namespace;
/*
* In protocol 3.0 and later, the startup packet length is not fixed, but
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index 2e2e9a364a..7d6f164037 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -255,18 +255,18 @@ extern PGDLLIMPORT int IntervalStyle;
#define MAXTZLEN 10 /* max TZ name len, not counting tr. null */
-extern bool enableFsync;
+extern PGDLLIMPORT bool enableFsync;
extern PGDLLIMPORT bool allowSystemTableMods;
extern PGDLLIMPORT int work_mem;
extern PGDLLIMPORT double hash_mem_multiplier;
extern PGDLLIMPORT int maintenance_work_mem;
extern PGDLLIMPORT int max_parallel_maintenance_workers;
-extern int VacuumCostPageHit;
-extern int VacuumCostPageMiss;
-extern int VacuumCostPageDirty;
-extern int VacuumCostLimit;
-extern double VacuumCostDelay;
+extern PGDLLIMPORT int VacuumCostPageHit;
+extern PGDLLIMPORT int VacuumCostPageMiss;
+extern PGDLLIMPORT int VacuumCostPageDirty;
+extern PGDLLIMPORT int VacuumCostLimit;
+extern PGDLLIMPORT double VacuumCostDelay;
extern int64 VacuumPageHit;
extern int64 VacuumPageMiss;
@@ -299,7 +299,7 @@ extern void PreventCommandIfParallelMode(const char *cmdname);
extern void PreventCommandDuringRecovery(const char *cmdname);
/* in utils/misc/guc.c */
-extern int trace_recovery_messages;
+extern PGDLLIMPORT int trace_recovery_messages;
extern int trace_recovery(int trace_level);
/*****************************************************************************
@@ -460,11 +460,11 @@ extern void InitPostgres(const char *in_dbname, Oid dboid, const char *username,
extern void BaseInit(void);
/* in utils/init/miscinit.c */
-extern bool IgnoreSystemIndexes;
+extern PGDLLIMPORT bool IgnoreSystemIndexes;
extern PGDLLIMPORT bool process_shared_preload_libraries_in_progress;
-extern char *session_preload_libraries_string;
-extern char *shared_preload_libraries_string;
-extern char *local_preload_libraries_string;
+extern PGDLLIMPORT char *session_preload_libraries_string;
+extern PGDLLIMPORT char *shared_preload_libraries_string;
+extern PGDLLIMPORT char *local_preload_libraries_string;
extern void CreateDataDirLockFile(bool amPostmaster);
extern void CreateSocketLockFile(const char *socketfile, bool amPostmaster,
diff --git a/src/include/optimizer/geqo.h b/src/include/optimizer/geqo.h
index 24dcdfb6cc..dd548232cf 100644
--- a/src/include/optimizer/geqo.h
+++ b/src/include/optimizer/geqo.h
@@ -48,23 +48,23 @@
*
* If you change these, update backend/utils/misc/postgresql.conf.sample
*/
-extern int Geqo_effort; /* 1 .. 10, knob for adjustment of defaults */
+extern PGDLLIMPORT int Geqo_effort; /* 1 .. 10, knob for adjustment of defaults */
#define DEFAULT_GEQO_EFFORT 5
#define MIN_GEQO_EFFORT 1
#define MAX_GEQO_EFFORT 10
-extern int Geqo_pool_size; /* 2 .. inf, or 0 to use default */
+extern PGDLLIMPORT int Geqo_pool_size; /* 2 .. inf, or 0 to use default */
-extern int Geqo_generations; /* 1 .. inf, or 0 to use default */
+extern PGDLLIMPORT int Geqo_generations; /* 1 .. inf, or 0 to use default */
-extern double Geqo_selection_bias;
+extern PGDLLIMPORT double Geqo_selection_bias;
#define DEFAULT_GEQO_SELECTION_BIAS 2.0
#define MIN_GEQO_SELECTION_BIAS 1.5
#define MAX_GEQO_SELECTION_BIAS 2.0
-extern double Geqo_seed; /* 0 .. 1 */
+extern PGDLLIMPORT double Geqo_seed; /* 0 .. 1 */
/*
diff --git a/src/include/optimizer/optimizer.h b/src/include/optimizer/optimizer.h
index 41b49b2662..db259f7d7a 100644
--- a/src/include/optimizer/optimizer.h
+++ b/src/include/optimizer/optimizer.h
@@ -111,8 +111,8 @@ typedef enum
} ForceParallelMode;
/* GUC parameters */
-extern int force_parallel_mode;
-extern bool parallel_leader_participation;
+extern PGDLLIMPORT int force_parallel_mode;
+extern PGDLLIMPORT bool parallel_leader_participation;
extern struct PlannedStmt *planner(Query *parse, const char *query_string,
int cursorOptions,
diff --git a/src/include/optimizer/planmain.h b/src/include/optimizer/planmain.h
index bf1adfc52a..4c622bbda9 100644
--- a/src/include/optimizer/planmain.h
+++ b/src/include/optimizer/planmain.h
@@ -19,7 +19,7 @@
/* GUC parameters */
#define DEFAULT_CURSOR_TUPLE_FRACTION 0.1
-extern double cursor_tuple_fraction;
+extern PGDLLIMPORT double cursor_tuple_fraction;
/* query_planner callback to compute query_pathkeys */
typedef void (*query_pathkeys_callback) (PlannerInfo *root, void *extra);
@@ -64,8 +64,8 @@ extern Limit *make_limit(Plan *lefttree, Node *limitOffset, Node *limitCount,
/*
* prototypes for plan/initsplan.c
*/
-extern int from_collapse_limit;
-extern int join_collapse_limit;
+extern PGDLLIMPORT int from_collapse_limit;
+extern PGDLLIMPORT int join_collapse_limit;
extern void add_base_rels_to_query(PlannerInfo *root, Node *jtnode);
extern void add_other_rels_to_query(PlannerInfo *root);
diff --git a/src/include/parser/parse_expr.h b/src/include/parser/parse_expr.h
index 8ac4a0a369..903aaaf1ec 100644
--- a/src/include/parser/parse_expr.h
+++ b/src/include/parser/parse_expr.h
@@ -16,7 +16,7 @@
#include "parser/parse_node.h"
/* GUC parameters */
-extern bool Transform_null_equals;
+extern PGDLLIMPORT bool Transform_null_equals;
extern Node *transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind);
diff --git a/src/include/parser/parser.h b/src/include/parser/parser.h
index 853b0f1606..2c7c315266 100644
--- a/src/include/parser/parser.h
+++ b/src/include/parser/parser.h
@@ -53,8 +53,8 @@ typedef enum
} BackslashQuoteType;
/* GUC variables in scan.l (every one of these is a bad idea :-() */
-extern int backslash_quote;
-extern bool escape_string_warning;
+extern PGDLLIMPORT int backslash_quote;
+extern PGDLLIMPORT bool escape_string_warning;
extern PGDLLIMPORT bool standard_conforming_strings;
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 509849c7ff..36e0cfa56f 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -940,9 +940,9 @@ typedef struct PgStat_FunctionCallUsage
*/
extern PGDLLIMPORT bool pgstat_track_counts;
extern PGDLLIMPORT int pgstat_track_functions;
-extern char *pgstat_stat_directory;
-extern char *pgstat_stat_tmpname;
-extern char *pgstat_stat_filename;
+extern PGDLLIMPORT char *pgstat_stat_directory;
+extern PGDLLIMPORT char *pgstat_stat_tmpname;
+extern PGDLLIMPORT char *pgstat_stat_filename;
/*
* BgWriter statistics counters are updated directly by bgwriter and bufmgr
diff --git a/src/include/pgtime.h b/src/include/pgtime.h
index 28bd27e7f7..8ec68fd5f2 100644
--- a/src/include/pgtime.h
+++ b/src/include/pgtime.h
@@ -71,7 +71,7 @@ extern size_t pg_strftime(char *s, size_t max, const char *format,
/* these functions and variables are in pgtz.c */
extern PGDLLIMPORT pg_tz *session_timezone;
-extern pg_tz *log_timezone;
+extern PGDLLIMPORT pg_tz *log_timezone;
extern void pg_timezone_initialize(void);
extern pg_tz *pg_tzset(const char *tzname);
diff --git a/src/include/postmaster/autovacuum.h b/src/include/postmaster/autovacuum.h
index aacdd0f575..9f067dfeac 100644
--- a/src/include/postmaster/autovacuum.h
+++ b/src/include/postmaster/autovacuum.h
@@ -27,25 +27,25 @@ typedef enum
/* GUC variables */
-extern bool autovacuum_start_daemon;
-extern int autovacuum_max_workers;
-extern int autovacuum_work_mem;
-extern int autovacuum_naptime;
-extern int autovacuum_vac_thresh;
-extern double autovacuum_vac_scale;
-extern int autovacuum_vac_ins_thresh;
-extern double autovacuum_vac_ins_scale;
-extern int autovacuum_anl_thresh;
-extern double autovacuum_anl_scale;
-extern int autovacuum_freeze_max_age;
-extern int autovacuum_multixact_freeze_max_age;
-extern double autovacuum_vac_cost_delay;
-extern int autovacuum_vac_cost_limit;
+extern PGDLLIMPORT bool autovacuum_start_daemon;
+extern PGDLLIMPORT int autovacuum_max_workers;
+extern PGDLLIMPORT int autovacuum_work_mem;
+extern PGDLLIMPORT int autovacuum_naptime;
+extern PGDLLIMPORT int autovacuum_vac_thresh;
+extern PGDLLIMPORT double autovacuum_vac_scale;
+extern PGDLLIMPORT int autovacuum_vac_ins_thresh;
+extern PGDLLIMPORT double autovacuum_vac_ins_scale;
+extern PGDLLIMPORT int autovacuum_anl_thresh;
+extern PGDLLIMPORT double autovacuum_anl_scale;
+extern PGDLLIMPORT int autovacuum_freeze_max_age;
+extern PGDLLIMPORT int autovacuum_multixact_freeze_max_age;
+extern PGDLLIMPORT double autovacuum_vac_cost_delay;
+extern PGDLLIMPORT int autovacuum_vac_cost_limit;
/* autovacuum launcher PID, only valid when worker is shutting down */
extern int AutovacuumLauncherPid;
-extern int Log_autovacuum_min_duration;
+extern PGDLLIMPORT int Log_autovacuum_min_duration;
/* Status inquiry functions */
extern bool AutoVacuumingActive(void);
diff --git a/src/include/postmaster/bgwriter.h b/src/include/postmaster/bgwriter.h
index c430b1b236..7089a2682c 100644
--- a/src/include/postmaster/bgwriter.h
+++ b/src/include/postmaster/bgwriter.h
@@ -22,10 +22,10 @@
/* GUC options */
-extern int BgWriterDelay;
-extern int CheckPointTimeout;
-extern int CheckPointWarning;
-extern double CheckPointCompletionTarget;
+extern PGDLLIMPORT int BgWriterDelay;
+extern PGDLLIMPORT int CheckPointTimeout;
+extern PGDLLIMPORT int CheckPointWarning;
+extern PGDLLIMPORT double CheckPointCompletionTarget;
extern void BackgroundWriterMain(void) pg_attribute_noreturn();
extern void CheckpointerMain(void) pg_attribute_noreturn();
diff --git a/src/include/postmaster/postmaster.h b/src/include/postmaster/postmaster.h
index 0efdd7c232..bea67c3719 100644
--- a/src/include/postmaster/postmaster.h
+++ b/src/include/postmaster/postmaster.h
@@ -14,22 +14,22 @@
#define _POSTMASTER_H
/* GUC options */
-extern bool EnableSSL;
-extern int ReservedBackends;
+extern PGDLLIMPORT bool EnableSSL;
+extern PGDLLIMPORT int ReservedBackends;
extern PGDLLIMPORT int PostPortNumber;
-extern int Unix_socket_permissions;
-extern char *Unix_socket_group;
-extern char *Unix_socket_directories;
-extern char *ListenAddresses;
+extern PGDLLIMPORT int Unix_socket_permissions;
+extern PGDLLIMPORT char *Unix_socket_group;
+extern PGDLLIMPORT char *Unix_socket_directories;
+extern PGDLLIMPORT char *ListenAddresses;
extern bool ClientAuthInProgress;
-extern int PreAuthDelay;
-extern int AuthenticationTimeout;
-extern bool Log_connections;
-extern bool log_hostname;
-extern bool enable_bonjour;
-extern char *bonjour_name;
-extern bool restart_after_crash;
-extern bool remove_temp_files_after_crash;
+extern PGDLLIMPORT int PreAuthDelay;
+extern PGDLLIMPORT int AuthenticationTimeout;
+extern PGDLLIMPORT bool Log_connections;
+extern PGDLLIMPORT bool log_hostname;
+extern PGDLLIMPORT bool enable_bonjour;
+extern PGDLLIMPORT char *bonjour_name;
+extern PGDLLIMPORT bool restart_after_crash;
+extern PGDLLIMPORT bool remove_temp_files_after_crash;
#ifdef WIN32
extern HANDLE PostmasterHandle;
diff --git a/src/include/postmaster/syslogger.h b/src/include/postmaster/syslogger.h
index 1491eecb0f..9dde75321c 100644
--- a/src/include/postmaster/syslogger.h
+++ b/src/include/postmaster/syslogger.h
@@ -62,13 +62,13 @@ typedef union
/* GUC options */
-extern bool Logging_collector;
-extern int Log_RotationAge;
-extern int Log_RotationSize;
+extern PGDLLIMPORT bool Logging_collector;
+extern PGDLLIMPORT int Log_RotationAge;
+extern PGDLLIMPORT int Log_RotationSize;
extern PGDLLIMPORT char *Log_directory;
extern PGDLLIMPORT char *Log_filename;
-extern bool Log_truncate_on_rotation;
-extern int Log_file_mode;
+extern PGDLLIMPORT bool Log_truncate_on_rotation;
+extern PGDLLIMPORT int Log_file_mode;
#ifndef WIN32
extern int syslogPipe[2];
diff --git a/src/include/postmaster/walwriter.h b/src/include/postmaster/walwriter.h
index 3ccc332333..e4cb844ea1 100644
--- a/src/include/postmaster/walwriter.h
+++ b/src/include/postmaster/walwriter.h
@@ -13,8 +13,8 @@
#define _WALWRITER_H
/* GUC options */
-extern int WalWriterDelay;
-extern int WalWriterFlushAfter;
+extern PGDLLIMPORT int WalWriterDelay;
+extern PGDLLIMPORT int WalWriterFlushAfter;
extern void WalWriterMain(void) pg_attribute_noreturn();
diff --git a/src/include/replication/logicallauncher.h b/src/include/replication/logicallauncher.h
index 301e494f7b..2c6f71e129 100644
--- a/src/include/replication/logicallauncher.h
+++ b/src/include/replication/logicallauncher.h
@@ -12,8 +12,8 @@
#ifndef LOGICALLAUNCHER_H
#define LOGICALLAUNCHER_H
-extern int max_logical_replication_workers;
-extern int max_sync_workers_per_subscription;
+extern PGDLLIMPORT int max_logical_replication_workers;
+extern PGDLLIMPORT int max_sync_workers_per_subscription;
extern void ApplyLauncherRegister(void);
extern void ApplyLauncherMain(Datum main_arg);
diff --git a/src/include/replication/syncrep.h b/src/include/replication/syncrep.h
index 4266afde8b..b4324810a4 100644
--- a/src/include/replication/syncrep.h
+++ b/src/include/replication/syncrep.h
@@ -79,7 +79,7 @@ extern SyncRepConfigData *syncrep_parse_result;
extern char *syncrep_parse_error_msg;
/* user-settable parameters for synchronous replication */
-extern char *SyncRepStandbyNames;
+extern PGDLLIMPORT char *SyncRepStandbyNames;
/* called by user backend */
extern void SyncRepWaitForLSN(XLogRecPtr lsn, bool commit);
diff --git a/src/include/replication/walreceiver.h b/src/include/replication/walreceiver.h
index 0b607ed777..3385c79b92 100644
--- a/src/include/replication/walreceiver.h
+++ b/src/include/replication/walreceiver.h
@@ -25,9 +25,9 @@
#include "utils/tuplestore.h"
/* user-settable parameters */
-extern int wal_receiver_status_interval;
-extern int wal_receiver_timeout;
-extern bool hot_standby_feedback;
+extern PGDLLIMPORT int wal_receiver_status_interval;
+extern PGDLLIMPORT int wal_receiver_timeout;
+extern PGDLLIMPORT bool hot_standby_feedback;
/*
* MAXCONNINFO: maximum size of a connection string.
diff --git a/src/include/replication/walsender.h b/src/include/replication/walsender.h
index 828106933c..d6618495a0 100644
--- a/src/include/replication/walsender.h
+++ b/src/include/replication/walsender.h
@@ -31,9 +31,9 @@ extern bool am_db_walsender;
extern bool wake_wal_senders;
/* user-settable parameters */
-extern int max_wal_senders;
-extern int wal_sender_timeout;
-extern bool log_replication_commands;
+extern PGDLLIMPORT int max_wal_senders;
+extern PGDLLIMPORT int wal_sender_timeout;
+extern PGDLLIMPORT bool log_replication_commands;
extern void InitWalSender(void);
extern bool exec_replication_command(const char *query_string);
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index cfce23ecbc..31c67a0065 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -65,16 +65,16 @@ struct SMgrRelationData;
extern PGDLLIMPORT int NBuffers;
/* in bufmgr.c */
-extern bool zero_damaged_pages;
-extern int bgwriter_lru_maxpages;
-extern double bgwriter_lru_multiplier;
-extern bool track_io_timing;
-extern int effective_io_concurrency;
-extern int maintenance_io_concurrency;
-
-extern int checkpoint_flush_after;
-extern int backend_flush_after;
-extern int bgwriter_flush_after;
+extern PGDLLIMPORT bool zero_damaged_pages;
+extern PGDLLIMPORT int bgwriter_lru_maxpages;
+extern PGDLLIMPORT double bgwriter_lru_multiplier;
+extern PGDLLIMPORT bool track_io_timing;
+extern PGDLLIMPORT int effective_io_concurrency;
+extern PGDLLIMPORT int maintenance_io_concurrency;
+
+extern PGDLLIMPORT int checkpoint_flush_after;
+extern PGDLLIMPORT int backend_flush_after;
+extern PGDLLIMPORT int bgwriter_flush_after;
/* in buf_init.c */
extern PGDLLIMPORT char *BufferBlocks;
diff --git a/src/include/storage/dsm_impl.h b/src/include/storage/dsm_impl.h
index ff72f7b0e5..5fc38b5e25 100644
--- a/src/include/storage/dsm_impl.h
+++ b/src/include/storage/dsm_impl.h
@@ -39,8 +39,8 @@
#endif
/* GUC. */
-extern int dynamic_shared_memory_type;
-extern int min_dynamic_shared_memory;
+extern PGDLLIMPORT int dynamic_shared_memory_type;
+extern PGDLLIMPORT int min_dynamic_shared_memory;
/*
* Directory for on-disk state.
diff --git a/src/include/storage/fd.h b/src/include/storage/fd.h
index 34602ae006..8f4d08e6a1 100644
--- a/src/include/storage/fd.h
+++ b/src/include/storage/fd.h
@@ -59,7 +59,7 @@ typedef int File;
/* GUC parameter */
extern PGDLLIMPORT int max_files_per_process;
extern PGDLLIMPORT bool data_sync_retry;
-extern int recovery_init_sync_method;
+extern PGDLLIMPORT int recovery_init_sync_method;
/*
* This is private to fd.c, but exported for save/restore_backend_variables()
diff --git a/src/include/storage/large_object.h b/src/include/storage/large_object.h
index ae1e2482ea..6e72b17a1b 100644
--- a/src/include/storage/large_object.h
+++ b/src/include/storage/large_object.h
@@ -79,7 +79,7 @@ typedef struct LargeObjectDesc
/*
* GUC: backwards-compatibility flag to suppress LO permission checks
*/
-extern bool lo_compat_privileges;
+extern PGDLLIMPORT bool lo_compat_privileges;
/*
* Function definitions...
diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h
index 9b2a421c32..0c7929251d 100644
--- a/src/include/storage/lock.h
+++ b/src/include/storage/lock.h
@@ -34,14 +34,14 @@ typedef struct PROC_QUEUE
} PROC_QUEUE;
/* GUC variables */
-extern int max_locks_per_xact;
+extern PGDLLIMPORT int max_locks_per_xact;
#ifdef LOCK_DEBUG
-extern int Trace_lock_oidmin;
-extern bool Trace_locks;
-extern bool Trace_userlocks;
-extern int Trace_lock_table;
-extern bool Debug_deadlocks;
+extern PGDLLIMPORT int Trace_lock_oidmin;
+extern PGDLLIMPORT bool Trace_locks;
+extern PGDLLIMPORT bool Trace_userlocks;
+extern PGDLLIMPORT int Trace_lock_table;
+extern PGDLLIMPORT bool Debug_deadlocks;
#endif /* LOCK_DEBUG */
diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h
index a8f052e484..00dba0f720 100644
--- a/src/include/storage/lwlock.h
+++ b/src/include/storage/lwlock.h
@@ -110,7 +110,7 @@ typedef enum LWLockMode
#ifdef LOCK_DEBUG
-extern bool Trace_lwlocks;
+extern PGDLLIMPORT bool Trace_lwlocks;
#endif
extern bool LWLockAcquire(LWLock *lock, LWLockMode mode);
diff --git a/src/include/storage/pg_shmem.h b/src/include/storage/pg_shmem.h
index 059df1b72c..6823538299 100644
--- a/src/include/storage/pg_shmem.h
+++ b/src/include/storage/pg_shmem.h
@@ -42,9 +42,9 @@ typedef struct PGShmemHeader /* standard header for all Postgres shmem */
} PGShmemHeader;
/* GUC variables */
-extern int shared_memory_type;
-extern int huge_pages;
-extern int huge_page_size;
+extern PGDLLIMPORT int shared_memory_type;
+extern PGDLLIMPORT int huge_pages;
+extern PGDLLIMPORT int huge_page_size;
/* Possible values for huge_pages */
typedef enum
diff --git a/src/include/storage/predicate.h b/src/include/storage/predicate.h
index 152b698611..bf0afbf181 100644
--- a/src/include/storage/predicate.h
+++ b/src/include/storage/predicate.h
@@ -22,9 +22,9 @@
/*
* GUC variables
*/
-extern int max_predicate_locks_per_xact;
-extern int max_predicate_locks_per_relation;
-extern int max_predicate_locks_per_page;
+extern PGDLLIMPORT int max_predicate_locks_per_xact;
+extern PGDLLIMPORT int max_predicate_locks_per_relation;
+extern PGDLLIMPORT int max_predicate_locks_per_page;
/* Number of SLRU buffers to use for Serial SLRU */
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
index be67d8a861..f9fd7572d6 100644
--- a/src/include/storage/proc.h
+++ b/src/include/storage/proc.h
@@ -382,7 +382,7 @@ extern PGDLLIMPORT int StatementTimeout;
extern PGDLLIMPORT int LockTimeout;
extern PGDLLIMPORT int IdleInTransactionSessionTimeout;
extern PGDLLIMPORT int IdleSessionTimeout;
-extern bool log_lock_waits;
+extern PGDLLIMPORT bool log_lock_waits;
/*
diff --git a/src/include/storage/standby.h b/src/include/storage/standby.h
index 38fd85a431..3c78d76c93 100644
--- a/src/include/storage/standby.h
+++ b/src/include/storage/standby.h
@@ -21,10 +21,10 @@
#include "storage/standbydefs.h"
/* User-settable GUC parameters */
-extern int vacuum_defer_cleanup_age;
-extern int max_standby_archive_delay;
-extern int max_standby_streaming_delay;
-extern bool log_recovery_conflict_waits;
+extern PGDLLIMPORT int vacuum_defer_cleanup_age;
+extern PGDLLIMPORT int max_standby_archive_delay;
+extern PGDLLIMPORT int max_standby_streaming_delay;
+extern PGDLLIMPORT bool log_recovery_conflict_waits;
extern void InitRecoveryTransactionEnvironment(void);
extern void ShutdownRecoveryTransactionEnvironment(void);
diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h
index 968345404e..a3a7c5cada 100644
--- a/src/include/tcop/tcopprot.h
+++ b/src/include/tcop/tcopprot.h
@@ -27,9 +27,9 @@
extern CommandDest whereToSendOutput;
extern PGDLLIMPORT const char *debug_query_string;
-extern int max_stack_depth;
-extern int PostAuthDelay;
-extern int client_connection_check_interval;
+extern PGDLLIMPORT int max_stack_depth;
+extern PGDLLIMPORT int PostAuthDelay;
+extern PGDLLIMPORT int client_connection_check_interval;
/* GUC-configurable parameters */
diff --git a/src/include/tsearch/ts_cache.h b/src/include/tsearch/ts_cache.h
index 888f7028b1..71e05509d6 100644
--- a/src/include/tsearch/ts_cache.h
+++ b/src/include/tsearch/ts_cache.h
@@ -84,7 +84,7 @@ typedef struct
/*
* GUC variable for current configuration
*/
-extern char *TSCurrentConfig;
+extern PGDLLIMPORT char *TSCurrentConfig;
extern TSParserCacheEntry *lookup_ts_parser_cache(Oid prsId);
diff --git a/src/include/utils/array.h b/src/include/utils/array.h
index 4ae6c3be2f..798e34cc67 100644
--- a/src/include/utils/array.h
+++ b/src/include/utils/array.h
@@ -339,7 +339,7 @@ typedef struct ArrayIteratorData *ArrayIterator;
/*
* GUC parameter
*/
-extern bool Array_nulls;
+extern PGDLLIMPORT bool Array_nulls;
/*
* prototypes for functions defined in arrayfuncs.c
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index 40fcb0ab6d..ee5335b7c5 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -65,7 +65,7 @@ extern char *regexp_fixed_prefix(text *text_re, bool case_insensitive,
Oid collation, bool *exact);
/* ruleutils.c */
-extern bool quote_all_identifiers;
+extern PGDLLIMPORT bool quote_all_identifiers;
extern const char *quote_identifier(const char *ident);
extern char *quote_qualified_identifier(const char *qualifier,
const char *ident);
diff --git a/src/include/utils/bytea.h b/src/include/utils/bytea.h
index eb9df9e4f7..8ab96920ec 100644
--- a/src/include/utils/bytea.h
+++ b/src/include/utils/bytea.h
@@ -22,6 +22,6 @@ typedef enum
BYTEA_OUTPUT_HEX
} ByteaOutputType;
-extern int bytea_output; /* ByteaOutputType, but int for GUC enum */
+extern PGDLLIMPORT int bytea_output; /* ByteaOutputType, but int for GUC enum */
#endif /* BYTEA_H */
diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h
index f53607e12e..0a4dc7473d 100644
--- a/src/include/utils/elog.h
+++ b/src/include/utils/elog.h
@@ -424,12 +424,12 @@ typedef enum
PGERROR_VERBOSE /* all the facts, ma'am */
} PGErrorVerbosity;
-extern int Log_error_verbosity;
-extern char *Log_line_prefix;
+extern PGDLLIMPORT int Log_error_verbosity;
+extern PGDLLIMPORT char *Log_line_prefix;
extern int Log_destination;
-extern char *Log_destination_string;
-extern bool syslog_sequence_numbers;
-extern bool syslog_split_messages;
+extern PGDLLIMPORT char *Log_destination_string;
+extern PGDLLIMPORT bool syslog_sequence_numbers;
+extern PGDLLIMPORT bool syslog_split_messages;
/* Log destination bitmap */
#define LOG_DESTINATION_STDERR 1
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index a7c3a4958e..76e1127757 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -233,53 +233,53 @@ typedef enum
/* GUC vars that are actually declared in guc.c, rather than elsewhere */
-extern bool Debug_print_plan;
-extern bool Debug_print_parse;
-extern bool Debug_print_rewritten;
-extern bool Debug_pretty_print;
+extern PGDLLIMPORT bool Debug_print_plan;
+extern PGDLLIMPORT bool Debug_print_parse;
+extern PGDLLIMPORT bool Debug_print_rewritten;
+extern PGDLLIMPORT bool Debug_pretty_print;
-extern bool log_parser_stats;
-extern bool log_planner_stats;
-extern bool log_executor_stats;
-extern bool log_statement_stats;
-extern bool log_btree_build_stats;
+extern PGDLLIMPORT bool log_parser_stats;
+extern PGDLLIMPORT bool log_planner_stats;
+extern PGDLLIMPORT bool log_executor_stats;
+extern PGDLLIMPORT bool log_statement_stats;
+extern PGDLLIMPORT bool log_btree_build_stats;
extern PGDLLIMPORT bool check_function_bodies;
-extern bool session_auth_is_superuser;
+extern PGDLLIMPORT bool session_auth_is_superuser;
-extern bool log_duration;
-extern int log_parameter_max_length;
-extern int log_parameter_max_length_on_error;
-extern int log_min_error_statement;
+extern PGDLLIMPORT bool log_duration;
+extern PGDLLIMPORT int log_parameter_max_length;
+extern PGDLLIMPORT int log_parameter_max_length_on_error;
+extern PGDLLIMPORT int log_min_error_statement;
extern PGDLLIMPORT int log_min_messages;
extern PGDLLIMPORT int client_min_messages;
-extern int log_min_duration_sample;
-extern int log_min_duration_statement;
-extern int log_temp_files;
-extern double log_statement_sample_rate;
-extern double log_xact_sample_rate;
-extern char *backtrace_functions;
+extern PGDLLIMPORT int log_min_duration_sample;
+extern PGDLLIMPORT int log_min_duration_statement;
+extern PGDLLIMPORT int log_temp_files;
+extern PGDLLIMPORT double log_statement_sample_rate;
+extern PGDLLIMPORT double log_xact_sample_rate;
+extern PGDLLIMPORT char *backtrace_functions;
extern char *backtrace_symbol_list;
-extern int temp_file_limit;
+extern PGDLLIMPORT int temp_file_limit;
-extern int num_temp_buffers;
+extern PGDLLIMPORT int num_temp_buffers;
-extern char *cluster_name;
+extern PGDLLIMPORT char *cluster_name;
extern PGDLLIMPORT char *ConfigFileName;
-extern char *HbaFileName;
-extern char *IdentFileName;
-extern char *external_pid_file;
+extern PGDLLIMPORT char *HbaFileName;
+extern PGDLLIMPORT char *IdentFileName;
+extern PGDLLIMPORT char *external_pid_file;
extern PGDLLIMPORT char *application_name;
-extern int tcp_keepalives_idle;
-extern int tcp_keepalives_interval;
-extern int tcp_keepalives_count;
-extern int tcp_user_timeout;
+extern PGDLLIMPORT int tcp_keepalives_idle;
+extern PGDLLIMPORT int tcp_keepalives_interval;
+extern PGDLLIMPORT int tcp_keepalives_count;
+extern PGDLLIMPORT int tcp_user_timeout;
#ifdef TRACE_SORT
-extern bool trace_sort;
+extern PGDLLIMPORT bool trace_sort;
#endif
/*
diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h
index 2946f46c76..d3f931c230 100644
--- a/src/include/utils/pg_locale.h
+++ b/src/include/utils/pg_locale.h
@@ -36,10 +36,10 @@
/* GUC settings */
-extern char *locale_messages;
-extern char *locale_monetary;
-extern char *locale_numeric;
-extern char *locale_time;
+extern PGDLLIMPORT char *locale_messages;
+extern PGDLLIMPORT char *locale_monetary;
+extern PGDLLIMPORT char *locale_numeric;
+extern PGDLLIMPORT char *locale_time;
/* lc_time localization cache */
extern char *localized_abbrev_days[];
diff --git a/src/include/utils/plancache.h b/src/include/utils/plancache.h
index ff09c63a02..caab48ee9f 100644
--- a/src/include/utils/plancache.h
+++ b/src/include/utils/plancache.h
@@ -35,7 +35,7 @@ typedef enum
} PlanCacheMode;
/* GUC parameter */
-extern int plan_cache_mode;
+extern PGDLLIMPORT int plan_cache_mode;
#define CACHEDPLANSOURCE_MAGIC 195726186
#define CACHEDPLAN_MAGIC 953717834
diff --git a/src/include/utils/ps_status.h b/src/include/utils/ps_status.h
index 9f43e1fdf0..bba463591f 100644
--- a/src/include/utils/ps_status.h
+++ b/src/include/utils/ps_status.h
@@ -12,7 +12,7 @@
#ifndef PS_STATUS_H
#define PS_STATUS_H
-extern bool update_process_title;
+extern PGDLLIMPORT bool update_process_title;
extern char **save_ps_display_args(int argc, char **argv);
diff --git a/src/include/utils/queryjumble.h b/src/include/utils/queryjumble.h
index 7af6652f3e..a0107f020a 100644
--- a/src/include/utils/queryjumble.h
+++ b/src/include/utils/queryjumble.h
@@ -61,7 +61,7 @@ enum ComputeQueryIdType
};
/* GUC parameters */
-extern int compute_query_id;
+extern PGDLLIMPORT int compute_query_id;
extern const char *CleanQuerytext(const char *query, int *location, int *len);
diff --git a/src/include/utils/rls.h b/src/include/utils/rls.h
index 46b32347c3..175c24633c 100644
--- a/src/include/utils/rls.h
+++ b/src/include/utils/rls.h
@@ -14,7 +14,7 @@
#define RLS_H
/* GUC variable */
-extern bool row_security;
+extern PGDLLIMPORT bool row_security;
/*
* Used by callers of check_enable_rls.
diff --git a/src/include/utils/xml.h b/src/include/utils/xml.h
index d79668f3c4..95dda63b10 100644
--- a/src/include/utils/xml.h
+++ b/src/include/utils/xml.h
@@ -75,9 +75,9 @@ extern char *map_sql_identifier_to_xml_name(const char *ident, bool fully_escape
extern char *map_xml_name_to_sql_identifier(const char *name);
extern char *map_sql_value_to_xml_value(Datum value, Oid type, bool xml_escape_strings);
-extern int xmlbinary; /* XmlBinaryType, but int for guc enum */
+extern PGDLLIMPORT int xmlbinary; /* XmlBinaryType, but int for guc enum */
-extern int xmloption; /* XmlOptionType, but int for guc enum */
+extern PGDLLIMPORT int xmloption; /* XmlOptionType, but int for guc enum */
extern const TableFuncRoutine XmlTableRoutine;
--
2.32.0
On Sun, Aug 22, 2021 at 04:10:33PM +0800, Julien Rouhaud wrote:
This topic has been raised multiple time over the years, and I don't see any
objection to add such an annotation at least for all GUC variables (either the
direct variables or the indirect variables set during the hook execution), so
PFA a patch that takes care of all the GUC.I don't now if that's still an option at that point, but backporting to at
least pg14 if that patch is accepted would be quite helpful.
These are usually just applied on HEAD, and on a parameter-basis based
on requests from extension authors. If you wish to make your
extensions able to work on Windows, that's a good idea, but I would
recommend to limit this exercise to what's really necessary for your
purpose.
--
Michael
On Sun, Aug 22, 2021 at 08:51:26PM +0900, Michael Paquier wrote:
On Sun, Aug 22, 2021 at 04:10:33PM +0800, Julien Rouhaud wrote:
This topic has been raised multiple time over the years, and I don't see any
objection to add such an annotation at least for all GUC variables (either the
direct variables or the indirect variables set during the hook execution), so
PFA a patch that takes care of all the GUC.I don't now if that's still an option at that point, but backporting to at
least pg14 if that patch is accepted would be quite helpful.These are usually just applied on HEAD
Yeah but 14 isn't released yet, and this is a really low risk change.
, and on a parameter-basis based
on requests from extension authors. If you wish to make your
extensions able to work on Windows, that's a good idea, but I would
recommend to limit this exercise to what's really necessary for your
purpose.
I disagree. For random global variables I agree that we shouldn't mark them
all blindly, but for GUCs it's pretty clear that they're intended to be
accessible from any caller, including extensions. Why treating Windows as a
second-class citizen, especially when any change can only be used a year after
someone complained?
ne 22. 8. 2021 v 14:08 odesílatel Julien Rouhaud <rjuju123@gmail.com>
napsal:
On Sun, Aug 22, 2021 at 08:51:26PM +0900, Michael Paquier wrote:
On Sun, Aug 22, 2021 at 04:10:33PM +0800, Julien Rouhaud wrote:
This topic has been raised multiple time over the years, and I don't
see any
objection to add such an annotation at least for all GUC variables
(either the
direct variables or the indirect variables set during the hook
execution), so
PFA a patch that takes care of all the GUC.
I don't now if that's still an option at that point, but backporting
to at
least pg14 if that patch is accepted would be quite helpful.
These are usually just applied on HEAD
Yeah but 14 isn't released yet, and this is a really low risk change.
, and on a parameter-basis based
on requests from extension authors. If you wish to make your
extensions able to work on Windows, that's a good idea, but I would
recommend to limit this exercise to what's really necessary for your
purpose.I disagree. For random global variables I agree that we shouldn't mark
them
all blindly, but for GUCs it's pretty clear that they're intended to be
accessible from any caller, including extensions. Why treating Windows as
a
second-class citizen, especially when any change can only be used a year
after
someone complained?
I had few problems with access with these variables too when I worked on
orafce.
Is true, so it increases differences between Windows and Unix, and fixing
these issues is not fun work. On the other hand, maybe direct access to
these variables from extensions is an antipattern, and we should use a
direct function call API and functions current_setting and set_config. The
overhead is usually not too big.
On Sun, Aug 22, 2021 at 02:17:16PM +0200, Pavel Stehule wrote:
Is true, so it increases differences between Windows and Unix, and fixing
these issues is not fun work. On the other hand, maybe direct access to
these variables from extensions is an antipattern, and we should use a
direct function call API and functions current_setting and set_config. The
overhead is usually not too big.
Yes, and that's what I did for one of my extensions. But that's still a bit of
overhead, and extra burden only seen when trying to have Windows compatiblity,
and I hope I can get rid of that at some point.
If direct variable access shouldn't be possible, then we should explicitly tag
those with __attribute__ ((visibility ("hidden"))) or something like that to
have a more consistent behavior.
Julien Rouhaud <rjuju123@gmail.com> writes:
On Sun, Aug 22, 2021 at 08:51:26PM +0900, Michael Paquier wrote:
... and on a parameter-basis based
on requests from extension authors. If you wish to make your
extensions able to work on Windows, that's a good idea, but I would
recommend to limit this exercise to what's really necessary for your
purpose.
I disagree. For random global variables I agree that we shouldn't mark them
all blindly, but for GUCs it's pretty clear that they're intended to be
accessible from any caller, including extensions.
Uh, no, it's exactly *not* clear. There are a lot of GUCs that are only
of interest to particular subsystems. I do not see why being a GUC makes
something automatically more interesting than any other global variable.
Usually, the fact that one is global is only so the GUC machinery itself
can get at it, otherwise it'd be static in the owning module.
As for "extensions should be able to get at the values", the GUC machinery
already provides uniform mechanisms for doing that safely. Direct access
to the variable's internal value would be unsafe in many cases.
regards, tom lane
On Sun, Aug 22, 2021 at 09:19:42AM -0400, Tom Lane wrote:
Uh, no, it's exactly *not* clear. There are a lot of GUCs that are only
of interest to particular subsystems. I do not see why being a GUC makes
something automatically more interesting than any other global variable.
Usually, the fact that one is global is only so the GUC machinery itself
can get at it, otherwise it'd be static in the owning module.As for "extensions should be able to get at the values", the GUC machinery
already provides uniform mechanisms for doing that safely. Direct access
to the variable's internal value would be unsafe in many cases.
Then shouldn't we try to prevent direct access on all platforms rather than
only one?
On Sun, Aug 22, 2021 at 09:29:01PM +0800, Julien Rouhaud wrote:
On Sun, Aug 22, 2021 at 09:19:42AM -0400, Tom Lane wrote:
Uh, no, it's exactly *not* clear. There are a lot of GUCs that are only
of interest to particular subsystems. I do not see why being a GUC makes
something automatically more interesting than any other global variable.
Usually, the fact that one is global is only so the GUC machinery itself
can get at it, otherwise it'd be static in the owning module.As for "extensions should be able to get at the values", the GUC machinery
already provides uniform mechanisms for doing that safely. Direct access
to the variable's internal value would be unsafe in many cases.Then shouldn't we try to prevent direct access on all platforms rather than
only one?
So since the non currently explicitly exported GUC global variables shouldn't
be accessible by third-party code, I'm attaching a POC patch that does the
opposite of v1: enforce that restriction using a new pg_attribute_hidden()
macro, defined with GCC only, to start discussing that topic.
It would probably be better to have some other macro (e.g. PG_GLOBAL_PUBLIC and
PG_GLOBAL_PRIVATE or similar) to make declarations more consistent, but given
the amount of changes it would represent I prefer to have some feedback before
spending time on that.
Attachments:
v2-0001-Make-all-GUC-ariables-non-previously-marked-as-PG.patchtext/x-diff; charset=us-asciiDownload
From b43c48a80f985e879a88d9d270fc1e2b283b5732 Mon Sep 17 00:00:00 2001
From: Julien Rouhaud <julien.rouhaud@free.fr>
Date: Sun, 22 Aug 2021 15:40:47 +0800
Subject: [PATCH v2] Make all GUC ariables non previously marked as PGDLLIMPORT
private.
---
src/backend/utils/misc/guc.c | 18 +++---
src/include/access/gin.h | 2 +-
src/include/access/tableam.h | 4 +-
src/include/access/toast_compression.h | 2 +-
src/include/access/xact.h | 12 ++--
src/include/access/xlog.h | 78 +++++++++++------------
src/include/c.h | 7 ++
src/include/catalog/namespace.h | 2 +-
src/include/catalog/storage.h | 2 +-
src/include/commands/async.h | 2 +-
src/include/commands/user.h | 2 +-
src/include/commands/vacuum.h | 12 ++--
src/include/fmgr.h | 2 +-
src/include/jit/jit.h | 20 +++---
src/include/libpq/auth.h | 4 +-
src/include/libpq/libpq.h | 24 +++----
src/include/libpq/pqcomm.h | 2 +-
src/include/miscadmin.h | 22 +++----
src/include/optimizer/geqo.h | 10 +--
src/include/optimizer/optimizer.h | 4 +-
src/include/optimizer/planmain.h | 6 +-
src/include/parser/parse_expr.h | 2 +-
src/include/parser/parser.h | 4 +-
src/include/pgstat.h | 6 +-
src/include/pgtime.h | 2 +-
src/include/postmaster/autovacuum.h | 30 ++++-----
src/include/postmaster/bgwriter.h | 8 +--
src/include/postmaster/postmaster.h | 28 ++++----
src/include/postmaster/syslogger.h | 10 +--
src/include/postmaster/walwriter.h | 4 +-
src/include/replication/logicallauncher.h | 4 +-
src/include/replication/syncrep.h | 2 +-
src/include/replication/walreceiver.h | 6 +-
src/include/replication/walsender.h | 6 +-
src/include/storage/bufmgr.h | 20 +++---
src/include/storage/dsm_impl.h | 4 +-
src/include/storage/fd.h | 2 +-
src/include/storage/large_object.h | 2 +-
src/include/storage/lock.h | 12 ++--
src/include/storage/lwlock.h | 2 +-
src/include/storage/pg_shmem.h | 6 +-
src/include/storage/predicate.h | 6 +-
src/include/storage/proc.h | 2 +-
src/include/storage/standby.h | 8 +--
src/include/tcop/tcopprot.h | 6 +-
src/include/tsearch/ts_cache.h | 2 +-
src/include/utils/array.h | 2 +-
src/include/utils/builtins.h | 2 +-
src/include/utils/bytea.h | 2 +-
src/include/utils/elog.h | 10 +--
src/include/utils/guc.h | 62 +++++++++---------
src/include/utils/pg_locale.h | 8 +--
src/include/utils/plancache.h | 2 +-
src/include/utils/ps_status.h | 2 +-
src/include/utils/queryjumble.h | 2 +-
src/include/utils/rls.h | 2 +-
src/include/utils/xml.h | 4 +-
57 files changed, 263 insertions(+), 256 deletions(-)
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index a2e0f8de7e..ca2d6042cd 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -129,20 +129,20 @@
#define REALTYPE_PRECISION 17
/* XXX these should appear in other modules' header files */
-extern bool Log_disconnections;
-extern int CommitDelay;
-extern int CommitSiblings;
-extern char *default_tablespace;
-extern char *temp_tablespaces;
-extern bool ignore_checksum_failure;
-extern bool ignore_invalid_pages;
+extern bool Log_disconnections pg_attribute_hidden();
+extern int CommitDelay pg_attribute_hidden();
+extern int CommitSiblings pg_attribute_hidden();
+extern char *default_tablespace pg_attribute_hidden();
+extern char *temp_tablespaces pg_attribute_hidden();
+extern bool ignore_checksum_failure pg_attribute_hidden();
+extern bool ignore_invalid_pages pg_attribute_hidden();
extern bool synchronize_seqscans;
#ifdef TRACE_SYNCSCAN
-extern bool trace_syncscan;
+extern bool trace_syncscan pg_attribute_hidden();
#endif
#ifdef DEBUG_BOUNDED_SORT
-extern bool optimize_bounded_sort;
+extern bool optimize_bounded_sort pg_attribute_hidden();
#endif
static int GUC_check_errcode_value;
diff --git a/src/include/access/gin.h b/src/include/access/gin.h
index 266cb07236..b614380327 100644
--- a/src/include/access/gin.h
+++ b/src/include/access/gin.h
@@ -68,7 +68,7 @@ typedef char GinTernaryValue;
/* GUC parameters */
extern PGDLLIMPORT int GinFuzzySearchLimit;
-extern int gin_pending_list_limit;
+extern int gin_pending_list_limit pg_attribute_hidden();
/* ginutil.c */
extern void ginGetStats(Relation index, GinStatsData *stats);
diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h
index 9f1e4a1ac9..445ce8a859 100644
--- a/src/include/access/tableam.h
+++ b/src/include/access/tableam.h
@@ -28,8 +28,8 @@
#define DEFAULT_TABLE_ACCESS_METHOD "heap"
/* GUCs */
-extern char *default_table_access_method;
-extern bool synchronize_seqscans;
+extern char *default_table_access_method pg_attribute_hidden();
+extern bool synchronize_seqscans pg_attribute_hidden();
struct BulkInsertStateData;
diff --git a/src/include/access/toast_compression.h b/src/include/access/toast_compression.h
index c992ece4c4..4889cfd386 100644
--- a/src/include/access/toast_compression.h
+++ b/src/include/access/toast_compression.h
@@ -20,7 +20,7 @@
* but the value is one of the char values defined below, as they appear in
* pg_attribute.attcompression, e.g. TOAST_PGLZ_COMPRESSION.
*/
-extern int default_toast_compression;
+extern int default_toast_compression pg_attribute_hidden();
/*
* Built-in compression method ID. The toast compression header will store
diff --git a/src/include/access/xact.h b/src/include/access/xact.h
index 134f6862da..cb8021d05c 100644
--- a/src/include/access/xact.h
+++ b/src/include/access/xact.h
@@ -38,7 +38,7 @@
#define XACT_REPEATABLE_READ 2
#define XACT_SERIALIZABLE 3
-extern int DefaultXactIsoLevel;
+extern int DefaultXactIsoLevel pg_attribute_hidden();
extern PGDLLIMPORT int XactIsoLevel;
/*
@@ -52,8 +52,8 @@ extern PGDLLIMPORT int XactIsoLevel;
#define IsolationIsSerializable() (XactIsoLevel == XACT_SERIALIZABLE)
/* Xact read-only state */
-extern bool DefaultXactReadOnly;
-extern bool XactReadOnly;
+extern bool DefaultXactReadOnly pg_attribute_hidden();
+extern bool XactReadOnly pg_attribute_hidden();
/* flag for logging statements in this transaction */
extern bool xact_is_sampled;
@@ -62,8 +62,8 @@ extern bool xact_is_sampled;
* Xact is deferrable -- only meaningful (currently) for read only
* SERIALIZABLE transactions
*/
-extern bool DefaultXactDeferrable;
-extern bool XactDeferrable;
+extern bool DefaultXactDeferrable pg_attribute_hidden();
+extern bool XactDeferrable pg_attribute_hidden();
typedef enum
{
@@ -80,7 +80,7 @@ typedef enum
#define SYNCHRONOUS_COMMIT_ON SYNCHRONOUS_COMMIT_REMOTE_FLUSH
/* Synchronous commit level */
-extern int synchronous_commit;
+extern int synchronous_commit pg_attribute_hidden();
/* used during logical streaming of a transaction */
extern PGDLLIMPORT TransactionId CheckXidAlive;
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index 0a8ede700d..6ad105026e 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -27,7 +27,7 @@
#define SYNC_METHOD_OPEN 2 /* for O_SYNC */
#define SYNC_METHOD_FSYNC_WRITETHROUGH 3
#define SYNC_METHOD_OPEN_DSYNC 4 /* for O_DSYNC */
-extern int sync_method;
+extern int sync_method pg_attribute_hidden();
extern PGDLLIMPORT TimeLineID ThisTimeLineID; /* current TLI */
@@ -62,45 +62,45 @@ extern PGDLLIMPORT XLogRecPtr XactLastCommitEnd;
extern bool reachedConsistency;
/* these variables are GUC parameters related to XLOG */
-extern int wal_segment_size;
-extern int min_wal_size_mb;
-extern int max_wal_size_mb;
-extern int wal_keep_size_mb;
-extern int max_slot_wal_keep_size_mb;
-extern int XLOGbuffers;
-extern int XLogArchiveTimeout;
-extern int wal_retrieve_retry_interval;
-extern char *XLogArchiveCommand;
-extern bool EnableHotStandby;
-extern bool fullPageWrites;
-extern bool wal_log_hints;
-extern int wal_compression;
-extern bool wal_init_zero;
-extern bool wal_recycle;
+extern int wal_segment_size pg_attribute_hidden();
+extern int min_wal_size_mb pg_attribute_hidden();
+extern int max_wal_size_mb pg_attribute_hidden();
+extern int wal_keep_size_mb pg_attribute_hidden();
+extern int max_slot_wal_keep_size_mb pg_attribute_hidden();
+extern int XLOGbuffers pg_attribute_hidden();
+extern int XLogArchiveTimeout pg_attribute_hidden();
+extern int wal_retrieve_retry_interval pg_attribute_hidden();
+extern char *XLogArchiveCommand pg_attribute_hidden();
+extern bool EnableHotStandby pg_attribute_hidden();
+extern bool fullPageWrites pg_attribute_hidden();
+extern bool wal_log_hints pg_attribute_hidden();
+extern int wal_compression pg_attribute_hidden();
+extern bool wal_init_zero pg_attribute_hidden();
+extern bool wal_recycle pg_attribute_hidden();
extern bool *wal_consistency_checking;
-extern char *wal_consistency_checking_string;
-extern bool log_checkpoints;
-extern char *recoveryRestoreCommand;
-extern char *recoveryEndCommand;
-extern char *archiveCleanupCommand;
-extern bool recoveryTargetInclusive;
-extern int recoveryTargetAction;
-extern int recovery_min_apply_delay;
-extern char *PrimaryConnInfo;
-extern char *PrimarySlotName;
-extern bool wal_receiver_create_temp_slot;
-extern bool track_wal_io_timing;
+extern char *wal_consistency_checking_string pg_attribute_hidden();
+extern bool log_checkpoints pg_attribute_hidden();
+extern char *recoveryRestoreCommand pg_attribute_hidden();
+extern char *recoveryEndCommand pg_attribute_hidden();
+extern char *archiveCleanupCommand pg_attribute_hidden();
+extern bool recoveryTargetInclusive pg_attribute_hidden();
+extern int recoveryTargetAction pg_attribute_hidden();
+extern int recovery_min_apply_delay pg_attribute_hidden();
+extern char *PrimaryConnInfo pg_attribute_hidden();
+extern char *PrimarySlotName pg_attribute_hidden();
+extern bool wal_receiver_create_temp_slot pg_attribute_hidden();
+extern bool track_wal_io_timing pg_attribute_hidden();
/* indirectly set via GUC system */
-extern TransactionId recoveryTargetXid;
-extern char *recovery_target_time_string;
-extern const char *recoveryTargetName;
-extern XLogRecPtr recoveryTargetLSN;
-extern RecoveryTargetType recoveryTarget;
-extern char *PromoteTriggerFile;
-extern RecoveryTargetTimeLineGoal recoveryTargetTimeLineGoal;
-extern TimeLineID recoveryTargetTLIRequested;
-extern TimeLineID recoveryTargetTLI;
+extern TransactionId recoveryTargetXid pg_attribute_hidden();
+extern char *recovery_target_time_string pg_attribute_hidden();
+extern const char *recoveryTargetName pg_attribute_hidden();
+extern XLogRecPtr recoveryTargetLSN pg_attribute_hidden();
+extern RecoveryTargetType recoveryTarget pg_attribute_hidden();
+extern char *PromoteTriggerFile pg_attribute_hidden();
+extern RecoveryTargetTimeLineGoal recoveryTargetTimeLineGoal pg_attribute_hidden();
+extern TimeLineID recoveryTargetTLIRequested pg_attribute_hidden();
+extern TimeLineID recoveryTargetTLI pg_attribute_hidden();
extern int CheckPointSegments;
@@ -115,7 +115,7 @@ typedef enum ArchiveMode
ARCHIVE_MODE_ON, /* enabled while server is running normally */
ARCHIVE_MODE_ALWAYS /* enabled always (even during recovery) */
} ArchiveMode;
-extern int XLogArchiveMode;
+extern int XLogArchiveMode pg_attribute_hidden();
/* WAL levels */
typedef enum WalLevel
@@ -183,7 +183,7 @@ extern PGDLLIMPORT int wal_level;
#define XLogLogicalInfoActive() (wal_level >= WAL_LEVEL_LOGICAL)
#ifdef WAL_DEBUG
-extern bool XLOG_DEBUG;
+extern bool XLOG_DEBUG pg_attribute_hidden();
#endif
/*
diff --git a/src/include/c.h b/src/include/c.h
index c8ede08273..8ff7db87c7 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -113,6 +113,13 @@
#define __has_attribute(attribute) 0
#endif
+/* only GCC supports the visibility attribute */
+#ifdef __GNUC__
+#define pg_attribute_hidden() __attribute__ ((visibility ("hidden")))
+#else
+#define pg_attribute_hidden()
+#endif
+
/* only GCC supports the unused attribute */
#ifdef __GNUC__
#define pg_attribute_unused() __attribute__((unused))
diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h
index b98f284356..bade81bd51 100644
--- a/src/include/catalog/namespace.h
+++ b/src/include/catalog/namespace.h
@@ -182,7 +182,7 @@ extern void AtEOSubXact_Namespace(bool isCommit, SubTransactionId mySubid,
SubTransactionId parentSubid);
/* stuff for search_path GUC variable */
-extern char *namespace_search_path;
+extern char *namespace_search_path pg_attribute_hidden();
extern List *fetch_search_path(bool includeImplicit);
extern int fetch_search_path_array(Oid *sarray, int sarray_len);
diff --git a/src/include/catalog/storage.h b/src/include/catalog/storage.h
index 0ab32b44e9..ac119fd794 100644
--- a/src/include/catalog/storage.h
+++ b/src/include/catalog/storage.h
@@ -20,7 +20,7 @@
#include "utils/relcache.h"
/* GUC variables */
-extern int wal_skip_threshold;
+extern int wal_skip_threshold pg_attribute_hidden();
extern SMgrRelation RelationCreateStorage(RelFileNode rnode, char relpersistence);
extern void RelationDropStorage(Relation rel);
diff --git a/src/include/commands/async.h b/src/include/commands/async.h
index 9217f66b91..042aee6566 100644
--- a/src/include/commands/async.h
+++ b/src/include/commands/async.h
@@ -20,7 +20,7 @@
*/
#define NUM_NOTIFY_BUFFERS 8
-extern bool Trace_notify;
+extern bool Trace_notify pg_attribute_hidden();
extern volatile sig_atomic_t notifyInterruptPending;
extern Size AsyncShmemSize(void);
diff --git a/src/include/commands/user.h b/src/include/commands/user.h
index 0b7a3cd65f..ace02febf4 100644
--- a/src/include/commands/user.h
+++ b/src/include/commands/user.h
@@ -17,7 +17,7 @@
#include "parser/parse_node.h"
/* GUC. Is actually of type PasswordType. */
-extern int Password_encryption;
+extern int Password_encryption pg_attribute_hidden();
/* Hook to check passwords in CreateRole() and AlterRole() */
typedef void (*check_password_hook_type) (const char *username, const char *shadow_pass, PasswordType password_type, Datum validuntil_time, bool validuntil_null);
diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h
index bf3126aa9b..847f448ac9 100644
--- a/src/include/commands/vacuum.h
+++ b/src/include/commands/vacuum.h
@@ -232,12 +232,12 @@ typedef struct VacuumParams
/* GUC parameters */
extern PGDLLIMPORT int default_statistics_target; /* PGDLLIMPORT for PostGIS */
-extern int vacuum_freeze_min_age;
-extern int vacuum_freeze_table_age;
-extern int vacuum_multixact_freeze_min_age;
-extern int vacuum_multixact_freeze_table_age;
-extern int vacuum_failsafe_age;
-extern int vacuum_multixact_failsafe_age;
+extern int vacuum_freeze_min_age pg_attribute_hidden();
+extern int vacuum_freeze_table_age pg_attribute_hidden();
+extern int vacuum_multixact_freeze_min_age pg_attribute_hidden();
+extern int vacuum_multixact_freeze_table_age pg_attribute_hidden();
+extern int vacuum_failsafe_age pg_attribute_hidden();
+extern int vacuum_multixact_failsafe_age pg_attribute_hidden();
/* Variables for cost-based parallel vacuum */
extern pg_atomic_uint32 *VacuumSharedCostBalance;
diff --git a/src/include/fmgr.h b/src/include/fmgr.h
index ab7b85c86e..52c0dc2768 100644
--- a/src/include/fmgr.h
+++ b/src/include/fmgr.h
@@ -716,7 +716,7 @@ extern bool CheckFunctionValidatorAccess(Oid validatorOid, Oid functionOid);
/*
* Routines in dfmgr.c
*/
-extern char *Dynamic_library_path;
+extern char *Dynamic_library_path pg_attribute_hidden();
extern void *load_external_function(const char *filename, const char *funcname,
bool signalNotFound, void **filehandle);
diff --git a/src/include/jit/jit.h b/src/include/jit/jit.h
index b634df30b9..bf40baa487 100644
--- a/src/include/jit/jit.h
+++ b/src/include/jit/jit.h
@@ -79,16 +79,16 @@ struct JitProviderCallbacks
/* GUCs */
-extern bool jit_enabled;
-extern char *jit_provider;
-extern bool jit_debugging_support;
-extern bool jit_dump_bitcode;
-extern bool jit_expressions;
-extern bool jit_profiling_support;
-extern bool jit_tuple_deforming;
-extern double jit_above_cost;
-extern double jit_inline_above_cost;
-extern double jit_optimize_above_cost;
+extern bool jit_enabled pg_attribute_hidden();
+extern char *jit_provider pg_attribute_hidden();
+extern bool jit_debugging_support pg_attribute_hidden();
+extern bool jit_dump_bitcode pg_attribute_hidden();
+extern bool jit_expressions pg_attribute_hidden();
+extern bool jit_profiling_support pg_attribute_hidden();
+extern bool jit_tuple_deforming pg_attribute_hidden();
+extern double jit_above_cost pg_attribute_hidden();
+extern double jit_inline_above_cost pg_attribute_hidden();
+extern double jit_optimize_above_cost pg_attribute_hidden();
extern void jit_reset_after_error(void);
diff --git a/src/include/libpq/auth.h b/src/include/libpq/auth.h
index 3d6734f253..2231e9804a 100644
--- a/src/include/libpq/auth.h
+++ b/src/include/libpq/auth.h
@@ -16,8 +16,8 @@
#include "libpq/libpq-be.h"
-extern char *pg_krb_server_keyfile;
-extern bool pg_krb_caseins_users;
+extern char *pg_krb_server_keyfile pg_attribute_hidden();
+extern bool pg_krb_caseins_users pg_attribute_hidden();
extern char *pg_krb_realm;
extern void ClientAuthentication(Port *port);
diff --git a/src/include/libpq/libpq.h b/src/include/libpq/libpq.h
index 6c51b2f20f..90c506ae87 100644
--- a/src/include/libpq/libpq.h
+++ b/src/include/libpq/libpq.h
@@ -85,13 +85,13 @@ extern bool pq_check_connection(void);
/*
* prototypes for functions in be-secure.c
*/
-extern char *ssl_library;
-extern char *ssl_cert_file;
-extern char *ssl_key_file;
-extern char *ssl_ca_file;
-extern char *ssl_crl_file;
-extern char *ssl_crl_dir;
-extern char *ssl_dh_params_file;
+extern char *ssl_library pg_attribute_hidden();
+extern char *ssl_cert_file pg_attribute_hidden();
+extern char *ssl_key_file pg_attribute_hidden();
+extern char *ssl_ca_file pg_attribute_hidden();
+extern char *ssl_crl_file pg_attribute_hidden();
+extern char *ssl_crl_dir pg_attribute_hidden();
+extern char *ssl_dh_params_file pg_attribute_hidden();
extern PGDLLIMPORT char *ssl_passphrase_command;
extern PGDLLIMPORT bool ssl_passphrase_command_supports_reload;
#ifdef USE_SSL
@@ -116,11 +116,11 @@ extern ssize_t secure_open_gssapi(Port *port);
#endif
/* GUCs */
-extern char *SSLCipherSuites;
-extern char *SSLECDHCurve;
-extern bool SSLPreferServerCiphers;
-extern int ssl_min_protocol_version;
-extern int ssl_max_protocol_version;
+extern char *SSLCipherSuites pg_attribute_hidden();
+extern char *SSLECDHCurve pg_attribute_hidden();
+extern bool SSLPreferServerCiphers pg_attribute_hidden();
+extern int ssl_min_protocol_version pg_attribute_hidden();
+extern int ssl_max_protocol_version pg_attribute_hidden();
enum ssl_protocol_versions
{
diff --git a/src/include/libpq/pqcomm.h b/src/include/libpq/pqcomm.h
index be9d970574..940acd10c7 100644
--- a/src/include/libpq/pqcomm.h
+++ b/src/include/libpq/pqcomm.h
@@ -135,7 +135,7 @@ typedef ProtocolVersion MsgType;
typedef uint32 PacketLen;
-extern bool Db_user_namespace;
+extern bool Db_user_namespace pg_attribute_hidden();
/*
* In protocol 3.0 and later, the startup packet length is not fixed, but
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index 2e2e9a364a..63ffe89275 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -255,18 +255,18 @@ extern PGDLLIMPORT int IntervalStyle;
#define MAXTZLEN 10 /* max TZ name len, not counting tr. null */
-extern bool enableFsync;
+extern bool enableFsync pg_attribute_hidden();
extern PGDLLIMPORT bool allowSystemTableMods;
extern PGDLLIMPORT int work_mem;
extern PGDLLIMPORT double hash_mem_multiplier;
extern PGDLLIMPORT int maintenance_work_mem;
extern PGDLLIMPORT int max_parallel_maintenance_workers;
-extern int VacuumCostPageHit;
-extern int VacuumCostPageMiss;
-extern int VacuumCostPageDirty;
-extern int VacuumCostLimit;
-extern double VacuumCostDelay;
+extern int VacuumCostPageHit pg_attribute_hidden();
+extern int VacuumCostPageMiss pg_attribute_hidden();
+extern int VacuumCostPageDirty pg_attribute_hidden();
+extern int VacuumCostLimit pg_attribute_hidden();
+extern double VacuumCostDelay pg_attribute_hidden();
extern int64 VacuumPageHit;
extern int64 VacuumPageMiss;
@@ -299,7 +299,7 @@ extern void PreventCommandIfParallelMode(const char *cmdname);
extern void PreventCommandDuringRecovery(const char *cmdname);
/* in utils/misc/guc.c */
-extern int trace_recovery_messages;
+extern int trace_recovery_messages pg_attribute_hidden();
extern int trace_recovery(int trace_level);
/*****************************************************************************
@@ -460,11 +460,11 @@ extern void InitPostgres(const char *in_dbname, Oid dboid, const char *username,
extern void BaseInit(void);
/* in utils/init/miscinit.c */
-extern bool IgnoreSystemIndexes;
+extern bool IgnoreSystemIndexes pg_attribute_hidden();
extern PGDLLIMPORT bool process_shared_preload_libraries_in_progress;
-extern char *session_preload_libraries_string;
-extern char *shared_preload_libraries_string;
-extern char *local_preload_libraries_string;
+extern char *session_preload_libraries_string pg_attribute_hidden();
+extern char *shared_preload_libraries_string pg_attribute_hidden();
+extern char *local_preload_libraries_string pg_attribute_hidden();
extern void CreateDataDirLockFile(bool amPostmaster);
extern void CreateSocketLockFile(const char *socketfile, bool amPostmaster,
diff --git a/src/include/optimizer/geqo.h b/src/include/optimizer/geqo.h
index 24dcdfb6cc..839c620182 100644
--- a/src/include/optimizer/geqo.h
+++ b/src/include/optimizer/geqo.h
@@ -48,23 +48,23 @@
*
* If you change these, update backend/utils/misc/postgresql.conf.sample
*/
-extern int Geqo_effort; /* 1 .. 10, knob for adjustment of defaults */
+extern int Geqo_effort pg_attribute_hidden(); /* 1 .. 10, knob for adjustment of defaults */
#define DEFAULT_GEQO_EFFORT 5
#define MIN_GEQO_EFFORT 1
#define MAX_GEQO_EFFORT 10
-extern int Geqo_pool_size; /* 2 .. inf, or 0 to use default */
+extern int Geqo_pool_size pg_attribute_hidden(); /* 2 .. inf, or 0 to use default */
-extern int Geqo_generations; /* 1 .. inf, or 0 to use default */
+extern int Geqo_generations pg_attribute_hidden(); /* 1 .. inf, or 0 to use default */
-extern double Geqo_selection_bias;
+extern double Geqo_selection_bias pg_attribute_hidden();
#define DEFAULT_GEQO_SELECTION_BIAS 2.0
#define MIN_GEQO_SELECTION_BIAS 1.5
#define MAX_GEQO_SELECTION_BIAS 2.0
-extern double Geqo_seed; /* 0 .. 1 */
+extern double Geqo_seed pg_attribute_hidden(); /* 0 .. 1 */
/*
diff --git a/src/include/optimizer/optimizer.h b/src/include/optimizer/optimizer.h
index 41b49b2662..8d7ebb6216 100644
--- a/src/include/optimizer/optimizer.h
+++ b/src/include/optimizer/optimizer.h
@@ -111,8 +111,8 @@ typedef enum
} ForceParallelMode;
/* GUC parameters */
-extern int force_parallel_mode;
-extern bool parallel_leader_participation;
+extern int force_parallel_mode pg_attribute_hidden();
+extern bool parallel_leader_participation pg_attribute_hidden();
extern struct PlannedStmt *planner(Query *parse, const char *query_string,
int cursorOptions,
diff --git a/src/include/optimizer/planmain.h b/src/include/optimizer/planmain.h
index bf1adfc52a..112bd31b79 100644
--- a/src/include/optimizer/planmain.h
+++ b/src/include/optimizer/planmain.h
@@ -19,7 +19,7 @@
/* GUC parameters */
#define DEFAULT_CURSOR_TUPLE_FRACTION 0.1
-extern double cursor_tuple_fraction;
+extern double cursor_tuple_fraction pg_attribute_hidden();
/* query_planner callback to compute query_pathkeys */
typedef void (*query_pathkeys_callback) (PlannerInfo *root, void *extra);
@@ -64,8 +64,8 @@ extern Limit *make_limit(Plan *lefttree, Node *limitOffset, Node *limitCount,
/*
* prototypes for plan/initsplan.c
*/
-extern int from_collapse_limit;
-extern int join_collapse_limit;
+extern int from_collapse_limit pg_attribute_hidden();
+extern int join_collapse_limit pg_attribute_hidden();
extern void add_base_rels_to_query(PlannerInfo *root, Node *jtnode);
extern void add_other_rels_to_query(PlannerInfo *root);
diff --git a/src/include/parser/parse_expr.h b/src/include/parser/parse_expr.h
index 8ac4a0a369..6b72a0f550 100644
--- a/src/include/parser/parse_expr.h
+++ b/src/include/parser/parse_expr.h
@@ -16,7 +16,7 @@
#include "parser/parse_node.h"
/* GUC parameters */
-extern bool Transform_null_equals;
+extern bool Transform_null_equals pg_attribute_hidden();
extern Node *transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind);
diff --git a/src/include/parser/parser.h b/src/include/parser/parser.h
index 853b0f1606..e6f0c6d05e 100644
--- a/src/include/parser/parser.h
+++ b/src/include/parser/parser.h
@@ -53,8 +53,8 @@ typedef enum
} BackslashQuoteType;
/* GUC variables in scan.l (every one of these is a bad idea :-() */
-extern int backslash_quote;
-extern bool escape_string_warning;
+extern int backslash_quote pg_attribute_hidden();
+extern bool escape_string_warning pg_attribute_hidden();
extern PGDLLIMPORT bool standard_conforming_strings;
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 509849c7ff..7de7c5eeca 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -940,9 +940,9 @@ typedef struct PgStat_FunctionCallUsage
*/
extern PGDLLIMPORT bool pgstat_track_counts;
extern PGDLLIMPORT int pgstat_track_functions;
-extern char *pgstat_stat_directory;
-extern char *pgstat_stat_tmpname;
-extern char *pgstat_stat_filename;
+extern char *pgstat_stat_directory pg_attribute_hidden();
+extern char *pgstat_stat_tmpname pg_attribute_hidden();
+extern char *pgstat_stat_filename pg_attribute_hidden();
/*
* BgWriter statistics counters are updated directly by bgwriter and bufmgr
diff --git a/src/include/pgtime.h b/src/include/pgtime.h
index 28bd27e7f7..c5d4436503 100644
--- a/src/include/pgtime.h
+++ b/src/include/pgtime.h
@@ -71,7 +71,7 @@ extern size_t pg_strftime(char *s, size_t max, const char *format,
/* these functions and variables are in pgtz.c */
extern PGDLLIMPORT pg_tz *session_timezone;
-extern pg_tz *log_timezone;
+extern pg_tz *log_timezone pg_attribute_hidden();
extern void pg_timezone_initialize(void);
extern pg_tz *pg_tzset(const char *tzname);
diff --git a/src/include/postmaster/autovacuum.h b/src/include/postmaster/autovacuum.h
index aacdd0f575..0928c7a0ef 100644
--- a/src/include/postmaster/autovacuum.h
+++ b/src/include/postmaster/autovacuum.h
@@ -27,25 +27,25 @@ typedef enum
/* GUC variables */
-extern bool autovacuum_start_daemon;
-extern int autovacuum_max_workers;
-extern int autovacuum_work_mem;
-extern int autovacuum_naptime;
-extern int autovacuum_vac_thresh;
-extern double autovacuum_vac_scale;
-extern int autovacuum_vac_ins_thresh;
-extern double autovacuum_vac_ins_scale;
-extern int autovacuum_anl_thresh;
-extern double autovacuum_anl_scale;
-extern int autovacuum_freeze_max_age;
-extern int autovacuum_multixact_freeze_max_age;
-extern double autovacuum_vac_cost_delay;
-extern int autovacuum_vac_cost_limit;
+extern bool autovacuum_start_daemon pg_attribute_hidden();
+extern int autovacuum_max_workers pg_attribute_hidden();
+extern int autovacuum_work_mem pg_attribute_hidden();
+extern int autovacuum_naptime pg_attribute_hidden();
+extern int autovacuum_vac_thresh pg_attribute_hidden();
+extern double autovacuum_vac_scale pg_attribute_hidden();
+extern int autovacuum_vac_ins_thresh pg_attribute_hidden();
+extern double autovacuum_vac_ins_scale pg_attribute_hidden();
+extern int autovacuum_anl_thresh pg_attribute_hidden();
+extern double autovacuum_anl_scale pg_attribute_hidden();
+extern int autovacuum_freeze_max_age pg_attribute_hidden();
+extern int autovacuum_multixact_freeze_max_age pg_attribute_hidden();
+extern double autovacuum_vac_cost_delay pg_attribute_hidden();
+extern int autovacuum_vac_cost_limit pg_attribute_hidden();
/* autovacuum launcher PID, only valid when worker is shutting down */
extern int AutovacuumLauncherPid;
-extern int Log_autovacuum_min_duration;
+extern int Log_autovacuum_min_duration pg_attribute_hidden();
/* Status inquiry functions */
extern bool AutoVacuumingActive(void);
diff --git a/src/include/postmaster/bgwriter.h b/src/include/postmaster/bgwriter.h
index c430b1b236..72c4a244f7 100644
--- a/src/include/postmaster/bgwriter.h
+++ b/src/include/postmaster/bgwriter.h
@@ -22,10 +22,10 @@
/* GUC options */
-extern int BgWriterDelay;
-extern int CheckPointTimeout;
-extern int CheckPointWarning;
-extern double CheckPointCompletionTarget;
+extern int BgWriterDelay pg_attribute_hidden();
+extern int CheckPointTimeout pg_attribute_hidden();
+extern int CheckPointWarning pg_attribute_hidden();
+extern double CheckPointCompletionTarget pg_attribute_hidden();
extern void BackgroundWriterMain(void) pg_attribute_noreturn();
extern void CheckpointerMain(void) pg_attribute_noreturn();
diff --git a/src/include/postmaster/postmaster.h b/src/include/postmaster/postmaster.h
index 0efdd7c232..247a328aa7 100644
--- a/src/include/postmaster/postmaster.h
+++ b/src/include/postmaster/postmaster.h
@@ -14,22 +14,22 @@
#define _POSTMASTER_H
/* GUC options */
-extern bool EnableSSL;
-extern int ReservedBackends;
+extern bool EnableSSL pg_attribute_hidden();
+extern int ReservedBackends pg_attribute_hidden();
extern PGDLLIMPORT int PostPortNumber;
-extern int Unix_socket_permissions;
-extern char *Unix_socket_group;
-extern char *Unix_socket_directories;
-extern char *ListenAddresses;
+extern int Unix_socket_permissions pg_attribute_hidden();
+extern char *Unix_socket_group pg_attribute_hidden();
+extern char *Unix_socket_directories pg_attribute_hidden();
+extern char *ListenAddresses pg_attribute_hidden();
extern bool ClientAuthInProgress;
-extern int PreAuthDelay;
-extern int AuthenticationTimeout;
-extern bool Log_connections;
-extern bool log_hostname;
-extern bool enable_bonjour;
-extern char *bonjour_name;
-extern bool restart_after_crash;
-extern bool remove_temp_files_after_crash;
+extern int PreAuthDelay pg_attribute_hidden();
+extern int AuthenticationTimeout pg_attribute_hidden();
+extern bool Log_connections pg_attribute_hidden();
+extern bool log_hostname pg_attribute_hidden();
+extern bool enable_bonjour pg_attribute_hidden();
+extern char *bonjour_name pg_attribute_hidden();
+extern bool restart_after_crash pg_attribute_hidden();
+extern bool remove_temp_files_after_crash pg_attribute_hidden();
#ifdef WIN32
extern HANDLE PostmasterHandle;
diff --git a/src/include/postmaster/syslogger.h b/src/include/postmaster/syslogger.h
index 1491eecb0f..bfd5d59314 100644
--- a/src/include/postmaster/syslogger.h
+++ b/src/include/postmaster/syslogger.h
@@ -62,13 +62,13 @@ typedef union
/* GUC options */
-extern bool Logging_collector;
-extern int Log_RotationAge;
-extern int Log_RotationSize;
+extern bool Logging_collector pg_attribute_hidden();
+extern int Log_RotationAge pg_attribute_hidden();
+extern int Log_RotationSize pg_attribute_hidden();
extern PGDLLIMPORT char *Log_directory;
extern PGDLLIMPORT char *Log_filename;
-extern bool Log_truncate_on_rotation;
-extern int Log_file_mode;
+extern bool Log_truncate_on_rotation pg_attribute_hidden();
+extern int Log_file_mode pg_attribute_hidden();
#ifndef WIN32
extern int syslogPipe[2];
diff --git a/src/include/postmaster/walwriter.h b/src/include/postmaster/walwriter.h
index 3ccc332333..ea72ff74bd 100644
--- a/src/include/postmaster/walwriter.h
+++ b/src/include/postmaster/walwriter.h
@@ -13,8 +13,8 @@
#define _WALWRITER_H
/* GUC options */
-extern int WalWriterDelay;
-extern int WalWriterFlushAfter;
+extern int WalWriterDelay pg_attribute_hidden();
+extern int WalWriterFlushAfter pg_attribute_hidden();
extern void WalWriterMain(void) pg_attribute_noreturn();
diff --git a/src/include/replication/logicallauncher.h b/src/include/replication/logicallauncher.h
index 301e494f7b..eb11346e05 100644
--- a/src/include/replication/logicallauncher.h
+++ b/src/include/replication/logicallauncher.h
@@ -12,8 +12,8 @@
#ifndef LOGICALLAUNCHER_H
#define LOGICALLAUNCHER_H
-extern int max_logical_replication_workers;
-extern int max_sync_workers_per_subscription;
+extern int max_logical_replication_workers pg_attribute_hidden();
+extern int max_sync_workers_per_subscription pg_attribute_hidden();
extern void ApplyLauncherRegister(void);
extern void ApplyLauncherMain(Datum main_arg);
diff --git a/src/include/replication/syncrep.h b/src/include/replication/syncrep.h
index 4266afde8b..5f299076bd 100644
--- a/src/include/replication/syncrep.h
+++ b/src/include/replication/syncrep.h
@@ -79,7 +79,7 @@ extern SyncRepConfigData *syncrep_parse_result;
extern char *syncrep_parse_error_msg;
/* user-settable parameters for synchronous replication */
-extern char *SyncRepStandbyNames;
+extern char *SyncRepStandbyNames pg_attribute_hidden();
/* called by user backend */
extern void SyncRepWaitForLSN(XLogRecPtr lsn, bool commit);
diff --git a/src/include/replication/walreceiver.h b/src/include/replication/walreceiver.h
index 0b607ed777..929a8f05d6 100644
--- a/src/include/replication/walreceiver.h
+++ b/src/include/replication/walreceiver.h
@@ -25,9 +25,9 @@
#include "utils/tuplestore.h"
/* user-settable parameters */
-extern int wal_receiver_status_interval;
-extern int wal_receiver_timeout;
-extern bool hot_standby_feedback;
+extern int wal_receiver_status_interval pg_attribute_hidden();
+extern int wal_receiver_timeout pg_attribute_hidden();
+extern bool hot_standby_feedback pg_attribute_hidden();
/*
* MAXCONNINFO: maximum size of a connection string.
diff --git a/src/include/replication/walsender.h b/src/include/replication/walsender.h
index 828106933c..660906beb4 100644
--- a/src/include/replication/walsender.h
+++ b/src/include/replication/walsender.h
@@ -31,9 +31,9 @@ extern bool am_db_walsender;
extern bool wake_wal_senders;
/* user-settable parameters */
-extern int max_wal_senders;
-extern int wal_sender_timeout;
-extern bool log_replication_commands;
+extern int max_wal_senders pg_attribute_hidden();
+extern int wal_sender_timeout pg_attribute_hidden();
+extern bool log_replication_commands pg_attribute_hidden();
extern void InitWalSender(void);
extern bool exec_replication_command(const char *query_string);
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index cfce23ecbc..7203d0dd1f 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -65,16 +65,16 @@ struct SMgrRelationData;
extern PGDLLIMPORT int NBuffers;
/* in bufmgr.c */
-extern bool zero_damaged_pages;
-extern int bgwriter_lru_maxpages;
-extern double bgwriter_lru_multiplier;
-extern bool track_io_timing;
-extern int effective_io_concurrency;
-extern int maintenance_io_concurrency;
-
-extern int checkpoint_flush_after;
-extern int backend_flush_after;
-extern int bgwriter_flush_after;
+extern bool zero_damaged_pages pg_attribute_hidden();
+extern int bgwriter_lru_maxpages pg_attribute_hidden();
+extern double bgwriter_lru_multiplier pg_attribute_hidden();
+extern bool track_io_timing pg_attribute_hidden();
+extern int effective_io_concurrency pg_attribute_hidden();
+extern int maintenance_io_concurrency pg_attribute_hidden();
+
+extern int checkpoint_flush_after pg_attribute_hidden();
+extern int backend_flush_after pg_attribute_hidden();
+extern int bgwriter_flush_after pg_attribute_hidden();
/* in buf_init.c */
extern PGDLLIMPORT char *BufferBlocks;
diff --git a/src/include/storage/dsm_impl.h b/src/include/storage/dsm_impl.h
index ff72f7b0e5..ed2d36aa25 100644
--- a/src/include/storage/dsm_impl.h
+++ b/src/include/storage/dsm_impl.h
@@ -39,8 +39,8 @@
#endif
/* GUC. */
-extern int dynamic_shared_memory_type;
-extern int min_dynamic_shared_memory;
+extern int dynamic_shared_memory_type pg_attribute_hidden();
+extern int min_dynamic_shared_memory pg_attribute_hidden();
/*
* Directory for on-disk state.
diff --git a/src/include/storage/fd.h b/src/include/storage/fd.h
index 34602ae006..e2dc043191 100644
--- a/src/include/storage/fd.h
+++ b/src/include/storage/fd.h
@@ -59,7 +59,7 @@ typedef int File;
/* GUC parameter */
extern PGDLLIMPORT int max_files_per_process;
extern PGDLLIMPORT bool data_sync_retry;
-extern int recovery_init_sync_method;
+extern int recovery_init_sync_method pg_attribute_hidden();
/*
* This is private to fd.c, but exported for save/restore_backend_variables()
diff --git a/src/include/storage/large_object.h b/src/include/storage/large_object.h
index ae1e2482ea..a7ec3052fd 100644
--- a/src/include/storage/large_object.h
+++ b/src/include/storage/large_object.h
@@ -79,7 +79,7 @@ typedef struct LargeObjectDesc
/*
* GUC: backwards-compatibility flag to suppress LO permission checks
*/
-extern bool lo_compat_privileges;
+extern bool lo_compat_privileges pg_attribute_hidden();
/*
* Function definitions...
diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h
index 9b2a421c32..e63fbebae9 100644
--- a/src/include/storage/lock.h
+++ b/src/include/storage/lock.h
@@ -34,14 +34,14 @@ typedef struct PROC_QUEUE
} PROC_QUEUE;
/* GUC variables */
-extern int max_locks_per_xact;
+extern int max_locks_per_xact pg_attribute_hidden();
#ifdef LOCK_DEBUG
-extern int Trace_lock_oidmin;
-extern bool Trace_locks;
-extern bool Trace_userlocks;
-extern int Trace_lock_table;
-extern bool Debug_deadlocks;
+extern int Trace_lock_oidmin pg_attribute_hidden();
+extern bool Trace_locks pg_attribute_hidden();
+extern bool Trace_userlocks pg_attribute_hidden();
+extern int Trace_lock_table pg_attribute_hidden();
+extern bool Debug_deadlocks pg_attribute_hidden();
#endif /* LOCK_DEBUG */
diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h
index a8f052e484..5c339662ef 100644
--- a/src/include/storage/lwlock.h
+++ b/src/include/storage/lwlock.h
@@ -110,7 +110,7 @@ typedef enum LWLockMode
#ifdef LOCK_DEBUG
-extern bool Trace_lwlocks;
+extern bool Trace_lwlocks pg_attribute_hidden();
#endif
extern bool LWLockAcquire(LWLock *lock, LWLockMode mode);
diff --git a/src/include/storage/pg_shmem.h b/src/include/storage/pg_shmem.h
index 059df1b72c..f44fcc3de7 100644
--- a/src/include/storage/pg_shmem.h
+++ b/src/include/storage/pg_shmem.h
@@ -42,9 +42,9 @@ typedef struct PGShmemHeader /* standard header for all Postgres shmem */
} PGShmemHeader;
/* GUC variables */
-extern int shared_memory_type;
-extern int huge_pages;
-extern int huge_page_size;
+extern int shared_memory_type pg_attribute_hidden();
+extern int huge_pages pg_attribute_hidden();
+extern int huge_page_size pg_attribute_hidden();
/* Possible values for huge_pages */
typedef enum
diff --git a/src/include/storage/predicate.h b/src/include/storage/predicate.h
index 152b698611..81154c2321 100644
--- a/src/include/storage/predicate.h
+++ b/src/include/storage/predicate.h
@@ -22,9 +22,9 @@
/*
* GUC variables
*/
-extern int max_predicate_locks_per_xact;
-extern int max_predicate_locks_per_relation;
-extern int max_predicate_locks_per_page;
+extern int max_predicate_locks_per_xact pg_attribute_hidden();
+extern int max_predicate_locks_per_relation pg_attribute_hidden();
+extern int max_predicate_locks_per_page pg_attribute_hidden();
/* Number of SLRU buffers to use for Serial SLRU */
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
index be67d8a861..c07c9948c0 100644
--- a/src/include/storage/proc.h
+++ b/src/include/storage/proc.h
@@ -382,7 +382,7 @@ extern PGDLLIMPORT int StatementTimeout;
extern PGDLLIMPORT int LockTimeout;
extern PGDLLIMPORT int IdleInTransactionSessionTimeout;
extern PGDLLIMPORT int IdleSessionTimeout;
-extern bool log_lock_waits;
+extern bool log_lock_waits pg_attribute_hidden();
/*
diff --git a/src/include/storage/standby.h b/src/include/storage/standby.h
index 38fd85a431..cebfcf2288 100644
--- a/src/include/storage/standby.h
+++ b/src/include/storage/standby.h
@@ -21,10 +21,10 @@
#include "storage/standbydefs.h"
/* User-settable GUC parameters */
-extern int vacuum_defer_cleanup_age;
-extern int max_standby_archive_delay;
-extern int max_standby_streaming_delay;
-extern bool log_recovery_conflict_waits;
+extern int vacuum_defer_cleanup_age pg_attribute_hidden();
+extern int max_standby_archive_delay pg_attribute_hidden();
+extern int max_standby_streaming_delay pg_attribute_hidden();
+extern bool log_recovery_conflict_waits pg_attribute_hidden();
extern void InitRecoveryTransactionEnvironment(void);
extern void ShutdownRecoveryTransactionEnvironment(void);
diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h
index 968345404e..87cf1327c7 100644
--- a/src/include/tcop/tcopprot.h
+++ b/src/include/tcop/tcopprot.h
@@ -27,9 +27,9 @@
extern CommandDest whereToSendOutput;
extern PGDLLIMPORT const char *debug_query_string;
-extern int max_stack_depth;
-extern int PostAuthDelay;
-extern int client_connection_check_interval;
+extern int max_stack_depth pg_attribute_hidden();
+extern int PostAuthDelay pg_attribute_hidden();
+extern int client_connection_check_interval pg_attribute_hidden();
/* GUC-configurable parameters */
diff --git a/src/include/tsearch/ts_cache.h b/src/include/tsearch/ts_cache.h
index 888f7028b1..a03412ed8c 100644
--- a/src/include/tsearch/ts_cache.h
+++ b/src/include/tsearch/ts_cache.h
@@ -84,7 +84,7 @@ typedef struct
/*
* GUC variable for current configuration
*/
-extern char *TSCurrentConfig;
+extern char *TSCurrentConfig pg_attribute_hidden();
extern TSParserCacheEntry *lookup_ts_parser_cache(Oid prsId);
diff --git a/src/include/utils/array.h b/src/include/utils/array.h
index 4ae6c3be2f..eeeb2f7995 100644
--- a/src/include/utils/array.h
+++ b/src/include/utils/array.h
@@ -339,7 +339,7 @@ typedef struct ArrayIteratorData *ArrayIterator;
/*
* GUC parameter
*/
-extern bool Array_nulls;
+extern bool Array_nulls pg_attribute_hidden();
/*
* prototypes for functions defined in arrayfuncs.c
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index 40fcb0ab6d..986a97b193 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -65,7 +65,7 @@ extern char *regexp_fixed_prefix(text *text_re, bool case_insensitive,
Oid collation, bool *exact);
/* ruleutils.c */
-extern bool quote_all_identifiers;
+extern bool quote_all_identifiers pg_attribute_hidden();
extern const char *quote_identifier(const char *ident);
extern char *quote_qualified_identifier(const char *qualifier,
const char *ident);
diff --git a/src/include/utils/bytea.h b/src/include/utils/bytea.h
index eb9df9e4f7..0bf0631f39 100644
--- a/src/include/utils/bytea.h
+++ b/src/include/utils/bytea.h
@@ -22,6 +22,6 @@ typedef enum
BYTEA_OUTPUT_HEX
} ByteaOutputType;
-extern int bytea_output; /* ByteaOutputType, but int for GUC enum */
+extern int bytea_output pg_attribute_hidden(); /* ByteaOutputType, but int for GUC enum */
#endif /* BYTEA_H */
diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h
index f53607e12e..76ac92e4a1 100644
--- a/src/include/utils/elog.h
+++ b/src/include/utils/elog.h
@@ -424,12 +424,12 @@ typedef enum
PGERROR_VERBOSE /* all the facts, ma'am */
} PGErrorVerbosity;
-extern int Log_error_verbosity;
-extern char *Log_line_prefix;
+extern int Log_error_verbosity pg_attribute_hidden();
+extern char *Log_line_prefix pg_attribute_hidden();
extern int Log_destination;
-extern char *Log_destination_string;
-extern bool syslog_sequence_numbers;
-extern bool syslog_split_messages;
+extern char *Log_destination_string pg_attribute_hidden();
+extern bool syslog_sequence_numbers pg_attribute_hidden();
+extern bool syslog_split_messages pg_attribute_hidden();
/* Log destination bitmap */
#define LOG_DESTINATION_STDERR 1
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index a7c3a4958e..4bbf76c3dc 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -233,53 +233,53 @@ typedef enum
/* GUC vars that are actually declared in guc.c, rather than elsewhere */
-extern bool Debug_print_plan;
-extern bool Debug_print_parse;
-extern bool Debug_print_rewritten;
-extern bool Debug_pretty_print;
+extern bool Debug_print_plan pg_attribute_hidden();
+extern bool Debug_print_parse pg_attribute_hidden();
+extern bool Debug_print_rewritten pg_attribute_hidden();
+extern bool Debug_pretty_print pg_attribute_hidden();
-extern bool log_parser_stats;
-extern bool log_planner_stats;
-extern bool log_executor_stats;
-extern bool log_statement_stats;
-extern bool log_btree_build_stats;
+extern bool log_parser_stats pg_attribute_hidden();
+extern bool log_planner_stats pg_attribute_hidden();
+extern bool log_executor_stats pg_attribute_hidden();
+extern bool log_statement_stats pg_attribute_hidden();
+extern bool log_btree_build_stats pg_attribute_hidden();
extern PGDLLIMPORT bool check_function_bodies;
-extern bool session_auth_is_superuser;
+extern bool session_auth_is_superuser pg_attribute_hidden();
-extern bool log_duration;
-extern int log_parameter_max_length;
-extern int log_parameter_max_length_on_error;
-extern int log_min_error_statement;
+extern bool log_duration pg_attribute_hidden();
+extern int log_parameter_max_length pg_attribute_hidden();
+extern int log_parameter_max_length_on_error pg_attribute_hidden();
+extern int log_min_error_statement pg_attribute_hidden();
extern PGDLLIMPORT int log_min_messages;
extern PGDLLIMPORT int client_min_messages;
-extern int log_min_duration_sample;
-extern int log_min_duration_statement;
-extern int log_temp_files;
-extern double log_statement_sample_rate;
-extern double log_xact_sample_rate;
-extern char *backtrace_functions;
+extern int log_min_duration_sample pg_attribute_hidden();
+extern int log_min_duration_statement pg_attribute_hidden();
+extern int log_temp_files pg_attribute_hidden();
+extern double log_statement_sample_rate pg_attribute_hidden();
+extern double log_xact_sample_rate pg_attribute_hidden();
+extern char *backtrace_functions pg_attribute_hidden();
extern char *backtrace_symbol_list;
-extern int temp_file_limit;
+extern int temp_file_limit pg_attribute_hidden();
-extern int num_temp_buffers;
+extern int num_temp_buffers pg_attribute_hidden();
-extern char *cluster_name;
+extern char *cluster_name pg_attribute_hidden();
extern PGDLLIMPORT char *ConfigFileName;
-extern char *HbaFileName;
-extern char *IdentFileName;
-extern char *external_pid_file;
+extern char *HbaFileName pg_attribute_hidden();
+extern char *IdentFileName pg_attribute_hidden();
+extern char *external_pid_file pg_attribute_hidden();
extern PGDLLIMPORT char *application_name;
-extern int tcp_keepalives_idle;
-extern int tcp_keepalives_interval;
-extern int tcp_keepalives_count;
-extern int tcp_user_timeout;
+extern int tcp_keepalives_idle pg_attribute_hidden();
+extern int tcp_keepalives_interval pg_attribute_hidden();
+extern int tcp_keepalives_count pg_attribute_hidden();
+extern int tcp_user_timeout pg_attribute_hidden();
#ifdef TRACE_SORT
-extern bool trace_sort;
+extern bool trace_sort pg_attribute_hidden();
#endif
/*
diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h
index 2946f46c76..202578c227 100644
--- a/src/include/utils/pg_locale.h
+++ b/src/include/utils/pg_locale.h
@@ -36,10 +36,10 @@
/* GUC settings */
-extern char *locale_messages;
-extern char *locale_monetary;
-extern char *locale_numeric;
-extern char *locale_time;
+extern char *locale_messages pg_attribute_hidden();
+extern char *locale_monetary pg_attribute_hidden();
+extern char *locale_numeric pg_attribute_hidden();
+extern char *locale_time pg_attribute_hidden();
/* lc_time localization cache */
extern char *localized_abbrev_days[];
diff --git a/src/include/utils/plancache.h b/src/include/utils/plancache.h
index ff09c63a02..39f5dbdbd6 100644
--- a/src/include/utils/plancache.h
+++ b/src/include/utils/plancache.h
@@ -35,7 +35,7 @@ typedef enum
} PlanCacheMode;
/* GUC parameter */
-extern int plan_cache_mode;
+extern int plan_cache_mode pg_attribute_hidden();
#define CACHEDPLANSOURCE_MAGIC 195726186
#define CACHEDPLAN_MAGIC 953717834
diff --git a/src/include/utils/ps_status.h b/src/include/utils/ps_status.h
index 9f43e1fdf0..1682b02f8e 100644
--- a/src/include/utils/ps_status.h
+++ b/src/include/utils/ps_status.h
@@ -12,7 +12,7 @@
#ifndef PS_STATUS_H
#define PS_STATUS_H
-extern bool update_process_title;
+extern bool update_process_title pg_attribute_hidden();
extern char **save_ps_display_args(int argc, char **argv);
diff --git a/src/include/utils/queryjumble.h b/src/include/utils/queryjumble.h
index 7af6652f3e..38bc6e3f19 100644
--- a/src/include/utils/queryjumble.h
+++ b/src/include/utils/queryjumble.h
@@ -61,7 +61,7 @@ enum ComputeQueryIdType
};
/* GUC parameters */
-extern int compute_query_id;
+extern int compute_query_id pg_attribute_hidden();
extern const char *CleanQuerytext(const char *query, int *location, int *len);
diff --git a/src/include/utils/rls.h b/src/include/utils/rls.h
index 46b32347c3..c1bc1d8029 100644
--- a/src/include/utils/rls.h
+++ b/src/include/utils/rls.h
@@ -14,7 +14,7 @@
#define RLS_H
/* GUC variable */
-extern bool row_security;
+extern bool row_security pg_attribute_hidden();
/*
* Used by callers of check_enable_rls.
diff --git a/src/include/utils/xml.h b/src/include/utils/xml.h
index d79668f3c4..12721051c6 100644
--- a/src/include/utils/xml.h
+++ b/src/include/utils/xml.h
@@ -75,9 +75,9 @@ extern char *map_sql_identifier_to_xml_name(const char *ident, bool fully_escape
extern char *map_xml_name_to_sql_identifier(const char *name);
extern char *map_sql_value_to_xml_value(Datum value, Oid type, bool xml_escape_strings);
-extern int xmlbinary; /* XmlBinaryType, but int for guc enum */
+extern int xmlbinary pg_attribute_hidden(); /* XmlBinaryType, but int for guc enum */
-extern int xmloption; /* XmlOptionType, but int for guc enum */
+extern int xmloption pg_attribute_hidden(); /* XmlOptionType, but int for guc enum */
extern const TableFuncRoutine XmlTableRoutine;
--
2.32.0
On Sun, Aug 22, 2021 at 09:29:01PM +0800, Julien Rouhaud wrote:
On Sun, Aug 22, 2021 at 09:19:42AM -0400, Tom Lane wrote:
Uh, no, it's exactly *not* clear. There are a lot of GUCs that are only
of interest to particular subsystems. I do not see why being a GUC makes
something automatically more interesting than any other global variable.
Usually, the fact that one is global is only so the GUC machinery itself
can get at it, otherwise it'd be static in the owning module.As for "extensions should be able to get at the values", the GUC machinery
already provides uniform mechanisms for doing that safely. Direct access
to the variable's internal value would be unsafe in many cases.Then shouldn't we try to prevent direct access on all platforms rather than
only one?
Agreed. If Julian says 99% of the non-export problems are GUCs, and we
can just export them all, why not do it? We already export every global
variable on Unix-like systems, and we have seen no downsides.
--
Bruce Momjian <bruce@momjian.us> https://momjian.us
EDB https://enterprisedb.com
If only the physical world exists, free will is an illusion.
Bruce Momjian <bruce@momjian.us> writes:
On Sun, Aug 22, 2021 at 09:29:01PM +0800, Julien Rouhaud wrote:
Then shouldn't we try to prevent direct access on all platforms rather than
only one?
Agreed. If Julian says 99% of the non-export problems are GUCs, and we
can just export them all, why not do it? We already export every global
variable on Unix-like systems, and we have seen no downsides.
By that argument, *every* globally-visible variable should be marked
PGDLLIMPORT. But the mere fact that two backend .c files need to access
some variable doesn't mean that we want any random bit of code doing so.
And yes, I absolutely would prohibit extensions from accessing many
of them, if there were a reasonable way to do it. It would be a good
start towards establishing a defined API for extensions.
regards, tom lane
On Mon, Aug 23, 2021 at 10:15:04AM -0400, Tom Lane wrote:
Bruce Momjian <bruce@momjian.us> writes:
On Sun, Aug 22, 2021 at 09:29:01PM +0800, Julien Rouhaud wrote:
Then shouldn't we try to prevent direct access on all platforms rather than
only one?Agreed. If Julian says 99% of the non-export problems are GUCs, and we
can just export them all, why not do it? We already export every global
variable on Unix-like systems, and we have seen no downsides.By that argument, *every* globally-visible variable should be marked
PGDLLIMPORT. But the mere fact that two backend .c files need to access
No, Julien says 99% need only the GUCs, so that is not the argument I am
making.
some variable doesn't mean that we want any random bit of code doing so.
And yes, I absolutely would prohibit extensions from accessing many
of them, if there were a reasonable way to do it. It would be a good
start towards establishing a defined API for extensions.
Well, if Unix needed it, we would have addressed this more regularly,
but since it is only Windows that has this _feature_, it is the rare
Windows cases that need adjustment, and usually as an afterthought since
Windows isn't usually a primary tested platform.
What I am saying is that if we blocked global variable access on Unix,
initial testing would have showed what needs to be exported and it would
not be as big a problem.
--
Bruce Momjian <bruce@momjian.us> https://momjian.us
EDB https://enterprisedb.com
If only the physical world exists, free will is an illusion.
Bruce Momjian <bruce@momjian.us> writes:
On Mon, Aug 23, 2021 at 10:15:04AM -0400, Tom Lane wrote:
By that argument, *every* globally-visible variable should be marked
PGDLLIMPORT. But the mere fact that two backend .c files need to access
No, Julien says 99% need only the GUCs, so that is not the argument I am
making.
That's a claim unbacked by any evidence that I've seen. More to
the point, we already have a mechanism that extensions can/should
use to read and write GUC settings, and it's not direct access.
regards, tom lane
On Mon, Aug 23, 2021 at 10:22:51AM -0400, Tom Lane wrote:
Bruce Momjian <bruce@momjian.us> writes:
On Mon, Aug 23, 2021 at 10:15:04AM -0400, Tom Lane wrote:
By that argument, *every* globally-visible variable should be marked
PGDLLIMPORT. But the mere fact that two backend .c files need to accessNo, Julien says 99% need only the GUCs, so that is not the argument I am
making.That's a claim unbacked by any evidence that I've seen. More to
the point, we already have a mechanism that extensions can/should
use to read and write GUC settings, and it's not direct access.
So the problem is that extensions only _need_ to use that API on
Windows, so many initially don't, or that the API is too limited?
--
Bruce Momjian <bruce@momjian.us> https://momjian.us
EDB https://enterprisedb.com
If only the physical world exists, free will is an illusion.
On Mon, Aug 23, 2021 at 10:22 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
Bruce Momjian <bruce@momjian.us> writes:
On Mon, Aug 23, 2021 at 10:15:04AM -0400, Tom Lane wrote:
By that argument, *every* globally-visible variable should be marked
PGDLLIMPORT. But the mere fact that two backend .c files need to accessNo, Julien says 99% need only the GUCs, so that is not the argument I am
making.That's a claim unbacked by any evidence that I've seen. More to
the point, we already have a mechanism that extensions can/should
use to read and write GUC settings, and it's not direct access.
I clearly didn't try all single extension available out there. It's
excessively annoying to compile extensions on Windows, and also I
don't have a lot of dependencies installed so there are some that I
wasn't able to test since I'm lacking some other lib and given my
absolute lack of knowledge of that platform I didn't spent time trying
to install those.
I think I tested a dozen of "small" extensions (I'm assuming that the
big one like postgis would require too much effort to build, and they
probably already take care of Windows compatibility), and I only faced
this problem. That's maybe not a representative set, but I also doubt
that I was unlucky enough to find the few only exceptions.
On Mon, Aug 23, 2021 at 10:36 PM Bruce Momjian <bruce@momjian.us> wrote:
So the problem is that extensions only _need_ to use that API on
Windows, so many initially don't, or that the API is too limited?
The inconvenience with that API is that it's only returning c strings,
so you gave to convert it back to the original datatype. That's
probably why most of the extensions simply read from the original
exposed variable rather than using the API, because they're usually
written on Linux or similar, not because they want to mess up the
stored value.
On Mon, Aug 23, 2021 at 10:15 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
And yes, I absolutely would prohibit extensions from accessing many
of them, if there were a reasonable way to do it. It would be a good
start towards establishing a defined API for extensions.
The v2 patch I sent does that, at least when compiling with GCC. I
didn't find something similar for clang, but I only checked quickly.
I'm assuming that the unreasonable part is having to add some extra
attribute to the variable? Would it be acceptable if wrapped into
some other macro, as I proposed?
On Mon, Aug 23, 2021 at 10:15 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
And yes, I absolutely would prohibit extensions from accessing many
of them, if there were a reasonable way to do it. It would be a good
start towards establishing a defined API for extensions.
Mostly, it would make extension development more difficult for no
discernable benefit to the project.
You've made this argument many times over the years ... but we're no
closer to having an extension API than we ever were, and we continue
to get complaints about breaking stuff on Windows on a pretty regular
basis.
Honestly, it seems unimaginable that an API is ever really going to be
possible. It would be a ton of work to maintain, and we'd just end up
breaking it every time we discover that there's a new feature we want
to implement which doesn't fit into the defined API now. That's what
we do *now* with functions that third-party extensions actually call,
and with variables that they access, and it's not something that, in
my experience, is any great problem in maintaining an extension.
You're running code that is running inside somebody else's executable
and sometimes you have to adjust it for upstream changes. That's life,
and I don't think that complaints about that topic are nearly as
frequent as complaints about extensions breaking on Windows because of
missing PGDLLIMPORT markings.
And more than that, I'm pretty sure that you've previously taken the
view that we shouldn't document all the hook functions that only exist
in the backend for the purpose of extension use. I think you would
argue against a patch to go and document all the variables that are
marked PGDLLIMPORT now. So it seems to me that you're for an API when
it means that we don't have to change anything, and against an API
when it means that we don't have to change anything, which doesn't
really seem like a consistent position. I think we should be
responding to the real, expressed needs of extension developers, and
the lack of PGDLLIMPORT markings on various global variables is surely
top of the list.
It's also a bit unfair to say, well we have APIs for accessing GUC
values. It's true that we do. But if the GUC variable is, say, a
Boolean, you do not want your extension to call some function that
does a bunch of shenanigans and returns a string so that you can then
turn around and parse the string to recover the Boolean value. Even
moreso if the value is an integer or a comma-separated list. You want
to access the value as the system represents it internally, not
duplicate the parsing logic in a way that is inefficient and
bug-prone.
In short, +1 from me for the original proposal of marking all GUCs as
PGDLLIMPORT. And, heck, +1 for marking all the other global variables
that way, too. We're not solving any problem here. We're just annoying
people, mostly people who are loyal community members and steady
contributors to the project.
--
Robert Haas
EDB: http://www.enterprisedb.com
On 08/23/21 10:36, Bruce Momjian wrote:
So the problem is that extensions only _need_ to use that API on
Windows, so many initially don't, or that the API is too limited?
I think there can be cases where it's too limited, such as when significant
computation or validation is needed between the form of the setting known
to the GUC machinery and the form that would otherwise be available in
the global.
I'm thinking, for instance, of the old example before session_timezone
was PGDLLIMPORTed, and you'd have to GETCONFIGOPTION("timezone") and
repeat the work done by pg_tzset to validate and map the timezone name
through the timezone database, to reconstruct the value that was
otherwise already available in session_timezone.
Maybe those cases aren't very numerous ... and maybe they're distinctive
enough to recognize when creating one ("hmm, I am creating a check or
assign hook that does significant work here, will it be worth exposing
a getter API for the product of the work?").
Regards,
-Chap
On 2021-Aug-23, Robert Haas wrote:
It's also a bit unfair to say, well we have APIs for accessing GUC
values. It's true that we do. But if the GUC variable is, say, a
Boolean, you do not want your extension to call some function that
does a bunch of shenanigans and returns a string so that you can then
turn around and parse the string to recover the Boolean value. Even
moreso if the value is an integer or a comma-separated list. You want
to access the value as the system represents it internally, not
duplicate the parsing logic in a way that is inefficient and
bug-prone.
In that case, why not improve the API with functions that return the
values in some native datatype? For scalars with native C types (int,
floats, Boolean etc) this is easy enough; I bet it'll solve 99% of the
problems or more.
--
Álvaro Herrera 39°49'30"S 73°17'W — https://www.EnterpriseDB.com/
On 08/23/21 10:57, Chapman Flack wrote:
Maybe those cases aren't very numerous ... and maybe they're distinctive
enough to recognize when creating one ("hmm, I am creating a check or
assign hook that does significant work here, will it be worth exposing
a getter API for the product of the work?").
How about a generic GetTypedConfigValue(char const *name, void *into) ?
By default the type of *into would correspond to the type of the GUC
(int for an enum) and would be returned directly from *conf->variable
by a getter hook installed by default when the GUC is defined. But the
definition could also supply a getter hook that would store a value of
a different type, or computed a different way, for a GUC where that's
appropriate.
The function return could be boolean, true if such a variable exists
and isn't a placeholder.
Pro: provides read access to the typed value of any GUC, without exposing
it to overwriting. Con: has to bsearch the GUCs every time the value
is wanted.
What I'd really like:
ObserveTypedConfigValue(char const *name, void *into, int *flags, int flag)
This would register an observer of the named GUC: whenever its typed value
changes, it is written at *into and flag is ORed into *flags.
This is more restrictive than allowing arbitrary code to be hooked into
GUC changes (as changes can happen at delicate times such as error
recovery), but allows an extension to always have the current typed
value available and to cheaply know when it has changed. Observers would
be updated in the normal course of processing a GUC change, eliminating
the bsearch-per-lookup cost of the first approach.
Thinkable?
Regards,
-Chap
On Mon, Aug 23, 2021 at 11:40 AM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:
In that case, why not improve the API with functions that return the
values in some native datatype? For scalars with native C types (int,
floats, Boolean etc) this is easy enough; I bet it'll solve 99% of the
problems or more.
Sure, but ... why bother?
The entire argument rests on the presumption that there is some harm
being done by people accessing the values directly, but I don't think
that's true. And, if it were true, it seems likely that this proposed
API would have the exact same problem, because it would let people do
exactly the same thing. And, going through this proposed API would
still be significantly more expensive than just accessing the bare
variables, because you'd at least have to do some kind of lookup based
on the GUC name to find the corresponding variable. It's just a
solution in search of a problem.
Nothing bad happens when people write extensions that access GUC
variables directly. It works totally, completely fine. Except on
Windows.
--
Robert Haas
EDB: http://www.enterprisedb.com
On Mon, Aug 23, 2021 at 7:57 AM Robert Haas <robertmhaas@gmail.com> wrote:
In short, +1 from me for the original proposal of marking all GUCs as
PGDLLIMPORT.
+1
And, heck, +1 for marking all the other global variables
that way, too. We're not solving any problem here. We're just annoying
people, mostly people who are loyal community members and steady
contributors to the project.
I'm +0.5 on this aspect -- the result might be a lot of verbosity for
no possible benefit.
I'm not sure how many global variables there are. Hopefully not that
many. Maybe making adding new global variables annoying would be a
useful disincentive -- sometimes we use global variables when it isn't
particularly natural (it's natural with GUCs, but not other things).
That might tip the scales, at least for me.
Unnecessary use of global variables are why Postgres 13 went through
several point releases before I accidentally found out that parallel
VACUUM doesn't respect cost limits -- a very simple bug concerning how
we propagate (or fail to propagate) state to parallel workers. I bet
it would have taken far longer for the bug to be discovered if it
wasn't for my Postgres 14 VACUUM refactoring work.
--
Peter Geoghegan
On Mon, Aug 23, 2021 at 10:56:52AM -0400, Robert Haas wrote:
On Mon, Aug 23, 2021 at 10:15 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
And yes, I absolutely would prohibit extensions from accessing many
of them, if there were a reasonable way to do it. It would be a good
start towards establishing a defined API for extensions.Mostly, it would make extension development more difficult for no
discernable benefit to the project.You've made this argument many times over the years ... but we're no
closer to having an extension API than we ever were, and we continue
to get complaints about breaking stuff on Windows on a pretty regular
basis.Honestly, it seems unimaginable that an API is ever really going to be
possible. It would be a ton of work to maintain, and we'd just end up
breaking it every time we discover that there's a new feature we want
to implement which doesn't fit into the defined API now. That's what
we do *now* with functions that third-party extensions actually call,
and with variables that they access, and it's not something that, in
my experience, is any great problem in maintaining an extension.
You're running code that is running inside somebody else's executable
and sometimes you have to adjust it for upstream changes. That's life,
and I don't think that complaints about that topic are nearly as
frequent as complaints about extensions breaking on Windows because of
missing PGDLLIMPORT markings.And more than that, I'm pretty sure that you've previously taken the
view that we shouldn't document all the hook functions that only exist
in the backend for the purpose of extension use.
As the person on the receiving end of that one, I was nonplussed, so I
took a step back to think it over. I recognized at that time that I
didn't have a great answer for a legitimate concern, namely that any
change, however trivial, that goes into the core and doesn't go
directly to core database functionality, represents a long-term
maintenance burden.
The thing I'm coming to is that the key architectural feature
PostgreSQL has that other RDBMSs don't is its extensibility. Because
that's been a stable feature over time, I'm pretty sure we actually
need to see documenting that as a thing that does actually go to core
database functionality. Yes, there are resources involved with doing a
thing like this, but I don't think that they require constant or even
frequent attention from committers or even from seasoned DB hackers.
Best,
David.
--
David Fetter <david(at)fetter(dot)org> http://fetter.org/
Phone: +1 415 235 3778
Remember to vote!
Consider donating to Postgres: http://www.postgresql.org/about/donate
On 08/23/21 14:30, Robert Haas wrote:
it seems likely that this proposed
API would have the exact same problem, because it would let people do
exactly the same thing. And, going through this proposed API would
still be significantly more expensive than just accessing the bare
variables, because you'd at least have to do some kind of lookup based
on the GUC name
I think the API ideas in [0]/messages/by-id/6123C425.3080409@anastigmatix.net would not let people do exactly the same thing.
They would avoid exposing the bare variables to overwrite. Not that
there has been any plague of extensions going and overwriting GUCs,
but I think in some messages on this thread I detected a sense that
in principle it's better if an API precludes it, and that makes sense
to me.
The second idea also avoids the expense of name-based lookup (except once
at extension initialization), and in fact minimizes the cost of obtaining
the current value when needed, by slightly increasing the infrequent cost
of updating values.
Regards,
-Chap
po 23. 8. 2021 v 23:08 odesílatel Chapman Flack <chap@anastigmatix.net>
napsal:
On 08/23/21 14:30, Robert Haas wrote:
it seems likely that this proposed
API would have the exact same problem, because it would let people do
exactly the same thing. And, going through this proposed API would
still be significantly more expensive than just accessing the bare
variables, because you'd at least have to do some kind of lookup based
on the GUC nameI think the API ideas in [0] would not let people do exactly the same
thing.They would avoid exposing the bare variables to overwrite. Not that
there has been any plague of extensions going and overwriting GUCs,
but I think in some messages on this thread I detected a sense that
in principle it's better if an API precludes it, and that makes sense
to me.The second idea also avoids the expense of name-based lookup (except once
at extension initialization), and in fact minimizes the cost of obtaining
the current value when needed, by slightly increasing the infrequent cost
of updating values.
There are few GUC variables, where we need extra fast access - work_mem,
encoding settings, and maybe an application name. For others I hadn't
needed to access it for over 20 years. But I understand that more complex
extensions like timescaledb will use more internal GUC.
Maybe a new light API based on enum identifiers instead of string
identifiers that ensure relatively fast access (and safe and secure) can be
a good solution. And for special variables, there can be envelope functions
for very fast access. But although the special interface, the
responsibility of the extension's author will not be less, and the C
extensions will not be more trusted, so it is hard to say something about
possible benefits. I am inclined to Robert's opinion, so the current state
is not too bad, and maybe the best thing that is possible now is the
decreasing difference between supported platforms.
Regards
Pavel
Show quoted text
On Tue, Aug 24, 2021 at 12:36 PM Pavel Stehule <pavel.stehule@gmail.com> wrote:
There are few GUC variables, where we need extra fast access - work_mem, encoding settings, and maybe an application name. For others I hadn't needed to access it for over 20 years. But I understand that more complex extensions like timescaledb will use more internal GUC.
Note that even trivial extensions require some other GUC access. For
instance any single extension that wants to aggregate data based on
the query_id has to store an array of query_id in shmem to know what a
parallel worker is working on. On top of wasting memory and CPU, it
also means that computing the maximum number of backends in required.
So you need to recompute MaxBackends, which means access to multiple
GUCs.
Unfortunately the patch to expose the query_id didn't fix that problem
as it only passes the top level query_id to the pararllel workers, not
the current one.
On Sun, 22 Aug 2021 at 21:29, Julien Rouhaud <rjuju123@gmail.com> wrote:
On Sun, Aug 22, 2021 at 09:19:42AM -0400, Tom Lane wrote:
Uh, no, it's exactly *not* clear. There are a lot of GUCs that are only
of interest to particular subsystems. I do not see why being a GUC makes
something automatically more interesting than any other global variable.
Usually, the fact that one is global is only so the GUC machinery itself
can get at it, otherwise it'd be static in the owning module.As for "extensions should be able to get at the values", the GUC
machinery
already provides uniform mechanisms for doing that safely. Direct access
to the variable's internal value would be unsafe in many cases.Then shouldn't we try to prevent direct access on all platforms rather than
only one?
Yes. That's what I think we should be doing if we're not going to
PGDLLIMPORT them all.
The current API is painful because it round-trips via a text
representation. We'd at least want some kind of
GetConfigOptionBool(...)
GetConfigOptionEnum(...)
etc.
I don't understand the objection to marking them all PGDLLIMPORT anyway
though.
Any pretense that Pg has any sort of public/private API divide is pure
fantasy. Whether things are static or not, in public headers or "internal"
headers, etc, is nearly random. We have absolutely no API surface control
such as __attribute__((visibility("hidden"))) annotations, and proposals to
add them have been soundly rejected in the past.
If we have a defined API, where is it defined and annotated?
If we don't, then Windows being different and incompatible is a bug, and
that bug should be fixed.
On Mon, 23 Aug 2021 at 22:15, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Bruce Momjian <bruce@momjian.us> writes:
On Sun, Aug 22, 2021 at 09:29:01PM +0800, Julien Rouhaud wrote:
Then shouldn't we try to prevent direct access on all platforms rather
than
only one?
Agreed. If Julian says 99% of the non-export problems are GUCs, and we
can just export them all, why not do it? We already export every global
variable on Unix-like systems, and we have seen no downsides.By that argument, *every* globally-visible variable should be marked
PGDLLIMPORT. But the mere fact that two backend .c files need to access
some variable doesn't mean that we want any random bit of code doing so.And yes, I absolutely would prohibit extensions from accessing many
of them, if there were a reasonable way to do it. It would be a good
start towards establishing a defined API for extensions.
There is: -fvisibility=hidden and __attribute__((visibility("default"))) .
Or if you prefer to explicitly mark private symbols, use
__attribute__((visiblity("hidden"))) .
In addition to API surface control this also gives you a smaller export
symbol table for faster dynamic linking, and it improves link-time
optimization.
I could've sworn I proposed its use in the past but I can't find a relevant
list thread except quite a recent one. All I can find is [1]/messages/by-id/CAMsr+YHa3TfA4rKtnZuzurwCSmxxXNQHFE3UE29BoDEQcwfuxA@mail.gmail.com . But that is
where we should start: switch from a linker script for libpq to using
PGDLLIMPORT (actually it'd be LIBPQDLLIMPORT) in libpq. When
-DBUILDING_LIBPQ this would expand to __declspec("dllexport") on Windows
and __attribute__((visibility("default"))) on gcc/clang. Otherwise it
expands to __declspec("dllimport") on Windows and empty on other targets.
This would also be a good time to rename the confusingly named BUILDING_DLL
macro to BUILDING_POSTGRES .
The next step would be to have PGDLLIMPORT expand to
__attribute__((visibility("default"))) on gcc/clang when building the
server itself. This won't do anything by itself since all symbols are
already default visibility. But once the "public API" of both function and
data symbol is so-annotated, we could switch to building Pg with
-fvisibility=hidden by default, and on Windows, we'd disable the linker
script that exports all functions using a generated .DEF file.
[1]: /messages/by-id/CAMsr+YHa3TfA4rKtnZuzurwCSmxxXNQHFE3UE29BoDEQcwfuxA@mail.gmail.com
/messages/by-id/CAMsr+YHa3TfA4rKtnZuzurwCSmxxXNQHFE3UE29BoDEQcwfuxA@mail.gmail.com
On Tue, 24 Aug 2021 at 02:31, Robert Haas <robertmhaas@gmail.com> wrote:
On Mon, Aug 23, 2021 at 11:40 AM Alvaro Herrera <alvherre@alvh.no-ip.org>
wrote:In that case, why not improve the API with functions that return the
values in some native datatype? For scalars with native C types (int,
floats, Boolean etc) this is easy enough; I bet it'll solve 99% of the
problems or more.Sure, but ... why bother?
The entire argument rests on the presumption that there is some harm
being done by people accessing the values directly, but I don't think
that's true. And, if it were true, it seems likely that this proposed
API would have the exact same problem, because it would let people do
exactly the same thing. And, going through this proposed API would
still be significantly more expensive than just accessing the bare
variables, because you'd at least have to do some kind of lookup based
on the GUC name to find the corresponding variable. It's just a
solution in search of a problem.Nothing bad happens when people write extensions that access GUC
variables directly. It works totally, completely fine. Except on
Windows.
Not only that, but postgres already exports every non-static function
symbol on both *nix and Windows, and every data symbol on *nix. A lot of
those function symbols are very internal and give anything that can call
them the ability to wreck absolute havoc on the server's state.
There is not even the thinnest pretense of Pg having a dedicated extension
API or any sort of internal vs public API separation. This ongoing pain
with PGDLLIMPORT on Windows is hard to see as anything but an excuse to
make working with and supporting Windows harder because some of us don't
like it. I happen to rather dislike working with Windows myself, but I get
to do it anyway, and I'd be very happy to remove this particular source of
pain.
On Tue, 24 Aug 2021 at 13:21, Craig Ringer <craig.ringer@enterprisedb.com>
wrote:
There is not even the thinnest pretense of Pg having a dedicated extension
API or any sort of internal vs public API separation.
Oh, and if we do want such a separation, we'll need to introduce a MUCH
lower-pain-and-overhead way to get related patches in. Otherwise it'll take
decades to add any necessary function wrappers for currently exported data
symbols, add necessary hooks, wrap or hide internal symbols and state, etc.
But ... what is the actual goal and expected outcome of such a hypothetical
public/private API separation?
It won't help meaningfully with server maintenance: We already break
extensions freely in major releases, and sometimes even minor releases. We
don't make any stable API promise at all. So any argument that it would
make maintenance of the core server easier is weak at best.
It won't help protect server runtime stability: The server is written in C,
and makes heavy use of non-opaque / non-hidden types. Many of which would
not be practical to hide without enormous refactoring if at all. Writing
any sort of "safe" C API is very difficult even when the exposed
functionality is very narrow and well defined. Even then such an API can
only help prevent inadvertent mistakes, since C programs are free to grovel
around in memory. Look at the mess with EXPORT_SYMBOL_GPL in the kernel for
just how ugly that can get. So I don't think there's any realistic way to
claim that narrowing the exposed API surface would make it safer to load
and run extensions that the user has not separately checked and reviewed or
obtained from a trusted source with robust testing practices. Certainly it
offers no benefit at all against a bad actor.
It won't make it safer to use untrusted extensions.
What will it do? Not much, in the short term, except cripple existing
extensions or add a pile of questionably useful code annotations. The only
real benefits I see are some improvement in link-time optimization and
export symbol table size. Both of which are nice, but IMO not worth the
pain by themselves for a pure C program. In C++, with its enormous symbol
tables it's absolutely worth it. But not really for Pg.
To be clear, I actually love the idea of starting to define a solid public
API, with API, ABI and semantic promises and associated tests. But to say
it's a nontrivial amount of work is an enormous understatement. And unless
done by an existing committer who is trusted to largely define a
provisional API without bike-shedding and arguing the merits of every
single part of it, it's nearly impossible to do with the way Pg is
currently developed.
It's completely beyond me why it's OK to export all function symbols on
Windows, but not all data symbols. Or why it's OK to export all data
symbols on *nix, but not on Windows.
On Tue, 24 Aug 2021 at 05:08, Chapman Flack <chap@anastigmatix.net> wrote:
On 08/23/21 14:30, Robert Haas wrote:
it seems likely that this proposed
API would have the exact same problem, because it would let people do
exactly the same thing. And, going through this proposed API would
still be significantly more expensive than just accessing the bare
variables, because you'd at least have to do some kind of lookup based
on the GUC nameI think the API ideas in [0] would not let people do exactly the same
thing.They would avoid exposing the bare variables to overwrite. Not that
there has been any plague of extensions going and overwriting GUCs,
but I think in some messages on this thread I detected a sense that
in principle it's better if an API precludes it, and that makes sense
to me.The second idea also avoids the expense of name-based lookup (except once
at extension initialization), and in fact minimizes the cost of obtaining
the current value when needed, by slightly increasing the infrequent cost
of updating values.
I'd be generally in favour of something that reduced our reliance on the
current chaotic and inconsistent jumble of globals which are a semi-random
combination of compilation-unit-scoped, globally-scoped-except-on-Windows
and globally scoped.
Tackling GUCs would be a good start. Especially given the number of GUCs
where the actual GUC value isn't the state that anyone should be
interacting with directly since a hook maintains the "real" state derived
from the GUC storage.
And preventing direct writes to GUCs seems like a clearly correct thing to
do.
Some consideration of performance would be important for some of the hotter
GUCs, of course, but most extensions won't be hammering most GUC access a
lot.
On Mon, 23 Aug 2021 at 22:45, Julien Rouhaud <rjuju123@gmail.com> wrote:
On Mon, Aug 23, 2021 at 10:22 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
Bruce Momjian <bruce@momjian.us> writes:
On Mon, Aug 23, 2021 at 10:15:04AM -0400, Tom Lane wrote:
By that argument, *every* globally-visible variable should be marked
PGDLLIMPORT. But the mere fact that two backend .c files need toaccess
No, Julien says 99% need only the GUCs, so that is not the argument I
am
making.
That's a claim unbacked by any evidence that I've seen. More to
the point, we already have a mechanism that extensions can/should
use to read and write GUC settings, and it's not direct access.I clearly didn't try all single extension available out there. It's
excessively annoying to compile extensions on Windows, and also I
don't have a lot of dependencies installed so there are some that I
wasn't able to test since I'm lacking some other lib and given my
absolute lack of knowledge of that platform I didn't spent time trying
to install those.
Plenty of them are closed too.
While that's not the Pg community's problem, as such, it'd be nice not to
arbitrarily break them all for no actual benefit.
On 23.08.21 16:47, Julien Rouhaud wrote:
On Mon, Aug 23, 2021 at 10:36 PM Bruce Momjian <bruce@momjian.us> wrote:
So the problem is that extensions only _need_ to use that API on
Windows, so many initially don't, or that the API is too limited?The inconvenience with that API is that it's only returning c strings,
so you gave to convert it back to the original datatype. That's
probably why most of the extensions simply read from the original
exposed variable rather than using the API, because they're usually
written on Linux or similar, not because they want to mess up the
stored value.
If there were an API, then in-core code should use it as well.
If, for example, an extension wanted to define a "float16" type, then it
should be able to access extra_float_digits in the *same way* as
float4out() and float8out() can access it. This is clearly not possible
today.
On Tue, Aug 24, 2021 at 4:28 AM Peter Eisentraut
<peter.eisentraut@enterprisedb.com> wrote:
If there were an API, then in-core code should use it as well.
...which is presumably never going to happen, because the performance
cost would, I think, be quite terrible. If you really had to force
everything through an API, I think what you'd want to do is define an
API where code can look up a handle object for a GUC using the name of
the GUC, and then hold onto a pointer to the handle and use that for
future accesses, so that you don't have to keep incurring the expense
of a hash table hit on every access. But even if you did that,
preventing "unauthorized" writes to GUC variables would require a
function call for every access. That function would be pretty trivial,
but it would have to exist, and...
If, for example, an extension wanted to define a "float16" type, then it
should be able to access extra_float_digits in the *same way* as
float4out() and float8out() can access it. This is clearly not possible
today.
...if you used it for something like this, it would probably show up
in the profile, and we would get demands to remove that API and allow
direct access to the variables, which is all anybody is asking for
here anyway, and which is what pretty much everyone, whether they
develop for core or some extension, does and wants to do.
This also brings me to another point, which is that I do not think
there is anyone who actually wants an API like this. I believe that
extension developers find it rather convenient that they can make use
of all of the backend functions and variables that PostgreSQL exposes,
and that a lot of them would be deeply unhappy if we removed that
access. As an occasional extension maintainer myself, I know I would
be. And, as Craig quite rightly points out upthread, we would not get
anything in return for making those people unhappy. I don't know why
we would even consider doing something that would benefit nobody,
greatly inconvenience some people, and generally stifle innovation in
the PostgreSQL ecosystem.
Adding PGDLLIMPORT markings, on the other hand, would hurt nobody, be
very convenient for some people, and encourage innovation in the
PostgreSQL ecosystem.
--
Robert Haas
EDB: http://www.enterprisedb.com
On 08/24/21 14:28, Robert Haas wrote:
cost would, I think, be quite terrible. If you really had to force
everything through an API, I think what you'd want to do is define an
API where code can look up a handle object for a GUC using the name of
the GUC, and then hold onto a pointer to the handle and use that for
future accesses, so that you don't have to keep incurring the expense
of a hash table hit on every access. But even if you did that,
preventing "unauthorized" writes to GUC variables would require a
function call for every access.
I don't think that's true of the second proposal in [0]/messages/by-id/6123C425.3080409@anastigmatix.net. I don't foresee
a noticeable runtime cost unless there is a plausible workload that
involves very frequent updates to GUC settings that are also of interest
to a bunch of extensions. Maybe I'll take a stab at a POC.
Regards,
-Chap
On Tue, Aug 24, 2021 at 2:52 PM Chapman Flack <chap@anastigmatix.net> wrote:
I don't think that's true of the second proposal in [0]. I don't foresee
a noticeable runtime cost unless there is a plausible workload that
involves very frequent updates to GUC settings that are also of interest
to a bunch of extensions. Maybe I'll take a stab at a POC.
I'm not sure I fully understand that proposal, but I find it hard to
believe that we would seriously consider replacing every direct GUC
reference in the backend with something that goes through an API. Even
if didn't hurt performance, I think it would uglify the code a whole
lot.
And as Peter says, if we're not going to do that, then it's not clear
why extensions should have to.
--
Robert Haas
EDB: http://www.enterprisedb.com
On 08/24/21 15:12, Robert Haas wrote:
I find it hard to
believe that we would seriously consider replacing every direct GUC
reference in the backend with something that goes through an API.
Peter may have advocated for that kind of across-the-board adoption;
my leaning is more to add an API that /can/ be adopted, initially with
separately-linked extensions as the audience. Nothing would stop it being
used in core as well, but no reason to change any site where it did not
offer an advantage.
I generally tend to be an incrementalist.
Regards,
-Chap
On Tue, Aug 24, 2021 at 3:36 PM Chapman Flack <chap@anastigmatix.net> wrote:
Peter may have advocated for that kind of across-the-board adoption;
my leaning is more to add an API that /can/ be adopted, initially with
separately-linked extensions as the audience. Nothing would stop it being
used in core as well, but no reason to change any site where it did not
offer an advantage.I generally tend to be an incrementalist.
Sure, me too, but the point for me is that there doesn't seem to be a
shred of a reason to go this way at all. We've turned a discussion
about adding PGDLLIMPORT, which ought to be totally uncontroversial,
into some kind of a discussion about adding an API layer that no one
wants to prevent a hypothetical failure mode not in evidence.
--
Robert Haas
EDB: http://www.enterprisedb.com
On 08/24/21 16:31, Robert Haas wrote:
about adding PGDLLIMPORT, which ought to be totally uncontroversial,
The thing is, I think I have somewhere a list of all the threads on this
topic that I've read through since the first time I had to come with my own
hat in hand asking for a PGDLLIMPORT on something, years ago now, and
I don't think I have ever seen one where it was as uncontroversial
as you suggest.
In each iteration, I think I've also seen a countervailing view expressed
in favor of looking into whether globals visibility could be further
/reduced/. Maybe that view is slowly losing adherents? I don't know; it
did get advanced again by some in this thread.
The positions seem to routinely fall into two boxes:
* Let's look into that, it would be a step toward having a more defined API
* No, what we have now is so far from a defined API that there's nothing
worth stepping toward.
The situation seems intermediate to me. The current condition is clearly
something that organically grew without a strong emphasis on defining API.
On the other hand, there are many corners of it that show evidence of
thought about encapsulation and API by the developers of those corners.
It seems to me like the kind of setting where incrementalists can find
room for small moves.
Regards,
-Chap
On Tue, Aug 24, 2021 at 04:31:32PM -0400, Robert Haas wrote:
On Tue, Aug 24, 2021 at 3:36 PM Chapman Flack <chap@anastigmatix.net> wrote:
Peter may have advocated for that kind of across-the-board adoption;
my leaning is more to add an API that /can/ be adopted, initially with
separately-linked extensions as the audience. Nothing would stop it being
used in core as well, but no reason to change any site where it did not
offer an advantage.I generally tend to be an incrementalist.
Sure, me too, but the point for me is that there doesn't seem to be a
shred of a reason to go this way at all. We've turned a discussion
about adding PGDLLIMPORT, which ought to be totally uncontroversial,
into some kind of a discussion about adding an API layer that no one
wants to prevent a hypothetical failure mode not in evidence.
+1
--
Bruce Momjian <bruce@momjian.us> https://momjian.us
EDB https://enterprisedb.com
If only the physical world exists, free will is an illusion.
On Tue, Aug 24, 2021 at 05:06:54PM -0400, Chapman Flack wrote:
On 08/24/21 16:31, Robert Haas wrote:
about adding PGDLLIMPORT, which ought to be totally uncontroversial,
The thing is, I think I have somewhere a list of all the threads on this
topic that I've read through since the first time I had to come with my own
hat in hand asking for a PGDLLIMPORT on something, years ago now, and
I don't think I have ever seen one where it was as uncontroversial
as you suggest.
The "ought" above is a load-bearing word. Nonetheless, here's a case, also
involving GUCs, where it was uncontroversial:
/messages/by-id/flat/20171120200230.iwcmptwznbvl6y4c@alap3.anarazel.de
On Tue, Aug 24, 2021 at 5:06 PM Chapman Flack <chap@anastigmatix.net> wrote:
The thing is, I think I have somewhere a list of all the threads on this
topic that I've read through since the first time I had to come with my own
hat in hand asking for a PGDLLIMPORT on something, years ago now, and
I don't think I have ever seen one where it was as uncontroversial
as you suggest.
It does tend to be controversial, but I think that's basically only
because Tom Lane has reservations about it. I think if Tom dropped his
opposition to this, nobody else would really care. And I think that
would be a good thing for the project.
In each iteration, I think I've also seen a countervailing view expressed
in favor of looking into whether globals visibility could be further
/reduced/.
But, like I say, that's only a view that gets advanced as a reason not
to mark things PGDLLIMPORT. Nobody ever wants that thing for its own
sake. I think it's a complete red herring.
If and when somebody wants to make a serious proposal to do something
like that, it can be considered on its own merits. But between now and
then, refusing to make things work on Windows as they do on Linux does
not benefit anyone. A ton of work has been made into making PostgreSQL
portable over the years, and abandoning it in just this one case is
unreasonable.
--
Robert Haas
EDB: http://www.enterprisedb.com
On Wed, Aug 25, 2021 at 4:06 PM Robert Haas <robertmhaas@gmail.com> wrote:
On Tue, Aug 24, 2021 at 5:06 PM Chapman Flack <chap@anastigmatix.net> wrote:
The thing is, I think I have somewhere a list of all the threads on this
topic that I've read through since the first time I had to come with my own
hat in hand asking for a PGDLLIMPORT on something, years ago now, and
I don't think I have ever seen one where it was as uncontroversial
as you suggest.It does tend to be controversial, but I think that's basically only
because Tom Lane has reservations about it. I think if Tom dropped his
opposition to this, nobody else would really care. And I think that
would be a good thing for the project.
I have only one consideration about it, and that's a technical one :)
Does this in some way have an effect on the size of the binary and/or
the time it takes to load it?
I ask, because IIRC back in the prehistoric days, adding all the
*functions* to the list of exports had a very significant impact on
the size of the binary, and some (but not very large) impact on the
loading time. Of course, we had to do that so that even our own
libraries would probably load. And at the time it was decided that we
definitely wanted to export all functions and not just the ones that
we would somehow define as an API.
Now, I'm pretty sure that the GUCs are few enough that this should
have no measurable effect on size/load time, but it's something that
should be verified.
But in particular, both on that argument, and on the general
maintenance argument, I have a very hard time seeing how exporting the
GUC variables would be any worse than exporting the many hundreds of
functions we already export.
--
Magnus Hagander
Me: https://www.hagander.net/
Work: https://www.redpill-linpro.com/
Magnus Hagander <magnus@hagander.net> writes:
On Wed, Aug 25, 2021 at 4:06 PM Robert Haas <robertmhaas@gmail.com> wrote:
It does tend to be controversial, but I think that's basically only
because Tom Lane has reservations about it. I think if Tom dropped his
opposition to this, nobody else would really care. And I think that
would be a good thing for the project.
But in particular, both on that argument, and on the general
maintenance argument, I have a very hard time seeing how exporting the
GUC variables would be any worse than exporting the many hundreds of
functions we already export.
My beef about it has nothing to do with binary-size concerns, although
that is an interesting angle. (I wonder whether marking a variable
PGDLLIMPORT has any negative effect on the cost of accessing it from
within the core code?) Rather, I'm unhappy with spreading even more
Microsoft-droppings all over our source. If there were some way to
just do this automatically for all global variables without any source
changes, I'd be content with that. That would *really* make the
platforms more nearly equivalent.
regards, tom lane
On Wed, Aug 25, 2021 at 4:41 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
Magnus Hagander <magnus@hagander.net> writes:
On Wed, Aug 25, 2021 at 4:06 PM Robert Haas <robertmhaas@gmail.com> wrote:
It does tend to be controversial, but I think that's basically only
because Tom Lane has reservations about it. I think if Tom dropped his
opposition to this, nobody else would really care. And I think that
would be a good thing for the project.But in particular, both on that argument, and on the general
maintenance argument, I have a very hard time seeing how exporting the
GUC variables would be any worse than exporting the many hundreds of
functions we already export.My beef about it has nothing to do with binary-size concerns, although
that is an interesting angle. (I wonder whether marking a variable
PGDLLIMPORT has any negative effect on the cost of accessing it from
within the core code?)
It should have no effect on local code.
PGDLLIMPORT turns into "__declspec (dllexport)" when building the
backend, which should have no effect on imports
(it turns into __declspec (dllimport) when building a frontend only,
but that's why we need it in the headers, iirc)
The only overhead I've seen discussions about int he docs around that
is the overhead of exporting by name vs exporting by ordinal.
Rather, I'm unhappy with spreading even more
Microsoft-droppings all over our source. If there were some way to
just do this automatically for all global variables without any source
changes, I'd be content with that. That would *really* make the
platforms more nearly equivalent.
Actually, ti's clearly been a while since I dug into this
AFAICT we *do* actually export all the data symbols as well? At least
in the MSVC build where we use gendef.pl? Specifically, see
a5eed4d770.
The thing we need the PGDLLIMPORT definition for is to *import* them
on the other end?
--
Magnus Hagander
Me: https://www.hagander.net/
Work: https://www.redpill-linpro.com/
On 2021-Aug-25, Magnus Hagander wrote:
The thing we need the PGDLLIMPORT definition for is to *import* them
on the other end?
Oh ... so modules that are willing to cheat can include their own
declarations of the variables they need, and mark them __declspec
(dllimport)?
--
Álvaro Herrera PostgreSQL Developer — https://www.EnterpriseDB.com/
"The Gord often wonders why people threaten never to come back after they've
been told never to return" (www.actsofgord.com)
On Thu, Aug 26, 2021 at 1:51 AM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:
On 2021-Aug-25, Magnus Hagander wrote:
The thing we need the PGDLLIMPORT definition for is to *import* them
on the other end?Oh ... so modules that are willing to cheat can include their own
declarations of the variables they need, and mark them __declspec
(dllimport)?
I just tried and msvc doesn't like it. It errors out with a C2370
error "redefinition; different storage class". According to
https://docs.microsoft.com/en-us/cpp/error-messages/compiler-errors-1/compiler-error-c2370
changing __declspec() on the other side is not possible.
On Wed, Aug 25, 2021 at 10:41:14AM -0400, Tom Lane wrote:
Magnus Hagander <magnus@hagander.net> writes:
On Wed, Aug 25, 2021 at 4:06 PM Robert Haas <robertmhaas@gmail.com> wrote:
It does tend to be controversial, but I think that's basically only
because Tom Lane has reservations about it. I think if Tom dropped his
opposition to this, nobody else would really care. And I think that
would be a good thing for the project.But in particular, both on that argument, and on the general
maintenance argument, I have a very hard time seeing how exporting the
GUC variables would be any worse than exporting the many hundreds of
functions we already export.My beef about it has nothing to do with binary-size concerns, although
that is an interesting angle. (I wonder whether marking a variable
PGDLLIMPORT has any negative effect on the cost of accessing it from
within the core code?) Rather, I'm unhappy with spreading even more
Microsoft-droppings all over our source. If there were some way to
just do this automatically for all global variables without any source
changes, I'd be content with that. That would *really* make the
platforms more nearly equivalent.
OK, so the big question is how can we minimize the code impact of this
feature? Can we add some kind of checking so we don't forget to mark
anything? Can we automate this somehow?
--
Bruce Momjian <bruce@momjian.us> https://momjian.us
EDB https://enterprisedb.com
If only the physical world exists, free will is an illusion.
On Thu, Aug 26, 2021 at 3:38 AM Julien Rouhaud <rjuju123@gmail.com> wrote:
On Thu, Aug 26, 2021 at 1:51 AM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:
On 2021-Aug-25, Magnus Hagander wrote:
The thing we need the PGDLLIMPORT definition for is to *import* them
on the other end?Oh ... so modules that are willing to cheat can include their own
declarations of the variables they need, and mark them __declspec
(dllimport)?I just tried and msvc doesn't like it. It errors out with a C2370
error "redefinition; different storage class". According to
https://docs.microsoft.com/en-us/cpp/error-messages/compiler-errors-1/compiler-error-c2370
changing __declspec() on the other side is not possible.
Yeah, but that does move the problem to the other side doesn't it? So
if you (as a pure test of course) were to remove the variable
completely from the included header and just declare it manually with
PGDLLSPEC in your file, it should work?
Ugly as it is, I wonder if there's a chance we could just process all
the headers at install times and inject the PGDLLIMPORT. We know which
symvols it is on account of what we're getting in the DEF file.
Not saying that's not a very ugly solution, but it might work?
--
Magnus Hagander
Me: https://www.hagander.net/
Work: https://www.redpill-linpro.com/
On Thu, Aug 26, 2021 at 3:42 PM Magnus Hagander <magnus@hagander.net> wrote:
Ugly as it is, I wonder if there's a chance we could just process all
the headers at install times and inject the PGDLLIMPORT. We know which
symvols it is on account of what we're getting in the DEF file.Not saying that's not a very ugly solution, but it might work?
If it's ugly, that might mean it's a bad idea and we shouldn't do it
... but if it can be made not-too-ugly, it would certainly be nice to
be able to stop worrying about this.
--
Robert Haas
EDB: http://www.enterprisedb.com
On 8/26/21 3:57 PM, Robert Haas wrote:
On Thu, Aug 26, 2021 at 3:42 PM Magnus Hagander <magnus@hagander.net> wrote:
Ugly as it is, I wonder if there's a chance we could just process all
the headers at install times and inject the PGDLLIMPORT. We know which
symvols it is on account of what we're getting in the DEF file.Not saying that's not a very ugly solution, but it might work?
If it's ugly, that might mean it's a bad idea and we shouldn't do it
... but if it can be made not-too-ugly, it would certainly be nice to
be able to stop worrying about this.
How is this going to affect msys builds? No gendef there IIRC. I guess
some similar procedure might be possible ...
cheers
andrew
--
Andrew Dunstan
EDB: https://www.enterprisedb.com
On Thu, Aug 26, 2021 at 05:10:39PM -0400, Andrew Dunstan wrote:
On 8/26/21 3:57 PM, Robert Haas wrote:
On Thu, Aug 26, 2021 at 3:42 PM Magnus Hagander <magnus@hagander.net> wrote:
Ugly as it is, I wonder if there's a chance we could just process all
the headers at install times and inject the PGDLLIMPORT. We know which
symvols it is on account of what we're getting in the DEF file.
Not saying that's not a very ugly solution, but it might work?
I missed the word "install" first here :)
If it's ugly, that might mean it's a bad idea and we shouldn't do it
... but if it can be made not-too-ugly, it would certainly be nice to
be able to stop worrying about this.How is this going to affect msys builds? No gendef there IIRC. I guess
some similar procedure might be possible ...
Wouldn't that be needed for cygwin as well? If we go down to enable
that for a maximum number of parameters, I would really agree for
doing things so as this never gets forgotten for new parameters and we
don't have to discuss the matter anymore. With all that in mind, that
would mean a new perl script that does the job, callable by both MSVC
and normal make builds. But we have nothing that does a manipulation
of the installation contents. And couldn't it be a problem if an
installation is overwritten, updated or upgradedd, where there may be
contents not coming from the in-core build process but from some
extension?
--
Michael
On Fri, Aug 27, 2021 at 3:42 AM Magnus Hagander <magnus@hagander.net> wrote:
Yeah, but that does move the problem to the other side doesn't it? So
if you (as a pure test of course) were to remove the variable
completely from the included header and just declare it manually with
PGDLLSPEC in your file, it should work?Ugly as it is, I wonder if there's a chance we could just process all
the headers at install times and inject the PGDLLIMPORT. We know which
symvols it is on account of what we're getting in the DEF file.Not saying that's not a very ugly solution, but it might work?
It's apparently not enough. I tried with autovacuum_max_workers GUC,
and it still errors out.
If I add a PGDLLIMPORT, there's a link error when trying to access the variable:
error LNK2019: unresolved external symbol __imp_autovacuum_max_workers
referenced in function...
I think that it means that msvc tries to link that to a DLL while it's
expected to be in postgres.lib as the __imp_ prefix is added in that
case.
If I use PGDLLEXPORT I simply get:
error LNK2001: unresolved external symbol aytovacuum_max_workers
On Wed, 25 Aug 2021 at 03:13, Robert Haas <robertmhaas@gmail.com> wrote:
On Tue, Aug 24, 2021 at 2:52 PM Chapman Flack <chap@anastigmatix.net>
wrote:I don't think that's true of the second proposal in [0]. I don't foresee
a noticeable runtime cost unless there is a plausible workload that
involves very frequent updates to GUC settings that are also of interest
to a bunch of extensions. Maybe I'll take a stab at a POC.I'm not sure I fully understand that proposal, but I find it hard to
believe that we would seriously consider replacing every direct GUC
reference in the backend with something that goes through an API. Even
if didn't hurt performance, I think it would uglify the code a whole
lot.
It'd probably have to be something that resolves the GUC storage addresses
at compile-time or once at runtime, if it's going to be used by core code.
While some code doesn't hit a lot of GUCs, some *really* hammers some
common GUCs.
There are various issues with cache lines and pointer chasing that are
beyond my low-level fu at work here. Adding a level of pointer indirection
can be very expensive in the wrong situations.
So you're probably looking at some kind of mess with token pasting, macros
and static inlines. Ew.
On Wed, 25 Aug 2021 at 22:36, Magnus Hagander <magnus@hagander.net> wrote:
On Wed, Aug 25, 2021 at 4:06 PM Robert Haas <robertmhaas@gmail.com> wrote:
On Tue, Aug 24, 2021 at 5:06 PM Chapman Flack <chap@anastigmatix.net>
wrote:
The thing is, I think I have somewhere a list of all the threads on
this
topic that I've read through since the first time I had to come with
my own
hat in hand asking for a PGDLLIMPORT on something, years ago now, and
I don't think I have ever seen one where it was as uncontroversial
as you suggest.It does tend to be controversial, but I think that's basically only
because Tom Lane has reservations about it. I think if Tom dropped his
opposition to this, nobody else would really care. And I think that
would be a good thing for the project.I have only one consideration about it, and that's a technical one :)
Does this in some way have an effect on the size of the binary and/or
the time it takes to load it?
On *nix, no.
On Windows, very, very minimally.
We *should* be looking into making private symbols we can't make
non-static have hidden visibility at link time, i.e. be DSO-private. This
can have a huge impact on link-time optimisation and inlining.
But doing so is quite orthogonal to the matter of fixing a linkage issue on
Windows. By making select symbols hidden we'd be *reducing* the exposed set
of functions and data symbols in a disciplined and progressive way on all
platforms. Useful but different.
On Thu, 26 Aug 2021 at 01:51, Alvaro Herrera <alvherre@alvh.no-ip.org>
wrote:
On 2021-Aug-25, Magnus Hagander wrote:
The thing we need the PGDLLIMPORT definition for is to *import* them
on the other end?Oh ... so modules that are willing to cheat can include their own
declarations of the variables they need, and mark them __declspec
(dllimport)?
Damn. I was hoping nobody would notice that.
I do exactly that in some extensions to work around some of this mess, but
it is quite awkward and has its limitations.
On Fri, 27 Aug 2021 at 08:59, Julien Rouhaud <rjuju123@gmail.com> wrote:
On Fri, Aug 27, 2021 at 3:42 AM Magnus Hagander <magnus@hagander.net>
wrote:Yeah, but that does move the problem to the other side doesn't it? So
if you (as a pure test of course) were to remove the variable
completely from the included header and just declare it manually with
PGDLLSPEC in your file, it should work?Ugly as it is, I wonder if there's a chance we could just process all
the headers at install times and inject the PGDLLIMPORT. We know which
symvols it is on account of what we're getting in the DEF file.Not saying that's not a very ugly solution, but it might work?
It's apparently not enough. I tried with autovacuum_max_workers GUC,
and it still errors out.
If I add a PGDLLIMPORT, there's a link error when trying to access the
variable:
error LNK2019: unresolved external symbol __imp_autovacuum_max_workers
referenced in function...If I use PGDLLEXPORT I simply get:
error LNK2001: unresolved external symbol aytovacuum_max_workers
It works, but you can't use PGDLLIMPORT, you have to implement the import
yourself without the help of __declspec(dllimport) .
Where you want
autovacuum_max_workers
you must instead write
*((int*)__imp_autovacuum_max_workers)
Here's the comment I wrote on the topic in something I was working on:
/*
* On Windows, a symbol is not accessible outside the executable or shared
* library (PE object) that it is defined in unless explicitly exported in
* the DLL interface.
*
* It must then be explicitly imported by objects that use it; Windows
doesn't
* do ELF-style fixups.
*
* The export part is usually accomplished by a __declspec(dllexport)
* annotation on the symbol or a .DEF file supplied as linker input.
Postgres
* uses the .DEF approach, auto-exporting all symbols using
* src\tools\msvc\gendef.pl . Internally this hides "symname" from the DLL
* interface and instead generates an export symbol "__imp_symname" that is
a
* pointer to the value of "symname".
*
* The import part is usually done with the __declspec(dllimport)
annotation on
* the symbol. The PGDLLIMPORT macro expands to __declspec(dllimport) when
* postgres headers are included during extension compilation. But not all
the
* symbols that pglogical needs are annotated with PGDLLIMPORT. Attempting
to
* access a symbol that is not so-annotated will fail at link time with an
* error like
*
* error LNK2001: unresolved external symbol
criticalSharedRelcachesBuilt
*
* Because of gendefs.pl, postgres still exports the symbol even if it isn't
* annotated PGDLLIMPORT. So we can just do the shorthand that
* __declspec(dllimport) does for us in the preprocessor instead: replace
each
* symbol with its __imp_symbol indirection and dereference it.
*
* There's one wrinkle in this though. MSVC doesn't generate a definition
for a
* global data symbol that is neither initialized nor explicitly marked
* __declspec(dllexport). gendefs.pl will think such symbols are references
to
* a symbol defined in another object file and will skip them without
emitting
* a DATA entry for them in the DEF file, so no __imp_ stub is generated in
the
* DLL interface. We can't use (*__imp_symbolname) if there's no import
stub.
*
* If they're GUCs, we can round-trip them through their text values
* to read them. Nothing should ever be assigning to GUC storage and
there's no
* reason to take the address of GUC storage, so this should work fine,
albeit
* slower. If we find any that aren't GUCs we're in trouble but so far there
* haven't been any.
*
* See also:
*
* -
https://docs.microsoft.com/en-us/cpp/build/importing-data-using-declspec-dllimport
* - https://docs.microsoft.com/en-us/cpp/build/importing-using-def-files
* -
https://docs.microsoft.com/en-us/cpp/build/exporting-from-a-dll-using-def-files
* -
https://docs.microsoft.com/en-us/cpp/build/determining-which-exporting-method-to-use
*/
This is gruesome and I hadn't planned to mention it, but now someone
noticed the .DEF file exports the symbols I guess it does no harm.
So can we just fix PGDLLIMPORT now?
Hi,
On 2021-08-23 14:53:34 +0800, Julien Rouhaud wrote:
So since the non currently explicitly exported GUC global variables shouldn't
be accessible by third-party code, I'm attaching a POC patch that does the
opposite of v1: enforce that restriction using a new pg_attribute_hidden()
macro, defined with GCC only, to start discussing that topic.
This fails on cfbot: https://cirrus-ci.com/task/6424663592009728?logs=build#L1
I'm not feeling a lot of enthusiasm for the change. But if we were to do this,
we'd have to have infrastructure to detect missing hidden declarations,
otherwise it's inevitable that they don't get added.
I kind of like the idea of hiding postgres symbols for other reasons than
win<->everything else parity. Namely that not exporting symbols can allow the
compiler to optimize more...
Greetings,
Andres Freund
Hi,
On Sat, Feb 12, 2022 at 07:59:56PM -0800, Andres Freund wrote:
On 2021-08-23 14:53:34 +0800, Julien Rouhaud wrote:
So since the non currently explicitly exported GUC global variables shouldn't
be accessible by third-party code, I'm attaching a POC patch that does the
opposite of v1: enforce that restriction using a new pg_attribute_hidden()
macro, defined with GCC only, to start discussing that topic.This fails on cfbot: https://cirrus-ci.com/task/6424663592009728?logs=build#L1
I'm not feeling a lot of enthusiasm for the change.
Yes, which is also why I'm not planning on spending more effort on that (or the
opposite) unless I get some sort of feedback, so thanks a lot for the answer
here.
Note that if everyone is happy with the status quo please say so. I will
happily mark the CF entry rejected and stop all efforts to try packaging
extensions on Windows. It will save me a lot of efforts that 99% of users
don't care about.
If not maybe we could improve the situation, and also learn for the max_backend
thread.
Maybe we could have an actually usable GUC API to retrieve values in their
native format rather than C string for instance, that we could make sure also
works for cases like max_backend?
But if we were to do this,
we'd have to have infrastructure to detect missing hidden declarations,
otherwise it's inevitable that they don't get added.
Agreed. For now I'm using a simple loop around
egrep "^\s+&[A-Za-z_]+,$" src/backend/utils/misc/guc.c | egrep -o "[A-Za-z_]+"
to get all the underlying symbols, and grep that again (actually using ag,
which makes it 3x faster) to detect the lack of wanted annotation. Were you
thinking of some script like that, maybe to run before a release, or something
more evolved?
I kind of like the idea of hiding postgres symbols for other reasons than
win<->everything else parity. Namely that not exporting symbols can allow the
compiler to optimize more...
Yeah I saw that in nearby threads and I entirely agree.
Hi,
On 02/13/22 02:29, Julien Rouhaud wrote:
Maybe we could have an actually usable GUC API to retrieve values in their
native format rather than C string for instance, that we could make sure also
works for cases like max_backend?
I proposed a sketch of such an API for discussion back in [0]/messages/by-id/6123C425.3080409@anastigmatix.net (the second
idea in that email, the "what I'd really like" one).
In that scheme, some extension code that was interested in (say,
for some reason) log_statement_sample_rate could say:
static double samprate;
static int gucs_changed = 0;
#define SAMPRATE_CHANGED 1
...
ObserveTypedConfigValue("log_statement_sample_rate",
&samprate, &gucs_changed, SAMPRATE_CHANGED);
...
and will be subscribed to have the native-format value stored into samprate,
and SAMPRATE_CHANGED ORed into gucs_changed, whenever the value changes.
The considerations leading me to that design were:
- avoid subscribing as a 'callback' sort of listener. GUCs can get set
(or, especially, reset) in delicate situations like error recovery
where calling out to arbitrary extra code might best be avoided.
- instead, just dump the value in a subscribed location. A copy,
of course, so no modification there affects the real value.
- but at the same time, OR a flag into a bit set, so subscribing code can
very cheaply poll for when a value of interest (or any of a bunch of
values of interest) has changed since last checked.
- do the variable lookup by name once only, and pay no further search cost
when the subscribing code wants the value.
I never pictured that proposal as the last word on the question, and
different proposals could result from putting different weights on those
objectives, or adding other objectives, but I thought it might serve
as a discussion-starter.
Regards,
-Chap
Chapman Flack <chap@anastigmatix.net> writes:
On 02/13/22 02:29, Julien Rouhaud wrote:
Maybe we could have an actually usable GUC API to retrieve values in their
native format rather than C string for instance, that we could make sure also
works for cases like max_backend?
I proposed a sketch of such an API for discussion back in [0] (the second
idea in that email, the "what I'd really like" one).
In that scheme, some extension code that was interested in (say,
for some reason) log_statement_sample_rate could say:
static double samprate;
static int gucs_changed = 0;
#define SAMPRATE_CHANGED 1
...
ObserveTypedConfigValue("log_statement_sample_rate",
&samprate, &gucs_changed, SAMPRATE_CHANGED);
...
and will be subscribed to have the native-format value stored into samprate,
and SAMPRATE_CHANGED ORed into gucs_changed, whenever the value changes.
That seems like about 10X more complexity than is warranted,
not only in terms of the infrastructure required, but also in
the intellectual complexity around "just when could that value
change?"
Why not just provide equivalents to GetConfigOption() that can
deliver int, float8, etc values instead of strings?
(In any case we'd need to rethink the GUC "show_hook" APIs, which
currently need only deal in string output.)
regards, tom lane
On 02/13/22 15:16, Tom Lane wrote:
That seems like about 10X more complexity than is warranted,
not only in terms of the infrastructure required, but also in
the intellectual complexity around "just when could that value
change?"Why not just provide equivalents to GetConfigOption() that can
deliver int, float8, etc values instead of strings?
And repeat the bsearch to find the option every time the interested
extension wants to check the value, even when what it learns is that
the value has not changed? And make it the job of every piece of
interested extension code to save the last-retrieved value and compare
if it wants to detect that it's changed? When the GUC machinery already
has code that executes exactly when a value is being supplied for
an option?
Clearly I'm not thinking here of the GUCs that are read-only views of
values that are determined some other way. How many of those are there
that are mutable, and could have their values changed without going
through the GUC mechanisms?
Also, I think there are some options that are only represented by
an int, float8, etc., when shown, but whose native internal form
is something else, like a struct. I was definitely contemplating
that you could 'subscribe' to one of those too, by passing the
address of an appropriate struct. But of course a GetConfigOption()
flavor could work that way too.
Regards,
-Chap
Hi,
On 2022-02-13 15:36:16 -0500, Chapman Flack wrote:
Clearly I'm not thinking here of the GUCs that are read-only views of
values that are determined some other way. How many of those are there
that are mutable, and could have their values changed without going
through the GUC mechanisms?
Is there any GUCs where one needs this? There are a few GUCs frequently
changing values, but it's stuff like transaction_read_only. Where I don't
really see a use for constantly checking the value.
Also, I think there are some options that are only represented by
an int, float8, etc., when shown, but whose native internal form
is something else, like a struct. I was definitely contemplating
that you could 'subscribe' to one of those too, by passing the
address of an appropriate struct. But of course a GetConfigOption()
flavor could work that way too.
I have a very hard time seeing a use-case for this. Nor how it'd even work
with a struct - you can't just copy the struct contents, because of pointers
to objects etc. I don't think there really are options like this anyway.
Greetings,
Andres Freund
Chapman Flack <chap@anastigmatix.net> writes:
On 02/13/22 15:16, Tom Lane wrote:
Why not just provide equivalents to GetConfigOption() that can
deliver int, float8, etc values instead of strings?
And repeat the bsearch to find the option every time the interested
extension wants to check the value, even when what it learns is that
the value has not changed? And make it the job of every piece of
interested extension code to save the last-retrieved value and compare
if it wants to detect that it's changed? When the GUC machinery already
has code that executes exactly when a value is being supplied for
an option?
(shrug) You could argue the performance aspect either way. If the
core GUC code updates a value 1000 times while the extension consults
the result once, you've probably lost money on the deal.
As for the bsearch, we could improve on that when and if it's shown
to be a bottleneck --- converting to a hash table ought to pretty
much fix any worries there. Or we could provide APIs that let an
extension look up a "struct config_generic *" once and then fetch
directly using that pointer. (But I'd prefer not to, since it'd
constrain the internals more than I think is wise.)
regards, tom lane
Andres Freund <andres@anarazel.de> writes:
On 2022-02-13 15:36:16 -0500, Chapman Flack wrote:
Also, I think there are some options that are only represented by
an int, float8, etc., when shown, but whose native internal form
is something else, like a struct. I was definitely contemplating
that you could 'subscribe' to one of those too, by passing the
address of an appropriate struct. But of course a GetConfigOption()
flavor could work that way too.
I have a very hard time seeing a use-case for this. Nor how it'd even work
with a struct - you can't just copy the struct contents, because of pointers
to objects etc. I don't think there really are options like this anyway.
There are a couple of legacy cases like "datestyle" where something
that the user sees as one GUC translates to multiple variables under
the hood, so you'd have to invent a struct if you wanted to pass
them through a mechanism like this. I don't have a big problem
with leaving those out of any such solution, though. (I see that
datestyle's underlying variables DateStyle and DateOrder are already
marked PGDLLIMPORT, and that's fine with me.) A possibly more
interesting case is something like search_path --- but again,
there are already special-purpose APIs for accessing the interpreted
value of that.
regards, tom lane
On 02/13/22 15:48, Tom Lane wrote:
much fix any worries there. Or we could provide APIs that let an
extension look up a "struct config_generic *" once and then fetch
directly using that pointer. (But I'd prefer not to, since it'd
constrain the internals more than I think is wise.)
There is GetConfigOptionByNum already ... but I'm not sure there's
an easy way to ask "what's the num for option foo?".
GetNumConfigOptions exists, so there is a brute-force way.
Regards,
-Chap
On Sun, Feb 13, 2022 at 3:17 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
...
ObserveTypedConfigValue("log_statement_sample_rate",
&samprate, &gucs_changed, SAMPRATE_CHANGED);
...and will be subscribed to have the native-format value stored into samprate,
and SAMPRATE_CHANGED ORed into gucs_changed, whenever the value changes.That seems like about 10X more complexity than is warranted,
not only in terms of the infrastructure required, but also in
the intellectual complexity around "just when could that value
change?"
I agree in the sense that I believe we should $SUBJECT rather than
fooling around with this. It is completely understandable that
extensions want to know the value of GUCs, and not just as strings,
and doing $SUBJECT would be by far the easiest way of accomplishing
that. I'm sure Andres is right when he says that there are cases where
not exposing symbols could improve the generated machine code, but I'm
also pretty sure that we just have to live with the cost when it's
core GUCs that we're talking about. It's just unrealistic to suppose
that extensions are not going to care.
But if we're not going to do that, then I don't see why Chapman's
proposal is overly complex. It seems completely understandable that if
(some_guc_var != last_observed_some_guc_var) { ...adapt accordingly...
} feels like an OK thing to do but if you have to make a function call
every time then it seems too expensive. Imagine a background worker
that has to do a bunch of extra setup every time some GUC changes, and
every iteration of the main loop just wants to check whether it's
changed, and the main loop could iterate very quickly in some cases. I
wouldn't want to worry about the cost of a function call on every trip
through the loop. Maybe it would be trivial in practice, but who
knows?
I don't particularly like Chapman's solution, but given that you've
repeatedly blocked every effort to just apply PGDLLIMPORT markings
across the board, I'm not sure what the realistic alternative is. It
doesn't seem fair to argue, on the one hand, that we can't just do
what I believe literally every other hacker on the project wants, and
that on the other hand, it's also unacceptable to add complexity to
work around the problem you've created by blocking that proposal every
time it's been raised year after year. It's really pretty frustrating
to me that we haven't just done the obvious thing here years ago. The
time we've spent arguing about it could have been better spent on just
about anything else, with absolutely zero harm to the project.
--
Robert Haas
EDB: http://www.enterprisedb.com
Robert Haas <robertmhaas@gmail.com> writes:
I don't particularly like Chapman's solution, but given that you've
repeatedly blocked every effort to just apply PGDLLIMPORT markings
across the board, I'm not sure what the realistic alternative is.
You do realize that I just have one vote in these matters? If I'm
outvoted then so be it. The impression I have though is that a
number of other people don't like the extra notational cruft either.
regards, tom lane
On Mon, Feb 14, 2022 at 10:38 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
Robert Haas <robertmhaas@gmail.com> writes:
I don't particularly like Chapman's solution, but given that you've
repeatedly blocked every effort to just apply PGDLLIMPORT markings
across the board, I'm not sure what the realistic alternative is.You do realize that I just have one vote in these matters? If I'm
outvoted then so be it. The impression I have though is that a
number of other people don't like the extra notational cruft either.
Hmm, I guess I'd need to know who those people are in order to be able
to review their comments. I don't *like* the extra notational cruft,
but applying it inconsistently isn't better than being consistent. As
I see it, we have four choices: (1) apply PGDLLIMPORT markings
relatively broadly so that people can get extensions to work on
Windows, (2) continue to apply them inconsistently, thus slightly
reducing notational clutter at the cost of breaking lots of extensions
on Windows, (3) put some complex system in place like what Chapman
proposes and get all extension authors to adopt it, and (4) remove the
Windows port. To the best of my current knowledge, everyone other than
you prefers (1), you prefer (2) or (4), and (3) is an attempt at
compromise that is nobody's first choice.
If that is correct, then I think we should do (1). If it's incorrect
then I think we should do our best to find a choice other than (2)
that does attract a consensus. The current situation, which is (2),
must be the worst of all possible options because it manages to bother
the people who dislike the clutter AND ALSO bother the people who want
to have their extensions work on Windows. Any other choice has a
chance of reaching a state where only one of those groups of people is
annoyed.
--
Robert Haas
EDB: http://www.enterprisedb.com
On 02/14/22 11:43, Robert Haas wrote:
On Mon, Feb 14, 2022 at 10:38 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
Robert Haas <robertmhaas@gmail.com> writes:
I don't particularly like Chapman's solution,
... and (3) is an attempt at compromise that is nobody's first choice.
Ok, I guess that's )sniffle( a pretty fair way of putting it.
... (3) put some complex system in place like what Chapman
proposes and get all extension authors to adopt it,
By the same token, I don't think it would entail anything like a big
flag day for extension authors. Provided no one proposes immediately
to /remove/ PGDLLIMPORT from things that now have it, the effect would
be more that the next time an extension author comes hat-in-hand
asking for a new PGDLLIMPORT because a thing won't build on Windows,
the answer can be "here, we have this API you can use for that now."
My reading of past discussions on the list suggest that stronger
encapsulation and API delineation have advocates in some quarters,
so I tried to accommodate that in what I proposed. It does, for example,
avoid exposing the 'real' value of a GUC to writing by a buggy
or compromised extension.
I'll be first to agree what I proposed isn't beautiful, but it might be
that a round or two of improvement by somebody smarter than me could lead
to something possibly preferable to PGDLLIMPORT-everywhere /when measured
against certain objectives/, like encapsulation.
So maybe this is in part a discussion about what the weights should be
on those various objectives.
Regards,
-Chap
Robert Haas <robertmhaas@gmail.com> writes:
Hmm, I guess I'd need to know who those people are in order to be able
to review their comments. I don't *like* the extra notational cruft,
but applying it inconsistently isn't better than being consistent. As
I see it, we have four choices: (1) apply PGDLLIMPORT markings
relatively broadly so that people can get extensions to work on
Windows, (2) continue to apply them inconsistently, thus slightly
reducing notational clutter at the cost of breaking lots of extensions
on Windows, (3) put some complex system in place like what Chapman
proposes and get all extension authors to adopt it, and (4) remove the
Windows port. To the best of my current knowledge, everyone other than
you prefers (1), you prefer (2) or (4), and (3) is an attempt at
compromise that is nobody's first choice.
I think you are attributing straw-man positions to me. What I'd actually
*like* is some solution that has the effect of (1) without having to mark
up our code with a bunch of Microsoft-isms. However I don't know how to
do that, and I do agree that (2), (3), and (4) are not better than (1).
There are some technical issues though:
* AFAICS, the patch of record doesn't actually do (1), it does something
else that adds yet more new notation. The cfbot says it fails, too.
* If we institute a policy that all GUCs should be PGDLLIMPORT'd,
how will we enforce that new patches follow that? I don't want to be
endlessly going back and adding forgotten PGDLLIMPORT markers.
* There's a moderately sizable subset of GUCs where the underlying
variable is not visible at all because it's static in guc.c.
Typically this is because that variable is only used for display
and there's an assign hook that stores the real data somewhere else.
I suppose what we want in such cases is for the "somewhere else"
to be PGDLLIMPORT'd, but in a lot of cases those variables are also
static in some other module. Does this proposal include exporting
variables that currently aren't visible to extensions at all?
I'm a little resistant to that. I can buy making sure that Windows
has a level playing field, but that's as far as I want to go.
regards, tom lane
On Mon, Feb 14, 2022 at 12:25 PM Chapman Flack <chap@anastigmatix.net> wrote:
On 02/14/22 11:43, Robert Haas wrote:
On Mon, Feb 14, 2022 at 10:38 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
Robert Haas <robertmhaas@gmail.com> writes:
I don't particularly like Chapman's solution,
... and (3) is an attempt at compromise that is nobody's first choice.
Ok, I guess that's )sniffle( a pretty fair way of putting it.
I mean I like it better than Tom does ... I just think it's a
complicated work around for a problem we don't really need to have.
My reading of past discussions on the list suggest that stronger
encapsulation and API delineation have advocates in some quarters,
so I tried to accommodate that in what I proposed. It does, for example,
avoid exposing the 'real' value of a GUC to writing by a buggy
or compromised extension.I'll be first to agree what I proposed isn't beautiful, but it might be
that a round or two of improvement by somebody smarter than me could lead
to something possibly preferable to PGDLLIMPORT-everywhere /when measured
against certain objectives/, like encapsulation.So maybe this is in part a discussion about what the weights should be
on those various objectives.
Keep in mind that there's nothing being set in stone here. Applying
PGDLLIMPORT to all GUCs across the board does not foreclose putting
some other system that restricts symbol visibility in the future. But
in the present, there is clearly no approach to the symbol visibility
problem that is fully baked or enjoys consensus. Yet, there is clearly
consensus that not being able to access GUCs in Windows extensions is
a problem. There must be like six different threads with people
complaining about that, and in every case the suggested solution is to
just add PGDLLIMPORT for crying out loud.
If in the future there is a consensus to restrict symbol visibility in
order to achieve some agreed-upon amount of encapsulation, then we can
do that then. Extension authors may not like it much, but every
serious extension author understands that the PostgreSQL code base
needs to keep moving forward, and that this will sometimes require
them to adjust for new major versions. This would be a bigger
adjustment than many, but I have confidence that if the benefits are
worthwhile, people will cope with it and adjust their extensions to
adhere to whatever new rules we put in place.
But between now and then, refusing to apply PGDLLIMPORT to a basically
random subset of GUCs is just annoying people without any compensating
benefit.
--
Robert Haas
EDB: http://www.enterprisedb.com
On Mon, Feb 14, 2022 at 12:34 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
I think you are attributing straw-man positions to me. What I'd actually
*like* is some solution that has the effect of (1) without having to mark
up our code with a bunch of Microsoft-isms. However I don't know how to
do that, and I do agree that (2), (3), and (4) are not better than (1).
OK, that sounds like we might be making some progress toward a useful agreement.
There are some technical issues though:
* AFAICS, the patch of record doesn't actually do (1), it does something
else that adds yet more new notation. The cfbot says it fails, too.
That sounds like a problem. Should be fixable.
* If we institute a policy that all GUCs should be PGDLLIMPORT'd,
how will we enforce that new patches follow that? I don't want to be
endlessly going back and adding forgotten PGDLLIMPORT markers.
It seems to me that it would be no different from bumping catversion
or updating nodefuncs.c: yes, it will get forgotten sometimes, but
hopefully people will mostly get used to it just like they do with
dozens of other PG-specific coding rules. I don't see that it's likely
to generate more than a handful of commits per year, so it doesn't
really seem worth worrying about to me, but YMMV. Maybe it's possible
to write a perl script to verify it, although it seems like it might
be complicated to code that up.
* There's a moderately sizable subset of GUCs where the underlying
variable is not visible at all because it's static in guc.c.
Typically this is because that variable is only used for display
and there's an assign hook that stores the real data somewhere else.
I suppose what we want in such cases is for the "somewhere else"
to be PGDLLIMPORT'd, but in a lot of cases those variables are also
static in some other module. Does this proposal include exporting
variables that currently aren't visible to extensions at all?
I'm a little resistant to that. I can buy making sure that Windows
has a level playing field, but that's as far as I want to go.
I can live with that. If someone complains about those variables being
static-to-file instead of globally visible, we can address that
complaint on its merits when it is presented.
An alternative rule which would dodge that particular issue would be
to just slap PGDLLIMPORT on every global variable in every header
file. That would arguably be a simpler rule, though it means even more
PGDLLIMPORT declarations floating around.
--
Robert Haas
EDB: http://www.enterprisedb.com
Robert Haas <robertmhaas@gmail.com> writes:
An alternative rule which would dodge that particular issue would be
to just slap PGDLLIMPORT on every global variable in every header
file. That would arguably be a simpler rule, though it means even more
PGDLLIMPORT declarations floating around.
Yeah, if the objective is "level playing field for Windows",
then it's hard to avoid the conclusion that we should just do that.
Again, I've never had an objection to that as the end result ---
I just wish that we could get the toolchain to do it for us.
But if we can't, we can't.
regards, tom lane
On Mon, Feb 14, 2022 at 12:55 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
Robert Haas <robertmhaas@gmail.com> writes:
An alternative rule which would dodge that particular issue would be
to just slap PGDLLIMPORT on every global variable in every header
file. That would arguably be a simpler rule, though it means even more
PGDLLIMPORT declarations floating around.Yeah, if the objective is "level playing field for Windows",
then it's hard to avoid the conclusion that we should just do that.
Again, I've never had an objection to that as the end result ---
I just wish that we could get the toolchain to do it for us.
But if we can't, we can't.
100% agreed.
--
Robert Haas
EDB: http://www.enterprisedb.com
Hi,
On 2022-02-14 12:45:08 -0500, Robert Haas wrote:
On Mon, Feb 14, 2022 at 12:34 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
* If we institute a policy that all GUCs should be PGDLLIMPORT'd,
how will we enforce that new patches follow that? I don't want to be
endlessly going back and adding forgotten PGDLLIMPORT markers.It seems to me that it would be no different from bumping catversion
or updating nodefuncs.c: yes, it will get forgotten sometimes, but
hopefully people will mostly get used to it just like they do with
dozens of other PG-specific coding rules. I don't see that it's likely
to generate more than a handful of commits per year, so it doesn't
really seem worth worrying about to me, but YMMV. Maybe it's possible
to write a perl script to verify it, although it seems like it might
be complicated to code that up.
I think it'd be better if we had scripts ensuring this stays sane. Several of
your examples do have that. Whereas I don't see what would cause us to missing
PGDLLIMPORTs for GUCs, given it's a windows only issue and that you need an
extension using the GUC with omitted PGDLLIMPORT.
An alternative rule which would dodge that particular issue would be
to just slap PGDLLIMPORT on every global variable in every header
file. That would arguably be a simpler rule, though it means even more
PGDLLIMPORT declarations floating around.
That would have the advantage of being comparatively easy to check in an
automated way. Might even be cheap enough to just make it part of the build.
But it seems like it'd be a fair amount of work and cause a lot of patch
rebasing pain? If we end up going that way, we should schedule this to happen
just after the feature freeze, I think.
If we consider doing this for all extern variables, we should think about
doing this for headers *and* functions. That'd allow us to get rid of the
fairly complicated logic to generate the .def file for the postgres binary on
windows (src/tools/gendef.pl). And maybe also the related thing on AIX
(src/backend/port/aix/mkldexport.sh)
I'm kind of partial to the "add explicit visibility information to everything"
approach because the windows export file generation is a decent chunk of the
meson patchset. And what's missing to make it work on AIX...
Greetings,
Andres Freund
On Mon, Feb 14, 2022 at 8:53 PM Andres Freund <andres@anarazel.de> wrote:
An alternative rule which would dodge that particular issue would be
to just slap PGDLLIMPORT on every global variable in every header
file. That would arguably be a simpler rule, though it means even more
PGDLLIMPORT declarations floating around.That would have the advantage of being comparatively easy to check in an
automated way. Might even be cheap enough to just make it part of the build.
I wasn't able to quickly write something that was smart enough to use
as part of the build, but I wrote something dumb that I think works
well enough to use with a little bit of human intelligence alongside.
See attached.
But it seems like it'd be a fair amount of work and cause a lot of patch
rebasing pain? If we end up going that way, we should schedule this to happen
just after the feature freeze, I think.
We could do that. I'd sort of rather get it done. We still have two
weeks before the last CommitFest officially starts, and it's not as if
there won't be tons of uncommitted patches floating around after that.
If we consider doing this for all extern variables, we should think about
doing this for headers *and* functions. That'd allow us to get rid of the
fairly complicated logic to generate the .def file for the postgres binary on
windows (src/tools/gendef.pl). And maybe also the related thing on AIX
(src/backend/port/aix/mkldexport.sh)
I don't know what you mean by this.
--
Robert Haas
EDB: http://www.enterprisedb.com
Attachments:
v1-0001-Dumb-script-to-apply-PGDLLIMPORT-markings.patchapplication/octet-stream; name=v1-0001-Dumb-script-to-apply-PGDLLIMPORT-markings.patchDownload
From 2ca0b4de166ed62958d4467a48d16c49a058b57a Mon Sep 17 00:00:00 2001
From: Robert Haas <rhaas@postgresql.org>
Date: Tue, 15 Feb 2022 08:44:28 -0500
Subject: [PATCH v1 1/2] Dumb script to apply PGDLLIMPORT markings.
---
src/tools/mark_pgdllimport.pl | 47 +++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
create mode 100755 src/tools/mark_pgdllimport.pl
diff --git a/src/tools/mark_pgdllimport.pl b/src/tools/mark_pgdllimport.pl
new file mode 100755
index 0000000000..020ef7364c
--- /dev/null
+++ b/src/tools/mark_pgdllimport.pl
@@ -0,0 +1,47 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+for my $include_file (@ARGV)
+{
+ open(my $rfh, '<', $include_file) || die "$include_file: $!";
+ my $buffer = '';
+ my $num_pgdllimport_added = 0;
+
+ while (<$rfh>)
+ {
+ my $needs_pgdllimport = 1;
+
+ # By convention we declare global variables explicitly extern. We're
+ # looking for those not already marked with PGDLLIMPORT.
+ $needs_pgdllimport = 0 if !/^extern\s+/ || /PGDLLIMPORT/;
+
+ # Variable declarations should end in a semicolon, but if the semicolon
+ # is preceded by a closing parenthesis, it's probably a function
+ # declaration.
+ $needs_pgdllimport = 0 if !/;$/ || /\);$/;
+
+ # Add PGDLLIMPORT marker, if required.
+ if ($needs_pgdllimport)
+ {
+ s/^extern/extern PGDLLIMPORT/;
+ ++$num_pgdllimport_added;
+ }
+
+ # Add line to buffer.
+ $buffer .= $_;
+ }
+
+ close($rfh);
+
+ # If we added any PGDLLIMPORT markers, rewrite the file.
+ if ($num_pgdllimport_added > 0)
+ {
+ printf "%s: adding %d PGDLLIMPORT markers\n",
+ $include_file, $num_pgdllimport_added;
+ open(my $wfh, '>', $include_file) || die "$include_file: $!";
+ print $wfh $buffer;
+ close($wfh);
+ }
+}
--
2.24.3 (Apple Git-128)
v1-0002-Plaster-PGDLLIMPORT-declarations-on-header-files.patchapplication/octet-stream; name=v1-0002-Plaster-PGDLLIMPORT-declarations-on-header-files.patchDownload
From 1eace4315be68662b8ffbc15a5cfe821787359e4 Mon Sep 17 00:00:00 2001
From: Robert Haas <rhaas@postgresql.org>
Date: Tue, 15 Feb 2022 08:53:25 -0500
Subject: [PATCH v1 2/2] Plaster PGDLLIMPORT declarations on header files.
---
src/include/access/gin.h | 2 +-
src/include/access/parallel.h | 2 +-
src/include/access/session.h | 2 +-
src/include/access/tableam.h | 4 +-
src/include/access/toast_compression.h | 2 +-
src/include/access/twophase_rmgr.h | 8 +-
src/include/access/xact.h | 16 ++--
src/include/access/xlog.h | 96 ++++++++++-----------
src/include/access/xlog_internal.h | 10 +--
src/include/access/xlogutils.h | 4 +-
src/include/bootstrap/bootstrap.h | 6 +-
src/include/catalog/namespace.h | 2 +-
src/include/catalog/objectaddress.h | 2 +-
src/include/catalog/storage.h | 2 +-
src/include/commands/async.h | 4 +-
src/include/commands/tablespace.h | 2 +-
src/include/commands/user.h | 2 +-
src/include/commands/vacuum.h | 18 ++--
src/include/common/file_perm.h | 6 +-
src/include/common/jsonapi.h | 2 +-
src/include/common/logging.h | 2 +-
src/include/common/pg_lzcompress.h | 4 +-
src/include/common/relpath.h | 2 +-
src/include/fe_utils/cancel.h | 2 +-
src/include/fe_utils/print.h | 6 +-
src/include/fe_utils/string_utils.h | 2 +-
src/include/fmgr.h | 2 +-
src/include/jit/jit.h | 20 ++---
src/include/jit/llvmjit.h | 44 +++++-----
src/include/libpq/auth.h | 6 +-
src/include/libpq/libpq-be.h | 2 +-
src/include/libpq/libpq.h | 28 +++---
src/include/libpq/pqcomm.h | 2 +-
src/include/libpq/scram.h | 2 +-
src/include/mb/pg_wchar.h | 6 +-
src/include/miscadmin.h | 52 +++++------
src/include/nodes/readfuncs.h | 2 +-
src/include/optimizer/geqo.h | 2 +-
src/include/optimizer/optimizer.h | 4 +-
src/include/optimizer/planmain.h | 6 +-
src/include/parser/parse_expr.h | 2 +-
src/include/parser/parser.h | 4 +-
src/include/pg_getopt.h | 10 +--
src/include/pgstat.h | 22 ++---
src/include/pgtime.h | 2 +-
src/include/port/win32_port.h | 6 +-
src/include/port/win32ntdll.h | 4 +-
src/include/postmaster/autovacuum.h | 32 +++----
src/include/postmaster/bgworker_internals.h | 2 +-
src/include/postmaster/bgwriter.h | 8 +-
src/include/postmaster/pgarch.h | 2 +-
src/include/postmaster/postmaster.h | 34 ++++----
src/include/postmaster/startup.h | 2 +-
src/include/postmaster/syslogger.h | 14 +--
src/include/postmaster/walwriter.h | 4 +-
src/include/replication/logicallauncher.h | 4 +-
src/include/replication/syncrep.h | 8 +-
src/include/replication/walreceiver.h | 8 +-
src/include/replication/walsender.h | 14 +--
src/include/replication/walsender_private.h | 6 +-
src/include/replication/worker_internal.h | 10 +--
src/include/storage/buf_internals.h | 4 +-
src/include/storage/bufmgr.h | 20 ++---
src/include/storage/dsm_impl.h | 4 +-
src/include/storage/fd.h | 4 +-
src/include/storage/large_object.h | 2 +-
src/include/storage/lock.h | 14 +--
src/include/storage/lwlock.h | 2 +-
src/include/storage/pg_shmem.h | 14 +--
src/include/storage/pmsignal.h | 2 +-
src/include/storage/predicate.h | 6 +-
src/include/storage/proc.h | 4 +-
src/include/storage/s_lock.h | 2 +-
src/include/storage/sinval.h | 4 +-
src/include/storage/spin.h | 2 +-
src/include/storage/standby.h | 8 +-
src/include/tcop/tcopprot.h | 8 +-
src/include/tsearch/ts_cache.h | 2 +-
src/include/tsearch/ts_type.h | 2 +-
src/include/utils/array.h | 2 +-
src/include/utils/builtins.h | 2 +-
src/include/utils/datetime.h | 2 +-
src/include/utils/elog.h | 12 +--
src/include/utils/fmgrtab.h | 4 +-
src/include/utils/guc.h | 64 +++++++-------
src/include/utils/guc_tables.h | 8 +-
src/include/utils/pg_locale.h | 16 ++--
src/include/utils/plancache.h | 2 +-
src/include/utils/ps_status.h | 2 +-
src/include/utils/queryjumble.h | 4 +-
src/include/utils/relcache.h | 4 +-
src/include/utils/rls.h | 2 +-
src/include/utils/snapmgr.h | 2 +-
src/include/utils/timestamp.h | 4 +-
src/include/utils/xml.h | 2 +-
95 files changed, 411 insertions(+), 411 deletions(-)
diff --git a/src/include/access/gin.h b/src/include/access/gin.h
index e83e0acd92..aacc665fdc 100644
--- a/src/include/access/gin.h
+++ b/src/include/access/gin.h
@@ -68,7 +68,7 @@ typedef char GinTernaryValue;
/* GUC parameters */
extern PGDLLIMPORT int GinFuzzySearchLimit;
-extern int gin_pending_list_limit;
+extern PGDLLIMPORT int gin_pending_list_limit;
/* ginutil.c */
extern void ginGetStats(Relation index, GinStatsData *stats);
diff --git a/src/include/access/parallel.h b/src/include/access/parallel.h
index 30786820f8..983841d45e 100644
--- a/src/include/access/parallel.h
+++ b/src/include/access/parallel.h
@@ -54,7 +54,7 @@ typedef struct ParallelWorkerContext
shm_toc *toc;
} ParallelWorkerContext;
-extern volatile bool ParallelMessagePending;
+extern PGDLLIMPORT volatile bool ParallelMessagePending;
extern PGDLLIMPORT int ParallelWorkerNumber;
extern PGDLLIMPORT bool InitializingParallelWorker;
diff --git a/src/include/access/session.h b/src/include/access/session.h
index 0ed52d4821..775888bbb0 100644
--- a/src/include/access/session.h
+++ b/src/include/access/session.h
@@ -39,6 +39,6 @@ extern void AttachSession(dsm_handle handle);
extern void DetachSession(void);
/* The current session, or NULL for none. */
-extern Session *CurrentSession;
+extern PGDLLIMPORT Session *CurrentSession;
#endif /* SESSION_H */
diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h
index bb365736b7..fe869c6c18 100644
--- a/src/include/access/tableam.h
+++ b/src/include/access/tableam.h
@@ -28,8 +28,8 @@
#define DEFAULT_TABLE_ACCESS_METHOD "heap"
/* GUCs */
-extern char *default_table_access_method;
-extern bool synchronize_seqscans;
+extern PGDLLIMPORT char *default_table_access_method;
+extern PGDLLIMPORT bool synchronize_seqscans;
struct BulkInsertStateData;
diff --git a/src/include/access/toast_compression.h b/src/include/access/toast_compression.h
index 9b433c7721..deb8f99da5 100644
--- a/src/include/access/toast_compression.h
+++ b/src/include/access/toast_compression.h
@@ -20,7 +20,7 @@
* but the value is one of the char values defined below, as they appear in
* pg_attribute.attcompression, e.g. TOAST_PGLZ_COMPRESSION.
*/
-extern int default_toast_compression;
+extern PGDLLIMPORT int default_toast_compression;
/*
* Built-in compression method ID. The toast compression header will store
diff --git a/src/include/access/twophase_rmgr.h b/src/include/access/twophase_rmgr.h
index 284c7539f8..96381a5e3f 100644
--- a/src/include/access/twophase_rmgr.h
+++ b/src/include/access/twophase_rmgr.h
@@ -28,10 +28,10 @@ typedef uint8 TwoPhaseRmgrId;
#define TWOPHASE_RM_PREDICATELOCK_ID 4
#define TWOPHASE_RM_MAX_ID TWOPHASE_RM_PREDICATELOCK_ID
-extern const TwoPhaseCallback twophase_recover_callbacks[];
-extern const TwoPhaseCallback twophase_postcommit_callbacks[];
-extern const TwoPhaseCallback twophase_postabort_callbacks[];
-extern const TwoPhaseCallback twophase_standby_recover_callbacks[];
+extern PGDLLIMPORT const TwoPhaseCallback twophase_recover_callbacks[];
+extern PGDLLIMPORT const TwoPhaseCallback twophase_postcommit_callbacks[];
+extern PGDLLIMPORT const TwoPhaseCallback twophase_postabort_callbacks[];
+extern PGDLLIMPORT const TwoPhaseCallback twophase_standby_recover_callbacks[];
extern void RegisterTwoPhaseRecord(TwoPhaseRmgrId rmid, uint16 info,
diff --git a/src/include/access/xact.h b/src/include/access/xact.h
index 17a6fa4abd..955c9cf061 100644
--- a/src/include/access/xact.h
+++ b/src/include/access/xact.h
@@ -38,7 +38,7 @@
#define XACT_REPEATABLE_READ 2
#define XACT_SERIALIZABLE 3
-extern int DefaultXactIsoLevel;
+extern PGDLLIMPORT int DefaultXactIsoLevel;
extern PGDLLIMPORT int XactIsoLevel;
/*
@@ -52,18 +52,18 @@ extern PGDLLIMPORT int XactIsoLevel;
#define IsolationIsSerializable() (XactIsoLevel == XACT_SERIALIZABLE)
/* Xact read-only state */
-extern bool DefaultXactReadOnly;
-extern bool XactReadOnly;
+extern PGDLLIMPORT bool DefaultXactReadOnly;
+extern PGDLLIMPORT bool XactReadOnly;
/* flag for logging statements in this transaction */
-extern bool xact_is_sampled;
+extern PGDLLIMPORT bool xact_is_sampled;
/*
* Xact is deferrable -- only meaningful (currently) for read only
* SERIALIZABLE transactions
*/
-extern bool DefaultXactDeferrable;
-extern bool XactDeferrable;
+extern PGDLLIMPORT bool DefaultXactDeferrable;
+extern PGDLLIMPORT bool XactDeferrable;
typedef enum
{
@@ -80,7 +80,7 @@ typedef enum
#define SYNCHRONOUS_COMMIT_ON SYNCHRONOUS_COMMIT_REMOTE_FLUSH
/* Synchronous commit level */
-extern int synchronous_commit;
+extern PGDLLIMPORT int synchronous_commit;
/* used during logical streaming of a transaction */
extern PGDLLIMPORT TransactionId CheckXidAlive;
@@ -93,7 +93,7 @@ extern PGDLLIMPORT bool bsysscan;
* globally accessible, so can be set from anywhere in the code which requires
* recording flags.
*/
-extern int MyXactFlags;
+extern PGDLLIMPORT int MyXactFlags;
/*
* XACT_FLAGS_ACCESSEDTEMPNAMESPACE - set when a temporary object is accessed.
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index a4b1c1286f..5872a8fd52 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -26,7 +26,7 @@
#define SYNC_METHOD_OPEN 2 /* for O_SYNC */
#define SYNC_METHOD_FSYNC_WRITETHROUGH 3
#define SYNC_METHOD_OPEN_DSYNC 4 /* for O_DSYNC */
-extern int sync_method;
+extern PGDLLIMPORT int sync_method;
/*
* Recovery target type.
@@ -52,58 +52,58 @@ typedef enum
RECOVERY_TARGET_TIMELINE_NUMERIC
} RecoveryTargetTimeLineGoal;
-extern XLogRecPtr ProcLastRecPtr;
-extern XLogRecPtr XactLastRecEnd;
+extern PGDLLIMPORT XLogRecPtr ProcLastRecPtr;
+extern PGDLLIMPORT XLogRecPtr XactLastRecEnd;
extern PGDLLIMPORT XLogRecPtr XactLastCommitEnd;
-extern bool reachedConsistency;
+extern PGDLLIMPORT bool reachedConsistency;
/* these variables are GUC parameters related to XLOG */
-extern int wal_segment_size;
-extern int min_wal_size_mb;
-extern int max_wal_size_mb;
-extern int wal_keep_size_mb;
-extern int max_slot_wal_keep_size_mb;
-extern int XLOGbuffers;
-extern int XLogArchiveTimeout;
-extern int wal_retrieve_retry_interval;
-extern char *XLogArchiveCommand;
-extern bool EnableHotStandby;
-extern bool fullPageWrites;
-extern bool wal_log_hints;
-extern int wal_compression;
-extern bool wal_init_zero;
-extern bool wal_recycle;
-extern bool *wal_consistency_checking;
-extern char *wal_consistency_checking_string;
-extern bool log_checkpoints;
-extern char *recoveryRestoreCommand;
-extern char *recoveryEndCommand;
-extern char *archiveCleanupCommand;
-extern bool recoveryTargetInclusive;
-extern int recoveryTargetAction;
-extern int recovery_min_apply_delay;
-extern char *PrimaryConnInfo;
-extern char *PrimarySlotName;
-extern bool wal_receiver_create_temp_slot;
-extern bool track_wal_io_timing;
+extern PGDLLIMPORT int wal_segment_size;
+extern PGDLLIMPORT int min_wal_size_mb;
+extern PGDLLIMPORT int max_wal_size_mb;
+extern PGDLLIMPORT int wal_keep_size_mb;
+extern PGDLLIMPORT int max_slot_wal_keep_size_mb;
+extern PGDLLIMPORT int XLOGbuffers;
+extern PGDLLIMPORT int XLogArchiveTimeout;
+extern PGDLLIMPORT int wal_retrieve_retry_interval;
+extern PGDLLIMPORT char *XLogArchiveCommand;
+extern PGDLLIMPORT bool EnableHotStandby;
+extern PGDLLIMPORT bool fullPageWrites;
+extern PGDLLIMPORT bool wal_log_hints;
+extern PGDLLIMPORT int wal_compression;
+extern PGDLLIMPORT bool wal_init_zero;
+extern PGDLLIMPORT bool wal_recycle;
+extern PGDLLIMPORT bool *wal_consistency_checking;
+extern PGDLLIMPORT char *wal_consistency_checking_string;
+extern PGDLLIMPORT bool log_checkpoints;
+extern PGDLLIMPORT char *recoveryRestoreCommand;
+extern PGDLLIMPORT char *recoveryEndCommand;
+extern PGDLLIMPORT char *archiveCleanupCommand;
+extern PGDLLIMPORT bool recoveryTargetInclusive;
+extern PGDLLIMPORT int recoveryTargetAction;
+extern PGDLLIMPORT int recovery_min_apply_delay;
+extern PGDLLIMPORT char *PrimaryConnInfo;
+extern PGDLLIMPORT char *PrimarySlotName;
+extern PGDLLIMPORT bool wal_receiver_create_temp_slot;
+extern PGDLLIMPORT bool track_wal_io_timing;
/* indirectly set via GUC system */
-extern TransactionId recoveryTargetXid;
-extern char *recovery_target_time_string;
-extern const char *recoveryTargetName;
-extern XLogRecPtr recoveryTargetLSN;
-extern RecoveryTargetType recoveryTarget;
-extern char *PromoteTriggerFile;
-extern RecoveryTargetTimeLineGoal recoveryTargetTimeLineGoal;
-extern TimeLineID recoveryTargetTLIRequested;
-extern TimeLineID recoveryTargetTLI;
-
-extern int CheckPointSegments;
+extern PGDLLIMPORT TransactionId recoveryTargetXid;
+extern PGDLLIMPORT char *recovery_target_time_string;
+extern PGDLLIMPORT const char *recoveryTargetName;
+extern PGDLLIMPORT XLogRecPtr recoveryTargetLSN;
+extern PGDLLIMPORT RecoveryTargetType recoveryTarget;
+extern PGDLLIMPORT char *PromoteTriggerFile;
+extern PGDLLIMPORT RecoveryTargetTimeLineGoal recoveryTargetTimeLineGoal;
+extern PGDLLIMPORT TimeLineID recoveryTargetTLIRequested;
+extern PGDLLIMPORT TimeLineID recoveryTargetTLI;
+
+extern PGDLLIMPORT int CheckPointSegments;
/* option set locally in startup process only when signal files exist */
-extern bool StandbyModeRequested;
-extern bool StandbyMode;
+extern PGDLLIMPORT bool StandbyModeRequested;
+extern PGDLLIMPORT bool StandbyMode;
/* Archive modes */
typedef enum ArchiveMode
@@ -112,7 +112,7 @@ typedef enum ArchiveMode
ARCHIVE_MODE_ON, /* enabled while server is running normally */
ARCHIVE_MODE_ALWAYS /* enabled always (even during recovery) */
} ArchiveMode;
-extern int XLogArchiveMode;
+extern PGDLLIMPORT int XLogArchiveMode;
/* WAL levels */
typedef enum WalLevel
@@ -179,7 +179,7 @@ extern PGDLLIMPORT int wal_level;
#define XLogLogicalInfoActive() (wal_level >= WAL_LEVEL_LOGICAL)
#ifdef WAL_DEBUG
-extern bool XLOG_DEBUG;
+extern PGDLLIMPORT bool XLOG_DEBUG;
#endif
/*
@@ -233,7 +233,7 @@ typedef struct CheckpointStatsData
* entire sync phase. */
} CheckpointStatsData;
-extern CheckpointStatsData CheckpointStats;
+extern PGDLLIMPORT CheckpointStatsData CheckpointStats;
/*
* GetWALAvailability return codes
diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h
index 849954a8e5..c0ce8026aa 100644
--- a/src/include/access/xlog_internal.h
+++ b/src/include/access/xlog_internal.h
@@ -319,7 +319,7 @@ typedef struct RmgrData
struct XLogRecordBuffer *buf);
} RmgrData;
-extern const RmgrData RmgrTable[];
+extern PGDLLIMPORT const RmgrData RmgrTable[];
/*
* Exported to support xlog switching from checkpointer
@@ -333,9 +333,9 @@ extern void GetOldestRestartPoint(XLogRecPtr *oldrecptr, TimeLineID *oldtli);
* Exported for the functions in timeline.c and xlogarchive.c. Only valid
* in the startup process.
*/
-extern bool ArchiveRecoveryRequested;
-extern bool InArchiveRecovery;
-extern bool StandbyMode;
-extern char *recoveryRestoreCommand;
+extern PGDLLIMPORT bool ArchiveRecoveryRequested;
+extern PGDLLIMPORT bool InArchiveRecovery;
+extern PGDLLIMPORT bool StandbyMode;
+extern PGDLLIMPORT char *recoveryRestoreCommand;
#endif /* XLOG_INTERNAL_H */
diff --git a/src/include/access/xlogutils.h b/src/include/access/xlogutils.h
index 64708949db..00889f76de 100644
--- a/src/include/access/xlogutils.h
+++ b/src/include/access/xlogutils.h
@@ -21,7 +21,7 @@
* potentially perform work during recovery should check RecoveryInProgress().
* See XLogCtl notes in xlog.c.
*/
-extern bool InRecovery;
+extern PGDLLIMPORT bool InRecovery;
/*
* Like InRecovery, standbyState is only valid in the startup process.
@@ -52,7 +52,7 @@ typedef enum
STANDBY_SNAPSHOT_READY
} HotStandbyState;
-extern HotStandbyState standbyState;
+extern PGDLLIMPORT HotStandbyState standbyState;
#define InHotStandby (standbyState >= STANDBY_SNAPSHOT_PENDING)
diff --git a/src/include/bootstrap/bootstrap.h b/src/include/bootstrap/bootstrap.h
index 471414909f..49d4ad560f 100644
--- a/src/include/bootstrap/bootstrap.h
+++ b/src/include/bootstrap/bootstrap.h
@@ -27,9 +27,9 @@
#define BOOTCOL_NULL_FORCE_NULL 2
#define BOOTCOL_NULL_FORCE_NOT_NULL 3
-extern Relation boot_reldesc;
-extern Form_pg_attribute attrtypes[MAXATTR];
-extern int numattr;
+extern PGDLLIMPORT Relation boot_reldesc;
+extern PGDLLIMPORT Form_pg_attribute attrtypes[MAXATTR];
+extern PGDLLIMPORT int numattr;
extern void BootstrapModeMain(int argc, char *argv[], bool check_only) pg_attribute_noreturn();
diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h
index f963d82797..1bc55c01a5 100644
--- a/src/include/catalog/namespace.h
+++ b/src/include/catalog/namespace.h
@@ -182,7 +182,7 @@ extern void AtEOSubXact_Namespace(bool isCommit, SubTransactionId mySubid,
SubTransactionId parentSubid);
/* stuff for search_path GUC variable */
-extern char *namespace_search_path;
+extern PGDLLIMPORT char *namespace_search_path;
extern List *fetch_search_path(bool includeImplicit);
extern int fetch_search_path_array(Oid *sarray, int sarray_len);
diff --git a/src/include/catalog/objectaddress.h b/src/include/catalog/objectaddress.h
index 274f300054..cf4d8b3107 100644
--- a/src/include/catalog/objectaddress.h
+++ b/src/include/catalog/objectaddress.h
@@ -28,7 +28,7 @@ typedef struct ObjectAddress
int32 objectSubId; /* Subitem within object (eg column), or 0 */
} ObjectAddress;
-extern const ObjectAddress InvalidObjectAddress;
+extern PGDLLIMPORT const ObjectAddress InvalidObjectAddress;
#define ObjectAddressSubSet(addr, class_id, object_id, object_sub_id) \
do { \
diff --git a/src/include/catalog/storage.h b/src/include/catalog/storage.h
index 9ffc741913..947c39c8a7 100644
--- a/src/include/catalog/storage.h
+++ b/src/include/catalog/storage.h
@@ -20,7 +20,7 @@
#include "utils/relcache.h"
/* GUC variables */
-extern int wal_skip_threshold;
+extern PGDLLIMPORT int wal_skip_threshold;
extern SMgrRelation RelationCreateStorage(RelFileNode rnode, char relpersistence);
extern void RelationDropStorage(Relation rel);
diff --git a/src/include/commands/async.h b/src/include/commands/async.h
index ebc9271789..926af933d1 100644
--- a/src/include/commands/async.h
+++ b/src/include/commands/async.h
@@ -20,8 +20,8 @@
*/
#define NUM_NOTIFY_BUFFERS 8
-extern bool Trace_notify;
-extern volatile sig_atomic_t notifyInterruptPending;
+extern PGDLLIMPORT bool Trace_notify;
+extern PGDLLIMPORT volatile sig_atomic_t notifyInterruptPending;
extern Size AsyncShmemSize(void);
extern void AsyncShmemInit(void);
diff --git a/src/include/commands/tablespace.h b/src/include/commands/tablespace.h
index 323528ebb8..24b647332d 100644
--- a/src/include/commands/tablespace.h
+++ b/src/include/commands/tablespace.h
@@ -19,7 +19,7 @@
#include "lib/stringinfo.h"
#include "nodes/parsenodes.h"
-extern bool allow_in_place_tablespaces;
+extern PGDLLIMPORT bool allow_in_place_tablespaces;
/* XLOG stuff */
#define XLOG_TBLSPC_CREATE 0x00
diff --git a/src/include/commands/user.h b/src/include/commands/user.h
index 0b7a3cd65f..d3dd8303d2 100644
--- a/src/include/commands/user.h
+++ b/src/include/commands/user.h
@@ -17,7 +17,7 @@
#include "parser/parse_node.h"
/* GUC. Is actually of type PasswordType. */
-extern int Password_encryption;
+extern PGDLLIMPORT int Password_encryption;
/* Hook to check passwords in CreateRole() and AlterRole() */
typedef void (*check_password_hook_type) (const char *username, const char *shadow_pass, PasswordType password_type, Datum validuntil_time, bool validuntil_null);
diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h
index d64f6268f2..239e0356fa 100644
--- a/src/include/commands/vacuum.h
+++ b/src/include/commands/vacuum.h
@@ -252,17 +252,17 @@ typedef struct VacDeadItems
/* GUC parameters */
extern PGDLLIMPORT int default_statistics_target; /* PGDLLIMPORT for PostGIS */
-extern int vacuum_freeze_min_age;
-extern int vacuum_freeze_table_age;
-extern int vacuum_multixact_freeze_min_age;
-extern int vacuum_multixact_freeze_table_age;
-extern int vacuum_failsafe_age;
-extern int vacuum_multixact_failsafe_age;
+extern PGDLLIMPORT int vacuum_freeze_min_age;
+extern PGDLLIMPORT int vacuum_freeze_table_age;
+extern PGDLLIMPORT int vacuum_multixact_freeze_min_age;
+extern PGDLLIMPORT int vacuum_multixact_freeze_table_age;
+extern PGDLLIMPORT int vacuum_failsafe_age;
+extern PGDLLIMPORT int vacuum_multixact_failsafe_age;
/* Variables for cost-based parallel vacuum */
-extern pg_atomic_uint32 *VacuumSharedCostBalance;
-extern pg_atomic_uint32 *VacuumActiveNWorkers;
-extern int VacuumCostBalanceLocal;
+extern PGDLLIMPORT pg_atomic_uint32 *VacuumSharedCostBalance;
+extern PGDLLIMPORT pg_atomic_uint32 *VacuumActiveNWorkers;
+extern PGDLLIMPORT int VacuumCostBalanceLocal;
/* in commands/vacuum.c */
diff --git a/src/include/common/file_perm.h b/src/include/common/file_perm.h
index 85d32ed141..48d68ef276 100644
--- a/src/include/common/file_perm.h
+++ b/src/include/common/file_perm.h
@@ -41,11 +41,11 @@
#define PG_FILE_MODE_GROUP (S_IRUSR | S_IWUSR | S_IRGRP)
/* Modes for creating directories and files in the data directory */
-extern int pg_dir_create_mode;
-extern int pg_file_create_mode;
+extern PGDLLIMPORT int pg_dir_create_mode;
+extern PGDLLIMPORT int pg_file_create_mode;
/* Mode mask to pass to umask() */
-extern int pg_mode_mask;
+extern PGDLLIMPORT int pg_mode_mask;
/* Set permissions and mask based on the provided mode */
extern void SetDataDirectoryCreatePerm(int dataDirMode);
diff --git a/src/include/common/jsonapi.h b/src/include/common/jsonapi.h
index 52cb4a9339..8d31630e5c 100644
--- a/src/include/common/jsonapi.h
+++ b/src/include/common/jsonapi.h
@@ -128,7 +128,7 @@ extern JsonParseErrorType pg_parse_json(JsonLexContext *lex,
JsonSemAction *sem);
/* the null action object used for pure validation */
-extern JsonSemAction nullSemAction;
+extern PGDLLIMPORT JsonSemAction nullSemAction;
/*
* json_count_array_elements performs a fast secondary parse to determine the
diff --git a/src/include/common/logging.h b/src/include/common/logging.h
index 43cc79afa8..61cfdce653 100644
--- a/src/include/common/logging.h
+++ b/src/include/common/logging.h
@@ -55,7 +55,7 @@ enum pg_log_level
PG_LOG_OFF,
};
-extern enum pg_log_level __pg_log_level;
+extern PGDLLIMPORT enum pg_log_level __pg_log_level;
/*
* Kind of a hack to be able to produce the psql output exactly as required by
diff --git a/src/include/common/pg_lzcompress.h b/src/include/common/pg_lzcompress.h
index 3e53fbe97b..2a12b33a00 100644
--- a/src/include/common/pg_lzcompress.h
+++ b/src/include/common/pg_lzcompress.h
@@ -75,8 +75,8 @@ typedef struct PGLZ_Strategy
* output would be larger than input.
* ----------
*/
-extern const PGLZ_Strategy *const PGLZ_strategy_default;
-extern const PGLZ_Strategy *const PGLZ_strategy_always;
+extern PGDLLIMPORT const PGLZ_Strategy *const PGLZ_strategy_default;
+extern PGDLLIMPORT const PGLZ_Strategy *const PGLZ_strategy_always;
/* ----------
diff --git a/src/include/common/relpath.h b/src/include/common/relpath.h
index a4b5dc853b..13849a3790 100644
--- a/src/include/common/relpath.h
+++ b/src/include/common/relpath.h
@@ -56,7 +56,7 @@ typedef enum ForkNumber
#define FORKNAMECHARS 4 /* max chars for a fork name */
-extern const char *const forkNames[];
+extern PGDLLIMPORT const char *const forkNames[];
extern ForkNumber forkname_to_number(const char *forkName);
extern int forkname_chars(const char *str, ForkNumber *fork);
diff --git a/src/include/fe_utils/cancel.h b/src/include/fe_utils/cancel.h
index 7005b804bc..3b84daf6eb 100644
--- a/src/include/fe_utils/cancel.h
+++ b/src/include/fe_utils/cancel.h
@@ -18,7 +18,7 @@
#include "libpq-fe.h"
-extern volatile sig_atomic_t CancelRequested;
+extern PGDLLIMPORT volatile sig_atomic_t CancelRequested;
extern void SetCancelConn(PGconn *conn);
extern void ResetCancelConn(void);
diff --git a/src/include/fe_utils/print.h b/src/include/fe_utils/print.h
index 836b4e29a8..5caf9e2d08 100644
--- a/src/include/fe_utils/print.h
+++ b/src/include/fe_utils/print.h
@@ -177,10 +177,10 @@ typedef struct printQueryOpt
} printQueryOpt;
-extern volatile sig_atomic_t cancel_pressed;
+extern PGDLLIMPORT volatile sig_atomic_t cancel_pressed;
-extern const printTextFormat pg_asciiformat;
-extern const printTextFormat pg_asciiformat_old;
+extern PGDLLIMPORT const printTextFormat pg_asciiformat;
+extern PGDLLIMPORT const printTextFormat pg_asciiformat_old;
extern printTextFormat pg_utf8format; /* ideally would be const, but... */
diff --git a/src/include/fe_utils/string_utils.h b/src/include/fe_utils/string_utils.h
index 3c88250e6c..b9b8708dab 100644
--- a/src/include/fe_utils/string_utils.h
+++ b/src/include/fe_utils/string_utils.h
@@ -20,7 +20,7 @@
#include "pqexpbuffer.h"
/* Global variables controlling behavior of fmtId() and fmtQualifiedId() */
-extern int quote_all_identifiers;
+extern PGDLLIMPORT int quote_all_identifiers;
extern PQExpBuffer (*getLocalPQExpBuffer) (void);
/* Functions */
diff --git a/src/include/fmgr.h b/src/include/fmgr.h
index 6560e462d6..a1cf4bd646 100644
--- a/src/include/fmgr.h
+++ b/src/include/fmgr.h
@@ -721,7 +721,7 @@ extern bool CheckFunctionValidatorAccess(Oid validatorOid, Oid functionOid);
/*
* Routines in dfmgr.c
*/
-extern char *Dynamic_library_path;
+extern PGDLLIMPORT char *Dynamic_library_path;
extern void *load_external_function(const char *filename, const char *funcname,
bool signalNotFound, void **filehandle);
diff --git a/src/include/jit/jit.h b/src/include/jit/jit.h
index 707176d9ed..d194033209 100644
--- a/src/include/jit/jit.h
+++ b/src/include/jit/jit.h
@@ -79,16 +79,16 @@ struct JitProviderCallbacks
/* GUCs */
-extern bool jit_enabled;
-extern char *jit_provider;
-extern bool jit_debugging_support;
-extern bool jit_dump_bitcode;
-extern bool jit_expressions;
-extern bool jit_profiling_support;
-extern bool jit_tuple_deforming;
-extern double jit_above_cost;
-extern double jit_inline_above_cost;
-extern double jit_optimize_above_cost;
+extern PGDLLIMPORT bool jit_enabled;
+extern PGDLLIMPORT char *jit_provider;
+extern PGDLLIMPORT bool jit_debugging_support;
+extern PGDLLIMPORT bool jit_dump_bitcode;
+extern PGDLLIMPORT bool jit_expressions;
+extern PGDLLIMPORT bool jit_profiling_support;
+extern PGDLLIMPORT bool jit_tuple_deforming;
+extern PGDLLIMPORT double jit_above_cost;
+extern PGDLLIMPORT double jit_inline_above_cost;
+extern PGDLLIMPORT double jit_optimize_above_cost;
extern void jit_reset_after_error(void);
diff --git a/src/include/jit/llvmjit.h b/src/include/jit/llvmjit.h
index 66143afccc..4541f9a2c4 100644
--- a/src/include/jit/llvmjit.h
+++ b/src/include/jit/llvmjit.h
@@ -56,30 +56,30 @@ typedef struct LLVMJitContext
} LLVMJitContext;
/* llvm module containing information about types */
-extern LLVMModuleRef llvm_types_module;
+extern PGDLLIMPORT LLVMModuleRef llvm_types_module;
/* type and struct definitions */
-extern LLVMTypeRef TypeParamBool;
-extern LLVMTypeRef TypePGFunction;
-extern LLVMTypeRef TypeSizeT;
-extern LLVMTypeRef TypeStorageBool;
-
-extern LLVMTypeRef StructNullableDatum;
-extern LLVMTypeRef StructTupleDescData;
-extern LLVMTypeRef StructHeapTupleData;
-extern LLVMTypeRef StructTupleTableSlot;
-extern LLVMTypeRef StructHeapTupleTableSlot;
-extern LLVMTypeRef StructMinimalTupleTableSlot;
-extern LLVMTypeRef StructMemoryContextData;
-extern LLVMTypeRef StructFunctionCallInfoData;
-extern LLVMTypeRef StructExprContext;
-extern LLVMTypeRef StructExprEvalStep;
-extern LLVMTypeRef StructExprState;
-extern LLVMTypeRef StructAggState;
-extern LLVMTypeRef StructAggStatePerTransData;
-extern LLVMTypeRef StructAggStatePerGroupData;
-
-extern LLVMValueRef AttributeTemplate;
+extern PGDLLIMPORT LLVMTypeRef TypeParamBool;
+extern PGDLLIMPORT LLVMTypeRef TypePGFunction;
+extern PGDLLIMPORT LLVMTypeRef TypeSizeT;
+extern PGDLLIMPORT LLVMTypeRef TypeStorageBool;
+
+extern PGDLLIMPORT LLVMTypeRef StructNullableDatum;
+extern PGDLLIMPORT LLVMTypeRef StructTupleDescData;
+extern PGDLLIMPORT LLVMTypeRef StructHeapTupleData;
+extern PGDLLIMPORT LLVMTypeRef StructTupleTableSlot;
+extern PGDLLIMPORT LLVMTypeRef StructHeapTupleTableSlot;
+extern PGDLLIMPORT LLVMTypeRef StructMinimalTupleTableSlot;
+extern PGDLLIMPORT LLVMTypeRef StructMemoryContextData;
+extern PGDLLIMPORT LLVMTypeRef StructFunctionCallInfoData;
+extern PGDLLIMPORT LLVMTypeRef StructExprContext;
+extern PGDLLIMPORT LLVMTypeRef StructExprEvalStep;
+extern PGDLLIMPORT LLVMTypeRef StructExprState;
+extern PGDLLIMPORT LLVMTypeRef StructAggState;
+extern PGDLLIMPORT LLVMTypeRef StructAggStatePerTransData;
+extern PGDLLIMPORT LLVMTypeRef StructAggStatePerGroupData;
+
+extern PGDLLIMPORT LLVMValueRef AttributeTemplate;
extern void llvm_enter_fatal_on_oom(void);
diff --git a/src/include/libpq/auth.h b/src/include/libpq/auth.h
index 6d7ee1acb9..d3c189efe3 100644
--- a/src/include/libpq/auth.h
+++ b/src/include/libpq/auth.h
@@ -16,9 +16,9 @@
#include "libpq/libpq-be.h"
-extern char *pg_krb_server_keyfile;
-extern bool pg_krb_caseins_users;
-extern char *pg_krb_realm;
+extern PGDLLIMPORT char *pg_krb_server_keyfile;
+extern PGDLLIMPORT bool pg_krb_caseins_users;
+extern PGDLLIMPORT char *pg_krb_realm;
extern void ClientAuthentication(Port *port);
extern void sendAuthRequest(Port *port, AuthRequest areq, const char *extradata,
diff --git a/src/include/libpq/libpq-be.h b/src/include/libpq/libpq-be.h
index dd3e5efba3..3beeaeee39 100644
--- a/src/include/libpq/libpq-be.h
+++ b/src/include/libpq/libpq-be.h
@@ -327,7 +327,7 @@ extern ssize_t be_gssapi_read(Port *port, void *ptr, size_t len);
extern ssize_t be_gssapi_write(Port *port, void *ptr, size_t len);
#endif /* ENABLE_GSS */
-extern ProtocolVersion FrontendProtocol;
+extern PGDLLIMPORT ProtocolVersion FrontendProtocol;
/* TCP keepalives configuration. These are no-ops on an AF_UNIX socket. */
diff --git a/src/include/libpq/libpq.h b/src/include/libpq/libpq.h
index d348a55812..2de7d9bad2 100644
--- a/src/include/libpq/libpq.h
+++ b/src/include/libpq/libpq.h
@@ -58,7 +58,7 @@ extern const PGDLLIMPORT PQcommMethods *PqCommMethods;
/*
* prototypes for functions in pqcomm.c
*/
-extern WaitEventSet *FeBeWaitSet;
+extern PGDLLIMPORT WaitEventSet *FeBeWaitSet;
#define FeBeWaitSetSocketPos 0
#define FeBeWaitSetLatchPos 1
@@ -87,17 +87,17 @@ extern bool pq_check_connection(void);
/*
* prototypes for functions in be-secure.c
*/
-extern char *ssl_library;
-extern char *ssl_cert_file;
-extern char *ssl_key_file;
-extern char *ssl_ca_file;
-extern char *ssl_crl_file;
-extern char *ssl_crl_dir;
-extern char *ssl_dh_params_file;
+extern PGDLLIMPORT char *ssl_library;
+extern PGDLLIMPORT char *ssl_cert_file;
+extern PGDLLIMPORT char *ssl_key_file;
+extern PGDLLIMPORT char *ssl_ca_file;
+extern PGDLLIMPORT char *ssl_crl_file;
+extern PGDLLIMPORT char *ssl_crl_dir;
+extern PGDLLIMPORT char *ssl_dh_params_file;
extern PGDLLIMPORT char *ssl_passphrase_command;
extern PGDLLIMPORT bool ssl_passphrase_command_supports_reload;
#ifdef USE_SSL
-extern bool ssl_loaded_verify_locations;
+extern PGDLLIMPORT bool ssl_loaded_verify_locations;
#endif
extern int secure_initialize(bool isServerStart);
@@ -118,11 +118,11 @@ extern ssize_t secure_open_gssapi(Port *port);
#endif
/* GUCs */
-extern char *SSLCipherSuites;
-extern char *SSLECDHCurve;
-extern bool SSLPreferServerCiphers;
-extern int ssl_min_protocol_version;
-extern int ssl_max_protocol_version;
+extern PGDLLIMPORT char *SSLCipherSuites;
+extern PGDLLIMPORT char *SSLECDHCurve;
+extern PGDLLIMPORT bool SSLPreferServerCiphers;
+extern PGDLLIMPORT int ssl_min_protocol_version;
+extern PGDLLIMPORT int ssl_max_protocol_version;
enum ssl_protocol_versions
{
diff --git a/src/include/libpq/pqcomm.h b/src/include/libpq/pqcomm.h
index ed26ad2256..b418283d5f 100644
--- a/src/include/libpq/pqcomm.h
+++ b/src/include/libpq/pqcomm.h
@@ -135,7 +135,7 @@ typedef ProtocolVersion MsgType;
typedef uint32 PacketLen;
-extern bool Db_user_namespace;
+extern PGDLLIMPORT bool Db_user_namespace;
/*
* In protocol 3.0 and later, the startup packet length is not fixed, but
diff --git a/src/include/libpq/scram.h b/src/include/libpq/scram.h
index e60992a0d2..c51e848c24 100644
--- a/src/include/libpq/scram.h
+++ b/src/include/libpq/scram.h
@@ -18,7 +18,7 @@
#include "libpq/sasl.h"
/* SASL implementation callbacks */
-extern const pg_be_sasl_mech pg_be_scram_mech;
+extern PGDLLIMPORT const pg_be_sasl_mech pg_be_scram_mech;
/* Routines to handle and check SCRAM-SHA-256 secret */
extern char *pg_be_scram_build_secret(const char *password);
diff --git a/src/include/mb/pg_wchar.h b/src/include/mb/pg_wchar.h
index fd89bee80b..31f5b393da 100644
--- a/src/include/mb/pg_wchar.h
+++ b/src/include/mb/pg_wchar.h
@@ -359,7 +359,7 @@ typedef struct pg_enc2name
#endif
} pg_enc2name;
-extern const pg_enc2name pg_enc2name_tbl[];
+extern PGDLLIMPORT const pg_enc2name pg_enc2name_tbl[];
/*
* Encoding names for gettext
@@ -370,7 +370,7 @@ typedef struct pg_enc2gettext
const char *name;
} pg_enc2gettext;
-extern const pg_enc2gettext pg_enc2gettext_tbl[];
+extern PGDLLIMPORT const pg_enc2gettext pg_enc2gettext_tbl[];
/*
* pg_wchar stuff
@@ -406,7 +406,7 @@ typedef struct
int maxmblen; /* max bytes for a char in this encoding */
} pg_wchar_tbl;
-extern const pg_wchar_tbl pg_wchar_table[];
+extern PGDLLIMPORT const pg_wchar_tbl pg_wchar_table[];
/*
* Data structures for conversions between UTF-8 and other encodings
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index 0abc3ad540..7a8ca4a2d2 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -181,15 +181,15 @@ extern PGDLLIMPORT pg_time_t MyStartTime;
extern PGDLLIMPORT TimestampTz MyStartTimestamp;
extern PGDLLIMPORT struct Port *MyProcPort;
extern PGDLLIMPORT struct Latch *MyLatch;
-extern int32 MyCancelKey;
-extern int MyPMChildSlot;
+extern PGDLLIMPORT int32 MyCancelKey;
+extern PGDLLIMPORT int MyPMChildSlot;
-extern char OutputFileName[];
+extern PGDLLIMPORT char OutputFileName[];
extern PGDLLIMPORT char my_exec_path[];
-extern char pkglib_path[];
+extern PGDLLIMPORT char pkglib_path[];
#ifdef EXEC_BACKEND
-extern char postgres_exec_path[];
+extern PGDLLIMPORT char postgres_exec_path[];
#endif
/*
@@ -254,25 +254,25 @@ extern PGDLLIMPORT int IntervalStyle;
#define MAXTZLEN 10 /* max TZ name len, not counting tr. null */
-extern bool enableFsync;
+extern PGDLLIMPORT bool enableFsync;
extern PGDLLIMPORT bool allowSystemTableMods;
extern PGDLLIMPORT int work_mem;
extern PGDLLIMPORT double hash_mem_multiplier;
extern PGDLLIMPORT int maintenance_work_mem;
extern PGDLLIMPORT int max_parallel_maintenance_workers;
-extern int VacuumCostPageHit;
-extern int VacuumCostPageMiss;
-extern int VacuumCostPageDirty;
-extern int VacuumCostLimit;
-extern double VacuumCostDelay;
+extern PGDLLIMPORT int VacuumCostPageHit;
+extern PGDLLIMPORT int VacuumCostPageMiss;
+extern PGDLLIMPORT int VacuumCostPageDirty;
+extern PGDLLIMPORT int VacuumCostLimit;
+extern PGDLLIMPORT double VacuumCostDelay;
-extern int64 VacuumPageHit;
-extern int64 VacuumPageMiss;
-extern int64 VacuumPageDirty;
+extern PGDLLIMPORT int64 VacuumPageHit;
+extern PGDLLIMPORT int64 VacuumPageMiss;
+extern PGDLLIMPORT int64 VacuumPageDirty;
-extern int VacuumCostBalance;
-extern bool VacuumCostActive;
+extern PGDLLIMPORT int VacuumCostBalance;
+extern PGDLLIMPORT bool VacuumCostActive;
/* in tcop/postgres.c */
@@ -298,7 +298,7 @@ extern void PreventCommandIfParallelMode(const char *cmdname);
extern void PreventCommandDuringRecovery(const char *cmdname);
/* in utils/misc/guc.c */
-extern int trace_recovery_messages;
+extern PGDLLIMPORT int trace_recovery_messages;
extern int trace_recovery(int trace_level);
/*****************************************************************************
@@ -311,7 +311,7 @@ extern int trace_recovery(int trace_level);
#define SECURITY_RESTRICTED_OPERATION 0x0002
#define SECURITY_NOFORCE_RLS 0x0004
-extern char *DatabasePath;
+extern PGDLLIMPORT char *DatabasePath;
/* now in utils/init/miscinit.c */
extern void InitPostmasterChild(void);
@@ -337,7 +337,7 @@ typedef enum BackendType
B_LOGGER,
} BackendType;
-extern BackendType MyBackendType;
+extern PGDLLIMPORT BackendType MyBackendType;
extern const char *GetBackendTypeDesc(BackendType backendType);
@@ -400,7 +400,7 @@ typedef enum ProcessingMode
NormalProcessing /* normal processing */
} ProcessingMode;
-extern ProcessingMode Mode;
+extern PGDLLIMPORT ProcessingMode Mode;
#define IsBootstrapProcessingMode() (Mode == BootstrapProcessing)
#define IsInitProcessingMode() (Mode == InitProcessing)
@@ -438,7 +438,7 @@ typedef enum
NUM_AUXPROCTYPES /* Must be last! */
} AuxProcType;
-extern AuxProcType MyAuxProcType;
+extern PGDLLIMPORT AuxProcType MyAuxProcType;
#define AmStartupProcess() (MyAuxProcType == StartupProcess)
#define AmBackgroundWriterProcess() (MyAuxProcType == BgWriterProcess)
@@ -456,18 +456,18 @@ extern AuxProcType MyAuxProcType;
/* in utils/init/postinit.c */
extern void pg_split_opts(char **argv, int *argcp, const char *optstr);
extern void InitializeMaxBackends(void);
-extern int GetMaxBackends(void);
+extern int GetMaxBackends(void);
extern void SetMaxBackends(int max_backends);
extern void InitPostgres(const char *in_dbname, Oid dboid, const char *username,
Oid useroid, char *out_dbname, bool override_allow_connections);
extern void BaseInit(void);
/* in utils/init/miscinit.c */
-extern bool IgnoreSystemIndexes;
+extern PGDLLIMPORT bool IgnoreSystemIndexes;
extern PGDLLIMPORT bool process_shared_preload_libraries_in_progress;
-extern char *session_preload_libraries_string;
-extern char *shared_preload_libraries_string;
-extern char *local_preload_libraries_string;
+extern PGDLLIMPORT char *session_preload_libraries_string;
+extern PGDLLIMPORT char *shared_preload_libraries_string;
+extern PGDLLIMPORT char *local_preload_libraries_string;
extern void CreateDataDirLockFile(bool amPostmaster);
extern void CreateSocketLockFile(const char *socketfile, bool amPostmaster,
diff --git a/src/include/nodes/readfuncs.h b/src/include/nodes/readfuncs.h
index 41794354e2..66717fd6c3 100644
--- a/src/include/nodes/readfuncs.h
+++ b/src/include/nodes/readfuncs.h
@@ -20,7 +20,7 @@
* variable in read.c that needs to be accessible to readfuncs.c
*/
#ifdef WRITE_READ_PARSE_PLAN_TREES
-extern bool restore_location_fields;
+extern PGDLLIMPORT bool restore_location_fields;
#endif
/*
diff --git a/src/include/optimizer/geqo.h b/src/include/optimizer/geqo.h
index 4563f200cd..2a0c3bfa97 100644
--- a/src/include/optimizer/geqo.h
+++ b/src/include/optimizer/geqo.h
@@ -59,7 +59,7 @@ extern int Geqo_pool_size; /* 2 .. inf, or 0 to use default */
extern int Geqo_generations; /* 1 .. inf, or 0 to use default */
-extern double Geqo_selection_bias;
+extern PGDLLIMPORT double Geqo_selection_bias;
#define DEFAULT_GEQO_SELECTION_BIAS 2.0
#define MIN_GEQO_SELECTION_BIAS 1.5
diff --git a/src/include/optimizer/optimizer.h b/src/include/optimizer/optimizer.h
index 6b8ee0c69f..82fc513433 100644
--- a/src/include/optimizer/optimizer.h
+++ b/src/include/optimizer/optimizer.h
@@ -111,8 +111,8 @@ typedef enum
} ForceParallelMode;
/* GUC parameters */
-extern int force_parallel_mode;
-extern bool parallel_leader_participation;
+extern PGDLLIMPORT int force_parallel_mode;
+extern PGDLLIMPORT bool parallel_leader_participation;
extern struct PlannedStmt *planner(Query *parse, const char *query_string,
int cursorOptions,
diff --git a/src/include/optimizer/planmain.h b/src/include/optimizer/planmain.h
index 54a0d4c188..a09b3a3e83 100644
--- a/src/include/optimizer/planmain.h
+++ b/src/include/optimizer/planmain.h
@@ -19,7 +19,7 @@
/* GUC parameters */
#define DEFAULT_CURSOR_TUPLE_FRACTION 0.1
-extern double cursor_tuple_fraction;
+extern PGDLLIMPORT double cursor_tuple_fraction;
/* query_planner callback to compute query_pathkeys */
typedef void (*query_pathkeys_callback) (PlannerInfo *root, void *extra);
@@ -64,8 +64,8 @@ extern Limit *make_limit(Plan *lefttree, Node *limitOffset, Node *limitCount,
/*
* prototypes for plan/initsplan.c
*/
-extern int from_collapse_limit;
-extern int join_collapse_limit;
+extern PGDLLIMPORT int from_collapse_limit;
+extern PGDLLIMPORT int join_collapse_limit;
extern void add_base_rels_to_query(PlannerInfo *root, Node *jtnode);
extern void add_other_rels_to_query(PlannerInfo *root);
diff --git a/src/include/parser/parse_expr.h b/src/include/parser/parse_expr.h
index 308e84edda..c8e5c57b43 100644
--- a/src/include/parser/parse_expr.h
+++ b/src/include/parser/parse_expr.h
@@ -16,7 +16,7 @@
#include "parser/parse_node.h"
/* GUC parameters */
-extern bool Transform_null_equals;
+extern PGDLLIMPORT bool Transform_null_equals;
extern Node *transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind);
diff --git a/src/include/parser/parser.h b/src/include/parser/parser.h
index 6aac0e096a..828150f01b 100644
--- a/src/include/parser/parser.h
+++ b/src/include/parser/parser.h
@@ -53,8 +53,8 @@ typedef enum
} BackslashQuoteType;
/* GUC variables in scan.l (every one of these is a bad idea :-() */
-extern int backslash_quote;
-extern bool escape_string_warning;
+extern PGDLLIMPORT int backslash_quote;
+extern PGDLLIMPORT bool escape_string_warning;
extern PGDLLIMPORT bool standard_conforming_strings;
diff --git a/src/include/pg_getopt.h b/src/include/pg_getopt.h
index ec9f6e6ee3..9d91e602e6 100644
--- a/src/include/pg_getopt.h
+++ b/src/include/pg_getopt.h
@@ -33,10 +33,10 @@
*/
#ifndef HAVE_GETOPT_H
-extern char *optarg;
-extern int optind;
-extern int opterr;
-extern int optopt;
+extern PGDLLIMPORT char *optarg;
+extern PGDLLIMPORT int optind;
+extern PGDLLIMPORT int opterr;
+extern PGDLLIMPORT int optopt;
#endif /* HAVE_GETOPT_H */
@@ -45,7 +45,7 @@ extern int optopt;
* Cygwin, however, doesn't like this either.
*/
#if defined(HAVE_INT_OPTRESET) && !defined(__CYGWIN__)
-extern int optreset;
+extern PGDLLIMPORT int optreset;
#endif
/* Provide getopt() declaration if the platform doesn't have it */
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index e10d20222a..146d6ba8ea 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -1045,44 +1045,44 @@ typedef struct PgStat_FunctionCallUsage
*/
extern PGDLLIMPORT bool pgstat_track_counts;
extern PGDLLIMPORT int pgstat_track_functions;
-extern char *pgstat_stat_directory;
-extern char *pgstat_stat_tmpname;
-extern char *pgstat_stat_filename;
+extern PGDLLIMPORT char *pgstat_stat_directory;
+extern PGDLLIMPORT char *pgstat_stat_tmpname;
+extern PGDLLIMPORT char *pgstat_stat_filename;
/*
* BgWriter statistics counters are updated directly by bgwriter and bufmgr
*/
-extern PgStat_MsgBgWriter PendingBgWriterStats;
+extern PGDLLIMPORT PgStat_MsgBgWriter PendingBgWriterStats;
/*
* Checkpointer statistics counters are updated directly by checkpointer and
* bufmgr.
*/
-extern PgStat_MsgCheckpointer PendingCheckpointerStats;
+extern PGDLLIMPORT PgStat_MsgCheckpointer PendingCheckpointerStats;
/*
* WAL statistics counter is updated by backends and background processes
*/
-extern PgStat_MsgWal WalStats;
+extern PGDLLIMPORT PgStat_MsgWal WalStats;
/*
* Updated by pgstat_count_buffer_*_time macros
*/
-extern PgStat_Counter pgStatBlockReadTime;
-extern PgStat_Counter pgStatBlockWriteTime;
+extern PGDLLIMPORT PgStat_Counter pgStatBlockReadTime;
+extern PGDLLIMPORT PgStat_Counter pgStatBlockWriteTime;
/*
* Updated by pgstat_count_conn_*_time macros, called by
* pgstat_report_activity().
*/
-extern PgStat_Counter pgStatActiveTime;
-extern PgStat_Counter pgStatTransactionIdleTime;
+extern PGDLLIMPORT PgStat_Counter pgStatActiveTime;
+extern PGDLLIMPORT PgStat_Counter pgStatTransactionIdleTime;
/*
* Updated by the traffic cop and in errfinish()
*/
-extern SessionEndType pgStatSessionEndCause;
+extern PGDLLIMPORT SessionEndType pgStatSessionEndCause;
/* ----------
* Functions called from postmaster
diff --git a/src/include/pgtime.h b/src/include/pgtime.h
index 2977b13aab..5934435978 100644
--- a/src/include/pgtime.h
+++ b/src/include/pgtime.h
@@ -78,7 +78,7 @@ extern size_t pg_strftime(char *s, size_t max, const char *format,
/* these functions and variables are in pgtz.c */
extern PGDLLIMPORT pg_tz *session_timezone;
-extern pg_tz *log_timezone;
+extern PGDLLIMPORT pg_tz *log_timezone;
extern void pg_timezone_initialize(void);
extern pg_tz *pg_tzset(const char *tzname);
diff --git a/src/include/port/win32_port.h b/src/include/port/win32_port.h
index d3cb765976..5051ce387d 100644
--- a/src/include/port/win32_port.h
+++ b/src/include/port/win32_port.h
@@ -449,8 +449,8 @@ extern char *pgwin32_setlocale(int category, const char *locale);
/* In backend/port/win32/signal.c */
extern PGDLLIMPORT volatile int pg_signal_queue;
extern PGDLLIMPORT int pg_signal_mask;
-extern HANDLE pgwin32_signal_event;
-extern HANDLE pgwin32_initial_signal_pipe;
+extern PGDLLIMPORT HANDLE pgwin32_signal_event;
+extern PGDLLIMPORT HANDLE pgwin32_initial_signal_pipe;
#define UNBLOCKED_SIGNAL_QUEUE() (pg_signal_queue & ~pg_signal_mask)
#define PG_SIGNAL_COUNT 32
@@ -485,7 +485,7 @@ int pgwin32_recv(SOCKET s, char *buf, int len, int flags);
int pgwin32_send(SOCKET s, const void *buf, int len, int flags);
int pgwin32_waitforsinglesocket(SOCKET s, int what, int timeout);
-extern int pgwin32_noblock;
+extern PGDLLIMPORT int pgwin32_noblock;
#endif /* FRONTEND */
diff --git a/src/include/port/win32ntdll.h b/src/include/port/win32ntdll.h
index 663b9754bd..291b067ea4 100644
--- a/src/include/port/win32ntdll.h
+++ b/src/include/port/win32ntdll.h
@@ -23,9 +23,9 @@
#include <ntstatus.h>
#include <winternl.h>
-typedef NTSTATUS (__stdcall *RtlGetLastNtStatus_t) (void);
+typedef NTSTATUS (__stdcall * RtlGetLastNtStatus_t) (void);
-extern RtlGetLastNtStatus_t pg_RtlGetLastNtStatus;
+extern PGDLLIMPORT RtlGetLastNtStatus_t pg_RtlGetLastNtStatus;
extern int initialize_ntdll(void);
diff --git a/src/include/postmaster/autovacuum.h b/src/include/postmaster/autovacuum.h
index 30a2b3274f..9d40fd6d54 100644
--- a/src/include/postmaster/autovacuum.h
+++ b/src/include/postmaster/autovacuum.h
@@ -27,25 +27,25 @@ typedef enum
/* GUC variables */
-extern bool autovacuum_start_daemon;
-extern int autovacuum_max_workers;
-extern int autovacuum_work_mem;
-extern int autovacuum_naptime;
-extern int autovacuum_vac_thresh;
-extern double autovacuum_vac_scale;
-extern int autovacuum_vac_ins_thresh;
-extern double autovacuum_vac_ins_scale;
-extern int autovacuum_anl_thresh;
-extern double autovacuum_anl_scale;
-extern int autovacuum_freeze_max_age;
-extern int autovacuum_multixact_freeze_max_age;
-extern double autovacuum_vac_cost_delay;
-extern int autovacuum_vac_cost_limit;
+extern PGDLLIMPORT bool autovacuum_start_daemon;
+extern PGDLLIMPORT int autovacuum_max_workers;
+extern PGDLLIMPORT int autovacuum_work_mem;
+extern PGDLLIMPORT int autovacuum_naptime;
+extern PGDLLIMPORT int autovacuum_vac_thresh;
+extern PGDLLIMPORT double autovacuum_vac_scale;
+extern PGDLLIMPORT int autovacuum_vac_ins_thresh;
+extern PGDLLIMPORT double autovacuum_vac_ins_scale;
+extern PGDLLIMPORT int autovacuum_anl_thresh;
+extern PGDLLIMPORT double autovacuum_anl_scale;
+extern PGDLLIMPORT int autovacuum_freeze_max_age;
+extern PGDLLIMPORT int autovacuum_multixact_freeze_max_age;
+extern PGDLLIMPORT double autovacuum_vac_cost_delay;
+extern PGDLLIMPORT int autovacuum_vac_cost_limit;
/* autovacuum launcher PID, only valid when worker is shutting down */
-extern int AutovacuumLauncherPid;
+extern PGDLLIMPORT int AutovacuumLauncherPid;
-extern int Log_autovacuum_min_duration;
+extern PGDLLIMPORT int Log_autovacuum_min_duration;
/* Status inquiry functions */
extern bool AutoVacuumingActive(void);
diff --git a/src/include/postmaster/bgworker_internals.h b/src/include/postmaster/bgworker_internals.h
index 75900686fc..387683546d 100644
--- a/src/include/postmaster/bgworker_internals.h
+++ b/src/include/postmaster/bgworker_internals.h
@@ -42,7 +42,7 @@ typedef struct RegisteredBgWorker
slist_node rw_lnode; /* list link */
} RegisteredBgWorker;
-extern slist_head BackgroundWorkerList;
+extern PGDLLIMPORT slist_head BackgroundWorkerList;
extern Size BackgroundWorkerShmemSize(void);
extern void BackgroundWorkerShmemInit(void);
diff --git a/src/include/postmaster/bgwriter.h b/src/include/postmaster/bgwriter.h
index 2882efd67b..2511ef451e 100644
--- a/src/include/postmaster/bgwriter.h
+++ b/src/include/postmaster/bgwriter.h
@@ -22,10 +22,10 @@
/* GUC options */
-extern int BgWriterDelay;
-extern int CheckPointTimeout;
-extern int CheckPointWarning;
-extern double CheckPointCompletionTarget;
+extern PGDLLIMPORT int BgWriterDelay;
+extern PGDLLIMPORT int CheckPointTimeout;
+extern PGDLLIMPORT int CheckPointWarning;
+extern PGDLLIMPORT double CheckPointCompletionTarget;
extern void BackgroundWriterMain(void) pg_attribute_noreturn();
extern void CheckpointerMain(void) pg_attribute_noreturn();
diff --git a/src/include/postmaster/pgarch.h b/src/include/postmaster/pgarch.h
index 9bc7593a2d..f366a159a8 100644
--- a/src/include/postmaster/pgarch.h
+++ b/src/include/postmaster/pgarch.h
@@ -36,7 +36,7 @@ extern void PgArchForceDirScan(void);
/*
* The value of the archive_library GUC.
*/
-extern char *XLogArchiveLibrary;
+extern PGDLLIMPORT char *XLogArchiveLibrary;
/*
* Archive module callbacks
diff --git a/src/include/postmaster/postmaster.h b/src/include/postmaster/postmaster.h
index 324a30ec1a..90e333ccd2 100644
--- a/src/include/postmaster/postmaster.h
+++ b/src/include/postmaster/postmaster.h
@@ -14,27 +14,27 @@
#define _POSTMASTER_H
/* GUC options */
-extern bool EnableSSL;
-extern int ReservedBackends;
+extern PGDLLIMPORT bool EnableSSL;
+extern PGDLLIMPORT int ReservedBackends;
extern PGDLLIMPORT int PostPortNumber;
-extern int Unix_socket_permissions;
-extern char *Unix_socket_group;
-extern char *Unix_socket_directories;
-extern char *ListenAddresses;
-extern bool ClientAuthInProgress;
-extern int PreAuthDelay;
-extern int AuthenticationTimeout;
-extern bool Log_connections;
-extern bool log_hostname;
-extern bool enable_bonjour;
-extern char *bonjour_name;
-extern bool restart_after_crash;
-extern bool remove_temp_files_after_crash;
+extern PGDLLIMPORT int Unix_socket_permissions;
+extern PGDLLIMPORT char *Unix_socket_group;
+extern PGDLLIMPORT char *Unix_socket_directories;
+extern PGDLLIMPORT char *ListenAddresses;
+extern PGDLLIMPORT bool ClientAuthInProgress;
+extern PGDLLIMPORT int PreAuthDelay;
+extern PGDLLIMPORT int AuthenticationTimeout;
+extern PGDLLIMPORT bool Log_connections;
+extern PGDLLIMPORT bool log_hostname;
+extern PGDLLIMPORT bool enable_bonjour;
+extern PGDLLIMPORT char *bonjour_name;
+extern PGDLLIMPORT bool restart_after_crash;
+extern PGDLLIMPORT bool remove_temp_files_after_crash;
#ifdef WIN32
-extern HANDLE PostmasterHandle;
+extern PGDLLIMPORT HANDLE PostmasterHandle;
#else
-extern int postmaster_alive_fds[2];
+extern PGDLLIMPORT int postmaster_alive_fds[2];
/*
* Constants that represent which of postmaster_alive_fds is held by
diff --git a/src/include/postmaster/startup.h b/src/include/postmaster/startup.h
index 7e39db7159..d66ec1fcb1 100644
--- a/src/include/postmaster/startup.h
+++ b/src/include/postmaster/startup.h
@@ -23,7 +23,7 @@
ereport(LOG, errmsg(msg, secs, (usecs / 10000), __VA_ARGS__ )); \
} while(0)
-extern int log_startup_progress_interval;
+extern PGDLLIMPORT int log_startup_progress_interval;
extern void HandleStartupProcInterrupts(void);
extern void StartupProcessMain(void) pg_attribute_noreturn();
diff --git a/src/include/postmaster/syslogger.h b/src/include/postmaster/syslogger.h
index 1ca326e52e..6436724f3d 100644
--- a/src/include/postmaster/syslogger.h
+++ b/src/include/postmaster/syslogger.h
@@ -67,18 +67,18 @@ typedef union
#define PIPE_PROTO_DEST_JSONLOG 0x40
/* GUC options */
-extern bool Logging_collector;
-extern int Log_RotationAge;
-extern int Log_RotationSize;
+extern PGDLLIMPORT bool Logging_collector;
+extern PGDLLIMPORT int Log_RotationAge;
+extern PGDLLIMPORT int Log_RotationSize;
extern PGDLLIMPORT char *Log_directory;
extern PGDLLIMPORT char *Log_filename;
-extern bool Log_truncate_on_rotation;
-extern int Log_file_mode;
+extern PGDLLIMPORT bool Log_truncate_on_rotation;
+extern PGDLLIMPORT int Log_file_mode;
#ifndef WIN32
-extern int syslogPipe[2];
+extern PGDLLIMPORT int syslogPipe[2];
#else
-extern HANDLE syslogPipe[2];
+extern PGDLLIMPORT HANDLE syslogPipe[2];
#endif
diff --git a/src/include/postmaster/walwriter.h b/src/include/postmaster/walwriter.h
index 5a3011d9c9..ddc943657e 100644
--- a/src/include/postmaster/walwriter.h
+++ b/src/include/postmaster/walwriter.h
@@ -13,8 +13,8 @@
#define _WALWRITER_H
/* GUC options */
-extern int WalWriterDelay;
-extern int WalWriterFlushAfter;
+extern PGDLLIMPORT int WalWriterDelay;
+extern PGDLLIMPORT int WalWriterFlushAfter;
extern void WalWriterMain(void) pg_attribute_noreturn();
diff --git a/src/include/replication/logicallauncher.h b/src/include/replication/logicallauncher.h
index 15596fe446..f1e2821e25 100644
--- a/src/include/replication/logicallauncher.h
+++ b/src/include/replication/logicallauncher.h
@@ -12,8 +12,8 @@
#ifndef LOGICALLAUNCHER_H
#define LOGICALLAUNCHER_H
-extern int max_logical_replication_workers;
-extern int max_sync_workers_per_subscription;
+extern PGDLLIMPORT int max_logical_replication_workers;
+extern PGDLLIMPORT int max_sync_workers_per_subscription;
extern void ApplyLauncherRegister(void);
extern void ApplyLauncherMain(Datum main_arg);
diff --git a/src/include/replication/syncrep.h b/src/include/replication/syncrep.h
index 27be230d77..4d7c90b9f0 100644
--- a/src/include/replication/syncrep.h
+++ b/src/include/replication/syncrep.h
@@ -72,14 +72,14 @@ typedef struct SyncRepConfigData
char member_names[FLEXIBLE_ARRAY_MEMBER];
} SyncRepConfigData;
-extern SyncRepConfigData *SyncRepConfig;
+extern PGDLLIMPORT SyncRepConfigData *SyncRepConfig;
/* communication variables for parsing synchronous_standby_names GUC */
-extern SyncRepConfigData *syncrep_parse_result;
-extern char *syncrep_parse_error_msg;
+extern PGDLLIMPORT SyncRepConfigData *syncrep_parse_result;
+extern PGDLLIMPORT char *syncrep_parse_error_msg;
/* user-settable parameters for synchronous replication */
-extern char *SyncRepStandbyNames;
+extern PGDLLIMPORT char *SyncRepStandbyNames;
/* called by user backend */
extern void SyncRepWaitForLSN(XLogRecPtr lsn, bool commit);
diff --git a/src/include/replication/walreceiver.h b/src/include/replication/walreceiver.h
index 92f73a55b8..81184aa92f 100644
--- a/src/include/replication/walreceiver.h
+++ b/src/include/replication/walreceiver.h
@@ -25,9 +25,9 @@
#include "utils/tuplestore.h"
/* user-settable parameters */
-extern int wal_receiver_status_interval;
-extern int wal_receiver_timeout;
-extern bool hot_standby_feedback;
+extern PGDLLIMPORT int wal_receiver_status_interval;
+extern PGDLLIMPORT int wal_receiver_timeout;
+extern PGDLLIMPORT bool hot_standby_feedback;
/*
* MAXCONNINFO: maximum size of a connection string.
@@ -160,7 +160,7 @@ typedef struct
sig_atomic_t force_reply; /* used as a bool */
} WalRcvData;
-extern WalRcvData *WalRcv;
+extern PGDLLIMPORT WalRcvData *WalRcv;
typedef struct
{
diff --git a/src/include/replication/walsender.h b/src/include/replication/walsender.h
index b1892e9e4b..d99a21b077 100644
--- a/src/include/replication/walsender.h
+++ b/src/include/replication/walsender.h
@@ -25,15 +25,15 @@ typedef enum
} CRSSnapshotAction;
/* global state */
-extern bool am_walsender;
-extern bool am_cascading_walsender;
-extern bool am_db_walsender;
-extern bool wake_wal_senders;
+extern PGDLLIMPORT bool am_walsender;
+extern PGDLLIMPORT bool am_cascading_walsender;
+extern PGDLLIMPORT bool am_db_walsender;
+extern PGDLLIMPORT bool wake_wal_senders;
/* user-settable parameters */
-extern int max_wal_senders;
-extern int wal_sender_timeout;
-extern bool log_replication_commands;
+extern PGDLLIMPORT int max_wal_senders;
+extern PGDLLIMPORT int wal_sender_timeout;
+extern PGDLLIMPORT bool log_replication_commands;
extern void InitWalSender(void);
extern bool exec_replication_command(const char *query_string);
diff --git a/src/include/replication/walsender_private.h b/src/include/replication/walsender_private.h
index 9631047c6c..c14888e493 100644
--- a/src/include/replication/walsender_private.h
+++ b/src/include/replication/walsender_private.h
@@ -80,7 +80,7 @@ typedef struct WalSnd
TimestampTz replyTime;
} WalSnd;
-extern WalSnd *MyWalSnd;
+extern PGDLLIMPORT WalSnd *MyWalSnd;
/* There is one WalSndCtl struct for the whole database cluster */
typedef struct
@@ -107,7 +107,7 @@ typedef struct
WalSnd walsnds[FLEXIBLE_ARRAY_MEMBER];
} WalSndCtlData;
-extern WalSndCtlData *WalSndCtl;
+extern PGDLLIMPORT WalSndCtlData *WalSndCtl;
extern void WalSndSetState(WalSndState state);
@@ -123,6 +123,6 @@ extern void replication_scanner_init(const char *query_string);
extern void replication_scanner_finish(void);
extern bool replication_scanner_is_replication_command(void);
-extern Node *replication_parse_result;
+extern PGDLLIMPORT Node *replication_parse_result;
#endif /* _WALSENDER_PRIVATE_H */
diff --git a/src/include/replication/worker_internal.h b/src/include/replication/worker_internal.h
index 3c3f5f6a3a..4485d4ebee 100644
--- a/src/include/replication/worker_internal.h
+++ b/src/include/replication/worker_internal.h
@@ -69,16 +69,16 @@ typedef struct LogicalRepWorker
} LogicalRepWorker;
/* Main memory context for apply worker. Permanent during worker lifetime. */
-extern MemoryContext ApplyContext;
+extern PGDLLIMPORT MemoryContext ApplyContext;
/* libpqreceiver connection */
-extern struct WalReceiverConn *LogRepWorkerWalRcvConn;
+extern PGDLLIMPORT struct WalReceiverConn *LogRepWorkerWalRcvConn;
/* Worker and subscription objects. */
-extern Subscription *MySubscription;
-extern LogicalRepWorker *MyLogicalRepWorker;
+extern PGDLLIMPORT Subscription *MySubscription;
+extern PGDLLIMPORT LogicalRepWorker *MyLogicalRepWorker;
-extern bool in_remote_transaction;
+extern PGDLLIMPORT bool in_remote_transaction;
extern void logicalrep_worker_attach(int slot);
extern LogicalRepWorker *logicalrep_worker_find(Oid subid, Oid relid,
diff --git a/src/include/storage/buf_internals.h b/src/include/storage/buf_internals.h
index b903d2bcaf..a17e7b28a5 100644
--- a/src/include/storage/buf_internals.h
+++ b/src/include/storage/buf_internals.h
@@ -279,7 +279,7 @@ extern PGDLLIMPORT BufferDescPadded *BufferDescriptors;
extern PGDLLIMPORT WritebackContext BackendWritebackContext;
/* in localbuf.c */
-extern BufferDesc *LocalBufferDescriptors;
+extern PGDLLIMPORT BufferDesc *LocalBufferDescriptors;
/* in bufmgr.c */
@@ -298,7 +298,7 @@ typedef struct CkptSortItem
int buf_id;
} CkptSortItem;
-extern CkptSortItem *CkptBufferIds;
+extern PGDLLIMPORT CkptSortItem *CkptBufferIds;
/*
* Internal buffer management routines
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index dd01841c30..6325eb0b49 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -65,16 +65,16 @@ struct SMgrRelationData;
extern PGDLLIMPORT int NBuffers;
/* in bufmgr.c */
-extern bool zero_damaged_pages;
-extern int bgwriter_lru_maxpages;
-extern double bgwriter_lru_multiplier;
-extern bool track_io_timing;
-extern int effective_io_concurrency;
-extern int maintenance_io_concurrency;
-
-extern int checkpoint_flush_after;
-extern int backend_flush_after;
-extern int bgwriter_flush_after;
+extern PGDLLIMPORT bool zero_damaged_pages;
+extern PGDLLIMPORT int bgwriter_lru_maxpages;
+extern PGDLLIMPORT double bgwriter_lru_multiplier;
+extern PGDLLIMPORT bool track_io_timing;
+extern PGDLLIMPORT int effective_io_concurrency;
+extern PGDLLIMPORT int maintenance_io_concurrency;
+
+extern PGDLLIMPORT int checkpoint_flush_after;
+extern PGDLLIMPORT int backend_flush_after;
+extern PGDLLIMPORT int bgwriter_flush_after;
/* in buf_init.c */
extern PGDLLIMPORT char *BufferBlocks;
diff --git a/src/include/storage/dsm_impl.h b/src/include/storage/dsm_impl.h
index f60b76f075..c51584dc6a 100644
--- a/src/include/storage/dsm_impl.h
+++ b/src/include/storage/dsm_impl.h
@@ -39,8 +39,8 @@
#endif
/* GUC. */
-extern int dynamic_shared_memory_type;
-extern int min_dynamic_shared_memory;
+extern PGDLLIMPORT int dynamic_shared_memory_type;
+extern PGDLLIMPORT int min_dynamic_shared_memory;
/*
* Directory for on-disk state.
diff --git a/src/include/storage/fd.h b/src/include/storage/fd.h
index 29209e2724..69549b000f 100644
--- a/src/include/storage/fd.h
+++ b/src/include/storage/fd.h
@@ -59,12 +59,12 @@ typedef int File;
/* GUC parameter */
extern PGDLLIMPORT int max_files_per_process;
extern PGDLLIMPORT bool data_sync_retry;
-extern int recovery_init_sync_method;
+extern PGDLLIMPORT int recovery_init_sync_method;
/*
* This is private to fd.c, but exported for save/restore_backend_variables()
*/
-extern int max_safe_fds;
+extern PGDLLIMPORT int max_safe_fds;
/*
* On Windows, we have to interpret EACCES as possibly meaning the same as
diff --git a/src/include/storage/large_object.h b/src/include/storage/large_object.h
index 274b97fd42..b826a7dcd5 100644
--- a/src/include/storage/large_object.h
+++ b/src/include/storage/large_object.h
@@ -79,7 +79,7 @@ typedef struct LargeObjectDesc
/*
* GUC: backwards-compatibility flag to suppress LO permission checks
*/
-extern bool lo_compat_privileges;
+extern PGDLLIMPORT bool lo_compat_privileges;
/*
* Function definitions...
diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h
index dc537e20f2..e4e1495b24 100644
--- a/src/include/storage/lock.h
+++ b/src/include/storage/lock.h
@@ -34,14 +34,14 @@ typedef struct PROC_QUEUE
} PROC_QUEUE;
/* GUC variables */
-extern int max_locks_per_xact;
+extern PGDLLIMPORT int max_locks_per_xact;
#ifdef LOCK_DEBUG
-extern int Trace_lock_oidmin;
-extern bool Trace_locks;
-extern bool Trace_userlocks;
-extern int Trace_lock_table;
-extern bool Debug_deadlocks;
+extern PGDLLIMPORT int Trace_lock_oidmin;
+extern PGDLLIMPORT bool Trace_locks;
+extern PGDLLIMPORT bool Trace_userlocks;
+extern PGDLLIMPORT int Trace_lock_table;
+extern PGDLLIMPORT bool Debug_deadlocks;
#endif /* LOCK_DEBUG */
@@ -154,7 +154,7 @@ typedef enum LockTagType
#define LOCKTAG_LAST_TYPE LOCKTAG_ADVISORY
-extern const char *const LockTagTypeNames[];
+extern PGDLLIMPORT const char *const LockTagTypeNames[];
/*
* The LOCKTAG struct is defined with malice aforethought to fit into 16
diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h
index 124977cf7e..ca8f82a34d 100644
--- a/src/include/storage/lwlock.h
+++ b/src/include/storage/lwlock.h
@@ -110,7 +110,7 @@ typedef enum LWLockMode
#ifdef LOCK_DEBUG
-extern bool Trace_lwlocks;
+extern PGDLLIMPORT bool Trace_lwlocks;
#endif
extern bool LWLockAcquire(LWLock *lock, LWLockMode mode);
diff --git a/src/include/storage/pg_shmem.h b/src/include/storage/pg_shmem.h
index 50e5c5f99b..da5962edb9 100644
--- a/src/include/storage/pg_shmem.h
+++ b/src/include/storage/pg_shmem.h
@@ -42,9 +42,9 @@ typedef struct PGShmemHeader /* standard header for all Postgres shmem */
} PGShmemHeader;
/* GUC variables */
-extern int shared_memory_type;
-extern int huge_pages;
-extern int huge_page_size;
+extern PGDLLIMPORT int shared_memory_type;
+extern PGDLLIMPORT int huge_pages;
+extern PGDLLIMPORT int huge_page_size;
/* Possible values for huge_pages */
typedef enum
@@ -63,12 +63,12 @@ typedef enum
} PGShmemType;
#ifndef WIN32
-extern unsigned long UsedShmemSegID;
+extern PGDLLIMPORT unsigned long UsedShmemSegID;
#else
-extern HANDLE UsedShmemSegID;
-extern void *ShmemProtectiveRegion;
+extern PGDLLIMPORT HANDLE UsedShmemSegID;
+extern PGDLLIMPORT void *ShmemProtectiveRegion;
#endif
-extern void *UsedShmemSegAddr;
+extern PGDLLIMPORT void *UsedShmemSegAddr;
#if !defined(WIN32) && !defined(EXEC_BACKEND)
#define DEFAULT_SHARED_MEMORY_TYPE SHMEM_TYPE_MMAP
diff --git a/src/include/storage/pmsignal.h b/src/include/storage/pmsignal.h
index ea42c2072d..58f4ddf476 100644
--- a/src/include/storage/pmsignal.h
+++ b/src/include/storage/pmsignal.h
@@ -89,7 +89,7 @@ extern void PostmasterDeathSignalInit(void);
#endif
#ifdef USE_POSTMASTER_DEATH_SIGNAL
-extern volatile sig_atomic_t postmaster_possibly_dead;
+extern PGDLLIMPORT volatile sig_atomic_t postmaster_possibly_dead;
static inline bool
PostmasterIsAlive(void)
diff --git a/src/include/storage/predicate.h b/src/include/storage/predicate.h
index ba12904f22..8dfcb3944b 100644
--- a/src/include/storage/predicate.h
+++ b/src/include/storage/predicate.h
@@ -22,9 +22,9 @@
/*
* GUC variables
*/
-extern int max_predicate_locks_per_xact;
-extern int max_predicate_locks_per_relation;
-extern int max_predicate_locks_per_page;
+extern PGDLLIMPORT int max_predicate_locks_per_xact;
+extern PGDLLIMPORT int max_predicate_locks_per_relation;
+extern PGDLLIMPORT int max_predicate_locks_per_page;
/* Number of SLRU buffers to use for Serial SLRU */
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
index a58888f9e9..135f070883 100644
--- a/src/include/storage/proc.h
+++ b/src/include/storage/proc.h
@@ -365,7 +365,7 @@ typedef struct PROC_HDR
extern PGDLLIMPORT PROC_HDR *ProcGlobal;
-extern PGPROC *PreparedXactProcs;
+extern PGDLLIMPORT PGPROC *PreparedXactProcs;
/* Accessor for PGPROC given a pgprocno. */
#define GetPGProcByNumber(n) (&ProcGlobal->allProcs[(n)])
@@ -386,7 +386,7 @@ extern PGDLLIMPORT int StatementTimeout;
extern PGDLLIMPORT int LockTimeout;
extern PGDLLIMPORT int IdleInTransactionSessionTimeout;
extern PGDLLIMPORT int IdleSessionTimeout;
-extern bool log_lock_waits;
+extern PGDLLIMPORT bool log_lock_waits;
/*
diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h
index 8a5a905e38..dae912c073 100644
--- a/src/include/storage/s_lock.h
+++ b/src/include/storage/s_lock.h
@@ -1025,7 +1025,7 @@ extern int tas(volatile slock_t *lock); /* in port/.../tas.s, or
#define TAS_SPIN(lock) TAS(lock)
#endif /* TAS_SPIN */
-extern slock_t dummy_spinlock;
+extern PGDLLIMPORT slock_t dummy_spinlock;
/*
* Platform-independent out-of-line support routines
diff --git a/src/include/storage/sinval.h b/src/include/storage/sinval.h
index 593a4211af..e7cd45658c 100644
--- a/src/include/storage/sinval.h
+++ b/src/include/storage/sinval.h
@@ -123,9 +123,9 @@ typedef union
/* Counter of messages processed; don't worry about overflow. */
-extern uint64 SharedInvalidMessageCounter;
+extern PGDLLIMPORT uint64 SharedInvalidMessageCounter;
-extern volatile sig_atomic_t catchupInterruptPending;
+extern PGDLLIMPORT volatile sig_atomic_t catchupInterruptPending;
extern void SendSharedInvalidMessages(const SharedInvalidationMessage *msgs,
int n);
diff --git a/src/include/storage/spin.h b/src/include/storage/spin.h
index 70070ca9ab..7031f1d2c5 100644
--- a/src/include/storage/spin.h
+++ b/src/include/storage/spin.h
@@ -71,7 +71,7 @@ extern Size SpinlockSemaSize(void);
#ifndef HAVE_SPINLOCKS
extern void SpinlockSemaInit(void);
-extern PGSemaphore *SpinlockSemaArray;
+extern PGDLLIMPORT PGSemaphore *SpinlockSemaArray;
#endif
#endif /* SPIN_H */
diff --git a/src/include/storage/standby.h b/src/include/storage/standby.h
index 58ea21aa13..6a7763264b 100644
--- a/src/include/storage/standby.h
+++ b/src/include/storage/standby.h
@@ -21,10 +21,10 @@
#include "storage/standbydefs.h"
/* User-settable GUC parameters */
-extern int vacuum_defer_cleanup_age;
-extern int max_standby_archive_delay;
-extern int max_standby_streaming_delay;
-extern bool log_recovery_conflict_waits;
+extern PGDLLIMPORT int vacuum_defer_cleanup_age;
+extern PGDLLIMPORT int max_standby_archive_delay;
+extern PGDLLIMPORT int max_standby_streaming_delay;
+extern PGDLLIMPORT bool log_recovery_conflict_waits;
extern void InitRecoveryTransactionEnvironment(void);
extern void ShutdownRecoveryTransactionEnvironment(void);
diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h
index 15a11bc3ff..5c7054ecaf 100644
--- a/src/include/tcop/tcopprot.h
+++ b/src/include/tcop/tcopprot.h
@@ -25,11 +25,11 @@
/* Required daylight between max_stack_depth and the kernel limit, in bytes */
#define STACK_DEPTH_SLOP (512 * 1024L)
-extern CommandDest whereToSendOutput;
+extern PGDLLIMPORT CommandDest whereToSendOutput;
extern PGDLLIMPORT const char *debug_query_string;
-extern int max_stack_depth;
-extern int PostAuthDelay;
-extern int client_connection_check_interval;
+extern PGDLLIMPORT int max_stack_depth;
+extern PGDLLIMPORT int PostAuthDelay;
+extern PGDLLIMPORT int client_connection_check_interval;
/* GUC-configurable parameters */
diff --git a/src/include/tsearch/ts_cache.h b/src/include/tsearch/ts_cache.h
index 5e70d74b41..5e4a49ea1c 100644
--- a/src/include/tsearch/ts_cache.h
+++ b/src/include/tsearch/ts_cache.h
@@ -84,7 +84,7 @@ typedef struct
/*
* GUC variable for current configuration
*/
-extern char *TSCurrentConfig;
+extern PGDLLIMPORT char *TSCurrentConfig;
extern TSParserCacheEntry *lookup_ts_parser_cache(Oid prsId);
diff --git a/src/include/tsearch/ts_type.h b/src/include/tsearch/ts_type.h
index 1a8bad8491..a2008f5504 100644
--- a/src/include/tsearch/ts_type.h
+++ b/src/include/tsearch/ts_type.h
@@ -169,7 +169,7 @@ typedef struct
#define OP_PHRASE 4 /* highest code, tsquery_cleanup.c */
#define OP_COUNT 4
-extern const int tsearch_op_priority[OP_COUNT];
+extern PGDLLIMPORT const int tsearch_op_priority[OP_COUNT];
/* get operation priority by its code*/
#define OP_PRIORITY(x) ( tsearch_op_priority[(x) - 1] )
diff --git a/src/include/utils/array.h b/src/include/utils/array.h
index 2dba156d35..656c766a9a 100644
--- a/src/include/utils/array.h
+++ b/src/include/utils/array.h
@@ -339,7 +339,7 @@ typedef struct ArrayIteratorData *ArrayIterator;
/*
* GUC parameter
*/
-extern bool Array_nulls;
+extern PGDLLIMPORT bool Array_nulls;
/*
* prototypes for functions defined in arrayfuncs.c
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index d8f05a7df3..9e643a1d6d 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -64,7 +64,7 @@ extern char *regexp_fixed_prefix(text *text_re, bool case_insensitive,
Oid collation, bool *exact);
/* ruleutils.c */
-extern bool quote_all_identifiers;
+extern PGDLLIMPORT bool quote_all_identifiers;
extern const char *quote_identifier(const char *ident);
extern char *quote_qualified_identifier(const char *qualifier,
const char *ident);
diff --git a/src/include/utils/datetime.h b/src/include/utils/datetime.h
index 0d158f3e4b..93bc2514a1 100644
--- a/src/include/utils/datetime.h
+++ b/src/include/utils/datetime.h
@@ -259,7 +259,7 @@ do { \
extern const char *const months[]; /* months (3-char abbreviations) */
extern const char *const days[]; /* days (full names) */
-extern const int day_tab[2][13];
+extern PGDLLIMPORT const int day_tab[2][13];
/*
* These are the rules for the Gregorian calendar, which was adopted in 1582.
diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h
index 3eb8de3966..f5c6cd904d 100644
--- a/src/include/utils/elog.h
+++ b/src/include/utils/elog.h
@@ -424,12 +424,12 @@ typedef enum
PGERROR_VERBOSE /* all the facts, ma'am */
} PGErrorVerbosity;
-extern int Log_error_verbosity;
-extern char *Log_line_prefix;
-extern int Log_destination;
-extern char *Log_destination_string;
-extern bool syslog_sequence_numbers;
-extern bool syslog_split_messages;
+extern PGDLLIMPORT int Log_error_verbosity;
+extern PGDLLIMPORT char *Log_line_prefix;
+extern PGDLLIMPORT int Log_destination;
+extern PGDLLIMPORT char *Log_destination_string;
+extern PGDLLIMPORT bool syslog_sequence_numbers;
+extern PGDLLIMPORT bool syslog_split_messages;
/* Log destination bitmap */
#define LOG_DESTINATION_STDERR 1
diff --git a/src/include/utils/fmgrtab.h b/src/include/utils/fmgrtab.h
index e5f53d6295..5d72b89db1 100644
--- a/src/include/utils/fmgrtab.h
+++ b/src/include/utils/fmgrtab.h
@@ -32,7 +32,7 @@ typedef struct
PGFunction func; /* pointer to compiled function */
} FmgrBuiltin;
-extern const FmgrBuiltin fmgr_builtins[];
+extern PGDLLIMPORT const FmgrBuiltin fmgr_builtins[];
extern const int fmgr_nbuiltins; /* number of entries in table */
@@ -43,6 +43,6 @@ extern const Oid fmgr_last_builtin_oid; /* highest function OID in table */
* array. This is indexed from 0 through fmgr_last_builtin_oid.
*/
#define InvalidOidBuiltinMapping PG_UINT16_MAX
-extern const uint16 fmgr_builtin_oid_index[];
+extern PGDLLIMPORT const uint16 fmgr_builtin_oid_index[];
#endif /* FMGRTAB_H */
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index 6bb81707b0..594739c7e1 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -239,53 +239,53 @@ typedef enum
/* GUC vars that are actually declared in guc.c, rather than elsewhere */
-extern bool Debug_print_plan;
-extern bool Debug_print_parse;
-extern bool Debug_print_rewritten;
-extern bool Debug_pretty_print;
+extern PGDLLIMPORT bool Debug_print_plan;
+extern PGDLLIMPORT bool Debug_print_parse;
+extern PGDLLIMPORT bool Debug_print_rewritten;
+extern PGDLLIMPORT bool Debug_pretty_print;
-extern bool log_parser_stats;
-extern bool log_planner_stats;
-extern bool log_executor_stats;
-extern bool log_statement_stats;
-extern bool log_btree_build_stats;
+extern PGDLLIMPORT bool log_parser_stats;
+extern PGDLLIMPORT bool log_planner_stats;
+extern PGDLLIMPORT bool log_executor_stats;
+extern PGDLLIMPORT bool log_statement_stats;
+extern PGDLLIMPORT bool log_btree_build_stats;
extern PGDLLIMPORT bool check_function_bodies;
-extern bool session_auth_is_superuser;
+extern PGDLLIMPORT bool session_auth_is_superuser;
-extern bool log_duration;
-extern int log_parameter_max_length;
-extern int log_parameter_max_length_on_error;
-extern int log_min_error_statement;
+extern PGDLLIMPORT bool log_duration;
+extern PGDLLIMPORT int log_parameter_max_length;
+extern PGDLLIMPORT int log_parameter_max_length_on_error;
+extern PGDLLIMPORT int log_min_error_statement;
extern PGDLLIMPORT int log_min_messages;
extern PGDLLIMPORT int client_min_messages;
-extern int log_min_duration_sample;
-extern int log_min_duration_statement;
-extern int log_temp_files;
-extern double log_statement_sample_rate;
-extern double log_xact_sample_rate;
-extern char *backtrace_functions;
-extern char *backtrace_symbol_list;
+extern PGDLLIMPORT int log_min_duration_sample;
+extern PGDLLIMPORT int log_min_duration_statement;
+extern PGDLLIMPORT int log_temp_files;
+extern PGDLLIMPORT double log_statement_sample_rate;
+extern PGDLLIMPORT double log_xact_sample_rate;
+extern PGDLLIMPORT char *backtrace_functions;
+extern PGDLLIMPORT char *backtrace_symbol_list;
-extern int temp_file_limit;
+extern PGDLLIMPORT int temp_file_limit;
-extern int num_temp_buffers;
+extern PGDLLIMPORT int num_temp_buffers;
-extern char *cluster_name;
+extern PGDLLIMPORT char *cluster_name;
extern PGDLLIMPORT char *ConfigFileName;
-extern char *HbaFileName;
-extern char *IdentFileName;
-extern char *external_pid_file;
+extern PGDLLIMPORT char *HbaFileName;
+extern PGDLLIMPORT char *IdentFileName;
+extern PGDLLIMPORT char *external_pid_file;
extern PGDLLIMPORT char *application_name;
-extern int tcp_keepalives_idle;
-extern int tcp_keepalives_interval;
-extern int tcp_keepalives_count;
-extern int tcp_user_timeout;
+extern PGDLLIMPORT int tcp_keepalives_idle;
+extern PGDLLIMPORT int tcp_keepalives_interval;
+extern PGDLLIMPORT int tcp_keepalives_count;
+extern PGDLLIMPORT int tcp_user_timeout;
#ifdef TRACE_SORT
-extern bool trace_sort;
+extern PGDLLIMPORT bool trace_sort;
#endif
/*
diff --git a/src/include/utils/guc_tables.h b/src/include/utils/guc_tables.h
index f7e54a87b7..9a55d0241b 100644
--- a/src/include/utils/guc_tables.h
+++ b/src/include/utils/guc_tables.h
@@ -248,10 +248,10 @@ struct config_enum
};
/* constant tables corresponding to enums above and in guc.h */
-extern const char *const config_group_names[];
-extern const char *const config_type_names[];
-extern const char *const GucContext_Names[];
-extern const char *const GucSource_Names[];
+extern PGDLLIMPORT const char *const config_group_names[];
+extern PGDLLIMPORT const char *const config_type_names[];
+extern PGDLLIMPORT const char *const GucContext_Names[];
+extern PGDLLIMPORT const char *const GucSource_Names[];
/* get the current set of variables */
extern struct config_generic **get_guc_variables(void);
diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h
index 30e423af0e..7a815a5867 100644
--- a/src/include/utils/pg_locale.h
+++ b/src/include/utils/pg_locale.h
@@ -38,16 +38,16 @@
#define LOCALE_NAME_BUFLEN 128
/* GUC settings */
-extern char *locale_messages;
-extern char *locale_monetary;
-extern char *locale_numeric;
-extern char *locale_time;
+extern PGDLLIMPORT char *locale_messages;
+extern PGDLLIMPORT char *locale_monetary;
+extern PGDLLIMPORT char *locale_numeric;
+extern PGDLLIMPORT char *locale_time;
/* lc_time localization cache */
-extern char *localized_abbrev_days[];
-extern char *localized_full_days[];
-extern char *localized_abbrev_months[];
-extern char *localized_full_months[];
+extern PGDLLIMPORT char *localized_abbrev_days[];
+extern PGDLLIMPORT char *localized_full_days[];
+extern PGDLLIMPORT char *localized_abbrev_months[];
+extern PGDLLIMPORT char *localized_full_months[];
extern bool check_locale_messages(char **newval, void **extra, GucSource source);
diff --git a/src/include/utils/plancache.h b/src/include/utils/plancache.h
index 95b99e3d25..0499635f59 100644
--- a/src/include/utils/plancache.h
+++ b/src/include/utils/plancache.h
@@ -35,7 +35,7 @@ typedef enum
} PlanCacheMode;
/* GUC parameter */
-extern int plan_cache_mode;
+extern PGDLLIMPORT int plan_cache_mode;
#define CACHEDPLANSOURCE_MAGIC 195726186
#define CACHEDPLAN_MAGIC 953717834
diff --git a/src/include/utils/ps_status.h b/src/include/utils/ps_status.h
index 9f43e1fdf0..bba463591f 100644
--- a/src/include/utils/ps_status.h
+++ b/src/include/utils/ps_status.h
@@ -12,7 +12,7 @@
#ifndef PS_STATUS_H
#define PS_STATUS_H
-extern bool update_process_title;
+extern PGDLLIMPORT bool update_process_title;
extern char **save_ps_display_args(int argc, char **argv);
diff --git a/src/include/utils/queryjumble.h b/src/include/utils/queryjumble.h
index a4c277269e..4719e50bc3 100644
--- a/src/include/utils/queryjumble.h
+++ b/src/include/utils/queryjumble.h
@@ -61,14 +61,14 @@ enum ComputeQueryIdType
};
/* GUC parameters */
-extern int compute_query_id;
+extern PGDLLIMPORT int compute_query_id;
extern const char *CleanQuerytext(const char *query, int *location, int *len);
extern JumbleState *JumbleQuery(Query *query, const char *querytext);
extern void EnableQueryId(void);
-extern bool query_id_enabled;
+extern PGDLLIMPORT bool query_id_enabled;
/*
* Returns whether query identifier computation has been enabled, either
diff --git a/src/include/utils/relcache.h b/src/include/utils/relcache.h
index 84d6afef19..db512264e7 100644
--- a/src/include/utils/relcache.h
+++ b/src/include/utils/relcache.h
@@ -144,9 +144,9 @@ extern void RelationCacheInitFilePostInvalidate(void);
extern void RelationCacheInitFileRemove(void);
/* should be used only by relcache.c and catcache.c */
-extern bool criticalRelcachesBuilt;
+extern PGDLLIMPORT bool criticalRelcachesBuilt;
/* should be used only by relcache.c and postinit.c */
-extern bool criticalSharedRelcachesBuilt;
+extern PGDLLIMPORT bool criticalSharedRelcachesBuilt;
#endif /* RELCACHE_H */
diff --git a/src/include/utils/rls.h b/src/include/utils/rls.h
index c1896d6735..75259cc1f7 100644
--- a/src/include/utils/rls.h
+++ b/src/include/utils/rls.h
@@ -14,7 +14,7 @@
#define RLS_H
/* GUC variable */
-extern bool row_security;
+extern PGDLLIMPORT bool row_security;
/*
* Used by callers of check_enable_rls.
diff --git a/src/include/utils/snapmgr.h b/src/include/utils/snapmgr.h
index 293c753034..760aa7121d 100644
--- a/src/include/utils/snapmgr.h
+++ b/src/include/utils/snapmgr.h
@@ -53,7 +53,7 @@ extern TimestampTz GetSnapshotCurrentTimestamp(void);
extern TimestampTz GetOldSnapshotThresholdTimestamp(void);
extern void SnapshotTooOldMagicForTest(void);
-extern bool FirstSnapshotSet;
+extern PGDLLIMPORT bool FirstSnapshotSet;
extern PGDLLIMPORT TransactionId TransactionXmin;
extern PGDLLIMPORT TransactionId RecentXmin;
diff --git a/src/include/utils/timestamp.h b/src/include/utils/timestamp.h
index c1a74f8e2b..bd86c523c0 100644
--- a/src/include/utils/timestamp.h
+++ b/src/include/utils/timestamp.h
@@ -57,10 +57,10 @@
/* Set at postmaster start */
-extern TimestampTz PgStartTime;
+extern PGDLLIMPORT TimestampTz PgStartTime;
/* Set at configuration reload */
-extern TimestampTz PgReloadTime;
+extern PGDLLIMPORT TimestampTz PgReloadTime;
/* Internal routines (not fmgr-callable) */
diff --git a/src/include/utils/xml.h b/src/include/utils/xml.h
index c1de08d15b..61f342bc3c 100644
--- a/src/include/utils/xml.h
+++ b/src/include/utils/xml.h
@@ -79,6 +79,6 @@ extern int xmlbinary; /* XmlBinaryType, but int for guc enum */
extern int xmloption; /* XmlOptionType, but int for guc enum */
-extern const TableFuncRoutine XmlTableRoutine;
+extern PGDLLIMPORT const TableFuncRoutine XmlTableRoutine;
#endif /* XML_H */
--
2.24.3 (Apple Git-128)
Hi,
On 2022-02-15 08:58:05 -0500, Robert Haas wrote:
On Mon, Feb 14, 2022 at 8:53 PM Andres Freund <andres@anarazel.de> wrote:
An alternative rule which would dodge that particular issue would be
to just slap PGDLLIMPORT on every global variable in every header
file. That would arguably be a simpler rule, though it means even more
PGDLLIMPORT declarations floating around.That would have the advantage of being comparatively easy to check in an
automated way. Might even be cheap enough to just make it part of the build.I wasn't able to quickly write something that was smart enough to use
as part of the build, but I wrote something dumb that I think works
well enough to use with a little bit of human intelligence alongside.
See attached.
Cool.
But it seems like it'd be a fair amount of work and cause a lot of patch
rebasing pain? If we end up going that way, we should schedule this to happen
just after the feature freeze, I think.We could do that. I'd sort of rather get it done. We still have two
weeks before the last CommitFest officially starts, and it's not as if
there won't be tons of uncommitted patches floating around after that.
Breaking close to every patch 6-7 weeks before freeze doesn't seem
great. Particularly because this is a mostly automatically generated patch, so
I don't really see a forcing function to do this now, rather than at a more
opportune moment.
The more I think about it the more I'm convinced that if we want to do this,
we should do it for variables and functions.
If we consider doing this for all extern variables, we should think about
doing this for headers *and* functions. That'd allow us to get rid of the
fairly complicated logic to generate the .def file for the postgres binary on
windows (src/tools/gendef.pl). And maybe also the related thing on AIX
(src/backend/port/aix/mkldexport.sh)I don't know what you mean by this.
We only need gendef.pl because we don't mark functions with visibility
information. If we attach PGDLLIMPORT to functions and variables we can a fair
bit of complexity. And I think not just for windows, but also AIX (there's a
whole section in src/backend/Makefile about AIX oddity), but I'm not sure
about it.
diff --git a/src/include/common/relpath.h b/src/include/common/relpath.h index a4b5dc853b..13849a3790 100644 --- a/src/include/common/relpath.h +++ b/src/include/common/relpath.h @@ -56,7 +56,7 @@ typedef enum ForkNumber#define FORKNAMECHARS 4 /* max chars for a fork name */
-extern const char *const forkNames[]; +extern PGDLLIMPORT const char *const forkNames[];extern ForkNumber forkname_to_number(const char *forkName);
extern int forkname_chars(const char *str, ForkNumber *fork);
I think we might need a new form of PGDLLIMPORT to mark these correctly - I
don't think they should be marked PGDLLIMPORT in frontend environment.
diff --git a/src/include/fe_utils/print.h b/src/include/fe_utils/print.h index 836b4e29a8..5caf9e2d08 100644 --- a/src/include/fe_utils/print.h +++ b/src/include/fe_utils/print.h @@ -177,10 +177,10 @@ typedef struct printQueryOpt } printQueryOpt;-extern volatile sig_atomic_t cancel_pressed; +extern PGDLLIMPORT volatile sig_atomic_t cancel_pressed;-extern const printTextFormat pg_asciiformat; -extern const printTextFormat pg_asciiformat_old; +extern PGDLLIMPORT const printTextFormat pg_asciiformat; +extern PGDLLIMPORT const printTextFormat pg_asciiformat_old; extern printTextFormat pg_utf8format; /* ideally would be const, but... */
Are these right? I don't think we should make frontend stuff exported without
a very clear reason.
extern void jit_reset_after_error(void); diff --git a/src/include/jit/llvmjit.h b/src/include/jit/llvmjit.h index 66143afccc..4541f9a2c4 100644 --- a/src/include/jit/llvmjit.h +++ b/src/include/jit/llvmjit.h @@ -56,30 +56,30 @@ typedef struct LLVMJitContext } LLVMJitContext;/* llvm module containing information about types */ -extern LLVMModuleRef llvm_types_module; +extern PGDLLIMPORT LLVMModuleRef llvm_types_module;
These are wrong I think, this is a shared library.
Greetings,
Andres Freund
Hi,
On Mon, Feb 14, 2022 at 12:45:08PM -0500, Robert Haas wrote:
On Mon, Feb 14, 2022 at 12:34 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
* There's a moderately sizable subset of GUCs where the underlying
variable is not visible at all because it's static in guc.c.
Typically this is because that variable is only used for display
and there's an assign hook that stores the real data somewhere else.
I suppose what we want in such cases is for the "somewhere else"
to be PGDLLIMPORT'd, but in a lot of cases those variables are also
static in some other module. Does this proposal include exporting
variables that currently aren't visible to extensions at all?
I'm a little resistant to that. I can buy making sure that Windows
has a level playing field, but that's as far as I want to go.I can live with that. If someone complains about those variables being
static-to-file instead of globally visible, we can address that
complaint on its merits when it is presented.
Same here, if any third-party project had any use of such variable, they would
have sent some patch for that already so I don't see any reason to change it
now.
On Wed, Feb 16, 2022 at 01:10:50AM +0800, Julien Rouhaud wrote:
Hi,
On Mon, Feb 14, 2022 at 12:45:08PM -0500, Robert Haas wrote:
On Mon, Feb 14, 2022 at 12:34 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
* There's a moderately sizable subset of GUCs where the underlying
variable is not visible at all because it's static in guc.c.
Typically this is because that variable is only used for display
and there's an assign hook that stores the real data somewhere else.
I suppose what we want in such cases is for the "somewhere else"
to be PGDLLIMPORT'd, but in a lot of cases those variables are also
static in some other module. Does this proposal include exporting
variables that currently aren't visible to extensions at all?
I'm a little resistant to that. I can buy making sure that Windows
has a level playing field, but that's as far as I want to go.I can live with that. If someone complains about those variables being
static-to-file instead of globally visible, we can address that
complaint on its merits when it is presented.Same here, if any third-party project had any use of such variable, they would
have sent some patch for that already so I don't see any reason to change it
now.
Agreed. I think the big goal here is to make Windows have the same
GUC variable visibility as Unix --- when we change things in a way that
breaks extensions, we hear about Unix breakage quickly and adjust for
it. It is Windows being different and only getting the problem reports
later that is the real problem.
--
Bruce Momjian <bruce@momjian.us> https://momjian.us
EDB https://enterprisedb.com
If only the physical world exists, free will is an illusion.
Hi,
Sorry for taking so much time to answer here. I definitely wanted to work on
that but I was under the impression that although we now had an agreement to
apply PGDLLIMPORT globally a patch itself wasn't really rushed, so I spent the
last two days trying to setup a new Windows environment as my previous one
isn't working anymore. That's taking much longer than I planned.
On Tue, Feb 15, 2022 at 08:06:58AM -0800, Andres Freund wrote:
Hi,
On 2022-02-15 08:58:05 -0500, Robert Haas wrote:
On Mon, Feb 14, 2022 at 8:53 PM Andres Freund <andres@anarazel.de> wrote:
An alternative rule which would dodge that particular issue would be
to just slap PGDLLIMPORT on every global variable in every header
file. That would arguably be a simpler rule, though it means even more
PGDLLIMPORT declarations floating around.That would have the advantage of being comparatively easy to check in an
automated way. Might even be cheap enough to just make it part of the build.I wasn't able to quickly write something that was smart enough to use
as part of the build, but I wrote something dumb that I think works
well enough to use with a little bit of human intelligence alongside.
See attached.Cool.
+1
But it seems like it'd be a fair amount of work and cause a lot of patch
rebasing pain? If we end up going that way, we should schedule this to happen
just after the feature freeze, I think.We could do that. I'd sort of rather get it done. We still have two
weeks before the last CommitFest officially starts, and it's not as if
there won't be tons of uncommitted patches floating around after that.Breaking close to every patch 6-7 weeks before freeze doesn't seem
great. Particularly because this is a mostly automatically generated patch, so
I don't really see a forcing function to do this now, rather than at a more
opportune moment.
Agreed, especially if we can do some cleanup in gendef.pl.
The more I think about it the more I'm convinced that if we want to do this,
we should do it for variables and functions.If we consider doing this for all extern variables, we should think about
doing this for headers *and* functions. That'd allow us to get rid of the
fairly complicated logic to generate the .def file for the postgres binary on
windows (src/tools/gendef.pl). And maybe also the related thing on AIX
(src/backend/port/aix/mkldexport.sh)I don't know what you mean by this.
We only need gendef.pl because we don't mark functions with visibility
information. If we attach PGDLLIMPORT to functions and variables we can a fair
bit of complexity. And I think not just for windows, but also AIX (there's a
whole section in src/backend/Makefile about AIX oddity), but I'm not sure
about it.
I will try to have a look at it once my build environment is ready.
On Tue, Feb 15, 2022 at 11:07 PM Andres Freund <andres@anarazel.de> wrote:
diff --git a/src/include/common/relpath.h b/src/include/common/relpath.h index a4b5dc853b..13849a3790 100644 --- a/src/include/common/relpath.h +++ b/src/include/common/relpath.h @@ -56,7 +56,7 @@ typedef enum ForkNumber#define FORKNAMECHARS 4 /* max chars for a fork name */
-extern const char *const forkNames[]; +extern PGDLLIMPORT const char *const forkNames[];extern ForkNumber forkname_to_number(const char *forkName);
extern int forkname_chars(const char *str, ForkNumber *fork);I think we might need a new form of PGDLLIMPORT to mark these correctly - I
don't think they should be marked PGDLLIMPORT in frontend environment.
That has been taken care of already, IIUC:
commit e04a8059a74c125a8af94acdcb7b15b92188470a
Author: Tom Lane <tgl@sss.pgh.pa.us>
Date: Mon Nov 29 11:00:00 2021 -0500
Simplify declaring variables exported from libpgcommon and libpgport.
This reverts commits c2d1eea9e and 11b500072, as well as similar hacks
elsewhere, in favor of setting up the PGDLLIMPORT macro so that it can
just be used unconditionally. That can work because in frontend code,
we need no marking in either the defining or consuming files for a
variable exported from these libraries; and frontend code has no need
to access variables exported from the core backend, either.
--
John Naylor
EDB: http://www.enterprisedb.com
Hi,
On 2022-02-15 08:06:58 -0800, Andres Freund wrote:
The more I think about it the more I'm convinced that if we want to do this,
we should do it for variables and functions.
Btw, if we were to do this, we should just use -fvisibility=hidden everywhere
and would see the same set of failures on unixoid systems as on windows. Of
course only in in-core extensions, but it'd still be better than nothing.
I proposed using -fvisibility=hidden in extensions:
/messages/by-id/20211101020311.av6hphdl6xbjbuif@alap3.anarazel.de
Mostly because using explicit symbol exports makes it a lot easier to build
extensions libraries on windows (with meson, but also everything built outside
of postgres with msvc). But also because it makes function calls *inside* an
extension have noticeably lower overhead. And it makes the set of symbols
exported smaller.
One problem I encountered was that it's actually kind of hard to set build
flags only for extension libraries:
/messages/by-id/20220111025328.iq5g6uck53j5qtin@alap3.anarazel.de
But if we added explicit exports to everything we export, we'd not need to
restrict the use of -fvisibility=hidden to extension libraries anymore. Would
get decent error messages on all platforms.
Subsequently we could yield a bit of performance from critical paths by
marking selected symbols as *not* exported. That'd make them a tad cheaper to
call and allow the optimizer more leeway.
Greetings,
Andres Freund
On Fri, Feb 18, 2022 at 7:02 PM Andres Freund <andres@anarazel.de> wrote:
On 2022-02-15 08:06:58 -0800, Andres Freund wrote:
The more I think about it the more I'm convinced that if we want to do this,
we should do it for variables and functions.Btw, if we were to do this, we should just use -fvisibility=hidden everywhere
and would see the same set of failures on unixoid systems as on windows. Of
course only in in-core extensions, but it'd still be better than nothing.
Let's be less ambitious for this release, and just get the variables
marked with PGDLLIMPORT. We seem to have consensus to create parity
between Windows and non-Windows builds, which means precisely applying
PGDLLIMPORT to variables marked in header files, and nothing more. The
merits of -fvisibility=hidden or PGDLLIMPORT on functions are a
separate question that can be debated on its own merits, but I don't
want that larger discussion to bog down this effort. Here are updated
patches for that.
@RMT: Andres proposed upthread that we should plan to do this just
after feature freeze. Accordingly I propose to commit at least 0002
and perhaps 0001 if people want it just after feature freeze. I
therefore ask that the RMT either (a) regard this change as not being
a feature (and thus not subject to the freeze) or (b) give it a 1-day
extension. The reason for committing it just after freeze is to
minimize the number of conflicts that it creates for other patches.
The reason why that's probably an OK thing to do is that applying
PGDLLIMPORT markings is low-risk.
Thanks,
--
Robert Haas
EDB: http://www.enterprisedb.com
Attachments:
v2-0001-Dumb-script-to-apply-PGDLLIMPORT-markings.patchapplication/octet-stream; name=v2-0001-Dumb-script-to-apply-PGDLLIMPORT-markings.patchDownload
From 2edec90c5a1b250e0228275cb4572c80b3059f5a Mon Sep 17 00:00:00 2001
From: Robert Haas <rhaas@postgresql.org>
Date: Tue, 15 Feb 2022 08:44:28 -0500
Subject: [PATCH v2 1/2] Dumb script to apply PGDLLIMPORT markings.
---
src/tools/mark_pgdllimport.pl | 54 +++++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
create mode 100755 src/tools/mark_pgdllimport.pl
diff --git a/src/tools/mark_pgdllimport.pl b/src/tools/mark_pgdllimport.pl
new file mode 100755
index 0000000000..570cd04fd6
--- /dev/null
+++ b/src/tools/mark_pgdllimport.pl
@@ -0,0 +1,54 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+for my $include_file (@ARGV)
+{
+ open(my $rfh, '<', $include_file) || die "$include_file: $!";
+ my $buffer = '';
+ my $num_pgdllimport_added = 0;
+
+ while (my $raw_line = <$rfh>)
+ {
+ my $needs_pgdllimport = 1;
+
+ # By convention we declare global variables explicitly extern. We're
+ # looking for those not already marked with PGDLLIMPORT.
+ $needs_pgdllimport = 0 if $raw_line !~ /^extern\s+/
+ || $raw_line =~ /PGDLLIMPORT/;
+
+ # Make a copy of the line and perform a simple-minded comment strip.
+ # Also strip trailing whitespace.
+ my $stripped_line = $raw_line;
+ $stripped_line =~ s/\/\*.*\*\///g;
+ $stripped_line =~ s/\s+$//;
+
+ # Variable declarations should end in a semicolon. If we see an
+ # opening parenthesis, it's probably a function declaration.
+ $needs_pgdllimport = 0 if $stripped_line !~ /;$/
+ || $stripped_line =~ /\(/;
+
+ # Add PGDLLIMPORT marker, if required.
+ if ($needs_pgdllimport)
+ {
+ $raw_line =~ s/^extern/extern PGDLLIMPORT/;
+ ++$num_pgdllimport_added;
+ }
+
+ # Add line to buffer.
+ $buffer .= $raw_line;
+ }
+
+ close($rfh);
+
+ # If we added any PGDLLIMPORT markers, rewrite the file.
+ if ($num_pgdllimport_added > 0)
+ {
+ printf "%s: adding %d PGDLLIMPORT markers\n",
+ $include_file, $num_pgdllimport_added;
+ open(my $wfh, '>', $include_file) || die "$include_file: $!";
+ print $wfh $buffer;
+ close($wfh);
+ }
+}
--
2.24.3 (Apple Git-128)
v2-0002-Plaster-PGDLLIMPORT-declarations-on-header-files.patchapplication/octet-stream; name=v2-0002-Plaster-PGDLLIMPORT-declarations-on-header-files.patchDownload
From 1934e00ce225e92b12033e12599031b633b5a987 Mon Sep 17 00:00:00 2001
From: Robert Haas <rhaas@postgresql.org>
Date: Tue, 15 Feb 2022 08:53:25 -0500
Subject: [PATCH v2 2/2] Plaster PGDLLIMPORT declarations on header files.
---
src/include/access/gin.h | 2 +-
src/include/access/parallel.h | 2 +-
src/include/access/session.h | 2 +-
src/include/access/tableam.h | 4 +-
src/include/access/toast_compression.h | 2 +-
src/include/access/twophase_rmgr.h | 8 +--
src/include/access/xact.h | 16 +++---
src/include/access/xlog.h | 54 +++++++++---------
src/include/access/xlog_internal.h | 10 ++--
src/include/access/xlogrecovery.h | 42 +++++++-------
src/include/access/xlogutils.h | 4 +-
src/include/bootstrap/bootstrap.h | 6 +-
src/include/catalog/namespace.h | 2 +-
src/include/catalog/objectaddress.h | 2 +-
src/include/catalog/storage.h | 2 +-
src/include/commands/async.h | 4 +-
src/include/commands/tablespace.h | 2 +-
src/include/commands/user.h | 2 +-
src/include/commands/vacuum.h | 18 +++---
src/include/common/file_perm.h | 6 +-
src/include/common/jsonapi.h | 2 +-
src/include/common/logging.h | 2 +-
src/include/common/pg_lzcompress.h | 4 +-
src/include/common/relpath.h | 2 +-
src/include/fe_utils/cancel.h | 2 +-
src/include/fe_utils/print.h | 9 +--
src/include/fe_utils/string_utils.h | 2 +-
src/include/fmgr.h | 2 +-
src/include/jit/jit.h | 20 +++----
src/include/jit/llvmjit.h | 44 +++++++--------
src/include/libpq/auth.h | 6 +-
src/include/libpq/libpq-be.h | 2 +-
src/include/libpq/libpq.h | 28 +++++-----
src/include/libpq/pqcomm.h | 2 +-
src/include/libpq/scram.h | 2 +-
src/include/mb/pg_wchar.h | 6 +-
src/include/miscadmin.h | 52 ++++++++---------
src/include/nodes/readfuncs.h | 2 +-
src/include/optimizer/geqo.h | 11 ++--
src/include/optimizer/optimizer.h | 4 +-
src/include/optimizer/planmain.h | 6 +-
src/include/parser/parse_expr.h | 2 +-
src/include/parser/parser.h | 4 +-
src/include/pg_getopt.h | 10 ++--
src/include/pgstat.h | 22 ++++----
src/include/pgtime.h | 2 +-
src/include/port/win32_port.h | 6 +-
src/include/port/win32ntdll.h | 4 +-
src/include/postmaster/autovacuum.h | 32 +++++------
src/include/postmaster/bgworker_internals.h | 2 +-
src/include/postmaster/bgwriter.h | 8 +--
src/include/postmaster/pgarch.h | 2 +-
src/include/postmaster/postmaster.h | 34 +++++------
src/include/postmaster/startup.h | 2 +-
src/include/postmaster/syslogger.h | 14 ++---
src/include/postmaster/walwriter.h | 4 +-
src/include/replication/logicallauncher.h | 4 +-
src/include/replication/syncrep.h | 8 +--
src/include/replication/walreceiver.h | 8 +--
src/include/replication/walsender.h | 14 ++---
src/include/replication/walsender_private.h | 6 +-
src/include/replication/worker_internal.h | 10 ++--
src/include/storage/buf_internals.h | 4 +-
src/include/storage/bufmgr.h | 20 +++----
src/include/storage/dsm_impl.h | 4 +-
src/include/storage/fd.h | 4 +-
src/include/storage/large_object.h | 2 +-
src/include/storage/lock.h | 14 ++---
src/include/storage/lwlock.h | 2 +-
src/include/storage/pg_shmem.h | 14 ++---
src/include/storage/pmsignal.h | 2 +-
src/include/storage/predicate.h | 6 +-
src/include/storage/proc.h | 4 +-
src/include/storage/s_lock.h | 2 +-
src/include/storage/sinval.h | 4 +-
src/include/storage/spin.h | 2 +-
src/include/storage/standby.h | 8 +--
src/include/tcop/tcopprot.h | 8 +--
src/include/tsearch/ts_cache.h | 2 +-
src/include/tsearch/ts_type.h | 2 +-
src/include/utils/array.h | 2 +-
src/include/utils/builtins.h | 2 +-
src/include/utils/bytea.h | 3 +-
src/include/utils/datetime.h | 7 ++-
src/include/utils/elog.h | 12 ++--
src/include/utils/fmgrtab.h | 9 +--
src/include/utils/guc.h | 62 ++++++++++-----------
src/include/utils/guc_tables.h | 8 +--
src/include/utils/pg_locale.h | 18 +++---
src/include/utils/pgstat_internal.h | 10 ++--
src/include/utils/plancache.h | 2 +-
src/include/utils/ps_status.h | 2 +-
src/include/utils/queryjumble.h | 4 +-
src/include/utils/relcache.h | 4 +-
src/include/utils/rls.h | 2 +-
src/include/utils/snapmgr.h | 2 +-
src/include/utils/timestamp.h | 4 +-
src/include/utils/xml.h | 6 +-
98 files changed, 433 insertions(+), 428 deletions(-)
diff --git a/src/include/access/gin.h b/src/include/access/gin.h
index e83e0acd92..aacc665fdc 100644
--- a/src/include/access/gin.h
+++ b/src/include/access/gin.h
@@ -68,7 +68,7 @@ typedef char GinTernaryValue;
/* GUC parameters */
extern PGDLLIMPORT int GinFuzzySearchLimit;
-extern int gin_pending_list_limit;
+extern PGDLLIMPORT int gin_pending_list_limit;
/* ginutil.c */
extern void ginGetStats(Relation index, GinStatsData *stats);
diff --git a/src/include/access/parallel.h b/src/include/access/parallel.h
index 30786820f8..983841d45e 100644
--- a/src/include/access/parallel.h
+++ b/src/include/access/parallel.h
@@ -54,7 +54,7 @@ typedef struct ParallelWorkerContext
shm_toc *toc;
} ParallelWorkerContext;
-extern volatile bool ParallelMessagePending;
+extern PGDLLIMPORT volatile bool ParallelMessagePending;
extern PGDLLIMPORT int ParallelWorkerNumber;
extern PGDLLIMPORT bool InitializingParallelWorker;
diff --git a/src/include/access/session.h b/src/include/access/session.h
index 0ed52d4821..775888bbb0 100644
--- a/src/include/access/session.h
+++ b/src/include/access/session.h
@@ -39,6 +39,6 @@ extern void AttachSession(dsm_handle handle);
extern void DetachSession(void);
/* The current session, or NULL for none. */
-extern Session *CurrentSession;
+extern PGDLLIMPORT Session *CurrentSession;
#endif /* SESSION_H */
diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h
index bb365736b7..fe869c6c18 100644
--- a/src/include/access/tableam.h
+++ b/src/include/access/tableam.h
@@ -28,8 +28,8 @@
#define DEFAULT_TABLE_ACCESS_METHOD "heap"
/* GUCs */
-extern char *default_table_access_method;
-extern bool synchronize_seqscans;
+extern PGDLLIMPORT char *default_table_access_method;
+extern PGDLLIMPORT bool synchronize_seqscans;
struct BulkInsertStateData;
diff --git a/src/include/access/toast_compression.h b/src/include/access/toast_compression.h
index 9b433c7721..deb8f99da5 100644
--- a/src/include/access/toast_compression.h
+++ b/src/include/access/toast_compression.h
@@ -20,7 +20,7 @@
* but the value is one of the char values defined below, as they appear in
* pg_attribute.attcompression, e.g. TOAST_PGLZ_COMPRESSION.
*/
-extern int default_toast_compression;
+extern PGDLLIMPORT int default_toast_compression;
/*
* Built-in compression method ID. The toast compression header will store
diff --git a/src/include/access/twophase_rmgr.h b/src/include/access/twophase_rmgr.h
index 284c7539f8..96381a5e3f 100644
--- a/src/include/access/twophase_rmgr.h
+++ b/src/include/access/twophase_rmgr.h
@@ -28,10 +28,10 @@ typedef uint8 TwoPhaseRmgrId;
#define TWOPHASE_RM_PREDICATELOCK_ID 4
#define TWOPHASE_RM_MAX_ID TWOPHASE_RM_PREDICATELOCK_ID
-extern const TwoPhaseCallback twophase_recover_callbacks[];
-extern const TwoPhaseCallback twophase_postcommit_callbacks[];
-extern const TwoPhaseCallback twophase_postabort_callbacks[];
-extern const TwoPhaseCallback twophase_standby_recover_callbacks[];
+extern PGDLLIMPORT const TwoPhaseCallback twophase_recover_callbacks[];
+extern PGDLLIMPORT const TwoPhaseCallback twophase_postcommit_callbacks[];
+extern PGDLLIMPORT const TwoPhaseCallback twophase_postabort_callbacks[];
+extern PGDLLIMPORT const TwoPhaseCallback twophase_standby_recover_callbacks[];
extern void RegisterTwoPhaseRecord(TwoPhaseRmgrId rmid, uint16 info,
diff --git a/src/include/access/xact.h b/src/include/access/xact.h
index 062cc7e17d..0ec4bb181b 100644
--- a/src/include/access/xact.h
+++ b/src/include/access/xact.h
@@ -38,7 +38,7 @@
#define XACT_REPEATABLE_READ 2
#define XACT_SERIALIZABLE 3
-extern int DefaultXactIsoLevel;
+extern PGDLLIMPORT int DefaultXactIsoLevel;
extern PGDLLIMPORT int XactIsoLevel;
/*
@@ -52,18 +52,18 @@ extern PGDLLIMPORT int XactIsoLevel;
#define IsolationIsSerializable() (XactIsoLevel == XACT_SERIALIZABLE)
/* Xact read-only state */
-extern bool DefaultXactReadOnly;
-extern bool XactReadOnly;
+extern PGDLLIMPORT bool DefaultXactReadOnly;
+extern PGDLLIMPORT bool XactReadOnly;
/* flag for logging statements in this transaction */
-extern bool xact_is_sampled;
+extern PGDLLIMPORT bool xact_is_sampled;
/*
* Xact is deferrable -- only meaningful (currently) for read only
* SERIALIZABLE transactions
*/
-extern bool DefaultXactDeferrable;
-extern bool XactDeferrable;
+extern PGDLLIMPORT bool DefaultXactDeferrable;
+extern PGDLLIMPORT bool XactDeferrable;
typedef enum
{
@@ -80,7 +80,7 @@ typedef enum
#define SYNCHRONOUS_COMMIT_ON SYNCHRONOUS_COMMIT_REMOTE_FLUSH
/* Synchronous commit level */
-extern int synchronous_commit;
+extern PGDLLIMPORT int synchronous_commit;
/* used during logical streaming of a transaction */
extern PGDLLIMPORT TransactionId CheckXidAlive;
@@ -93,7 +93,7 @@ extern PGDLLIMPORT bool bsysscan;
* globally accessible, so can be set from anywhere in the code which requires
* recording flags.
*/
-extern int MyXactFlags;
+extern PGDLLIMPORT int MyXactFlags;
/*
* XACT_FLAGS_ACCESSEDTEMPNAMESPACE - set when a temporary object is accessed.
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index 09f6464331..05cfd3accf 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -24,34 +24,34 @@
#define SYNC_METHOD_OPEN 2 /* for O_SYNC */
#define SYNC_METHOD_FSYNC_WRITETHROUGH 3
#define SYNC_METHOD_OPEN_DSYNC 4 /* for O_DSYNC */
-extern int sync_method;
+extern PGDLLIMPORT int sync_method;
-extern XLogRecPtr ProcLastRecPtr;
-extern XLogRecPtr XactLastRecEnd;
+extern PGDLLIMPORT XLogRecPtr ProcLastRecPtr;
+extern PGDLLIMPORT XLogRecPtr XactLastRecEnd;
extern PGDLLIMPORT XLogRecPtr XactLastCommitEnd;
/* these variables are GUC parameters related to XLOG */
-extern int wal_segment_size;
-extern int min_wal_size_mb;
-extern int max_wal_size_mb;
-extern int wal_keep_size_mb;
-extern int max_slot_wal_keep_size_mb;
-extern int XLOGbuffers;
-extern int XLogArchiveTimeout;
-extern int wal_retrieve_retry_interval;
-extern char *XLogArchiveCommand;
-extern bool EnableHotStandby;
-extern bool fullPageWrites;
-extern bool wal_log_hints;
-extern int wal_compression;
-extern bool wal_init_zero;
-extern bool wal_recycle;
-extern bool *wal_consistency_checking;
-extern char *wal_consistency_checking_string;
-extern bool log_checkpoints;
-extern bool track_wal_io_timing;
-
-extern int CheckPointSegments;
+extern PGDLLIMPORT int wal_segment_size;
+extern PGDLLIMPORT int min_wal_size_mb;
+extern PGDLLIMPORT int max_wal_size_mb;
+extern PGDLLIMPORT int wal_keep_size_mb;
+extern PGDLLIMPORT int max_slot_wal_keep_size_mb;
+extern PGDLLIMPORT int XLOGbuffers;
+extern PGDLLIMPORT int XLogArchiveTimeout;
+extern PGDLLIMPORT int wal_retrieve_retry_interval;
+extern PGDLLIMPORT char *XLogArchiveCommand;
+extern PGDLLIMPORT bool EnableHotStandby;
+extern PGDLLIMPORT bool fullPageWrites;
+extern PGDLLIMPORT bool wal_log_hints;
+extern PGDLLIMPORT int wal_compression;
+extern PGDLLIMPORT bool wal_init_zero;
+extern PGDLLIMPORT bool wal_recycle;
+extern PGDLLIMPORT bool *wal_consistency_checking;
+extern PGDLLIMPORT char *wal_consistency_checking_string;
+extern PGDLLIMPORT bool log_checkpoints;
+extern PGDLLIMPORT bool track_wal_io_timing;
+
+extern PGDLLIMPORT int CheckPointSegments;
/* Archive modes */
typedef enum ArchiveMode
@@ -60,7 +60,7 @@ typedef enum ArchiveMode
ARCHIVE_MODE_ON, /* enabled while server is running normally */
ARCHIVE_MODE_ALWAYS /* enabled always (even during recovery) */
} ArchiveMode;
-extern int XLogArchiveMode;
+extern PGDLLIMPORT int XLogArchiveMode;
/* WAL levels */
typedef enum WalLevel
@@ -120,7 +120,7 @@ extern PGDLLIMPORT int wal_level;
#define XLogLogicalInfoActive() (wal_level >= WAL_LEVEL_LOGICAL)
#ifdef WAL_DEBUG
-extern bool XLOG_DEBUG;
+extern PGDLLIMPORT bool XLOG_DEBUG;
#endif
/*
@@ -174,7 +174,7 @@ typedef struct CheckpointStatsData
* entire sync phase. */
} CheckpointStatsData;
-extern CheckpointStatsData CheckpointStats;
+extern PGDLLIMPORT CheckpointStatsData CheckpointStats;
/*
* GetWALAvailability return codes
diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h
index 0e94833129..2cde27e70e 100644
--- a/src/include/access/xlog_internal.h
+++ b/src/include/access/xlog_internal.h
@@ -319,7 +319,7 @@ typedef struct RmgrData
struct XLogRecordBuffer *buf);
} RmgrData;
-extern const RmgrData RmgrTable[];
+extern PGDLLIMPORT const RmgrData RmgrTable[];
/*
* Exported to support xlog switching from checkpointer
@@ -333,9 +333,9 @@ extern void GetOldestRestartPoint(XLogRecPtr *oldrecptr, TimeLineID *oldtli);
* Exported for the functions in timeline.c and xlogarchive.c. Only valid
* in the startup process.
*/
-extern bool ArchiveRecoveryRequested;
-extern bool InArchiveRecovery;
-extern bool StandbyMode;
-extern char *recoveryRestoreCommand;
+extern PGDLLIMPORT bool ArchiveRecoveryRequested;
+extern PGDLLIMPORT bool InArchiveRecovery;
+extern PGDLLIMPORT bool StandbyMode;
+extern PGDLLIMPORT char *recoveryRestoreCommand;
#endif /* XLOG_INTERNAL_H */
diff --git a/src/include/access/xlogrecovery.h b/src/include/access/xlogrecovery.h
index 75a0f5fe5e..0aa85d90e8 100644
--- a/src/include/access/xlogrecovery.h
+++ b/src/include/access/xlogrecovery.h
@@ -49,33 +49,33 @@ typedef enum RecoveryPauseState
} RecoveryPauseState;
/* User-settable GUC parameters */
-extern bool recoveryTargetInclusive;
-extern int recoveryTargetAction;
-extern int recovery_min_apply_delay;
-extern char *PrimaryConnInfo;
-extern char *PrimarySlotName;
-extern char *recoveryRestoreCommand;
-extern char *recoveryEndCommand;
-extern char *archiveCleanupCommand;
+extern PGDLLIMPORT bool recoveryTargetInclusive;
+extern PGDLLIMPORT int recoveryTargetAction;
+extern PGDLLIMPORT int recovery_min_apply_delay;
+extern PGDLLIMPORT char *PrimaryConnInfo;
+extern PGDLLIMPORT char *PrimarySlotName;
+extern PGDLLIMPORT char *recoveryRestoreCommand;
+extern PGDLLIMPORT char *recoveryEndCommand;
+extern PGDLLIMPORT char *archiveCleanupCommand;
/* indirectly set via GUC system */
-extern TransactionId recoveryTargetXid;
-extern char *recovery_target_time_string;
-extern TimestampTz recoveryTargetTime;
-extern const char *recoveryTargetName;
-extern XLogRecPtr recoveryTargetLSN;
-extern RecoveryTargetType recoveryTarget;
-extern char *PromoteTriggerFile;
-extern bool wal_receiver_create_temp_slot;
-extern RecoveryTargetTimeLineGoal recoveryTargetTimeLineGoal;
-extern TimeLineID recoveryTargetTLIRequested;
-extern TimeLineID recoveryTargetTLI;
+extern PGDLLIMPORT TransactionId recoveryTargetXid;
+extern PGDLLIMPORT char *recovery_target_time_string;
+extern PGDLLIMPORT TimestampTz recoveryTargetTime;
+extern PGDLLIMPORT const char *recoveryTargetName;
+extern PGDLLIMPORT XLogRecPtr recoveryTargetLSN;
+extern PGDLLIMPORT RecoveryTargetType recoveryTarget;
+extern PGDLLIMPORT char *PromoteTriggerFile;
+extern PGDLLIMPORT bool wal_receiver_create_temp_slot;
+extern PGDLLIMPORT RecoveryTargetTimeLineGoal recoveryTargetTimeLineGoal;
+extern PGDLLIMPORT TimeLineID recoveryTargetTLIRequested;
+extern PGDLLIMPORT TimeLineID recoveryTargetTLI;
/* Have we already reached a consistent database state? */
-extern bool reachedConsistency;
+extern PGDLLIMPORT bool reachedConsistency;
/* Are we currently in standby mode? */
-extern bool StandbyMode;
+extern PGDLLIMPORT bool StandbyMode;
extern Size XLogRecoveryShmemSize(void);
extern void XLogRecoveryShmemInit(void);
diff --git a/src/include/access/xlogutils.h b/src/include/access/xlogutils.h
index 64708949db..00889f76de 100644
--- a/src/include/access/xlogutils.h
+++ b/src/include/access/xlogutils.h
@@ -21,7 +21,7 @@
* potentially perform work during recovery should check RecoveryInProgress().
* See XLogCtl notes in xlog.c.
*/
-extern bool InRecovery;
+extern PGDLLIMPORT bool InRecovery;
/*
* Like InRecovery, standbyState is only valid in the startup process.
@@ -52,7 +52,7 @@ typedef enum
STANDBY_SNAPSHOT_READY
} HotStandbyState;
-extern HotStandbyState standbyState;
+extern PGDLLIMPORT HotStandbyState standbyState;
#define InHotStandby (standbyState >= STANDBY_SNAPSHOT_PENDING)
diff --git a/src/include/bootstrap/bootstrap.h b/src/include/bootstrap/bootstrap.h
index 471414909f..49d4ad560f 100644
--- a/src/include/bootstrap/bootstrap.h
+++ b/src/include/bootstrap/bootstrap.h
@@ -27,9 +27,9 @@
#define BOOTCOL_NULL_FORCE_NULL 2
#define BOOTCOL_NULL_FORCE_NOT_NULL 3
-extern Relation boot_reldesc;
-extern Form_pg_attribute attrtypes[MAXATTR];
-extern int numattr;
+extern PGDLLIMPORT Relation boot_reldesc;
+extern PGDLLIMPORT Form_pg_attribute attrtypes[MAXATTR];
+extern PGDLLIMPORT int numattr;
extern void BootstrapModeMain(int argc, char *argv[], bool check_only) pg_attribute_noreturn();
diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h
index f963d82797..1bc55c01a5 100644
--- a/src/include/catalog/namespace.h
+++ b/src/include/catalog/namespace.h
@@ -182,7 +182,7 @@ extern void AtEOSubXact_Namespace(bool isCommit, SubTransactionId mySubid,
SubTransactionId parentSubid);
/* stuff for search_path GUC variable */
-extern char *namespace_search_path;
+extern PGDLLIMPORT char *namespace_search_path;
extern List *fetch_search_path(bool includeImplicit);
extern int fetch_search_path_array(Oid *sarray, int sarray_len);
diff --git a/src/include/catalog/objectaddress.h b/src/include/catalog/objectaddress.h
index 274f300054..cf4d8b3107 100644
--- a/src/include/catalog/objectaddress.h
+++ b/src/include/catalog/objectaddress.h
@@ -28,7 +28,7 @@ typedef struct ObjectAddress
int32 objectSubId; /* Subitem within object (eg column), or 0 */
} ObjectAddress;
-extern const ObjectAddress InvalidObjectAddress;
+extern PGDLLIMPORT const ObjectAddress InvalidObjectAddress;
#define ObjectAddressSubSet(addr, class_id, object_id, object_sub_id) \
do { \
diff --git a/src/include/catalog/storage.h b/src/include/catalog/storage.h
index 844a023b2c..59f3404ac6 100644
--- a/src/include/catalog/storage.h
+++ b/src/include/catalog/storage.h
@@ -20,7 +20,7 @@
#include "utils/relcache.h"
/* GUC variables */
-extern int wal_skip_threshold;
+extern PGDLLIMPORT int wal_skip_threshold;
extern SMgrRelation RelationCreateStorage(RelFileNode rnode,
char relpersistence,
diff --git a/src/include/commands/async.h b/src/include/commands/async.h
index ebc9271789..926af933d1 100644
--- a/src/include/commands/async.h
+++ b/src/include/commands/async.h
@@ -20,8 +20,8 @@
*/
#define NUM_NOTIFY_BUFFERS 8
-extern bool Trace_notify;
-extern volatile sig_atomic_t notifyInterruptPending;
+extern PGDLLIMPORT bool Trace_notify;
+extern PGDLLIMPORT volatile sig_atomic_t notifyInterruptPending;
extern Size AsyncShmemSize(void);
extern void AsyncShmemInit(void);
diff --git a/src/include/commands/tablespace.h b/src/include/commands/tablespace.h
index 323528ebb8..24b647332d 100644
--- a/src/include/commands/tablespace.h
+++ b/src/include/commands/tablespace.h
@@ -19,7 +19,7 @@
#include "lib/stringinfo.h"
#include "nodes/parsenodes.h"
-extern bool allow_in_place_tablespaces;
+extern PGDLLIMPORT bool allow_in_place_tablespaces;
/* XLOG stuff */
#define XLOG_TBLSPC_CREATE 0x00
diff --git a/src/include/commands/user.h b/src/include/commands/user.h
index 0b7a3cd65f..d3dd8303d2 100644
--- a/src/include/commands/user.h
+++ b/src/include/commands/user.h
@@ -17,7 +17,7 @@
#include "parser/parse_node.h"
/* GUC. Is actually of type PasswordType. */
-extern int Password_encryption;
+extern PGDLLIMPORT int Password_encryption;
/* Hook to check passwords in CreateRole() and AlterRole() */
typedef void (*check_password_hook_type) (const char *username, const char *shadow_pass, PasswordType password_type, Datum validuntil_time, bool validuntil_null);
diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h
index d64f6268f2..239e0356fa 100644
--- a/src/include/commands/vacuum.h
+++ b/src/include/commands/vacuum.h
@@ -252,17 +252,17 @@ typedef struct VacDeadItems
/* GUC parameters */
extern PGDLLIMPORT int default_statistics_target; /* PGDLLIMPORT for PostGIS */
-extern int vacuum_freeze_min_age;
-extern int vacuum_freeze_table_age;
-extern int vacuum_multixact_freeze_min_age;
-extern int vacuum_multixact_freeze_table_age;
-extern int vacuum_failsafe_age;
-extern int vacuum_multixact_failsafe_age;
+extern PGDLLIMPORT int vacuum_freeze_min_age;
+extern PGDLLIMPORT int vacuum_freeze_table_age;
+extern PGDLLIMPORT int vacuum_multixact_freeze_min_age;
+extern PGDLLIMPORT int vacuum_multixact_freeze_table_age;
+extern PGDLLIMPORT int vacuum_failsafe_age;
+extern PGDLLIMPORT int vacuum_multixact_failsafe_age;
/* Variables for cost-based parallel vacuum */
-extern pg_atomic_uint32 *VacuumSharedCostBalance;
-extern pg_atomic_uint32 *VacuumActiveNWorkers;
-extern int VacuumCostBalanceLocal;
+extern PGDLLIMPORT pg_atomic_uint32 *VacuumSharedCostBalance;
+extern PGDLLIMPORT pg_atomic_uint32 *VacuumActiveNWorkers;
+extern PGDLLIMPORT int VacuumCostBalanceLocal;
/* in commands/vacuum.c */
diff --git a/src/include/common/file_perm.h b/src/include/common/file_perm.h
index 85d32ed141..48d68ef276 100644
--- a/src/include/common/file_perm.h
+++ b/src/include/common/file_perm.h
@@ -41,11 +41,11 @@
#define PG_FILE_MODE_GROUP (S_IRUSR | S_IWUSR | S_IRGRP)
/* Modes for creating directories and files in the data directory */
-extern int pg_dir_create_mode;
-extern int pg_file_create_mode;
+extern PGDLLIMPORT int pg_dir_create_mode;
+extern PGDLLIMPORT int pg_file_create_mode;
/* Mode mask to pass to umask() */
-extern int pg_mode_mask;
+extern PGDLLIMPORT int pg_mode_mask;
/* Set permissions and mask based on the provided mode */
extern void SetDataDirectoryCreatePerm(int dataDirMode);
diff --git a/src/include/common/jsonapi.h b/src/include/common/jsonapi.h
index 52cb4a9339..8d31630e5c 100644
--- a/src/include/common/jsonapi.h
+++ b/src/include/common/jsonapi.h
@@ -128,7 +128,7 @@ extern JsonParseErrorType pg_parse_json(JsonLexContext *lex,
JsonSemAction *sem);
/* the null action object used for pure validation */
-extern JsonSemAction nullSemAction;
+extern PGDLLIMPORT JsonSemAction nullSemAction;
/*
* json_count_array_elements performs a fast secondary parse to determine the
diff --git a/src/include/common/logging.h b/src/include/common/logging.h
index 43cc79afa8..61cfdce653 100644
--- a/src/include/common/logging.h
+++ b/src/include/common/logging.h
@@ -55,7 +55,7 @@ enum pg_log_level
PG_LOG_OFF,
};
-extern enum pg_log_level __pg_log_level;
+extern PGDLLIMPORT enum pg_log_level __pg_log_level;
/*
* Kind of a hack to be able to produce the psql output exactly as required by
diff --git a/src/include/common/pg_lzcompress.h b/src/include/common/pg_lzcompress.h
index 3e53fbe97b..2a12b33a00 100644
--- a/src/include/common/pg_lzcompress.h
+++ b/src/include/common/pg_lzcompress.h
@@ -75,8 +75,8 @@ typedef struct PGLZ_Strategy
* output would be larger than input.
* ----------
*/
-extern const PGLZ_Strategy *const PGLZ_strategy_default;
-extern const PGLZ_Strategy *const PGLZ_strategy_always;
+extern PGDLLIMPORT const PGLZ_Strategy *const PGLZ_strategy_default;
+extern PGDLLIMPORT const PGLZ_Strategy *const PGLZ_strategy_always;
/* ----------
diff --git a/src/include/common/relpath.h b/src/include/common/relpath.h
index a4b5dc853b..13849a3790 100644
--- a/src/include/common/relpath.h
+++ b/src/include/common/relpath.h
@@ -56,7 +56,7 @@ typedef enum ForkNumber
#define FORKNAMECHARS 4 /* max chars for a fork name */
-extern const char *const forkNames[];
+extern PGDLLIMPORT const char *const forkNames[];
extern ForkNumber forkname_to_number(const char *forkName);
extern int forkname_chars(const char *str, ForkNumber *fork);
diff --git a/src/include/fe_utils/cancel.h b/src/include/fe_utils/cancel.h
index 7005b804bc..3b84daf6eb 100644
--- a/src/include/fe_utils/cancel.h
+++ b/src/include/fe_utils/cancel.h
@@ -18,7 +18,7 @@
#include "libpq-fe.h"
-extern volatile sig_atomic_t CancelRequested;
+extern PGDLLIMPORT volatile sig_atomic_t CancelRequested;
extern void SetCancelConn(PGconn *conn);
extern void ResetCancelConn(void);
diff --git a/src/include/fe_utils/print.h b/src/include/fe_utils/print.h
index 836b4e29a8..bb2f1bf4e6 100644
--- a/src/include/fe_utils/print.h
+++ b/src/include/fe_utils/print.h
@@ -177,11 +177,12 @@ typedef struct printQueryOpt
} printQueryOpt;
-extern volatile sig_atomic_t cancel_pressed;
+extern PGDLLIMPORT volatile sig_atomic_t cancel_pressed;
-extern const printTextFormat pg_asciiformat;
-extern const printTextFormat pg_asciiformat_old;
-extern printTextFormat pg_utf8format; /* ideally would be const, but... */
+extern PGDLLIMPORT const printTextFormat pg_asciiformat;
+extern PGDLLIMPORT const printTextFormat pg_asciiformat_old;
+extern PGDLLIMPORT printTextFormat pg_utf8format; /* ideally would be const,
+ * but... */
extern void disable_sigpipe_trap(void);
diff --git a/src/include/fe_utils/string_utils.h b/src/include/fe_utils/string_utils.h
index 3c88250e6c..b9b8708dab 100644
--- a/src/include/fe_utils/string_utils.h
+++ b/src/include/fe_utils/string_utils.h
@@ -20,7 +20,7 @@
#include "pqexpbuffer.h"
/* Global variables controlling behavior of fmtId() and fmtQualifiedId() */
-extern int quote_all_identifiers;
+extern PGDLLIMPORT int quote_all_identifiers;
extern PQExpBuffer (*getLocalPQExpBuffer) (void);
/* Functions */
diff --git a/src/include/fmgr.h b/src/include/fmgr.h
index 6560e462d6..a1cf4bd646 100644
--- a/src/include/fmgr.h
+++ b/src/include/fmgr.h
@@ -721,7 +721,7 @@ extern bool CheckFunctionValidatorAccess(Oid validatorOid, Oid functionOid);
/*
* Routines in dfmgr.c
*/
-extern char *Dynamic_library_path;
+extern PGDLLIMPORT char *Dynamic_library_path;
extern void *load_external_function(const char *filename, const char *funcname,
bool signalNotFound, void **filehandle);
diff --git a/src/include/jit/jit.h b/src/include/jit/jit.h
index 707176d9ed..d194033209 100644
--- a/src/include/jit/jit.h
+++ b/src/include/jit/jit.h
@@ -79,16 +79,16 @@ struct JitProviderCallbacks
/* GUCs */
-extern bool jit_enabled;
-extern char *jit_provider;
-extern bool jit_debugging_support;
-extern bool jit_dump_bitcode;
-extern bool jit_expressions;
-extern bool jit_profiling_support;
-extern bool jit_tuple_deforming;
-extern double jit_above_cost;
-extern double jit_inline_above_cost;
-extern double jit_optimize_above_cost;
+extern PGDLLIMPORT bool jit_enabled;
+extern PGDLLIMPORT char *jit_provider;
+extern PGDLLIMPORT bool jit_debugging_support;
+extern PGDLLIMPORT bool jit_dump_bitcode;
+extern PGDLLIMPORT bool jit_expressions;
+extern PGDLLIMPORT bool jit_profiling_support;
+extern PGDLLIMPORT bool jit_tuple_deforming;
+extern PGDLLIMPORT double jit_above_cost;
+extern PGDLLIMPORT double jit_inline_above_cost;
+extern PGDLLIMPORT double jit_optimize_above_cost;
extern void jit_reset_after_error(void);
diff --git a/src/include/jit/llvmjit.h b/src/include/jit/llvmjit.h
index 66143afccc..4541f9a2c4 100644
--- a/src/include/jit/llvmjit.h
+++ b/src/include/jit/llvmjit.h
@@ -56,30 +56,30 @@ typedef struct LLVMJitContext
} LLVMJitContext;
/* llvm module containing information about types */
-extern LLVMModuleRef llvm_types_module;
+extern PGDLLIMPORT LLVMModuleRef llvm_types_module;
/* type and struct definitions */
-extern LLVMTypeRef TypeParamBool;
-extern LLVMTypeRef TypePGFunction;
-extern LLVMTypeRef TypeSizeT;
-extern LLVMTypeRef TypeStorageBool;
-
-extern LLVMTypeRef StructNullableDatum;
-extern LLVMTypeRef StructTupleDescData;
-extern LLVMTypeRef StructHeapTupleData;
-extern LLVMTypeRef StructTupleTableSlot;
-extern LLVMTypeRef StructHeapTupleTableSlot;
-extern LLVMTypeRef StructMinimalTupleTableSlot;
-extern LLVMTypeRef StructMemoryContextData;
-extern LLVMTypeRef StructFunctionCallInfoData;
-extern LLVMTypeRef StructExprContext;
-extern LLVMTypeRef StructExprEvalStep;
-extern LLVMTypeRef StructExprState;
-extern LLVMTypeRef StructAggState;
-extern LLVMTypeRef StructAggStatePerTransData;
-extern LLVMTypeRef StructAggStatePerGroupData;
-
-extern LLVMValueRef AttributeTemplate;
+extern PGDLLIMPORT LLVMTypeRef TypeParamBool;
+extern PGDLLIMPORT LLVMTypeRef TypePGFunction;
+extern PGDLLIMPORT LLVMTypeRef TypeSizeT;
+extern PGDLLIMPORT LLVMTypeRef TypeStorageBool;
+
+extern PGDLLIMPORT LLVMTypeRef StructNullableDatum;
+extern PGDLLIMPORT LLVMTypeRef StructTupleDescData;
+extern PGDLLIMPORT LLVMTypeRef StructHeapTupleData;
+extern PGDLLIMPORT LLVMTypeRef StructTupleTableSlot;
+extern PGDLLIMPORT LLVMTypeRef StructHeapTupleTableSlot;
+extern PGDLLIMPORT LLVMTypeRef StructMinimalTupleTableSlot;
+extern PGDLLIMPORT LLVMTypeRef StructMemoryContextData;
+extern PGDLLIMPORT LLVMTypeRef StructFunctionCallInfoData;
+extern PGDLLIMPORT LLVMTypeRef StructExprContext;
+extern PGDLLIMPORT LLVMTypeRef StructExprEvalStep;
+extern PGDLLIMPORT LLVMTypeRef StructExprState;
+extern PGDLLIMPORT LLVMTypeRef StructAggState;
+extern PGDLLIMPORT LLVMTypeRef StructAggStatePerTransData;
+extern PGDLLIMPORT LLVMTypeRef StructAggStatePerGroupData;
+
+extern PGDLLIMPORT LLVMValueRef AttributeTemplate;
extern void llvm_enter_fatal_on_oom(void);
diff --git a/src/include/libpq/auth.h b/src/include/libpq/auth.h
index 6d7ee1acb9..d3c189efe3 100644
--- a/src/include/libpq/auth.h
+++ b/src/include/libpq/auth.h
@@ -16,9 +16,9 @@
#include "libpq/libpq-be.h"
-extern char *pg_krb_server_keyfile;
-extern bool pg_krb_caseins_users;
-extern char *pg_krb_realm;
+extern PGDLLIMPORT char *pg_krb_server_keyfile;
+extern PGDLLIMPORT bool pg_krb_caseins_users;
+extern PGDLLIMPORT char *pg_krb_realm;
extern void ClientAuthentication(Port *port);
extern void sendAuthRequest(Port *port, AuthRequest areq, const char *extradata,
diff --git a/src/include/libpq/libpq-be.h b/src/include/libpq/libpq-be.h
index dd3e5efba3..3beeaeee39 100644
--- a/src/include/libpq/libpq-be.h
+++ b/src/include/libpq/libpq-be.h
@@ -327,7 +327,7 @@ extern ssize_t be_gssapi_read(Port *port, void *ptr, size_t len);
extern ssize_t be_gssapi_write(Port *port, void *ptr, size_t len);
#endif /* ENABLE_GSS */
-extern ProtocolVersion FrontendProtocol;
+extern PGDLLIMPORT ProtocolVersion FrontendProtocol;
/* TCP keepalives configuration. These are no-ops on an AF_UNIX socket. */
diff --git a/src/include/libpq/libpq.h b/src/include/libpq/libpq.h
index d348a55812..2de7d9bad2 100644
--- a/src/include/libpq/libpq.h
+++ b/src/include/libpq/libpq.h
@@ -58,7 +58,7 @@ extern const PGDLLIMPORT PQcommMethods *PqCommMethods;
/*
* prototypes for functions in pqcomm.c
*/
-extern WaitEventSet *FeBeWaitSet;
+extern PGDLLIMPORT WaitEventSet *FeBeWaitSet;
#define FeBeWaitSetSocketPos 0
#define FeBeWaitSetLatchPos 1
@@ -87,17 +87,17 @@ extern bool pq_check_connection(void);
/*
* prototypes for functions in be-secure.c
*/
-extern char *ssl_library;
-extern char *ssl_cert_file;
-extern char *ssl_key_file;
-extern char *ssl_ca_file;
-extern char *ssl_crl_file;
-extern char *ssl_crl_dir;
-extern char *ssl_dh_params_file;
+extern PGDLLIMPORT char *ssl_library;
+extern PGDLLIMPORT char *ssl_cert_file;
+extern PGDLLIMPORT char *ssl_key_file;
+extern PGDLLIMPORT char *ssl_ca_file;
+extern PGDLLIMPORT char *ssl_crl_file;
+extern PGDLLIMPORT char *ssl_crl_dir;
+extern PGDLLIMPORT char *ssl_dh_params_file;
extern PGDLLIMPORT char *ssl_passphrase_command;
extern PGDLLIMPORT bool ssl_passphrase_command_supports_reload;
#ifdef USE_SSL
-extern bool ssl_loaded_verify_locations;
+extern PGDLLIMPORT bool ssl_loaded_verify_locations;
#endif
extern int secure_initialize(bool isServerStart);
@@ -118,11 +118,11 @@ extern ssize_t secure_open_gssapi(Port *port);
#endif
/* GUCs */
-extern char *SSLCipherSuites;
-extern char *SSLECDHCurve;
-extern bool SSLPreferServerCiphers;
-extern int ssl_min_protocol_version;
-extern int ssl_max_protocol_version;
+extern PGDLLIMPORT char *SSLCipherSuites;
+extern PGDLLIMPORT char *SSLECDHCurve;
+extern PGDLLIMPORT bool SSLPreferServerCiphers;
+extern PGDLLIMPORT int ssl_min_protocol_version;
+extern PGDLLIMPORT int ssl_max_protocol_version;
enum ssl_protocol_versions
{
diff --git a/src/include/libpq/pqcomm.h b/src/include/libpq/pqcomm.h
index ed26ad2256..b418283d5f 100644
--- a/src/include/libpq/pqcomm.h
+++ b/src/include/libpq/pqcomm.h
@@ -135,7 +135,7 @@ typedef ProtocolVersion MsgType;
typedef uint32 PacketLen;
-extern bool Db_user_namespace;
+extern PGDLLIMPORT bool Db_user_namespace;
/*
* In protocol 3.0 and later, the startup packet length is not fixed, but
diff --git a/src/include/libpq/scram.h b/src/include/libpq/scram.h
index e60992a0d2..c51e848c24 100644
--- a/src/include/libpq/scram.h
+++ b/src/include/libpq/scram.h
@@ -18,7 +18,7 @@
#include "libpq/sasl.h"
/* SASL implementation callbacks */
-extern const pg_be_sasl_mech pg_be_scram_mech;
+extern PGDLLIMPORT const pg_be_sasl_mech pg_be_scram_mech;
/* Routines to handle and check SCRAM-SHA-256 secret */
extern char *pg_be_scram_build_secret(const char *password);
diff --git a/src/include/mb/pg_wchar.h b/src/include/mb/pg_wchar.h
index fd89bee80b..31f5b393da 100644
--- a/src/include/mb/pg_wchar.h
+++ b/src/include/mb/pg_wchar.h
@@ -359,7 +359,7 @@ typedef struct pg_enc2name
#endif
} pg_enc2name;
-extern const pg_enc2name pg_enc2name_tbl[];
+extern PGDLLIMPORT const pg_enc2name pg_enc2name_tbl[];
/*
* Encoding names for gettext
@@ -370,7 +370,7 @@ typedef struct pg_enc2gettext
const char *name;
} pg_enc2gettext;
-extern const pg_enc2gettext pg_enc2gettext_tbl[];
+extern PGDLLIMPORT const pg_enc2gettext pg_enc2gettext_tbl[];
/*
* pg_wchar stuff
@@ -406,7 +406,7 @@ typedef struct
int maxmblen; /* max bytes for a char in this encoding */
} pg_wchar_tbl;
-extern const pg_wchar_tbl pg_wchar_table[];
+extern PGDLLIMPORT const pg_wchar_tbl pg_wchar_table[];
/*
* Data structures for conversions between UTF-8 and other encodings
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index 0abc3ad540..7a8ca4a2d2 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -181,15 +181,15 @@ extern PGDLLIMPORT pg_time_t MyStartTime;
extern PGDLLIMPORT TimestampTz MyStartTimestamp;
extern PGDLLIMPORT struct Port *MyProcPort;
extern PGDLLIMPORT struct Latch *MyLatch;
-extern int32 MyCancelKey;
-extern int MyPMChildSlot;
+extern PGDLLIMPORT int32 MyCancelKey;
+extern PGDLLIMPORT int MyPMChildSlot;
-extern char OutputFileName[];
+extern PGDLLIMPORT char OutputFileName[];
extern PGDLLIMPORT char my_exec_path[];
-extern char pkglib_path[];
+extern PGDLLIMPORT char pkglib_path[];
#ifdef EXEC_BACKEND
-extern char postgres_exec_path[];
+extern PGDLLIMPORT char postgres_exec_path[];
#endif
/*
@@ -254,25 +254,25 @@ extern PGDLLIMPORT int IntervalStyle;
#define MAXTZLEN 10 /* max TZ name len, not counting tr. null */
-extern bool enableFsync;
+extern PGDLLIMPORT bool enableFsync;
extern PGDLLIMPORT bool allowSystemTableMods;
extern PGDLLIMPORT int work_mem;
extern PGDLLIMPORT double hash_mem_multiplier;
extern PGDLLIMPORT int maintenance_work_mem;
extern PGDLLIMPORT int max_parallel_maintenance_workers;
-extern int VacuumCostPageHit;
-extern int VacuumCostPageMiss;
-extern int VacuumCostPageDirty;
-extern int VacuumCostLimit;
-extern double VacuumCostDelay;
+extern PGDLLIMPORT int VacuumCostPageHit;
+extern PGDLLIMPORT int VacuumCostPageMiss;
+extern PGDLLIMPORT int VacuumCostPageDirty;
+extern PGDLLIMPORT int VacuumCostLimit;
+extern PGDLLIMPORT double VacuumCostDelay;
-extern int64 VacuumPageHit;
-extern int64 VacuumPageMiss;
-extern int64 VacuumPageDirty;
+extern PGDLLIMPORT int64 VacuumPageHit;
+extern PGDLLIMPORT int64 VacuumPageMiss;
+extern PGDLLIMPORT int64 VacuumPageDirty;
-extern int VacuumCostBalance;
-extern bool VacuumCostActive;
+extern PGDLLIMPORT int VacuumCostBalance;
+extern PGDLLIMPORT bool VacuumCostActive;
/* in tcop/postgres.c */
@@ -298,7 +298,7 @@ extern void PreventCommandIfParallelMode(const char *cmdname);
extern void PreventCommandDuringRecovery(const char *cmdname);
/* in utils/misc/guc.c */
-extern int trace_recovery_messages;
+extern PGDLLIMPORT int trace_recovery_messages;
extern int trace_recovery(int trace_level);
/*****************************************************************************
@@ -311,7 +311,7 @@ extern int trace_recovery(int trace_level);
#define SECURITY_RESTRICTED_OPERATION 0x0002
#define SECURITY_NOFORCE_RLS 0x0004
-extern char *DatabasePath;
+extern PGDLLIMPORT char *DatabasePath;
/* now in utils/init/miscinit.c */
extern void InitPostmasterChild(void);
@@ -337,7 +337,7 @@ typedef enum BackendType
B_LOGGER,
} BackendType;
-extern BackendType MyBackendType;
+extern PGDLLIMPORT BackendType MyBackendType;
extern const char *GetBackendTypeDesc(BackendType backendType);
@@ -400,7 +400,7 @@ typedef enum ProcessingMode
NormalProcessing /* normal processing */
} ProcessingMode;
-extern ProcessingMode Mode;
+extern PGDLLIMPORT ProcessingMode Mode;
#define IsBootstrapProcessingMode() (Mode == BootstrapProcessing)
#define IsInitProcessingMode() (Mode == InitProcessing)
@@ -438,7 +438,7 @@ typedef enum
NUM_AUXPROCTYPES /* Must be last! */
} AuxProcType;
-extern AuxProcType MyAuxProcType;
+extern PGDLLIMPORT AuxProcType MyAuxProcType;
#define AmStartupProcess() (MyAuxProcType == StartupProcess)
#define AmBackgroundWriterProcess() (MyAuxProcType == BgWriterProcess)
@@ -456,18 +456,18 @@ extern AuxProcType MyAuxProcType;
/* in utils/init/postinit.c */
extern void pg_split_opts(char **argv, int *argcp, const char *optstr);
extern void InitializeMaxBackends(void);
-extern int GetMaxBackends(void);
+extern int GetMaxBackends(void);
extern void SetMaxBackends(int max_backends);
extern void InitPostgres(const char *in_dbname, Oid dboid, const char *username,
Oid useroid, char *out_dbname, bool override_allow_connections);
extern void BaseInit(void);
/* in utils/init/miscinit.c */
-extern bool IgnoreSystemIndexes;
+extern PGDLLIMPORT bool IgnoreSystemIndexes;
extern PGDLLIMPORT bool process_shared_preload_libraries_in_progress;
-extern char *session_preload_libraries_string;
-extern char *shared_preload_libraries_string;
-extern char *local_preload_libraries_string;
+extern PGDLLIMPORT char *session_preload_libraries_string;
+extern PGDLLIMPORT char *shared_preload_libraries_string;
+extern PGDLLIMPORT char *local_preload_libraries_string;
extern void CreateDataDirLockFile(bool amPostmaster);
extern void CreateSocketLockFile(const char *socketfile, bool amPostmaster,
diff --git a/src/include/nodes/readfuncs.h b/src/include/nodes/readfuncs.h
index 41794354e2..66717fd6c3 100644
--- a/src/include/nodes/readfuncs.h
+++ b/src/include/nodes/readfuncs.h
@@ -20,7 +20,7 @@
* variable in read.c that needs to be accessible to readfuncs.c
*/
#ifdef WRITE_READ_PARSE_PLAN_TREES
-extern bool restore_location_fields;
+extern PGDLLIMPORT bool restore_location_fields;
#endif
/*
diff --git a/src/include/optimizer/geqo.h b/src/include/optimizer/geqo.h
index 4563f200cd..d399323332 100644
--- a/src/include/optimizer/geqo.h
+++ b/src/include/optimizer/geqo.h
@@ -49,23 +49,24 @@
*
* If you change these, update backend/utils/misc/postgresql.conf.sample
*/
-extern int Geqo_effort; /* 1 .. 10, knob for adjustment of defaults */
+extern PGDLLIMPORT int Geqo_effort; /* 1 .. 10, knob for adjustment of
+ * defaults */
#define DEFAULT_GEQO_EFFORT 5
#define MIN_GEQO_EFFORT 1
#define MAX_GEQO_EFFORT 10
-extern int Geqo_pool_size; /* 2 .. inf, or 0 to use default */
+extern PGDLLIMPORT int Geqo_pool_size; /* 2 .. inf, or 0 to use default */
-extern int Geqo_generations; /* 1 .. inf, or 0 to use default */
+extern PGDLLIMPORT int Geqo_generations; /* 1 .. inf, or 0 to use default */
-extern double Geqo_selection_bias;
+extern PGDLLIMPORT double Geqo_selection_bias;
#define DEFAULT_GEQO_SELECTION_BIAS 2.0
#define MIN_GEQO_SELECTION_BIAS 1.5
#define MAX_GEQO_SELECTION_BIAS 2.0
-extern double Geqo_seed; /* 0 .. 1 */
+extern PGDLLIMPORT double Geqo_seed; /* 0 .. 1 */
/*
diff --git a/src/include/optimizer/optimizer.h b/src/include/optimizer/optimizer.h
index 2302ab6d54..d40ce2eae1 100644
--- a/src/include/optimizer/optimizer.h
+++ b/src/include/optimizer/optimizer.h
@@ -112,8 +112,8 @@ typedef enum
} ForceParallelMode;
/* GUC parameters */
-extern int force_parallel_mode;
-extern bool parallel_leader_participation;
+extern PGDLLIMPORT int force_parallel_mode;
+extern PGDLLIMPORT bool parallel_leader_participation;
extern struct PlannedStmt *planner(Query *parse, const char *query_string,
int cursorOptions,
diff --git a/src/include/optimizer/planmain.h b/src/include/optimizer/planmain.h
index 54a0d4c188..a09b3a3e83 100644
--- a/src/include/optimizer/planmain.h
+++ b/src/include/optimizer/planmain.h
@@ -19,7 +19,7 @@
/* GUC parameters */
#define DEFAULT_CURSOR_TUPLE_FRACTION 0.1
-extern double cursor_tuple_fraction;
+extern PGDLLIMPORT double cursor_tuple_fraction;
/* query_planner callback to compute query_pathkeys */
typedef void (*query_pathkeys_callback) (PlannerInfo *root, void *extra);
@@ -64,8 +64,8 @@ extern Limit *make_limit(Plan *lefttree, Node *limitOffset, Node *limitCount,
/*
* prototypes for plan/initsplan.c
*/
-extern int from_collapse_limit;
-extern int join_collapse_limit;
+extern PGDLLIMPORT int from_collapse_limit;
+extern PGDLLIMPORT int join_collapse_limit;
extern void add_base_rels_to_query(PlannerInfo *root, Node *jtnode);
extern void add_other_rels_to_query(PlannerInfo *root);
diff --git a/src/include/parser/parse_expr.h b/src/include/parser/parse_expr.h
index 308e84edda..c8e5c57b43 100644
--- a/src/include/parser/parse_expr.h
+++ b/src/include/parser/parse_expr.h
@@ -16,7 +16,7 @@
#include "parser/parse_node.h"
/* GUC parameters */
-extern bool Transform_null_equals;
+extern PGDLLIMPORT bool Transform_null_equals;
extern Node *transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind);
diff --git a/src/include/parser/parser.h b/src/include/parser/parser.h
index 6aac0e096a..828150f01b 100644
--- a/src/include/parser/parser.h
+++ b/src/include/parser/parser.h
@@ -53,8 +53,8 @@ typedef enum
} BackslashQuoteType;
/* GUC variables in scan.l (every one of these is a bad idea :-() */
-extern int backslash_quote;
-extern bool escape_string_warning;
+extern PGDLLIMPORT int backslash_quote;
+extern PGDLLIMPORT bool escape_string_warning;
extern PGDLLIMPORT bool standard_conforming_strings;
diff --git a/src/include/pg_getopt.h b/src/include/pg_getopt.h
index ec9f6e6ee3..9d91e602e6 100644
--- a/src/include/pg_getopt.h
+++ b/src/include/pg_getopt.h
@@ -33,10 +33,10 @@
*/
#ifndef HAVE_GETOPT_H
-extern char *optarg;
-extern int optind;
-extern int opterr;
-extern int optopt;
+extern PGDLLIMPORT char *optarg;
+extern PGDLLIMPORT int optind;
+extern PGDLLIMPORT int opterr;
+extern PGDLLIMPORT int optopt;
#endif /* HAVE_GETOPT_H */
@@ -45,7 +45,7 @@ extern int optopt;
* Cygwin, however, doesn't like this either.
*/
#if defined(HAVE_INT_OPTRESET) && !defined(__CYGWIN__)
-extern int optreset;
+extern PGDLLIMPORT int optreset;
#endif
/* Provide getopt() declaration if the platform doesn't have it */
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 534d595ca0..b36511a850 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -1207,9 +1207,9 @@ extern void pgstat_send_wal(bool force);
/* GUC parameters */
extern PGDLLIMPORT bool pgstat_track_counts;
extern PGDLLIMPORT int pgstat_track_functions;
-extern char *pgstat_stat_directory;
-extern char *pgstat_stat_tmpname;
-extern char *pgstat_stat_filename;
+extern PGDLLIMPORT char *pgstat_stat_directory;
+extern PGDLLIMPORT char *pgstat_stat_tmpname;
+extern PGDLLIMPORT char *pgstat_stat_filename;
/*
@@ -1217,7 +1217,7 @@ extern char *pgstat_stat_filename;
*/
/* updated directly by bgwriter and bufmgr */
-extern PgStat_MsgBgWriter PendingBgWriterStats;
+extern PGDLLIMPORT PgStat_MsgBgWriter PendingBgWriterStats;
/*
@@ -1228,7 +1228,7 @@ extern PgStat_MsgBgWriter PendingBgWriterStats;
* Checkpointer statistics counters are updated directly by checkpointer and
* bufmgr.
*/
-extern PgStat_MsgCheckpointer PendingCheckpointerStats;
+extern PGDLLIMPORT PgStat_MsgCheckpointer PendingCheckpointerStats;
/*
@@ -1236,18 +1236,18 @@ extern PgStat_MsgCheckpointer PendingCheckpointerStats;
*/
/* Updated by pgstat_count_buffer_*_time macros */
-extern PgStat_Counter pgStatBlockReadTime;
-extern PgStat_Counter pgStatBlockWriteTime;
+extern PGDLLIMPORT PgStat_Counter pgStatBlockReadTime;
+extern PGDLLIMPORT PgStat_Counter pgStatBlockWriteTime;
/*
* Updated by pgstat_count_conn_*_time macros, called by
* pgstat_report_activity().
*/
-extern PgStat_Counter pgStatActiveTime;
-extern PgStat_Counter pgStatTransactionIdleTime;
+extern PGDLLIMPORT PgStat_Counter pgStatActiveTime;
+extern PGDLLIMPORT PgStat_Counter pgStatTransactionIdleTime;
/* updated by the traffic cop and in errfinish() */
-extern SessionEndType pgStatSessionEndCause;
+extern PGDLLIMPORT SessionEndType pgStatSessionEndCause;
/*
@@ -1255,7 +1255,7 @@ extern SessionEndType pgStatSessionEndCause;
*/
/* updated directly by backends and background processes */
-extern PgStat_MsgWal WalStats;
+extern PGDLLIMPORT PgStat_MsgWal WalStats;
#endif /* PGSTAT_H */
diff --git a/src/include/pgtime.h b/src/include/pgtime.h
index 2977b13aab..5934435978 100644
--- a/src/include/pgtime.h
+++ b/src/include/pgtime.h
@@ -78,7 +78,7 @@ extern size_t pg_strftime(char *s, size_t max, const char *format,
/* these functions and variables are in pgtz.c */
extern PGDLLIMPORT pg_tz *session_timezone;
-extern pg_tz *log_timezone;
+extern PGDLLIMPORT pg_tz *log_timezone;
extern void pg_timezone_initialize(void);
extern pg_tz *pg_tzset(const char *tzname);
diff --git a/src/include/port/win32_port.h b/src/include/port/win32_port.h
index 4bb6fc5e1e..5045ced91b 100644
--- a/src/include/port/win32_port.h
+++ b/src/include/port/win32_port.h
@@ -449,8 +449,8 @@ extern char *pgwin32_setlocale(int category, const char *locale);
/* In backend/port/win32/signal.c */
extern PGDLLIMPORT volatile int pg_signal_queue;
extern PGDLLIMPORT int pg_signal_mask;
-extern HANDLE pgwin32_signal_event;
-extern HANDLE pgwin32_initial_signal_pipe;
+extern PGDLLIMPORT HANDLE pgwin32_signal_event;
+extern PGDLLIMPORT HANDLE pgwin32_initial_signal_pipe;
#define UNBLOCKED_SIGNAL_QUEUE() (pg_signal_queue & ~pg_signal_mask)
#define PG_SIGNAL_COUNT 32
@@ -485,7 +485,7 @@ int pgwin32_recv(SOCKET s, char *buf, int len, int flags);
int pgwin32_send(SOCKET s, const void *buf, int len, int flags);
int pgwin32_waitforsinglesocket(SOCKET s, int what, int timeout);
-extern int pgwin32_noblock;
+extern PGDLLIMPORT int pgwin32_noblock;
#endif /* FRONTEND */
diff --git a/src/include/port/win32ntdll.h b/src/include/port/win32ntdll.h
index 663b9754bd..291b067ea4 100644
--- a/src/include/port/win32ntdll.h
+++ b/src/include/port/win32ntdll.h
@@ -23,9 +23,9 @@
#include <ntstatus.h>
#include <winternl.h>
-typedef NTSTATUS (__stdcall *RtlGetLastNtStatus_t) (void);
+typedef NTSTATUS (__stdcall * RtlGetLastNtStatus_t) (void);
-extern RtlGetLastNtStatus_t pg_RtlGetLastNtStatus;
+extern PGDLLIMPORT RtlGetLastNtStatus_t pg_RtlGetLastNtStatus;
extern int initialize_ntdll(void);
diff --git a/src/include/postmaster/autovacuum.h b/src/include/postmaster/autovacuum.h
index 30a2b3274f..9d40fd6d54 100644
--- a/src/include/postmaster/autovacuum.h
+++ b/src/include/postmaster/autovacuum.h
@@ -27,25 +27,25 @@ typedef enum
/* GUC variables */
-extern bool autovacuum_start_daemon;
-extern int autovacuum_max_workers;
-extern int autovacuum_work_mem;
-extern int autovacuum_naptime;
-extern int autovacuum_vac_thresh;
-extern double autovacuum_vac_scale;
-extern int autovacuum_vac_ins_thresh;
-extern double autovacuum_vac_ins_scale;
-extern int autovacuum_anl_thresh;
-extern double autovacuum_anl_scale;
-extern int autovacuum_freeze_max_age;
-extern int autovacuum_multixact_freeze_max_age;
-extern double autovacuum_vac_cost_delay;
-extern int autovacuum_vac_cost_limit;
+extern PGDLLIMPORT bool autovacuum_start_daemon;
+extern PGDLLIMPORT int autovacuum_max_workers;
+extern PGDLLIMPORT int autovacuum_work_mem;
+extern PGDLLIMPORT int autovacuum_naptime;
+extern PGDLLIMPORT int autovacuum_vac_thresh;
+extern PGDLLIMPORT double autovacuum_vac_scale;
+extern PGDLLIMPORT int autovacuum_vac_ins_thresh;
+extern PGDLLIMPORT double autovacuum_vac_ins_scale;
+extern PGDLLIMPORT int autovacuum_anl_thresh;
+extern PGDLLIMPORT double autovacuum_anl_scale;
+extern PGDLLIMPORT int autovacuum_freeze_max_age;
+extern PGDLLIMPORT int autovacuum_multixact_freeze_max_age;
+extern PGDLLIMPORT double autovacuum_vac_cost_delay;
+extern PGDLLIMPORT int autovacuum_vac_cost_limit;
/* autovacuum launcher PID, only valid when worker is shutting down */
-extern int AutovacuumLauncherPid;
+extern PGDLLIMPORT int AutovacuumLauncherPid;
-extern int Log_autovacuum_min_duration;
+extern PGDLLIMPORT int Log_autovacuum_min_duration;
/* Status inquiry functions */
extern bool AutoVacuumingActive(void);
diff --git a/src/include/postmaster/bgworker_internals.h b/src/include/postmaster/bgworker_internals.h
index 75900686fc..387683546d 100644
--- a/src/include/postmaster/bgworker_internals.h
+++ b/src/include/postmaster/bgworker_internals.h
@@ -42,7 +42,7 @@ typedef struct RegisteredBgWorker
slist_node rw_lnode; /* list link */
} RegisteredBgWorker;
-extern slist_head BackgroundWorkerList;
+extern PGDLLIMPORT slist_head BackgroundWorkerList;
extern Size BackgroundWorkerShmemSize(void);
extern void BackgroundWorkerShmemInit(void);
diff --git a/src/include/postmaster/bgwriter.h b/src/include/postmaster/bgwriter.h
index 2882efd67b..2511ef451e 100644
--- a/src/include/postmaster/bgwriter.h
+++ b/src/include/postmaster/bgwriter.h
@@ -22,10 +22,10 @@
/* GUC options */
-extern int BgWriterDelay;
-extern int CheckPointTimeout;
-extern int CheckPointWarning;
-extern double CheckPointCompletionTarget;
+extern PGDLLIMPORT int BgWriterDelay;
+extern PGDLLIMPORT int CheckPointTimeout;
+extern PGDLLIMPORT int CheckPointWarning;
+extern PGDLLIMPORT double CheckPointCompletionTarget;
extern void BackgroundWriterMain(void) pg_attribute_noreturn();
extern void CheckpointerMain(void) pg_attribute_noreturn();
diff --git a/src/include/postmaster/pgarch.h b/src/include/postmaster/pgarch.h
index 9bc7593a2d..f366a159a8 100644
--- a/src/include/postmaster/pgarch.h
+++ b/src/include/postmaster/pgarch.h
@@ -36,7 +36,7 @@ extern void PgArchForceDirScan(void);
/*
* The value of the archive_library GUC.
*/
-extern char *XLogArchiveLibrary;
+extern PGDLLIMPORT char *XLogArchiveLibrary;
/*
* Archive module callbacks
diff --git a/src/include/postmaster/postmaster.h b/src/include/postmaster/postmaster.h
index 324a30ec1a..90e333ccd2 100644
--- a/src/include/postmaster/postmaster.h
+++ b/src/include/postmaster/postmaster.h
@@ -14,27 +14,27 @@
#define _POSTMASTER_H
/* GUC options */
-extern bool EnableSSL;
-extern int ReservedBackends;
+extern PGDLLIMPORT bool EnableSSL;
+extern PGDLLIMPORT int ReservedBackends;
extern PGDLLIMPORT int PostPortNumber;
-extern int Unix_socket_permissions;
-extern char *Unix_socket_group;
-extern char *Unix_socket_directories;
-extern char *ListenAddresses;
-extern bool ClientAuthInProgress;
-extern int PreAuthDelay;
-extern int AuthenticationTimeout;
-extern bool Log_connections;
-extern bool log_hostname;
-extern bool enable_bonjour;
-extern char *bonjour_name;
-extern bool restart_after_crash;
-extern bool remove_temp_files_after_crash;
+extern PGDLLIMPORT int Unix_socket_permissions;
+extern PGDLLIMPORT char *Unix_socket_group;
+extern PGDLLIMPORT char *Unix_socket_directories;
+extern PGDLLIMPORT char *ListenAddresses;
+extern PGDLLIMPORT bool ClientAuthInProgress;
+extern PGDLLIMPORT int PreAuthDelay;
+extern PGDLLIMPORT int AuthenticationTimeout;
+extern PGDLLIMPORT bool Log_connections;
+extern PGDLLIMPORT bool log_hostname;
+extern PGDLLIMPORT bool enable_bonjour;
+extern PGDLLIMPORT char *bonjour_name;
+extern PGDLLIMPORT bool restart_after_crash;
+extern PGDLLIMPORT bool remove_temp_files_after_crash;
#ifdef WIN32
-extern HANDLE PostmasterHandle;
+extern PGDLLIMPORT HANDLE PostmasterHandle;
#else
-extern int postmaster_alive_fds[2];
+extern PGDLLIMPORT int postmaster_alive_fds[2];
/*
* Constants that represent which of postmaster_alive_fds is held by
diff --git a/src/include/postmaster/startup.h b/src/include/postmaster/startup.h
index 7e39db7159..d66ec1fcb1 100644
--- a/src/include/postmaster/startup.h
+++ b/src/include/postmaster/startup.h
@@ -23,7 +23,7 @@
ereport(LOG, errmsg(msg, secs, (usecs / 10000), __VA_ARGS__ )); \
} while(0)
-extern int log_startup_progress_interval;
+extern PGDLLIMPORT int log_startup_progress_interval;
extern void HandleStartupProcInterrupts(void);
extern void StartupProcessMain(void) pg_attribute_noreturn();
diff --git a/src/include/postmaster/syslogger.h b/src/include/postmaster/syslogger.h
index 1ca326e52e..6436724f3d 100644
--- a/src/include/postmaster/syslogger.h
+++ b/src/include/postmaster/syslogger.h
@@ -67,18 +67,18 @@ typedef union
#define PIPE_PROTO_DEST_JSONLOG 0x40
/* GUC options */
-extern bool Logging_collector;
-extern int Log_RotationAge;
-extern int Log_RotationSize;
+extern PGDLLIMPORT bool Logging_collector;
+extern PGDLLIMPORT int Log_RotationAge;
+extern PGDLLIMPORT int Log_RotationSize;
extern PGDLLIMPORT char *Log_directory;
extern PGDLLIMPORT char *Log_filename;
-extern bool Log_truncate_on_rotation;
-extern int Log_file_mode;
+extern PGDLLIMPORT bool Log_truncate_on_rotation;
+extern PGDLLIMPORT int Log_file_mode;
#ifndef WIN32
-extern int syslogPipe[2];
+extern PGDLLIMPORT int syslogPipe[2];
#else
-extern HANDLE syslogPipe[2];
+extern PGDLLIMPORT HANDLE syslogPipe[2];
#endif
diff --git a/src/include/postmaster/walwriter.h b/src/include/postmaster/walwriter.h
index 5a3011d9c9..ddc943657e 100644
--- a/src/include/postmaster/walwriter.h
+++ b/src/include/postmaster/walwriter.h
@@ -13,8 +13,8 @@
#define _WALWRITER_H
/* GUC options */
-extern int WalWriterDelay;
-extern int WalWriterFlushAfter;
+extern PGDLLIMPORT int WalWriterDelay;
+extern PGDLLIMPORT int WalWriterFlushAfter;
extern void WalWriterMain(void) pg_attribute_noreturn();
diff --git a/src/include/replication/logicallauncher.h b/src/include/replication/logicallauncher.h
index 15596fe446..f1e2821e25 100644
--- a/src/include/replication/logicallauncher.h
+++ b/src/include/replication/logicallauncher.h
@@ -12,8 +12,8 @@
#ifndef LOGICALLAUNCHER_H
#define LOGICALLAUNCHER_H
-extern int max_logical_replication_workers;
-extern int max_sync_workers_per_subscription;
+extern PGDLLIMPORT int max_logical_replication_workers;
+extern PGDLLIMPORT int max_sync_workers_per_subscription;
extern void ApplyLauncherRegister(void);
extern void ApplyLauncherMain(Datum main_arg);
diff --git a/src/include/replication/syncrep.h b/src/include/replication/syncrep.h
index 27be230d77..4d7c90b9f0 100644
--- a/src/include/replication/syncrep.h
+++ b/src/include/replication/syncrep.h
@@ -72,14 +72,14 @@ typedef struct SyncRepConfigData
char member_names[FLEXIBLE_ARRAY_MEMBER];
} SyncRepConfigData;
-extern SyncRepConfigData *SyncRepConfig;
+extern PGDLLIMPORT SyncRepConfigData *SyncRepConfig;
/* communication variables for parsing synchronous_standby_names GUC */
-extern SyncRepConfigData *syncrep_parse_result;
-extern char *syncrep_parse_error_msg;
+extern PGDLLIMPORT SyncRepConfigData *syncrep_parse_result;
+extern PGDLLIMPORT char *syncrep_parse_error_msg;
/* user-settable parameters for synchronous replication */
-extern char *SyncRepStandbyNames;
+extern PGDLLIMPORT char *SyncRepStandbyNames;
/* called by user backend */
extern void SyncRepWaitForLSN(XLogRecPtr lsn, bool commit);
diff --git a/src/include/replication/walreceiver.h b/src/include/replication/walreceiver.h
index 92f73a55b8..81184aa92f 100644
--- a/src/include/replication/walreceiver.h
+++ b/src/include/replication/walreceiver.h
@@ -25,9 +25,9 @@
#include "utils/tuplestore.h"
/* user-settable parameters */
-extern int wal_receiver_status_interval;
-extern int wal_receiver_timeout;
-extern bool hot_standby_feedback;
+extern PGDLLIMPORT int wal_receiver_status_interval;
+extern PGDLLIMPORT int wal_receiver_timeout;
+extern PGDLLIMPORT bool hot_standby_feedback;
/*
* MAXCONNINFO: maximum size of a connection string.
@@ -160,7 +160,7 @@ typedef struct
sig_atomic_t force_reply; /* used as a bool */
} WalRcvData;
-extern WalRcvData *WalRcv;
+extern PGDLLIMPORT WalRcvData *WalRcv;
typedef struct
{
diff --git a/src/include/replication/walsender.h b/src/include/replication/walsender.h
index b1892e9e4b..d99a21b077 100644
--- a/src/include/replication/walsender.h
+++ b/src/include/replication/walsender.h
@@ -25,15 +25,15 @@ typedef enum
} CRSSnapshotAction;
/* global state */
-extern bool am_walsender;
-extern bool am_cascading_walsender;
-extern bool am_db_walsender;
-extern bool wake_wal_senders;
+extern PGDLLIMPORT bool am_walsender;
+extern PGDLLIMPORT bool am_cascading_walsender;
+extern PGDLLIMPORT bool am_db_walsender;
+extern PGDLLIMPORT bool wake_wal_senders;
/* user-settable parameters */
-extern int max_wal_senders;
-extern int wal_sender_timeout;
-extern bool log_replication_commands;
+extern PGDLLIMPORT int max_wal_senders;
+extern PGDLLIMPORT int wal_sender_timeout;
+extern PGDLLIMPORT bool log_replication_commands;
extern void InitWalSender(void);
extern bool exec_replication_command(const char *query_string);
diff --git a/src/include/replication/walsender_private.h b/src/include/replication/walsender_private.h
index 9631047c6c..c14888e493 100644
--- a/src/include/replication/walsender_private.h
+++ b/src/include/replication/walsender_private.h
@@ -80,7 +80,7 @@ typedef struct WalSnd
TimestampTz replyTime;
} WalSnd;
-extern WalSnd *MyWalSnd;
+extern PGDLLIMPORT WalSnd *MyWalSnd;
/* There is one WalSndCtl struct for the whole database cluster */
typedef struct
@@ -107,7 +107,7 @@ typedef struct
WalSnd walsnds[FLEXIBLE_ARRAY_MEMBER];
} WalSndCtlData;
-extern WalSndCtlData *WalSndCtl;
+extern PGDLLIMPORT WalSndCtlData *WalSndCtl;
extern void WalSndSetState(WalSndState state);
@@ -123,6 +123,6 @@ extern void replication_scanner_init(const char *query_string);
extern void replication_scanner_finish(void);
extern bool replication_scanner_is_replication_command(void);
-extern Node *replication_parse_result;
+extern PGDLLIMPORT Node *replication_parse_result;
#endif /* _WALSENDER_PRIVATE_H */
diff --git a/src/include/replication/worker_internal.h b/src/include/replication/worker_internal.h
index 3c3f5f6a3a..4485d4ebee 100644
--- a/src/include/replication/worker_internal.h
+++ b/src/include/replication/worker_internal.h
@@ -69,16 +69,16 @@ typedef struct LogicalRepWorker
} LogicalRepWorker;
/* Main memory context for apply worker. Permanent during worker lifetime. */
-extern MemoryContext ApplyContext;
+extern PGDLLIMPORT MemoryContext ApplyContext;
/* libpqreceiver connection */
-extern struct WalReceiverConn *LogRepWorkerWalRcvConn;
+extern PGDLLIMPORT struct WalReceiverConn *LogRepWorkerWalRcvConn;
/* Worker and subscription objects. */
-extern Subscription *MySubscription;
-extern LogicalRepWorker *MyLogicalRepWorker;
+extern PGDLLIMPORT Subscription *MySubscription;
+extern PGDLLIMPORT LogicalRepWorker *MyLogicalRepWorker;
-extern bool in_remote_transaction;
+extern PGDLLIMPORT bool in_remote_transaction;
extern void logicalrep_worker_attach(int slot);
extern LogicalRepWorker *logicalrep_worker_find(Oid subid, Oid relid,
diff --git a/src/include/storage/buf_internals.h b/src/include/storage/buf_internals.h
index b903d2bcaf..a17e7b28a5 100644
--- a/src/include/storage/buf_internals.h
+++ b/src/include/storage/buf_internals.h
@@ -279,7 +279,7 @@ extern PGDLLIMPORT BufferDescPadded *BufferDescriptors;
extern PGDLLIMPORT WritebackContext BackendWritebackContext;
/* in localbuf.c */
-extern BufferDesc *LocalBufferDescriptors;
+extern PGDLLIMPORT BufferDesc *LocalBufferDescriptors;
/* in bufmgr.c */
@@ -298,7 +298,7 @@ typedef struct CkptSortItem
int buf_id;
} CkptSortItem;
-extern CkptSortItem *CkptBufferIds;
+extern PGDLLIMPORT CkptSortItem *CkptBufferIds;
/*
* Internal buffer management routines
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index a6b657f0ba..58391406f6 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -65,16 +65,16 @@ struct SMgrRelationData;
extern PGDLLIMPORT int NBuffers;
/* in bufmgr.c */
-extern bool zero_damaged_pages;
-extern int bgwriter_lru_maxpages;
-extern double bgwriter_lru_multiplier;
-extern bool track_io_timing;
-extern int effective_io_concurrency;
-extern int maintenance_io_concurrency;
-
-extern int checkpoint_flush_after;
-extern int backend_flush_after;
-extern int bgwriter_flush_after;
+extern PGDLLIMPORT bool zero_damaged_pages;
+extern PGDLLIMPORT int bgwriter_lru_maxpages;
+extern PGDLLIMPORT double bgwriter_lru_multiplier;
+extern PGDLLIMPORT bool track_io_timing;
+extern PGDLLIMPORT int effective_io_concurrency;
+extern PGDLLIMPORT int maintenance_io_concurrency;
+
+extern PGDLLIMPORT int checkpoint_flush_after;
+extern PGDLLIMPORT int backend_flush_after;
+extern PGDLLIMPORT int bgwriter_flush_after;
/* in buf_init.c */
extern PGDLLIMPORT char *BufferBlocks;
diff --git a/src/include/storage/dsm_impl.h b/src/include/storage/dsm_impl.h
index f60b76f075..c51584dc6a 100644
--- a/src/include/storage/dsm_impl.h
+++ b/src/include/storage/dsm_impl.h
@@ -39,8 +39,8 @@
#endif
/* GUC. */
-extern int dynamic_shared_memory_type;
-extern int min_dynamic_shared_memory;
+extern PGDLLIMPORT int dynamic_shared_memory_type;
+extern PGDLLIMPORT int min_dynamic_shared_memory;
/*
* Directory for on-disk state.
diff --git a/src/include/storage/fd.h b/src/include/storage/fd.h
index 29209e2724..69549b000f 100644
--- a/src/include/storage/fd.h
+++ b/src/include/storage/fd.h
@@ -59,12 +59,12 @@ typedef int File;
/* GUC parameter */
extern PGDLLIMPORT int max_files_per_process;
extern PGDLLIMPORT bool data_sync_retry;
-extern int recovery_init_sync_method;
+extern PGDLLIMPORT int recovery_init_sync_method;
/*
* This is private to fd.c, but exported for save/restore_backend_variables()
*/
-extern int max_safe_fds;
+extern PGDLLIMPORT int max_safe_fds;
/*
* On Windows, we have to interpret EACCES as possibly meaning the same as
diff --git a/src/include/storage/large_object.h b/src/include/storage/large_object.h
index 274b97fd42..b826a7dcd5 100644
--- a/src/include/storage/large_object.h
+++ b/src/include/storage/large_object.h
@@ -79,7 +79,7 @@ typedef struct LargeObjectDesc
/*
* GUC: backwards-compatibility flag to suppress LO permission checks
*/
-extern bool lo_compat_privileges;
+extern PGDLLIMPORT bool lo_compat_privileges;
/*
* Function definitions...
diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h
index dc537e20f2..e4e1495b24 100644
--- a/src/include/storage/lock.h
+++ b/src/include/storage/lock.h
@@ -34,14 +34,14 @@ typedef struct PROC_QUEUE
} PROC_QUEUE;
/* GUC variables */
-extern int max_locks_per_xact;
+extern PGDLLIMPORT int max_locks_per_xact;
#ifdef LOCK_DEBUG
-extern int Trace_lock_oidmin;
-extern bool Trace_locks;
-extern bool Trace_userlocks;
-extern int Trace_lock_table;
-extern bool Debug_deadlocks;
+extern PGDLLIMPORT int Trace_lock_oidmin;
+extern PGDLLIMPORT bool Trace_locks;
+extern PGDLLIMPORT bool Trace_userlocks;
+extern PGDLLIMPORT int Trace_lock_table;
+extern PGDLLIMPORT bool Debug_deadlocks;
#endif /* LOCK_DEBUG */
@@ -154,7 +154,7 @@ typedef enum LockTagType
#define LOCKTAG_LAST_TYPE LOCKTAG_ADVISORY
-extern const char *const LockTagTypeNames[];
+extern PGDLLIMPORT const char *const LockTagTypeNames[];
/*
* The LOCKTAG struct is defined with malice aforethought to fit into 16
diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h
index c3d5889d7b..cbd5e3ebce 100644
--- a/src/include/storage/lwlock.h
+++ b/src/include/storage/lwlock.h
@@ -110,7 +110,7 @@ typedef enum LWLockMode
#ifdef LOCK_DEBUG
-extern bool Trace_lwlocks;
+extern PGDLLIMPORT bool Trace_lwlocks;
#endif
extern bool LWLockAcquire(LWLock *lock, LWLockMode mode);
diff --git a/src/include/storage/pg_shmem.h b/src/include/storage/pg_shmem.h
index 50e5c5f99b..da5962edb9 100644
--- a/src/include/storage/pg_shmem.h
+++ b/src/include/storage/pg_shmem.h
@@ -42,9 +42,9 @@ typedef struct PGShmemHeader /* standard header for all Postgres shmem */
} PGShmemHeader;
/* GUC variables */
-extern int shared_memory_type;
-extern int huge_pages;
-extern int huge_page_size;
+extern PGDLLIMPORT int shared_memory_type;
+extern PGDLLIMPORT int huge_pages;
+extern PGDLLIMPORT int huge_page_size;
/* Possible values for huge_pages */
typedef enum
@@ -63,12 +63,12 @@ typedef enum
} PGShmemType;
#ifndef WIN32
-extern unsigned long UsedShmemSegID;
+extern PGDLLIMPORT unsigned long UsedShmemSegID;
#else
-extern HANDLE UsedShmemSegID;
-extern void *ShmemProtectiveRegion;
+extern PGDLLIMPORT HANDLE UsedShmemSegID;
+extern PGDLLIMPORT void *ShmemProtectiveRegion;
#endif
-extern void *UsedShmemSegAddr;
+extern PGDLLIMPORT void *UsedShmemSegAddr;
#if !defined(WIN32) && !defined(EXEC_BACKEND)
#define DEFAULT_SHARED_MEMORY_TYPE SHMEM_TYPE_MMAP
diff --git a/src/include/storage/pmsignal.h b/src/include/storage/pmsignal.h
index ea42c2072d..58f4ddf476 100644
--- a/src/include/storage/pmsignal.h
+++ b/src/include/storage/pmsignal.h
@@ -89,7 +89,7 @@ extern void PostmasterDeathSignalInit(void);
#endif
#ifdef USE_POSTMASTER_DEATH_SIGNAL
-extern volatile sig_atomic_t postmaster_possibly_dead;
+extern PGDLLIMPORT volatile sig_atomic_t postmaster_possibly_dead;
static inline bool
PostmasterIsAlive(void)
diff --git a/src/include/storage/predicate.h b/src/include/storage/predicate.h
index ba12904f22..8dfcb3944b 100644
--- a/src/include/storage/predicate.h
+++ b/src/include/storage/predicate.h
@@ -22,9 +22,9 @@
/*
* GUC variables
*/
-extern int max_predicate_locks_per_xact;
-extern int max_predicate_locks_per_relation;
-extern int max_predicate_locks_per_page;
+extern PGDLLIMPORT int max_predicate_locks_per_xact;
+extern PGDLLIMPORT int max_predicate_locks_per_relation;
+extern PGDLLIMPORT int max_predicate_locks_per_page;
/* Number of SLRU buffers to use for Serial SLRU */
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
index 36ecf7d005..c02001d3a0 100644
--- a/src/include/storage/proc.h
+++ b/src/include/storage/proc.h
@@ -400,7 +400,7 @@ typedef struct PROC_HDR
extern PGDLLIMPORT PROC_HDR *ProcGlobal;
-extern PGPROC *PreparedXactProcs;
+extern PGDLLIMPORT PGPROC *PreparedXactProcs;
/* Accessor for PGPROC given a pgprocno. */
#define GetPGProcByNumber(n) (&ProcGlobal->allProcs[(n)])
@@ -421,7 +421,7 @@ extern PGDLLIMPORT int StatementTimeout;
extern PGDLLIMPORT int LockTimeout;
extern PGDLLIMPORT int IdleInTransactionSessionTimeout;
extern PGDLLIMPORT int IdleSessionTimeout;
-extern bool log_lock_waits;
+extern PGDLLIMPORT bool log_lock_waits;
/*
diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h
index 8a5a905e38..dae912c073 100644
--- a/src/include/storage/s_lock.h
+++ b/src/include/storage/s_lock.h
@@ -1025,7 +1025,7 @@ extern int tas(volatile slock_t *lock); /* in port/.../tas.s, or
#define TAS_SPIN(lock) TAS(lock)
#endif /* TAS_SPIN */
-extern slock_t dummy_spinlock;
+extern PGDLLIMPORT slock_t dummy_spinlock;
/*
* Platform-independent out-of-line support routines
diff --git a/src/include/storage/sinval.h b/src/include/storage/sinval.h
index 593a4211af..e7cd45658c 100644
--- a/src/include/storage/sinval.h
+++ b/src/include/storage/sinval.h
@@ -123,9 +123,9 @@ typedef union
/* Counter of messages processed; don't worry about overflow. */
-extern uint64 SharedInvalidMessageCounter;
+extern PGDLLIMPORT uint64 SharedInvalidMessageCounter;
-extern volatile sig_atomic_t catchupInterruptPending;
+extern PGDLLIMPORT volatile sig_atomic_t catchupInterruptPending;
extern void SendSharedInvalidMessages(const SharedInvalidationMessage *msgs,
int n);
diff --git a/src/include/storage/spin.h b/src/include/storage/spin.h
index 70070ca9ab..7031f1d2c5 100644
--- a/src/include/storage/spin.h
+++ b/src/include/storage/spin.h
@@ -71,7 +71,7 @@ extern Size SpinlockSemaSize(void);
#ifndef HAVE_SPINLOCKS
extern void SpinlockSemaInit(void);
-extern PGSemaphore *SpinlockSemaArray;
+extern PGDLLIMPORT PGSemaphore *SpinlockSemaArray;
#endif
#endif /* SPIN_H */
diff --git a/src/include/storage/standby.h b/src/include/storage/standby.h
index 58ea21aa13..6a7763264b 100644
--- a/src/include/storage/standby.h
+++ b/src/include/storage/standby.h
@@ -21,10 +21,10 @@
#include "storage/standbydefs.h"
/* User-settable GUC parameters */
-extern int vacuum_defer_cleanup_age;
-extern int max_standby_archive_delay;
-extern int max_standby_streaming_delay;
-extern bool log_recovery_conflict_waits;
+extern PGDLLIMPORT int vacuum_defer_cleanup_age;
+extern PGDLLIMPORT int max_standby_archive_delay;
+extern PGDLLIMPORT int max_standby_streaming_delay;
+extern PGDLLIMPORT bool log_recovery_conflict_waits;
extern void InitRecoveryTransactionEnvironment(void);
extern void ShutdownRecoveryTransactionEnvironment(void);
diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h
index 92291a750d..87e408b719 100644
--- a/src/include/tcop/tcopprot.h
+++ b/src/include/tcop/tcopprot.h
@@ -25,11 +25,11 @@
/* Required daylight between max_stack_depth and the kernel limit, in bytes */
#define STACK_DEPTH_SLOP (512 * 1024L)
-extern CommandDest whereToSendOutput;
+extern PGDLLIMPORT CommandDest whereToSendOutput;
extern PGDLLIMPORT const char *debug_query_string;
-extern int max_stack_depth;
-extern int PostAuthDelay;
-extern int client_connection_check_interval;
+extern PGDLLIMPORT int max_stack_depth;
+extern PGDLLIMPORT int PostAuthDelay;
+extern PGDLLIMPORT int client_connection_check_interval;
/* GUC-configurable parameters */
diff --git a/src/include/tsearch/ts_cache.h b/src/include/tsearch/ts_cache.h
index 5e70d74b41..5e4a49ea1c 100644
--- a/src/include/tsearch/ts_cache.h
+++ b/src/include/tsearch/ts_cache.h
@@ -84,7 +84,7 @@ typedef struct
/*
* GUC variable for current configuration
*/
-extern char *TSCurrentConfig;
+extern PGDLLIMPORT char *TSCurrentConfig;
extern TSParserCacheEntry *lookup_ts_parser_cache(Oid prsId);
diff --git a/src/include/tsearch/ts_type.h b/src/include/tsearch/ts_type.h
index 1a8bad8491..a2008f5504 100644
--- a/src/include/tsearch/ts_type.h
+++ b/src/include/tsearch/ts_type.h
@@ -169,7 +169,7 @@ typedef struct
#define OP_PHRASE 4 /* highest code, tsquery_cleanup.c */
#define OP_COUNT 4
-extern const int tsearch_op_priority[OP_COUNT];
+extern PGDLLIMPORT const int tsearch_op_priority[OP_COUNT];
/* get operation priority by its code*/
#define OP_PRIORITY(x) ( tsearch_op_priority[(x) - 1] )
diff --git a/src/include/utils/array.h b/src/include/utils/array.h
index 2dba156d35..656c766a9a 100644
--- a/src/include/utils/array.h
+++ b/src/include/utils/array.h
@@ -339,7 +339,7 @@ typedef struct ArrayIteratorData *ArrayIterator;
/*
* GUC parameter
*/
-extern bool Array_nulls;
+extern PGDLLIMPORT bool Array_nulls;
/*
* prototypes for functions defined in arrayfuncs.c
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index 666e545496..221c3e6c3d 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -64,7 +64,7 @@ extern char *regexp_fixed_prefix(text *text_re, bool case_insensitive,
Oid collation, bool *exact);
/* ruleutils.c */
-extern bool quote_all_identifiers;
+extern PGDLLIMPORT bool quote_all_identifiers;
extern const char *quote_identifier(const char *ident);
extern char *quote_qualified_identifier(const char *qualifier,
const char *ident);
diff --git a/src/include/utils/bytea.h b/src/include/utils/bytea.h
index dfef8e2d52..c3c9e54707 100644
--- a/src/include/utils/bytea.h
+++ b/src/include/utils/bytea.h
@@ -22,6 +22,7 @@ typedef enum
BYTEA_OUTPUT_HEX
} ByteaOutputType;
-extern int bytea_output; /* ByteaOutputType, but int for GUC enum */
+extern PGDLLIMPORT int bytea_output; /* ByteaOutputType, but int for GUC
+ * enum */
#endif /* BYTEA_H */
diff --git a/src/include/utils/datetime.h b/src/include/utils/datetime.h
index 0d158f3e4b..199724e5d3 100644
--- a/src/include/utils/datetime.h
+++ b/src/include/utils/datetime.h
@@ -257,9 +257,10 @@ do { \
* Include check for leap year.
*/
-extern const char *const months[]; /* months (3-char abbreviations) */
-extern const char *const days[]; /* days (full names) */
-extern const int day_tab[2][13];
+extern PGDLLIMPORT const char *const months[]; /* months (3-char
+ * abbreviations) */
+extern PGDLLIMPORT const char *const days[]; /* days (full names) */
+extern PGDLLIMPORT const int day_tab[2][13];
/*
* These are the rules for the Gregorian calendar, which was adopted in 1582.
diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h
index 3eb8de3966..f5c6cd904d 100644
--- a/src/include/utils/elog.h
+++ b/src/include/utils/elog.h
@@ -424,12 +424,12 @@ typedef enum
PGERROR_VERBOSE /* all the facts, ma'am */
} PGErrorVerbosity;
-extern int Log_error_verbosity;
-extern char *Log_line_prefix;
-extern int Log_destination;
-extern char *Log_destination_string;
-extern bool syslog_sequence_numbers;
-extern bool syslog_split_messages;
+extern PGDLLIMPORT int Log_error_verbosity;
+extern PGDLLIMPORT char *Log_line_prefix;
+extern PGDLLIMPORT int Log_destination;
+extern PGDLLIMPORT char *Log_destination_string;
+extern PGDLLIMPORT bool syslog_sequence_numbers;
+extern PGDLLIMPORT bool syslog_split_messages;
/* Log destination bitmap */
#define LOG_DESTINATION_STDERR 1
diff --git a/src/include/utils/fmgrtab.h b/src/include/utils/fmgrtab.h
index e5f53d6295..0a59937656 100644
--- a/src/include/utils/fmgrtab.h
+++ b/src/include/utils/fmgrtab.h
@@ -32,17 +32,18 @@ typedef struct
PGFunction func; /* pointer to compiled function */
} FmgrBuiltin;
-extern const FmgrBuiltin fmgr_builtins[];
+extern PGDLLIMPORT const FmgrBuiltin fmgr_builtins[];
-extern const int fmgr_nbuiltins; /* number of entries in table */
+extern PGDLLIMPORT const int fmgr_nbuiltins; /* number of entries in table */
-extern const Oid fmgr_last_builtin_oid; /* highest function OID in table */
+extern PGDLLIMPORT const Oid fmgr_last_builtin_oid; /* highest function OID in
+ * table */
/*
* Mapping from a builtin function's OID to its index in the fmgr_builtins
* array. This is indexed from 0 through fmgr_last_builtin_oid.
*/
#define InvalidOidBuiltinMapping PG_UINT16_MAX
-extern const uint16 fmgr_builtin_oid_index[];
+extern PGDLLIMPORT const uint16 fmgr_builtin_oid_index[];
#endif /* FMGRTAB_H */
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index ea774968f0..debdb4f5f1 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -239,53 +239,53 @@ typedef enum
/* GUC vars that are actually declared in guc.c, rather than elsewhere */
-extern bool Debug_print_plan;
-extern bool Debug_print_parse;
-extern bool Debug_print_rewritten;
-extern bool Debug_pretty_print;
+extern PGDLLIMPORT bool Debug_print_plan;
+extern PGDLLIMPORT bool Debug_print_parse;
+extern PGDLLIMPORT bool Debug_print_rewritten;
+extern PGDLLIMPORT bool Debug_pretty_print;
-extern bool log_parser_stats;
-extern bool log_planner_stats;
-extern bool log_executor_stats;
-extern bool log_statement_stats;
-extern bool log_btree_build_stats;
+extern PGDLLIMPORT bool log_parser_stats;
+extern PGDLLIMPORT bool log_planner_stats;
+extern PGDLLIMPORT bool log_executor_stats;
+extern PGDLLIMPORT bool log_statement_stats;
+extern PGDLLIMPORT bool log_btree_build_stats;
extern PGDLLIMPORT bool check_function_bodies;
-extern bool session_auth_is_superuser;
+extern PGDLLIMPORT bool session_auth_is_superuser;
-extern bool log_duration;
-extern int log_parameter_max_length;
-extern int log_parameter_max_length_on_error;
-extern int log_min_error_statement;
+extern PGDLLIMPORT bool log_duration;
+extern PGDLLIMPORT int log_parameter_max_length;
+extern PGDLLIMPORT int log_parameter_max_length_on_error;
+extern PGDLLIMPORT int log_min_error_statement;
extern PGDLLIMPORT int log_min_messages;
extern PGDLLIMPORT int client_min_messages;
-extern int log_min_duration_sample;
-extern int log_min_duration_statement;
-extern int log_temp_files;
-extern double log_statement_sample_rate;
-extern double log_xact_sample_rate;
-extern char *backtrace_functions;
-extern char *backtrace_symbol_list;
+extern PGDLLIMPORT int log_min_duration_sample;
+extern PGDLLIMPORT int log_min_duration_statement;
+extern PGDLLIMPORT int log_temp_files;
+extern PGDLLIMPORT double log_statement_sample_rate;
+extern PGDLLIMPORT double log_xact_sample_rate;
+extern PGDLLIMPORT char *backtrace_functions;
+extern PGDLLIMPORT char *backtrace_symbol_list;
-extern int temp_file_limit;
+extern PGDLLIMPORT int temp_file_limit;
-extern int num_temp_buffers;
+extern PGDLLIMPORT int num_temp_buffers;
extern PGDLLIMPORT char *cluster_name;
extern PGDLLIMPORT char *ConfigFileName;
-extern char *HbaFileName;
-extern char *IdentFileName;
-extern char *external_pid_file;
+extern PGDLLIMPORT char *HbaFileName;
+extern PGDLLIMPORT char *IdentFileName;
+extern PGDLLIMPORT char *external_pid_file;
extern PGDLLIMPORT char *application_name;
-extern int tcp_keepalives_idle;
-extern int tcp_keepalives_interval;
-extern int tcp_keepalives_count;
-extern int tcp_user_timeout;
+extern PGDLLIMPORT int tcp_keepalives_idle;
+extern PGDLLIMPORT int tcp_keepalives_interval;
+extern PGDLLIMPORT int tcp_keepalives_count;
+extern PGDLLIMPORT int tcp_user_timeout;
#ifdef TRACE_SORT
-extern bool trace_sort;
+extern PGDLLIMPORT bool trace_sort;
#endif
/*
diff --git a/src/include/utils/guc_tables.h b/src/include/utils/guc_tables.h
index f7e54a87b7..9a55d0241b 100644
--- a/src/include/utils/guc_tables.h
+++ b/src/include/utils/guc_tables.h
@@ -248,10 +248,10 @@ struct config_enum
};
/* constant tables corresponding to enums above and in guc.h */
-extern const char *const config_group_names[];
-extern const char *const config_type_names[];
-extern const char *const GucContext_Names[];
-extern const char *const GucSource_Names[];
+extern PGDLLIMPORT const char *const config_group_names[];
+extern PGDLLIMPORT const char *const config_type_names[];
+extern PGDLLIMPORT const char *const GucContext_Names[];
+extern PGDLLIMPORT const char *const GucSource_Names[];
/* get the current set of variables */
extern struct config_generic **get_guc_variables(void);
diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h
index a44e17ffdf..e7385faef8 100644
--- a/src/include/utils/pg_locale.h
+++ b/src/include/utils/pg_locale.h
@@ -38,16 +38,16 @@
#define LOCALE_NAME_BUFLEN 128
/* GUC settings */
-extern char *locale_messages;
-extern char *locale_monetary;
-extern char *locale_numeric;
-extern char *locale_time;
+extern PGDLLIMPORT char *locale_messages;
+extern PGDLLIMPORT char *locale_monetary;
+extern PGDLLIMPORT char *locale_numeric;
+extern PGDLLIMPORT char *locale_time;
/* lc_time localization cache */
-extern char *localized_abbrev_days[];
-extern char *localized_full_days[];
-extern char *localized_abbrev_months[];
-extern char *localized_full_months[];
+extern PGDLLIMPORT char *localized_abbrev_days[];
+extern PGDLLIMPORT char *localized_full_days[];
+extern PGDLLIMPORT char *localized_abbrev_months[];
+extern PGDLLIMPORT char *localized_full_months[];
extern bool check_locale_messages(char **newval, void **extra, GucSource source);
@@ -103,7 +103,7 @@ struct pg_locale_struct
typedef struct pg_locale_struct *pg_locale_t;
-extern struct pg_locale_struct default_locale;
+extern PGDLLIMPORT struct pg_locale_struct default_locale;
extern void make_icu_collator(const char *iculocstr,
struct pg_locale_struct *resultp);
diff --git a/src/include/utils/pgstat_internal.h b/src/include/utils/pgstat_internal.h
index abbb4f8d96..44f7de0baa 100644
--- a/src/include/utils/pgstat_internal.h
+++ b/src/include/utils/pgstat_internal.h
@@ -133,29 +133,29 @@ extern bool pgstat_wal_pending(void);
* Variables in pgstat.c
*/
-extern pgsocket pgStatSock;
+extern PGDLLIMPORT pgsocket pgStatSock;
/*
* Variables in pgstat_database.c
*/
-extern int pgStatXactCommit;
-extern int pgStatXactRollback;
+extern PGDLLIMPORT int pgStatXactCommit;
+extern PGDLLIMPORT int pgStatXactRollback;
/*
* Variables in pgstat_functions.c
*/
-extern bool have_function_stats;
+extern PGDLLIMPORT bool have_function_stats;
/*
* Variables in pgstat_relation.c
*/
-extern bool have_relation_stats;
+extern PGDLLIMPORT bool have_relation_stats;
#endif /* PGSTAT_INTERNAL_H */
diff --git a/src/include/utils/plancache.h b/src/include/utils/plancache.h
index 95b99e3d25..0499635f59 100644
--- a/src/include/utils/plancache.h
+++ b/src/include/utils/plancache.h
@@ -35,7 +35,7 @@ typedef enum
} PlanCacheMode;
/* GUC parameter */
-extern int plan_cache_mode;
+extern PGDLLIMPORT int plan_cache_mode;
#define CACHEDPLANSOURCE_MAGIC 195726186
#define CACHEDPLAN_MAGIC 953717834
diff --git a/src/include/utils/ps_status.h b/src/include/utils/ps_status.h
index 9f43e1fdf0..bba463591f 100644
--- a/src/include/utils/ps_status.h
+++ b/src/include/utils/ps_status.h
@@ -12,7 +12,7 @@
#ifndef PS_STATUS_H
#define PS_STATUS_H
-extern bool update_process_title;
+extern PGDLLIMPORT bool update_process_title;
extern char **save_ps_display_args(int argc, char **argv);
diff --git a/src/include/utils/queryjumble.h b/src/include/utils/queryjumble.h
index c670662db2..3c2d9beab2 100644
--- a/src/include/utils/queryjumble.h
+++ b/src/include/utils/queryjumble.h
@@ -62,14 +62,14 @@ enum ComputeQueryIdType
};
/* GUC parameters */
-extern int compute_query_id;
+extern PGDLLIMPORT int compute_query_id;
extern const char *CleanQuerytext(const char *query, int *location, int *len);
extern JumbleState *JumbleQuery(Query *query, const char *querytext);
extern void EnableQueryId(void);
-extern bool query_id_enabled;
+extern PGDLLIMPORT bool query_id_enabled;
/*
* Returns whether query identifier computation has been enabled, either
diff --git a/src/include/utils/relcache.h b/src/include/utils/relcache.h
index 2281a7dc53..86dddbd975 100644
--- a/src/include/utils/relcache.h
+++ b/src/include/utils/relcache.h
@@ -145,9 +145,9 @@ extern void RelationCacheInitFilePostInvalidate(void);
extern void RelationCacheInitFileRemove(void);
/* should be used only by relcache.c and catcache.c */
-extern bool criticalRelcachesBuilt;
+extern PGDLLIMPORT bool criticalRelcachesBuilt;
/* should be used only by relcache.c and postinit.c */
-extern bool criticalSharedRelcachesBuilt;
+extern PGDLLIMPORT bool criticalSharedRelcachesBuilt;
#endif /* RELCACHE_H */
diff --git a/src/include/utils/rls.h b/src/include/utils/rls.h
index c1896d6735..75259cc1f7 100644
--- a/src/include/utils/rls.h
+++ b/src/include/utils/rls.h
@@ -14,7 +14,7 @@
#define RLS_H
/* GUC variable */
-extern bool row_security;
+extern PGDLLIMPORT bool row_security;
/*
* Used by callers of check_enable_rls.
diff --git a/src/include/utils/snapmgr.h b/src/include/utils/snapmgr.h
index e04018c034..67b217b1c1 100644
--- a/src/include/utils/snapmgr.h
+++ b/src/include/utils/snapmgr.h
@@ -53,7 +53,7 @@ extern TimestampTz GetSnapshotCurrentTimestamp(void);
extern TimestampTz GetOldSnapshotThresholdTimestamp(void);
extern void SnapshotTooOldMagicForTest(void);
-extern bool FirstSnapshotSet;
+extern PGDLLIMPORT bool FirstSnapshotSet;
extern PGDLLIMPORT TransactionId TransactionXmin;
extern PGDLLIMPORT TransactionId RecentXmin;
diff --git a/src/include/utils/timestamp.h b/src/include/utils/timestamp.h
index c1a74f8e2b..bd86c523c0 100644
--- a/src/include/utils/timestamp.h
+++ b/src/include/utils/timestamp.h
@@ -57,10 +57,10 @@
/* Set at postmaster start */
-extern TimestampTz PgStartTime;
+extern PGDLLIMPORT TimestampTz PgStartTime;
/* Set at configuration reload */
-extern TimestampTz PgReloadTime;
+extern PGDLLIMPORT TimestampTz PgReloadTime;
/* Internal routines (not fmgr-callable) */
diff --git a/src/include/utils/xml.h b/src/include/utils/xml.h
index c1de08d15b..6620a62619 100644
--- a/src/include/utils/xml.h
+++ b/src/include/utils/xml.h
@@ -75,10 +75,10 @@ extern char *map_sql_identifier_to_xml_name(const char *ident, bool fully_escape
extern char *map_xml_name_to_sql_identifier(const char *name);
extern char *map_sql_value_to_xml_value(Datum value, Oid type, bool xml_escape_strings);
-extern int xmlbinary; /* XmlBinaryType, but int for guc enum */
+extern PGDLLIMPORT int xmlbinary; /* XmlBinaryType, but int for guc enum */
-extern int xmloption; /* XmlOptionType, but int for guc enum */
+extern PGDLLIMPORT int xmloption; /* XmlOptionType, but int for guc enum */
-extern const TableFuncRoutine XmlTableRoutine;
+extern PGDLLIMPORT const TableFuncRoutine XmlTableRoutine;
#endif /* XML_H */
--
2.24.3 (Apple Git-128)
On 3/30/22 14:37, Robert Haas wrote:
On Fri, Feb 18, 2022 at 7:02 PM Andres Freund <andres@anarazel.de> wrote:
On 2022-02-15 08:06:58 -0800, Andres Freund wrote:
The more I think about it the more I'm convinced that if we want to do this,
we should do it for variables and functions.Btw, if we were to do this, we should just use -fvisibility=hidden everywhere
and would see the same set of failures on unixoid systems as on windows. Of
course only in in-core extensions, but it'd still be better than nothing.Let's be less ambitious for this release, and just get the variables
marked with PGDLLIMPORT. We seem to have consensus to create parity
between Windows and non-Windows builds, which means precisely applying
PGDLLIMPORT to variables marked in header files, and nothing more. The
merits of -fvisibility=hidden or PGDLLIMPORT on functions are a
separate question that can be debated on its own merits, but I don't
want that larger discussion to bog down this effort. Here are updated
patches for that.@RMT: Andres proposed upthread that we should plan to do this just
after feature freeze. Accordingly I propose to commit at least 0002
and perhaps 0001 if people want it just after feature freeze. I
therefore ask that the RMT either (a) regard this change as not being
a feature (and thus not subject to the freeze) or (b) give it a 1-day
extension. The reason for committing it just after freeze is to
minimize the number of conflicts that it creates for other patches.
The reason why that's probably an OK thing to do is that applying
PGDLLIMPORT markings is low-risk.Thanks,
WFM. I think Tom also has an item he wants to do right at the end of
feature freeze.
The script looks fine, needs a copyright notice and a comment at the top
describing what it does. It seems like something we might need to do
from time to time, as it will be easy to forget to mark variables and we
should periodically run this as a check.
cheers
andrew
--
Andrew Dunstan
EDB: https://www.enterprisedb.com
Andrew Dunstan <andrew@dunslane.net> writes:
On 3/30/22 14:37, Robert Haas wrote:
@RMT: Andres proposed upthread that we should plan to do this just
after feature freeze. Accordingly I propose to commit at least 0002
and perhaps 0001 if people want it just after feature freeze. I
therefore ask that the RMT either (a) regard this change as not being
a feature (and thus not subject to the freeze) or (b) give it a 1-day
extension. The reason for committing it just after freeze is to
minimize the number of conflicts that it creates for other patches.
The reason why that's probably an OK thing to do is that applying
PGDLLIMPORT markings is low-risk.
WFM. I think Tom also has an item he wants to do right at the end of
feature freeze.
Yeah, the frontend error message rework in [1]https://commitfest.postgresql.org/37/3574/. That has exactly
the same constraint that it's likely to break other open patches,
so it'd be better to do it after the CF cutoff. I think that doing
that concurrently with Robert's thing shouldn't be too risky, because
it only affects frontend code while his patch should touch only backend.
regards, tom lane
On Tue, Apr 5, 2022 at 10:07 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
Yeah, the frontend error message rework in [1]. That has exactly
the same constraint that it's likely to break other open patches,
so it'd be better to do it after the CF cutoff. I think that doing
that concurrently with Robert's thing shouldn't be too risky, because
it only affects frontend code while his patch should touch only backend.
So when *exactly* do we want to land these patches? None of the
calendar programs I use support "anywhere on earth" as a time zone,
but I think that feature freeze is 8am on Friday on the East coast of
the United States. If I commit the PGDLLIMPORT change within a few
hours after that time, is that good? Should I try to do it earlier,
before we technically hit 8am? Should I do it the night before, last
thing before I go to bed on Thursday? Do you care whether your commit
or mine goes in first?
--
Robert Haas
EDB: http://www.enterprisedb.com
On Tue, Apr 5, 2022 at 10:06 PM Robert Haas <robertmhaas@gmail.com> wrote:
On Tue, Apr 5, 2022 at 10:07 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
Yeah, the frontend error message rework in [1]. That has exactly
the same constraint that it's likely to break other open patches,
so it'd be better to do it after the CF cutoff. I think that doing
that concurrently with Robert's thing shouldn't be too risky, because
it only affects frontend code while his patch should touch only backend.So when *exactly* do we want to land these patches? None of the
calendar programs I use support "anywhere on earth" as a time zone,
but I think that feature freeze is 8am on Friday on the East coast of
the United States.
I understand it to be noon UTC on Friday.
If I commit the PGDLLIMPORT change within a few
hours after that time, is that good? Should I try to do it earlier,
before we technically hit 8am? Should I do it the night before, last
thing before I go to bed on Thursday? Do you care whether your commit
or mine goes in first?
For these two patches, I'd say a day or two after feature freeze is a
reasonable goal.
--
John Naylor
EDB: http://www.enterprisedb.com
Robert Haas <robertmhaas@gmail.com> writes:
Do you care whether your commit
or mine goes in first?
I do not. If they're not independent, at least one of us has messed up.
I have family commitments on Saturday, so if I don't get mine in
on Friday it'll likely not happen before Sunday.
regards, tom lane
On Wed, Apr 06, 2022 at 12:57:29AM +0700, John Naylor wrote:
For these two patches, I'd say a day or two after feature freeze is a
reasonable goal.
Yeah. For patches as invasive as the PGDLLIMPORT business and the
frontend error refactoring, I am also fine to have two exceptions with
the freeze deadline.
--
Michael
On Wed, Apr 6, 2022 at 7:56 PM Michael Paquier <michael@paquier.xyz> wrote:
On Wed, Apr 06, 2022 at 12:57:29AM +0700, John Naylor wrote:
For these two patches, I'd say a day or two after feature freeze is a
reasonable goal.Yeah. For patches as invasive as the PGDLLIMPORT business and the
frontend error refactoring, I am also fine to have two exceptions with
the freeze deadline.
Done now.
--
Robert Haas
EDB: http://www.enterprisedb.com
On Fri, Apr 8, 2022 at 2:42 PM Robert Haas <robertmhaas@gmail.com> wrote:
On Wed, Apr 6, 2022 at 7:56 PM Michael Paquier <michael@paquier.xyz>
wrote:On Wed, Apr 06, 2022 at 12:57:29AM +0700, John Naylor wrote:
For these two patches, I'd say a day or two after feature freeze is a
reasonable goal.Yeah. For patches as invasive as the PGDLLIMPORT business and the
frontend error refactoring, I am also fine to have two exceptions with
the freeze deadline.Done now.
\o/
--
Magnus Hagander
Me: https://www.hagander.net/ <http://www.hagander.net/>
Work: https://www.redpill-linpro.com/ <http://www.redpill-linpro.com/>
On Fri, Apr 08, 2022 at 03:04:18PM +0200, Magnus Hagander wrote:
On Fri, Apr 8, 2022 at 2:42 PM Robert Haas <robertmhaas@gmail.com> wrote:
On Wed, Apr 6, 2022 at 7:56 PM Michael Paquier <michael@paquier.xyz>
wrote:On Wed, Apr 06, 2022 at 12:57:29AM +0700, John Naylor wrote:
For these two patches, I'd say a day or two after feature freeze is a
reasonable goal.Yeah. For patches as invasive as the PGDLLIMPORT business and the
frontend error refactoring, I am also fine to have two exceptions with
the freeze deadline.Done now.
\o/
Woohoo! Thanks a lot!
Hi,
On 2022-04-08 08:42:38 -0400, Robert Haas wrote:
On Wed, Apr 6, 2022 at 7:56 PM Michael Paquier <michael@paquier.xyz> wrote:
On Wed, Apr 06, 2022 at 12:57:29AM +0700, John Naylor wrote:
For these two patches, I'd say a day or two after feature freeze is a
reasonable goal.Yeah. For patches as invasive as the PGDLLIMPORT business and the
frontend error refactoring, I am also fine to have two exceptions with
the freeze deadline.Done now.
Just noticed that
extern sigset_t UnBlockSig,
BlockSig,
StartupBlockSig;
are unadorned.
There's also a number of variables that are only declared in .c files that
!windows can still access. Some likely aren't worth caring about, but some
others are underlying GUCs, so we probably do? E.g.
CommitDelay
CommitSiblings
default_tablespace
ignore_checksum_failure
ignore_invalid_pages
Log_disconnections
ssl_renegotiation_limit
temp_tablespaces
Unix_socket_group
Unix_socket_permissions
wal_level_options
Likely don't care:
dynamic_shared_memory_options
gistBufferingOptValues
recovery_target_action_options
ssl_protocol_versions_info
Also noticed that the bbsink_ops variables are const, instead of static const,
was that intentional?
Greetings,
Andres Freund
On Fri, May 06, 2022 at 04:49:24PM -0700, Andres Freund wrote:
Just noticed that
extern sigset_t UnBlockSig,
BlockSig,
StartupBlockSig;
are unadorned.
mark_pgdllimport.pl is not able to capture this part of the change
because of this logic, where we assume that the header line has to
finish with a semicolon:
# Variable declarations should end in a semicolon. If we see an
# opening parenthesis, it's probably a function declaration.
$needs_pgdllimport = 0 if $stripped_line !~ /;$/ ||
$stripped_line =~ /\(/;
It is quite common to define one variable per line, so I would not put
the blame on the script and just update pqsignal.h. And it is common
to finish lines with a comma for function declarations..
There's also a number of variables that are only declared in .c files that
!windows can still access. Some likely aren't worth caring about, but some
others are underlying GUCs, so we probably do? E.g.
CommitDelay
CommitSiblings
default_tablespace
ignore_checksum_failure
ignore_invalid_pages
Log_disconnections
ssl_renegotiation_limit
temp_tablespaces
wal_level_options
These are indeed declared in .c files. So you mean that we'd better
declare them in headers and mark them as PGDLLIMPORT? I am not sure
if that's worth the addition, nobody has asked for these to be
available yet, AFAIK.
Unix_socket_group
Unix_socket_permissions
Already marked with PGDLLIMPORT.
Also noticed that the bbsink_ops variables are const, instead of static const,
was that intentional?
Yep, that looks like an error.
While on it, I think that it would be a good idea to document in the
script that we need pass down a list of header files as arguments to
rewrite them.
--
Michael
On Mon, May 9, 2022 at 3:15 AM Michael Paquier <michael@paquier.xyz> wrote:
On Fri, May 06, 2022 at 04:49:24PM -0700, Andres Freund wrote:
Just noticed that
extern sigset_t UnBlockSig,
BlockSig,
StartupBlockSig;
are unadorned.mark_pgdllimport.pl is not able to capture this part of the change
because of this logic, where we assume that the header line has to
finish with a semicolon:
# Variable declarations should end in a semicolon. If we see an
# opening parenthesis, it's probably a function declaration.
$needs_pgdllimport = 0 if $stripped_line !~ /;$/ ||
$stripped_line =~ /\(/;It is quite common to define one variable per line, so I would not put
the blame on the script and just update pqsignal.h. And it is common
to finish lines with a comma for function declarations..
Right. I didn't try to equip the script with a real C parser. Just
enough to catch our typical style - which those declarations aren't.
There's also a number of variables that are only declared in .c files that
!windows can still access. Some likely aren't worth caring about, but some
others are underlying GUCs, so we probably do? E.g.
CommitDelay
CommitSiblings
default_tablespace
ignore_checksum_failure
ignore_invalid_pages
Log_disconnections
ssl_renegotiation_limit
temp_tablespaces
wal_level_optionsThese are indeed declared in .c files. So you mean that we'd better
declare them in headers and mark them as PGDLLIMPORT? I am not sure
if that's worth the addition, nobody has asked for these to be
available yet, AFAIK.
Completely agree. The agreed-upon charter was to adjust the header
files, not move any declarations into header files. I'm not against
doing that; I think it's good for extensions to have access to GUC
values. But it wasn't the mission.
Also noticed that the bbsink_ops variables are const, instead of static const,
was that intentional?Yep, that looks like an error.
While on it, I think that it would be a good idea to document in the
script that we need pass down a list of header files as arguments to
rewrite them.
Either of you please feel free to change these things, at least as far
as I'm concerned.
--
Robert Haas
EDB: http://www.enterprisedb.com
On Mon, May 09, 2022 at 09:23:47AM -0400, Robert Haas wrote:
Either of you please feel free to change these things, at least as far
as I'm concerned.
Well, what about the attached then? While looking at all the headers
in the tree, I have noticed that __pg_log_level is not marked, but
we'd better paint a PGDLLIMPORT also for it? This is getting used by
pgbench for some unlikely() business, as one example.
--
Michael
Attachments:
dllimport-missed.patchtext/x-diff; charset=us-asciiDownload
diff --git a/src/include/common/logging.h b/src/include/common/logging.h
index 9f426c32d6..2ab9f0ea50 100644
--- a/src/include/common/logging.h
+++ b/src/include/common/logging.h
@@ -51,7 +51,7 @@ enum pg_log_level
/*
* __pg_log_level is the minimum log level that will actually be shown.
*/
-extern enum pg_log_level __pg_log_level;
+extern PGDLLIMPORT enum pg_log_level __pg_log_level;
/*
* A log message can have several parts. The primary message is required,
diff --git a/src/include/libpq/pqsignal.h b/src/include/libpq/pqsignal.h
index 016fc89bd9..41227a30e2 100644
--- a/src/include/libpq/pqsignal.h
+++ b/src/include/libpq/pqsignal.h
@@ -30,9 +30,9 @@ extern int pqsigsetmask(int mask);
#define sigdelset(set, signum) (*(set) &= ~(sigmask(signum)))
#endif /* WIN32 */
-extern sigset_t UnBlockSig,
- BlockSig,
- StartupBlockSig;
+extern PGDLLIMPORT sigset_t UnBlockSig;
+extern PGDLLIMPORT sigset_t BlockSig;
+extern PGDLLIMPORT sigset_t StartupBlockSig;
extern void pqinitmask(void);
diff --git a/src/tools/mark_pgdllimport.pl b/src/tools/mark_pgdllimport.pl
index 83b90db6ef..834fcac5b5 100755
--- a/src/tools/mark_pgdllimport.pl
+++ b/src/tools/mark_pgdllimport.pl
@@ -12,7 +12,8 @@
# smart and may not catch all cases.
#
# It's probably a good idea to run pgindent on any files that this
-# script modifies before committing.
+# script modifies before committing. This script uses as arguments
+# a list of the header files to scan for the markings.
#
# Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
# Portions Copyright (c) 1994, Regents of the University of California
On Tue, May 10, 2022 at 04:09:47PM +0900, Michael Paquier wrote:
Well, what about the attached then? While looking at all the headers
in the tree, I have noticed that __pg_log_level is not marked, but
we'd better paint a PGDLLIMPORT also for it? This is getting used by
pgbench for some unlikely() business, as one example.
After an extra look, PGDLLIMPORT missing from __pg_log_level looks
like an imbroglio between 8ec5694, that has added the marking, and
9a374b77 that has removed it the same day. All that has been fixed in
5edeb57.
--
Michael
Hi,
On 2022-05-12 15:15:10 +0900, Michael Paquier wrote:
On Tue, May 10, 2022 at 04:09:47PM +0900, Michael Paquier wrote:
Well, what about the attached then? While looking at all the headers
in the tree, I have noticed that __pg_log_level is not marked, but
we'd better paint a PGDLLIMPORT also for it? This is getting used by
pgbench for some unlikely() business, as one example.After an extra look, PGDLLIMPORT missing from __pg_log_level looks
like an imbroglio between 8ec5694, that has added the marking, and
9a374b77 that has removed it the same day. All that has been fixed in
5edeb57.
It seems pretty nonsensical to add PGDLLIMPORT to frontend only headers /
variables. What is that supposed to mean?
Greetings,
Andres Freund
Andres Freund <andres@anarazel.de> writes:
On 2022-05-12 15:15:10 +0900, Michael Paquier wrote:
After an extra look, PGDLLIMPORT missing from __pg_log_level looks
like an imbroglio between 8ec5694, that has added the marking, and
9a374b77 that has removed it the same day. All that has been fixed in
5edeb57.
It seems pretty nonsensical to add PGDLLIMPORT to frontend only headers /
variables. What is that supposed to mean?
Yeah, that's why I removed it in 9a374b77.
regards, tom lane
On Thu, May 12, 2022 at 11:59:49AM -0400, Tom Lane wrote:
It seems pretty nonsensical to add PGDLLIMPORT to frontend only headers /
variables. What is that supposed to mean?Yeah, that's why I removed it in 9a374b77.
Perhaps we should try to remove it from the header itself in the long
run, even if that's used in a couple of macros? pgbench relies on it
to avoid building a debug string for a meta-command, and logging.h has
it in those compat macros.. I won't fight on that, though.
Anyway, I'll go remove the marking. My apologies for the noise.
--
Michael