summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/transam/xlog.c2
-rw-r--r--src/backend/access/transam/xloginsert.c15
-rw-r--r--src/backend/catalog/pg_constraint.c10
-rw-r--r--src/backend/catalog/system_views.sql1
-rw-r--r--src/backend/commands/subscriptioncmds.c4
-rw-r--r--src/backend/executor/instrument.c2
-rw-r--r--src/backend/parser/parser.c8
-rw-r--r--src/backend/parser/scan.l8
-rw-r--r--src/backend/replication/logical/launcher.c40
-rw-r--r--src/backend/replication/logical/syncutils.c3
-rw-r--r--src/backend/replication/logical/tablesync.c11
-rw-r--r--src/backend/replication/logical/worker.c8
-rw-r--r--src/backend/utils/activity/pgstat_backend.c1
-rw-r--r--src/backend/utils/activity/pgstat_wal.c1
-rw-r--r--src/backend/utils/adt/formatting.c341
-rw-r--r--src/backend/utils/adt/jsonpath_scan.l6
-rw-r--r--src/backend/utils/adt/pg_locale_builtin.c44
-rw-r--r--src/backend/utils/adt/pg_locale_icu.c5
-rw-r--r--src/backend/utils/adt/pg_locale_libc.c3
-rw-r--r--src/backend/utils/adt/pgstatfuncs.c20
-rw-r--r--src/backend/utils/adt/selfuncs.c7
-rw-r--r--src/backend/utils/adt/varlena.c40
-rw-r--r--src/backend/utils/cache/relcache.c12
-rw-r--r--src/backend/utils/mb/mbutils.c4
-rw-r--r--src/backend/utils/misc/gen_guc_tables.pl53
-rw-r--r--src/backend/utils/misc/guc.c847
-rw-r--r--src/backend/utils/misc/guc_funcs.c14
-rw-r--r--src/backend/utils/misc/help_config.c59
-rw-r--r--src/bin/pg_verifybackup/pg_verifybackup.c4
-rw-r--r--src/bin/pg_verifybackup/pg_verifybackup.h4
-rw-r--r--src/bin/psql/prompt.c11
-rw-r--r--src/common/logging.c4
-rw-r--r--src/common/saslprep.c48
-rw-r--r--src/common/string.c2
-rw-r--r--src/common/unicode/case_test.c23
-rw-r--r--src/common/unicode/category_test.c3
-rw-r--r--src/common/unicode/generate-norm_test_table.pl4
-rw-r--r--src/common/unicode/generate-unicode_case_table.pl7
-rw-r--r--src/common/unicode/generate-unicode_category_table.pl8
-rw-r--r--src/common/unicode/norm_test.c6
-rw-r--r--src/common/unicode_case.c56
-rw-r--r--src/common/unicode_category.c50
-rw-r--r--src/common/unicode_norm.c56
-rw-r--r--src/fe_utils/mbprint.c10
-rw-r--r--src/include/access/xlog.h1
-rw-r--r--src/include/c.h31
-rw-r--r--src/include/catalog/catversion.h2
-rw-r--r--src/include/catalog/pg_proc.dat12
-rw-r--r--src/include/common/logging.h4
-rw-r--r--src/include/common/string.h2
-rw-r--r--src/include/common/unicode_case.h10
-rw-r--r--src/include/common/unicode_case_table.h13
-rw-r--r--src/include/common/unicode_category.h46
-rw-r--r--src/include/common/unicode_category_table.h8
-rw-r--r--src/include/common/unicode_norm.h6
-rw-r--r--src/include/executor/instrument.h1
-rw-r--r--src/include/libpq/pqformat.h12
-rw-r--r--src/include/mb/pg_wchar.h32
-rw-r--r--src/include/pg_config.h.in7
-rw-r--r--src/include/pgstat.h3
-rw-r--r--src/include/replication/worker_internal.h9
-rw-r--r--src/include/utils/guc_tables.h180
-rw-r--r--src/interfaces/libpq/t/006_service.pl12
-rw-r--r--src/test/ldap/t/003_ldap_connection_param_lookup.pl43
-rw-r--r--src/test/regress/expected/rules.out3
-rw-r--r--src/tools/pgindent/typedefs.list3
66 files changed, 1114 insertions, 1191 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index eceab341255..fd91bcd68ec 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -749,6 +749,7 @@ XLogInsertRecord(XLogRecData *rdata,
XLogRecPtr fpw_lsn,
uint8 flags,
int num_fpi,
+ uint64 fpi_bytes,
bool topxid_included)
{
XLogCtlInsert *Insert = &XLogCtl->Insert;
@@ -1081,6 +1082,7 @@ XLogInsertRecord(XLogRecData *rdata,
pgWalUsage.wal_bytes += rechdr->xl_tot_len;
pgWalUsage.wal_records++;
pgWalUsage.wal_fpi += num_fpi;
+ pgWalUsage.wal_fpi_bytes += fpi_bytes;
/* Required for the flush of pending stats WAL data */
pgstat_report_fixed = true;
diff --git a/src/backend/access/transam/xloginsert.c b/src/backend/access/transam/xloginsert.c
index 496e0fa4ac6..58cb4b1b00c 100644
--- a/src/backend/access/transam/xloginsert.c
+++ b/src/backend/access/transam/xloginsert.c
@@ -33,12 +33,14 @@
#include "access/xloginsert.h"
#include "catalog/pg_control.h"
#include "common/pg_lzcompress.h"
+#include "executor/instrument.h"
#include "miscadmin.h"
#include "pg_trace.h"
#include "replication/origin.h"
#include "storage/bufmgr.h"
#include "storage/proc.h"
#include "utils/memutils.h"
+#include "utils/pgstat_internal.h"
/*
* Guess the maximum buffer size required to store a compressed version of
@@ -137,6 +139,7 @@ static MemoryContext xloginsert_cxt;
static XLogRecData *XLogRecordAssemble(RmgrId rmid, uint8 info,
XLogRecPtr RedoRecPtr, bool doPageWrites,
XLogRecPtr *fpw_lsn, int *num_fpi,
+ uint64 *fpi_bytes,
bool *topxid_included);
static bool XLogCompressBackupBlock(const PageData *page, uint16 hole_offset,
uint16 hole_length, void *dest, uint16 *dlen);
@@ -510,6 +513,7 @@ XLogInsert(RmgrId rmid, uint8 info)
XLogRecPtr fpw_lsn;
XLogRecData *rdt;
int num_fpi = 0;
+ uint64 fpi_bytes = 0;
/*
* Get values needed to decide whether to do full-page writes. Since
@@ -519,10 +523,11 @@ XLogInsert(RmgrId rmid, uint8 info)
GetFullPageWriteInfo(&RedoRecPtr, &doPageWrites);
rdt = XLogRecordAssemble(rmid, info, RedoRecPtr, doPageWrites,
- &fpw_lsn, &num_fpi, &topxid_included);
+ &fpw_lsn, &num_fpi, &fpi_bytes,
+ &topxid_included);
EndPos = XLogInsertRecord(rdt, fpw_lsn, curinsert_flags, num_fpi,
- topxid_included);
+ fpi_bytes, topxid_included);
} while (EndPos == InvalidXLogRecPtr);
XLogResetInsertion();
@@ -560,7 +565,8 @@ XLogSimpleInsertInt64(RmgrId rmid, uint8 info, int64 value)
static XLogRecData *
XLogRecordAssemble(RmgrId rmid, uint8 info,
XLogRecPtr RedoRecPtr, bool doPageWrites,
- XLogRecPtr *fpw_lsn, int *num_fpi, bool *topxid_included)
+ XLogRecPtr *fpw_lsn, int *num_fpi, uint64 *fpi_bytes,
+ bool *topxid_included)
{
XLogRecData *rdt;
uint64 total_len = 0;
@@ -796,6 +802,9 @@ XLogRecordAssemble(RmgrId rmid, uint8 info,
}
total_len += bimg.length;
+
+ /* Track the WAL full page images in bytes */
+ *fpi_bytes += bimg.length;
}
if (needs_data)
diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c
index 6002fd0002f..9944e4bd2d1 100644
--- a/src/backend/catalog/pg_constraint.c
+++ b/src/backend/catalog/pg_constraint.c
@@ -937,10 +937,12 @@ RemoveConstraintById(Oid conId)
con->conrelid);
classForm = (Form_pg_class) GETSTRUCT(relTup);
- if (classForm->relchecks == 0) /* should not happen */
- elog(ERROR, "relation \"%s\" has relchecks = 0",
- RelationGetRelationName(rel));
- classForm->relchecks--;
+ if (classForm->relchecks > 0)
+ classForm->relchecks--;
+ else
+ /* should not happen */
+ elog(WARNING, "relation \"%s\" has relchecks = %d",
+ RelationGetRelationName(rel), classForm->relchecks);
CatalogTupleUpdate(pgrel, &relTup->t_self, relTup);
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 823776c1498..dec8df4f8ee 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -1221,6 +1221,7 @@ CREATE VIEW pg_stat_wal AS
w.wal_records,
w.wal_fpi,
w.wal_bytes,
+ w.wal_fpi_bytes,
w.wal_buffers_full,
w.stats_reset
FROM pg_stat_get_wal() w;
diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c
index a0974d71de1..1f45444b499 100644
--- a/src/backend/commands/subscriptioncmds.c
+++ b/src/backend/commands/subscriptioncmds.c
@@ -1082,7 +1082,7 @@ AlterSubscription_refresh(Subscription *sub, bool copy_data,
sub_remove_rels = lappend(sub_remove_rels, remove_rel);
- logicalrep_worker_stop(sub->oid, relid);
+ logicalrep_worker_stop(WORKERTYPE_TABLESYNC, sub->oid, relid);
/*
* For READY state, we would have already dropped the
@@ -2134,7 +2134,7 @@ DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel)
{
LogicalRepWorker *w = (LogicalRepWorker *) lfirst(lc);
- logicalrep_worker_stop(w->subid, w->relid);
+ logicalrep_worker_stop(w->type, w->subid, w->relid);
}
list_free(subworkers);
diff --git a/src/backend/executor/instrument.c b/src/backend/executor/instrument.c
index 56e635f4700..9e11c662a7c 100644
--- a/src/backend/executor/instrument.c
+++ b/src/backend/executor/instrument.c
@@ -280,6 +280,7 @@ WalUsageAdd(WalUsage *dst, WalUsage *add)
dst->wal_bytes += add->wal_bytes;
dst->wal_records += add->wal_records;
dst->wal_fpi += add->wal_fpi;
+ dst->wal_fpi_bytes += add->wal_fpi_bytes;
dst->wal_buffers_full += add->wal_buffers_full;
}
@@ -289,5 +290,6 @@ WalUsageAccumDiff(WalUsage *dst, const WalUsage *add, const WalUsage *sub)
dst->wal_bytes += add->wal_bytes - sub->wal_bytes;
dst->wal_records += add->wal_records - sub->wal_records;
dst->wal_fpi += add->wal_fpi - sub->wal_fpi;
+ dst->wal_fpi_bytes += add->wal_fpi_bytes - sub->wal_fpi_bytes;
dst->wal_buffers_full += add->wal_buffers_full - sub->wal_buffers_full;
}
diff --git a/src/backend/parser/parser.c b/src/backend/parser/parser.c
index 33a040506b4..a3679f8e86c 100644
--- a/src/backend/parser/parser.c
+++ b/src/backend/parser/parser.c
@@ -339,7 +339,7 @@ hexval(unsigned char c)
/* is Unicode code point acceptable? */
static void
-check_unicode_value(pg_wchar c)
+check_unicode_value(char32_t c)
{
if (!is_valid_unicode_codepoint(c))
ereport(ERROR,
@@ -376,7 +376,7 @@ str_udeescape(const char *str, char escape,
char *new,
*out;
size_t new_len;
- pg_wchar pair_first = 0;
+ char16_t pair_first = 0;
ScannerCallbackState scbstate;
/*
@@ -420,7 +420,7 @@ str_udeescape(const char *str, char escape,
isxdigit((unsigned char) in[3]) &&
isxdigit((unsigned char) in[4]))
{
- pg_wchar unicode;
+ char32_t unicode;
unicode = (hexval(in[1]) << 12) +
(hexval(in[2]) << 8) +
@@ -457,7 +457,7 @@ str_udeescape(const char *str, char escape,
isxdigit((unsigned char) in[6]) &&
isxdigit((unsigned char) in[7]))
{
- pg_wchar unicode;
+ char32_t unicode;
unicode = (hexval(in[2]) << 20) +
(hexval(in[3]) << 16) +
diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l
index 08990831fe8..a67815339b7 100644
--- a/src/backend/parser/scan.l
+++ b/src/backend/parser/scan.l
@@ -121,7 +121,7 @@ static void addlitchar(unsigned char ychar, core_yyscan_t yyscanner);
static char *litbufdup(core_yyscan_t yyscanner);
static unsigned char unescape_single_char(unsigned char c, core_yyscan_t yyscanner);
static int process_integer_literal(const char *token, YYSTYPE *lval, int base);
-static void addunicode(pg_wchar c, yyscan_t yyscanner);
+static void addunicode(char32_t c, yyscan_t yyscanner);
#define yyerror(msg) scanner_yyerror(msg, yyscanner)
@@ -640,7 +640,7 @@ other .
addlit(yytext, yyleng, yyscanner);
}
<xe>{xeunicode} {
- pg_wchar c = strtoul(yytext + 2, NULL, 16);
+ char32_t c = strtoul(yytext + 2, NULL, 16);
/*
* For consistency with other productions, issue any
@@ -668,7 +668,7 @@ other .
POP_YYLLOC();
}
<xeu>{xeunicode} {
- pg_wchar c = strtoul(yytext + 2, NULL, 16);
+ char32_t c = strtoul(yytext + 2, NULL, 16);
/* Remember start of overall string token ... */
PUSH_YYLLOC();
@@ -1376,7 +1376,7 @@ process_integer_literal(const char *token, YYSTYPE *lval, int base)
}
static void
-addunicode(pg_wchar c, core_yyscan_t yyscanner)
+addunicode(char32_t c, core_yyscan_t yyscanner)
{
ScannerCallbackState scbstate;
char buf[MAX_UNICODE_EQUIVALENT_STRING + 1];
diff --git a/src/backend/replication/logical/launcher.c b/src/backend/replication/logical/launcher.c
index 218cefe86e2..95b5cae9a55 100644
--- a/src/backend/replication/logical/launcher.c
+++ b/src/backend/replication/logical/launcher.c
@@ -245,20 +245,25 @@ WaitForReplicationWorkerAttach(LogicalRepWorker *worker,
}
/*
- * Walks the workers array and searches for one that matches given
- * subscription id and relid.
+ * Walks the workers array and searches for one that matches given worker type,
+ * subscription id, and relation id.
*
- * We are only interested in the leader apply worker or table sync worker.
+ * For apply workers, the relid should be set to InvalidOid, as they manage
+ * changes across all tables. For table sync workers, the relid should be set
+ * to the OID of the relation being synchronized.
*/
LogicalRepWorker *
-logicalrep_worker_find(Oid subid, Oid relid, bool only_running)
+logicalrep_worker_find(LogicalRepWorkerType wtype, Oid subid, Oid relid,
+ bool only_running)
{
int i;
LogicalRepWorker *res = NULL;
+ /* relid must be valid only for table sync workers */
+ Assert((wtype == WORKERTYPE_TABLESYNC) == OidIsValid(relid));
Assert(LWLockHeldByMe(LogicalRepWorkerLock));
- /* Search for attached worker for a given subscription id. */
+ /* Search for an attached worker that matches the specified criteria. */
for (i = 0; i < max_logical_replication_workers; i++)
{
LogicalRepWorker *w = &LogicalRepCtx->workers[i];
@@ -268,7 +273,7 @@ logicalrep_worker_find(Oid subid, Oid relid, bool only_running)
continue;
if (w->in_use && w->subid == subid && w->relid == relid &&
- (!only_running || w->proc))
+ w->type == wtype && (!only_running || w->proc))
{
res = w;
break;
@@ -627,16 +632,20 @@ logicalrep_worker_stop_internal(LogicalRepWorker *worker, int signo)
}
/*
- * Stop the logical replication worker for subid/relid, if any.
+ * Stop the logical replication worker that matches the specified worker type,
+ * subscription id, and relation id.
*/
void
-logicalrep_worker_stop(Oid subid, Oid relid)
+logicalrep_worker_stop(LogicalRepWorkerType wtype, Oid subid, Oid relid)
{
LogicalRepWorker *worker;
+ /* relid must be valid only for table sync workers */
+ Assert((wtype == WORKERTYPE_TABLESYNC) == OidIsValid(relid));
+
LWLockAcquire(LogicalRepWorkerLock, LW_SHARED);
- worker = logicalrep_worker_find(subid, relid, false);
+ worker = logicalrep_worker_find(wtype, subid, relid, false);
if (worker)
{
@@ -694,16 +703,20 @@ logicalrep_pa_worker_stop(ParallelApplyWorkerInfo *winfo)
}
/*
- * Wake up (using latch) any logical replication worker for specified sub/rel.
+ * Wake up (using latch) any logical replication worker that matches the
+ * specified worker type, subscription id, and relation id.
*/
void
-logicalrep_worker_wakeup(Oid subid, Oid relid)
+logicalrep_worker_wakeup(LogicalRepWorkerType wtype, Oid subid, Oid relid)
{
LogicalRepWorker *worker;
+ /* relid must be valid only for table sync workers */
+ Assert((wtype == WORKERTYPE_TABLESYNC) == OidIsValid(relid));
+
LWLockAcquire(LogicalRepWorkerLock, LW_SHARED);
- worker = logicalrep_worker_find(subid, relid, true);
+ worker = logicalrep_worker_find(wtype, subid, relid, true);
if (worker)
logicalrep_worker_wakeup_ptr(worker);
@@ -1260,7 +1273,8 @@ ApplyLauncherMain(Datum main_arg)
continue;
LWLockAcquire(LogicalRepWorkerLock, LW_SHARED);
- w = logicalrep_worker_find(sub->oid, InvalidOid, false);
+ w = logicalrep_worker_find(WORKERTYPE_APPLY, sub->oid, InvalidOid,
+ false);
if (w != NULL)
{
diff --git a/src/backend/replication/logical/syncutils.c b/src/backend/replication/logical/syncutils.c
index e452a1e78d4..ae8c9385916 100644
--- a/src/backend/replication/logical/syncutils.c
+++ b/src/backend/replication/logical/syncutils.c
@@ -69,7 +69,8 @@ FinishSyncWorker(void)
CommitTransactionCommand();
/* Find the leader apply worker and signal it. */
- logicalrep_worker_wakeup(MyLogicalRepWorker->subid, InvalidOid);
+ logicalrep_worker_wakeup(WORKERTYPE_APPLY, MyLogicalRepWorker->subid,
+ InvalidOid);
/* Stop gracefully */
proc_exit(0);
diff --git a/src/backend/replication/logical/tablesync.c b/src/backend/replication/logical/tablesync.c
index 40e1ed3c20e..58c98488d7b 100644
--- a/src/backend/replication/logical/tablesync.c
+++ b/src/backend/replication/logical/tablesync.c
@@ -160,7 +160,8 @@ wait_for_table_state_change(Oid relid, char expected_state)
/* Check if the sync worker is still running and bail if not. */
LWLockAcquire(LogicalRepWorkerLock, LW_SHARED);
- worker = logicalrep_worker_find(MyLogicalRepWorker->subid, relid,
+ worker = logicalrep_worker_find(WORKERTYPE_TABLESYNC,
+ MyLogicalRepWorker->subid, relid,
false);
LWLockRelease(LogicalRepWorkerLock);
if (!worker)
@@ -207,8 +208,9 @@ wait_for_worker_state_change(char expected_state)
* waiting.
*/
LWLockAcquire(LogicalRepWorkerLock, LW_SHARED);
- worker = logicalrep_worker_find(MyLogicalRepWorker->subid,
- InvalidOid, false);
+ worker = logicalrep_worker_find(WORKERTYPE_APPLY,
+ MyLogicalRepWorker->subid, InvalidOid,
+ false);
if (worker && worker->proc)
logicalrep_worker_wakeup_ptr(worker);
LWLockRelease(LogicalRepWorkerLock);
@@ -476,7 +478,8 @@ ProcessSyncingTablesForApply(XLogRecPtr current_lsn)
*/
LWLockAcquire(LogicalRepWorkerLock, LW_SHARED);
- syncworker = logicalrep_worker_find(MyLogicalRepWorker->subid,
+ syncworker = logicalrep_worker_find(WORKERTYPE_TABLESYNC,
+ MyLogicalRepWorker->subid,
rstate->relid, false);
if (syncworker)
diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c
index 5df5a4612b6..7edd1c9cf06 100644
--- a/src/backend/replication/logical/worker.c
+++ b/src/backend/replication/logical/worker.c
@@ -1817,7 +1817,8 @@ apply_handle_stream_start(StringInfo s)
* Signal the leader apply worker, as it may be waiting for
* us.
*/
- logicalrep_worker_wakeup(MyLogicalRepWorker->subid, InvalidOid);
+ logicalrep_worker_wakeup(WORKERTYPE_APPLY,
+ MyLogicalRepWorker->subid, InvalidOid);
}
parallel_stream_nchanges = 0;
@@ -3284,8 +3285,9 @@ FindDeletedTupleInLocalRel(Relation localrel, Oid localidxoid,
* maybe_advance_nonremovable_xid() for details).
*/
LWLockAcquire(LogicalRepWorkerLock, LW_SHARED);
- leader = logicalrep_worker_find(MyLogicalRepWorker->subid,
- InvalidOid, false);
+ leader = logicalrep_worker_find(WORKERTYPE_APPLY,
+ MyLogicalRepWorker->subid, InvalidOid,
+ false);
if (!leader)
{
ereport(ERROR,
diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c
index a864ae8e6a6..199ba2cc17a 100644
--- a/src/backend/utils/activity/pgstat_backend.c
+++ b/src/backend/utils/activity/pgstat_backend.c
@@ -252,6 +252,7 @@ pgstat_flush_backend_entry_wal(PgStat_EntryRef *entry_ref)
WALSTAT_ACC(wal_records, wal_usage_diff);
WALSTAT_ACC(wal_fpi, wal_usage_diff);
WALSTAT_ACC(wal_bytes, wal_usage_diff);
+ WALSTAT_ACC(wal_fpi_bytes, wal_usage_diff);
#undef WALSTAT_ACC
/*
diff --git a/src/backend/utils/activity/pgstat_wal.c b/src/backend/utils/activity/pgstat_wal.c
index 0d04480d2f6..d4edb8b5733 100644
--- a/src/backend/utils/activity/pgstat_wal.c
+++ b/src/backend/utils/activity/pgstat_wal.c
@@ -121,6 +121,7 @@ pgstat_wal_flush_cb(bool nowait)
WALSTAT_ACC(wal_records, wal_usage_diff);
WALSTAT_ACC(wal_fpi, wal_usage_diff);
WALSTAT_ACC(wal_bytes, wal_usage_diff);
+ WALSTAT_ACC(wal_fpi_bytes, wal_usage_diff);
WALSTAT_ACC(wal_buffers_full, wal_usage_diff);
#undef WALSTAT_ACC
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 78e19ac39ac..85418d73198 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -1,4 +1,4 @@
-/* -----------------------------------------------------------------------
+/*-------------------------------------------------------------------------
* formatting.c
*
* src/backend/utils/adt/formatting.c
@@ -54,7 +54,7 @@
* than Oracle :-),
* to_char('Hello', 'X X X X X') -> 'H e l l o'
*
- * -----------------------------------------------------------------------
+ *-------------------------------------------------------------------------
*/
#ifdef DEBUG_TO_FROM_CHAR
@@ -92,44 +92,39 @@
#include "varatt.h"
-/* ----------
+/*
* Routines flags
- * ----------
*/
#define DCH_FLAG 0x1 /* DATE-TIME flag */
#define NUM_FLAG 0x2 /* NUMBER flag */
#define STD_FLAG 0x4 /* STANDARD flag */
-/* ----------
+/*
* KeyWord Index (ascii from position 32 (' ') to 126 (~))
- * ----------
*/
#define KeyWord_INDEX_SIZE ('~' - ' ')
#define KeyWord_INDEX_FILTER(_c) ((_c) <= ' ' || (_c) >= '~' ? 0 : 1)
-/* ----------
+/*
* Maximal length of one node
- * ----------
*/
#define DCH_MAX_ITEM_SIZ 12 /* max localized day name */
#define NUM_MAX_ITEM_SIZ 8 /* roman number (RN has 15 chars) */
-/* ----------
+/*
* Format parser structs
- * ----------
*/
typedef struct
{
const char *name; /* suffix string */
- int len, /* suffix length */
- id, /* used in node->suffix */
- type; /* prefix / postfix */
+ size_t len; /* suffix length */
+ int id; /* used in node->suffix */
+ int type; /* prefix / postfix */
} KeySuffix;
-/* ----------
+/*
* FromCharDateMode
- * ----------
*
* This value is used to nominate one of several distinct (and mutually
* exclusive) date conventions that a keyword can belong to.
@@ -144,7 +139,7 @@ typedef enum
typedef struct
{
const char *name;
- int len;
+ size_t len;
int id;
bool is_digit;
FromCharDateMode date_mode;
@@ -171,9 +166,8 @@ typedef struct
#define CLOCK_12_HOUR 1
-/* ----------
+/*
* Full months
- * ----------
*/
static const char *const months_full[] = {
"January", "February", "March", "April", "May", "June", "July",
@@ -184,9 +178,9 @@ static const char *const days_short[] = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL
};
-/* ----------
+/*
* AD / BC
- * ----------
+ *
* There is no 0 AD. Years go from 1 BC to 1 AD, so we make it
* positive and map year == -1 to year zero, and shift all negative
* years up one. For interval years, we just return the year.
@@ -216,9 +210,8 @@ static const char *const days_short[] = {
static const char *const adbc_strings[] = {ad_STR, bc_STR, AD_STR, BC_STR, NULL};
static const char *const adbc_strings_long[] = {a_d_STR, b_c_STR, A_D_STR, B_C_STR, NULL};
-/* ----------
+/*
* AM / PM
- * ----------
*/
#define A_M_STR "A.M."
#define a_m_STR "a.m."
@@ -243,11 +236,10 @@ static const char *const adbc_strings_long[] = {a_d_STR, b_c_STR, A_D_STR, B_C_S
static const char *const ampm_strings[] = {am_STR, pm_STR, AM_STR, PM_STR, NULL};
static const char *const ampm_strings_long[] = {a_m_STR, p_m_STR, A_M_STR, P_M_STR, NULL};
-/* ----------
+/*
* Months in roman-numeral
* (Must be in reverse order for seq_search (in FROM_CHAR), because
* 'VIII' must have higher precedence than 'V')
- * ----------
*/
static const char *const rm_months_upper[] =
{"XII", "XI", "X", "IX", "VIII", "VII", "VI", "V", "IV", "III", "II", "I", NULL};
@@ -255,9 +247,8 @@ static const char *const rm_months_upper[] =
static const char *const rm_months_lower[] =
{"xii", "xi", "x", "ix", "viii", "vii", "vi", "v", "iv", "iii", "ii", "i", NULL};
-/* ----------
+/*
* Roman numerals
- * ----------
*/
static const char *const rm1[] = {"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", NULL};
static const char *const rm10[] = {"X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC", NULL};
@@ -289,23 +280,20 @@ static const char *const rm100[] = {"C", "CC", "CCC", "CD", "D", "DC", "DCC", "D
*/
#define MAX_ROMAN_LEN 15
-/* ----------
+/*
* Ordinal postfixes
- * ----------
*/
static const char *const numTH[] = {"ST", "ND", "RD", "TH", NULL};
static const char *const numth[] = {"st", "nd", "rd", "th", NULL};
-/* ----------
+/*
* Flags & Options:
- * ----------
*/
#define TH_UPPER 1
#define TH_LOWER 2
-/* ----------
+/*
* Number description struct
- * ----------
*/
typedef struct
{
@@ -320,9 +308,8 @@ typedef struct
need_locale; /* needs it locale */
} NUMDesc;
-/* ----------
+/*
* Flags for NUMBER version
- * ----------
*/
#define NUM_F_DECIMAL (1 << 1)
#define NUM_F_LDECIMAL (1 << 2)
@@ -343,9 +330,8 @@ typedef struct
#define NUM_LSIGN_POST 1
#define NUM_LSIGN_NONE 0
-/* ----------
+/*
* Tests
- * ----------
*/
#define IS_DECIMAL(_f) ((_f)->flag & NUM_F_DECIMAL)
#define IS_LDECIMAL(_f) ((_f)->flag & NUM_F_LDECIMAL)
@@ -360,7 +346,7 @@ typedef struct
#define IS_MULTI(_f) ((_f)->flag & NUM_F_MULTI)
#define IS_EEEE(_f) ((_f)->flag & NUM_F_EEEE)
-/* ----------
+/*
* Format picture cache
*
* We will cache datetime format pictures up to DCH_CACHE_SIZE bytes long;
@@ -376,7 +362,6 @@ typedef struct
*
* The max number of entries in each cache is DCH_CACHE_ENTRIES
* resp. NUM_CACHE_ENTRIES.
- * ----------
*/
#define DCH_CACHE_OVERHEAD \
MAXALIGN(sizeof(bool) + sizeof(int))
@@ -419,9 +404,8 @@ static NUMCacheEntry *NUMCache[NUM_CACHE_ENTRIES];
static int n_NUMCache = 0; /* current number of entries */
static int NUMCounter = 0; /* aging-event counter */
-/* ----------
+/*
* For char->date/time conversion
- * ----------
*/
typedef struct
{
@@ -452,7 +436,7 @@ typedef struct
bool has_tz; /* was there a TZ field? */
int gmtoffset; /* GMT offset of fixed-offset zone abbrev */
pg_tz *tzp; /* pg_tz for dynamic abbrev */
- char *abbrev; /* dynamic abbrev */
+ const char *abbrev; /* dynamic abbrev */
} TmFromChar;
#define ZERO_tmfc(_X) memset(_X, 0, sizeof(TmFromChar))
@@ -463,9 +447,8 @@ struct fmt_tz /* do_to_timestamp's timezone info output */
int gmtoffset; /* GMT offset in seconds */
};
-/* ----------
+/*
* Debug
- * ----------
*/
#ifdef DEBUG_TO_FROM_CHAR
#define DEBUG_TMFC(_X) \
@@ -484,13 +467,12 @@ struct fmt_tz /* do_to_timestamp's timezone info output */
#define DEBUG_TM(_X)
#endif
-/* ----------
+/*
* Datetime to char conversion
*
* To support intervals as well as timestamps, we use a custom "tm" struct
* that is almost like struct pg_tm, but has a 64-bit tm_hour field.
* We omit the tm_isdst and tm_zone fields, which are not used here.
- * ----------
*/
struct fmt_tm
{
@@ -561,9 +543,8 @@ do { \
* KeyWord definitions
*****************************************************************************/
-/* ----------
+/*
* Suffixes (FormatNode.suffix is an OR of these codes)
- * ----------
*/
#define DCH_S_FM 0x01
#define DCH_S_TH 0x02
@@ -571,9 +552,8 @@ do { \
#define DCH_S_SP 0x08
#define DCH_S_TM 0x10
-/* ----------
+/*
* Suffix tests
- * ----------
*/
#define S_THth(_s) ((((_s) & DCH_S_TH) || ((_s) & DCH_S_th)) ? 1 : 0)
#define S_TH(_s) (((_s) & DCH_S_TH) ? 1 : 0)
@@ -585,9 +565,8 @@ do { \
#define S_SP(_s) (((_s) & DCH_S_SP) ? 1 : 0)
#define S_TM(_s) (((_s) & DCH_S_TM) ? 1 : 0)
-/* ----------
+/*
* Suffixes definition for DATE-TIME TO/FROM CHAR
- * ----------
*/
#define TM_SUFFIX_LEN 2
@@ -604,7 +583,7 @@ static const KeySuffix DCH_suff[] = {
};
-/* ----------
+/*
* Format-pictures (KeyWord).
*
* The KeyWord field; alphabetic sorted, *BUT* strings alike is sorted
@@ -628,8 +607,6 @@ static const KeySuffix DCH_suff[] = {
* 1) see in index to index['M' - 32],
* 2) take keywords position (enum DCH_MI) from index
* 3) run sequential search in keywords[] from this position
- *
- * ----------
*/
typedef enum
@@ -794,9 +771,8 @@ typedef enum
_NUM_last_
} NUM_poz;
-/* ----------
+/*
* KeyWords for DATE-TIME version
- * ----------
*/
static const KeyWord DCH_keywords[] = {
/* name, len, id, is_digit, date_mode */
@@ -917,11 +893,10 @@ static const KeyWord DCH_keywords[] = {
{NULL, 0, 0, 0, 0}
};
-/* ----------
+/*
* KeyWords for NUMBER version
*
* The is_digit and date_mode fields are not relevant here.
- * ----------
*/
static const KeyWord NUM_keywords[] = {
/* name, len, id is in Index */
@@ -967,9 +942,8 @@ static const KeyWord NUM_keywords[] = {
};
-/* ----------
+/*
* KeyWords index for DATE-TIME version
- * ----------
*/
static const int DCH_index[KeyWord_INDEX_SIZE] = {
/*
@@ -991,9 +965,8 @@ static const int DCH_index[KeyWord_INDEX_SIZE] = {
/*---- chars over 126 are skipped ----*/
};
-/* ----------
+/*
* KeyWords index for NUMBER version
- * ----------
*/
static const int NUM_index[KeyWord_INDEX_SIZE] = {
/*
@@ -1015,9 +988,8 @@ static const int NUM_index[KeyWord_INDEX_SIZE] = {
/*---- chars over 126 are skipped ----*/
};
-/* ----------
+/*
* Number processor struct
- * ----------
*/
typedef struct NUMProc
{
@@ -1062,9 +1034,8 @@ typedef struct NUMProc
#define AMOUNT_TEST(s) (Np->inout_p <= Np->inout + (input_len - (s)))
-/* ----------
+/*
* Functions
- * ----------
*/
static const KeyWord *index_seq_search(const char *str, const KeyWord *kw,
const int *index);
@@ -1084,38 +1055,38 @@ static void dump_index(const KeyWord *k, const int *index);
static void dump_node(FormatNode *node, int max);
#endif
-static const char *get_th(char *num, int type);
-static char *str_numth(char *dest, char *num, int type);
+static const char *get_th(const char *num, int type);
+static char *str_numth(char *dest, const char *num, int type);
static int adjust_partial_year_to_2020(int year);
-static int strspace_len(const char *str);
+static size_t strspace_len(const char *str);
static bool from_char_set_mode(TmFromChar *tmfc, const FromCharDateMode mode,
Node *escontext);
static bool from_char_set_int(int *dest, const int value, const FormatNode *node,
Node *escontext);
-static int from_char_parse_int_len(int *dest, const char **src, const int len,
+static int from_char_parse_int_len(int *dest, const char **src, const size_t len,
FormatNode *node, Node *escontext);
static int from_char_parse_int(int *dest, const char **src, FormatNode *node,
Node *escontext);
-static int seq_search_ascii(const char *name, const char *const *array, int *len);
-static int seq_search_localized(const char *name, char **array, int *len,
+static int seq_search_ascii(const char *name, const char *const *array, size_t *len);
+static int seq_search_localized(const char *name, char **array, size_t *len,
Oid collid);
static bool from_char_seq_search(int *dest, const char **src,
const char *const *array,
char **localized_array, Oid collid,
FormatNode *node, Node *escontext);
-static bool do_to_timestamp(text *date_txt, text *fmt, Oid collid, bool std,
+static bool do_to_timestamp(const text *date_txt, const text *fmt, Oid collid, bool std,
struct pg_tm *tm, fsec_t *fsec, struct fmt_tz *tz,
int *fprec, uint32 *flags, Node *escontext);
static char *fill_str(char *str, int c, int max);
-static FormatNode *NUM_cache(int len, NUMDesc *Num, text *pars_str, bool *shouldFree);
+static FormatNode *NUM_cache(int len, NUMDesc *Num, const text *pars_str, bool *shouldFree);
static char *int_to_roman(int number);
-static int roman_to_int(NUMProc *Np, int input_len);
+static int roman_to_int(NUMProc *Np, size_t input_len);
static void NUM_prepare_locale(NUMProc *Np);
-static char *get_last_relevant_decnum(char *num);
-static void NUM_numpart_from_char(NUMProc *Np, int id, int input_len);
+static char *get_last_relevant_decnum(const char *num);
+static void NUM_numpart_from_char(NUMProc *Np, int id, size_t input_len);
static void NUM_numpart_to_char(NUMProc *Np, int id);
static char *NUM_processor(FormatNode *node, NUMDesc *Num, char *inout,
- char *number, int input_len, int to_char_out_pre_spaces,
+ char *number, size_t input_len, int to_char_out_pre_spaces,
int sign, bool is_to_char, Oid collid);
static DCHCacheEntry *DCH_cache_getnew(const char *str, bool std);
static DCHCacheEntry *DCH_cache_search(const char *str, bool std);
@@ -1125,11 +1096,10 @@ static NUMCacheEntry *NUM_cache_search(const char *str);
static NUMCacheEntry *NUM_cache_fetch(const char *str);
-/* ----------
+/*
* Fast sequential search, use index for data selection which
* go to seq. cycle (it is very fast for unwanted strings)
* (can't be used binary search in format parsing)
- * ----------
*/
static const KeyWord *
index_seq_search(const char *str, const KeyWord *kw, const int *index)
@@ -1139,7 +1109,7 @@ index_seq_search(const char *str, const KeyWord *kw, const int *index)
if (!KeyWord_INDEX_FILTER(*str))
return NULL;
- if ((poz = *(index + (*str - ' '))) > -1)
+ if ((poz = index[*str - ' ']) > -1)
{
const KeyWord *k = kw + poz;
@@ -1158,9 +1128,7 @@ index_seq_search(const char *str, const KeyWord *kw, const int *index)
static const KeySuffix *
suff_search(const char *str, const KeySuffix *suf, int type)
{
- const KeySuffix *s;
-
- for (s = suf; s->name != NULL; s++)
+ for (const KeySuffix *s = suf; s->name != NULL; s++)
{
if (s->type != type)
continue;
@@ -1181,9 +1149,8 @@ is_separator_char(const char *str)
!(*str >= '0' && *str <= '9'));
}
-/* ----------
+/*
* Prepare NUMDesc (number description struct) via FormatNode struct
- * ----------
*/
static void
NUMDesc_prepare(NUMDesc *num, FormatNode *n)
@@ -1233,7 +1200,7 @@ NUMDesc_prepare(NUMDesc *num, FormatNode *n)
break;
case NUM_B:
- if (num->pre == 0 && num->post == 0 && (!IS_ZERO(num)))
+ if (num->pre == 0 && num->post == 0 && !IS_ZERO(num))
num->flag |= NUM_F_BLANK;
break;
@@ -1364,12 +1331,11 @@ NUMDesc_prepare(NUMDesc *num, FormatNode *n)
errdetail("\"RN\" may only be used together with \"FM\".")));
}
-/* ----------
+/*
* Format parser, search small keywords and keyword's suffixes, and make
* format-node tree.
*
* for DATE-TIME & NUMBER version
- * ----------
*/
static void
parse_format(FormatNode *node, const char *str, const KeyWord *kw,
@@ -1514,9 +1480,8 @@ parse_format(FormatNode *node, const char *str, const KeyWord *kw,
n->suffix = 0;
}
-/* ----------
+/*
* DEBUG: Dump the FormatNode Tree (debug)
- * ----------
*/
#ifdef DEBUG_TO_FROM_CHAR
@@ -1554,20 +1519,19 @@ dump_node(FormatNode *node, int max)
* Private utils
*****************************************************************************/
-/* ----------
+/*
* Return ST/ND/RD/TH for simple (1..9) numbers
* type --> 0 upper, 1 lower
- * ----------
*/
static const char *
-get_th(char *num, int type)
+get_th(const char *num, int type)
{
- int len = strlen(num),
- last;
+ size_t len = strlen(num);
+ char last;
Assert(len > 0);
- last = *(num + (len - 1));
+ last = num[len - 1];
if (!isdigit((unsigned char) last))
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
@@ -1577,7 +1541,7 @@ get_th(char *num, int type)
* All "teens" (<x>1[0-9]) get 'TH/th', while <x>[02-9][123] still get
* 'ST/st', 'ND/nd', 'RD/rd', respectively
*/
- if ((len > 1) && (num[len - 2] == '1'))
+ if (len > 1 && num[len - 2] == '1')
last = 0;
switch (last)
@@ -1601,13 +1565,12 @@ get_th(char *num, int type)
}
}
-/* ----------
+/*
* Convert string-number to ordinal string-number
* type --> 0 upper, 1 lower
- * ----------
*/
static char *
-str_numth(char *dest, char *num, int type)
+str_numth(char *dest, const char *num, int type)
{
if (dest != num)
strcpy(dest, num);
@@ -1900,14 +1863,13 @@ char *
asc_tolower(const char *buff, size_t nbytes)
{
char *result;
- char *p;
if (!buff)
return NULL;
result = pnstrdup(buff, nbytes);
- for (p = result; *p; p++)
+ for (char *p = result; *p; p++)
*p = pg_ascii_tolower((unsigned char) *p);
return result;
@@ -1923,14 +1885,13 @@ char *
asc_toupper(const char *buff, size_t nbytes)
{
char *result;
- char *p;
if (!buff)
return NULL;
result = pnstrdup(buff, nbytes);
- for (p = result; *p; p++)
+ for (char *p = result; *p; p++)
*p = pg_ascii_toupper((unsigned char) *p);
return result;
@@ -1946,7 +1907,6 @@ char *
asc_initcap(const char *buff, size_t nbytes)
{
char *result;
- char *p;
int wasalnum = false;
if (!buff)
@@ -1954,7 +1914,7 @@ asc_initcap(const char *buff, size_t nbytes)
result = pnstrdup(buff, nbytes);
- for (p = result; *p; p++)
+ for (char *p = result; *p; p++)
{
char c;
@@ -2006,11 +1966,10 @@ asc_toupper_z(const char *buff)
/* asc_initcap_z is not currently needed */
-/* ----------
+/*
* Skip TM / th in FROM_CHAR
*
* If S_THth is on, skip two chars, assuming there are two available
- * ----------
*/
#define SKIP_THth(ptr, _suf) \
do { \
@@ -2023,21 +1982,19 @@ asc_toupper_z(const char *buff)
#ifdef DEBUG_TO_FROM_CHAR
-/* -----------
+/*
* DEBUG: Call for debug and for index checking; (Show ASCII char
* and defined keyword for each used position
- * ----------
*/
static void
dump_index(const KeyWord *k, const int *index)
{
- int i,
- count = 0,
+ int count = 0,
free_i = 0;
elog(DEBUG_elog_output, "TO-FROM_CHAR: Dump KeyWord Index:");
- for (i = 0; i < KeyWord_INDEX_SIZE; i++)
+ for (int i = 0; i < KeyWord_INDEX_SIZE; i++)
{
if (index[i] != -1)
{
@@ -2055,9 +2012,8 @@ dump_index(const KeyWord *k, const int *index)
}
#endif /* DEBUG */
-/* ----------
+/*
* Return true if next format picture is not digit value
- * ----------
*/
static bool
is_next_separator(FormatNode *n)
@@ -2116,10 +2072,10 @@ adjust_partial_year_to_2020(int year)
}
-static int
+static size_t
strspace_len(const char *str)
{
- int len = 0;
+ size_t len = 0;
while (*str && isspace((unsigned char) *str))
{
@@ -2202,13 +2158,13 @@ from_char_set_int(int *dest, const int value, const FormatNode *node,
* with DD and MI).
*/
static int
-from_char_parse_int_len(int *dest, const char **src, const int len, FormatNode *node,
+from_char_parse_int_len(int *dest, const char **src, const size_t len, FormatNode *node,
Node *escontext)
{
long result;
char copy[DCH_MAX_ITEM_SIZ + 1];
const char *init = *src;
- int used;
+ size_t used;
/*
* Skip any whitespace before parsing the integer.
@@ -2216,7 +2172,7 @@ from_char_parse_int_len(int *dest, const char **src, const int len, FormatNode *
*src += strspace_len(*src);
Assert(len <= DCH_MAX_ITEM_SIZ);
- used = (int) strlcpy(copy, *src, len + 1);
+ used = strlcpy(copy, *src, len + 1);
if (S_FM(node->suffix) || is_next_separator(node))
{
@@ -2243,7 +2199,7 @@ from_char_parse_int_len(int *dest, const char **src, const int len, FormatNode *
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
errmsg("source string too short for \"%s\" formatting field",
node->key->name),
- errdetail("Field requires %d characters, but only %d remain.",
+ errdetail("Field requires %zu characters, but only %zu remain.",
len, used),
errhint("If your source string is not fixed-width, "
"try using the \"FM\" modifier.")));
@@ -2257,7 +2213,7 @@ from_char_parse_int_len(int *dest, const char **src, const int len, FormatNode *
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
errmsg("invalid value \"%s\" for \"%s\"",
copy, node->key->name),
- errdetail("Field requires %d characters, but only %d could be parsed.",
+ errdetail("Field requires %zu characters, but only %zu could be parsed.",
len, used),
errhint("If your source string is not fixed-width, "
"try using the \"FM\" modifier.")));
@@ -2317,10 +2273,9 @@ from_char_parse_int(int *dest, const char **src, FormatNode *node,
* suitable for comparisons to ASCII strings.
*/
static int
-seq_search_ascii(const char *name, const char *const *array, int *len)
+seq_search_ascii(const char *name, const char *const *array, size_t *len)
{
unsigned char firstc;
- const char *const *a;
*len = 0;
@@ -2331,17 +2286,14 @@ seq_search_ascii(const char *name, const char *const *array, int *len)
/* we handle first char specially to gain some speed */
firstc = pg_ascii_tolower((unsigned char) *name);
- for (a = array; *a != NULL; a++)
+ for (const char *const *a = array; *a != NULL; a++)
{
- const char *p;
- const char *n;
-
/* compare first chars */
if (pg_ascii_tolower((unsigned char) **a) != firstc)
continue;
/* compare rest of string */
- for (p = *a + 1, n = name + 1;; p++, n++)
+ for (const char *p = *a + 1, *n = name + 1;; p++, n++)
{
/* return success if we matched whole array entry */
if (*p == '\0')
@@ -2374,9 +2326,8 @@ seq_search_ascii(const char *name, const char *const *array, int *len)
* the arrays exported by pg_locale.c aren't const.
*/
static int
-seq_search_localized(const char *name, char **array, int *len, Oid collid)
+seq_search_localized(const char *name, char **array, size_t *len, Oid collid)
{
- char **a;
char *upper_name;
char *lower_name;
@@ -2390,9 +2341,9 @@ seq_search_localized(const char *name, char **array, int *len, Oid collid)
* The case-folding processing done below is fairly expensive, so before
* doing that, make a quick pass to see if there is an exact match.
*/
- for (a = array; *a != NULL; a++)
+ for (char **a = array; *a != NULL; a++)
{
- int element_len = strlen(*a);
+ size_t element_len = strlen(*a);
if (strncmp(name, *a, element_len) == 0)
{
@@ -2409,11 +2360,11 @@ seq_search_localized(const char *name, char **array, int *len, Oid collid)
lower_name = str_tolower(upper_name, strlen(upper_name), collid);
pfree(upper_name);
- for (a = array; *a != NULL; a++)
+ for (char **a = array; *a != NULL; a++)
{
char *upper_element;
char *lower_element;
- int element_len;
+ size_t element_len;
/* Likewise upper/lower-case array element */
upper_element = str_toupper(*a, strlen(*a), collid);
@@ -2462,7 +2413,7 @@ from_char_seq_search(int *dest, const char **src, const char *const *array,
char **localized_array, Oid collid,
FormatNode *node, Node *escontext)
{
- int len;
+ size_t len;
if (localized_array == NULL)
*dest = seq_search_ascii(*src, array, &len);
@@ -2476,9 +2427,8 @@ from_char_seq_search(int *dest, const char **src, const char *const *array,
* any) to avoid including irrelevant data.
*/
char *copy = pstrdup(*src);
- char *c;
- for (c = copy; *c; c++)
+ for (char *c = copy; *c; c++)
{
if (scanner_isspace(*c))
{
@@ -2498,15 +2448,13 @@ from_char_seq_search(int *dest, const char **src, const char *const *array,
return true;
}
-/* ----------
+/*
* Process a TmToChar struct as denoted by a list of FormatNodes.
* The formatted data is written to the string pointed to by 'out'.
- * ----------
*/
static void
DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid collid)
{
- FormatNode *n;
char *s;
struct fmt_tm *tm = &in->tm;
int i;
@@ -2515,7 +2463,7 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
cache_locale_time();
s = out;
- for (n = node; n->type != NODE_TYPE_END; n++)
+ for (FormatNode *n = node; n->type != NODE_TYPE_END; n++)
{
if (n->type != NODE_TYPE_ACTION)
{
@@ -3725,10 +3673,9 @@ DCH_prevent_counter_overflow(void)
static int
DCH_datetime_type(FormatNode *node)
{
- FormatNode *n;
int flags = 0;
- for (n = node; n->type != NODE_TYPE_END; n++)
+ for (FormatNode *n = node; n->type != NODE_TYPE_END; n++)
{
if (n->type != NODE_TYPE_ACTION)
continue;
@@ -3928,13 +3875,13 @@ DCH_cache_fetch(const char *str, bool std)
* for formatting.
*/
static text *
-datetime_to_char_body(TmToChar *tmtc, text *fmt, bool is_interval, Oid collid)
+datetime_to_char_body(TmToChar *tmtc, const text *fmt, bool is_interval, Oid collid)
{
FormatNode *format;
char *fmt_str,
*result;
bool incache;
- int fmt_len;
+ size_t fmt_len;
text *res;
/*
@@ -3992,9 +3939,8 @@ datetime_to_char_body(TmToChar *tmtc, text *fmt, bool is_interval, Oid collid)
* Public routines
***************************************************************************/
-/* -------------------
+/*
* TIMESTAMP to_char()
- * -------------------
*/
Datum
timestamp_to_char(PG_FUNCTION_ARGS)
@@ -4068,9 +4014,8 @@ timestamptz_to_char(PG_FUNCTION_ARGS)
}
-/* -------------------
+/*
* INTERVAL to_char()
- * -------------------
*/
Datum
interval_to_char(PG_FUNCTION_ARGS)
@@ -4107,12 +4052,11 @@ interval_to_char(PG_FUNCTION_ARGS)
PG_RETURN_TEXT_P(res);
}
-/* ---------------------
+/*
* TO_TIMESTAMP()
*
* Make Timestamp from date_str which is formatted at argument 'fmt'
* ( to_timestamp is reverse to_char() )
- * ---------------------
*/
Datum
to_timestamp(PG_FUNCTION_ARGS)
@@ -4148,10 +4092,9 @@ to_timestamp(PG_FUNCTION_ARGS)
PG_RETURN_TIMESTAMP(result);
}
-/* ----------
+/*
* TO_DATE
* Make Date from date_str which is formatted at argument 'fmt'
- * ----------
*/
Datum
to_date(PG_FUNCTION_ARGS)
@@ -4368,7 +4311,7 @@ bool
datetime_format_has_tz(const char *fmt_str)
{
bool incache;
- int fmt_len = strlen(fmt_str);
+ size_t fmt_len = strlen(fmt_str);
int result;
FormatNode *format;
@@ -4428,7 +4371,7 @@ datetime_format_has_tz(const char *fmt_str)
* struct 'tm', 'fsec', struct 'tz', and 'fprec'.
*/
static bool
-do_to_timestamp(text *date_txt, text *fmt, Oid collid, bool std,
+do_to_timestamp(const text *date_txt, const text *fmt, Oid collid, bool std,
struct pg_tm *tm, fsec_t *fsec, struct fmt_tz *tz,
int *fprec, uint32 *flags, Node *escontext)
{
@@ -4864,7 +4807,7 @@ static char *
fill_str(char *str, int c, int max)
{
memset(str, c, max);
- *(str + max) = '\0';
+ str[max] = '\0';
return str;
}
@@ -4998,12 +4941,11 @@ NUM_cache_fetch(const char *str)
return ent;
}
-/* ----------
+/*
* Cache routine for NUM to_char version
- * ----------
*/
static FormatNode *
-NUM_cache(int len, NUMDesc *Num, text *pars_str, bool *shouldFree)
+NUM_cache(int len, NUMDesc *Num, const text *pars_str, bool *shouldFree)
{
FormatNode *format = NULL;
char *str;
@@ -5070,8 +5012,7 @@ int_to_roman(int number)
{
int len,
num;
- char *p,
- *result,
+ char *result,
numstr[12];
result = (char *) palloc(MAX_ROMAN_LEN + 1);
@@ -5092,7 +5033,7 @@ int_to_roman(int number)
len = snprintf(numstr, sizeof(numstr), "%d", number);
Assert(len > 0 && len <= 4);
- for (p = numstr; *p != '\0'; p++, --len)
+ for (char *p = numstr; *p != '\0'; p++, --len)
{
num = *p - ('0' + 1);
if (num < 0)
@@ -5126,10 +5067,10 @@ int_to_roman(int number)
* If input is invalid, return -1.
*/
static int
-roman_to_int(NUMProc *Np, int input_len)
+roman_to_int(NUMProc *Np, size_t input_len)
{
int result = 0;
- int len;
+ size_t len;
char romanChars[MAX_ROMAN_LEN];
int romanValues[MAX_ROMAN_LEN];
int repeatCount = 1;
@@ -5168,7 +5109,7 @@ roman_to_int(NUMProc *Np, int input_len)
return -1; /* No valid roman numerals. */
/* Check for valid combinations and compute the represented value. */
- for (int i = 0; i < len; i++)
+ for (size_t i = 0; i < len; i++)
{
char currChar = romanChars[i];
int currValue = romanValues[i];
@@ -5271,9 +5212,8 @@ roman_to_int(NUMProc *Np, int input_len)
}
-/* ----------
+/*
* Locale
- * ----------
*/
static void
NUM_prepare_locale(NUMProc *Np)
@@ -5349,16 +5289,15 @@ NUM_prepare_locale(NUMProc *Np)
}
}
-/* ----------
+/*
* Return pointer of last relevant number after decimal point
* 12.0500 --> last relevant is '5'
* 12.0000 --> last relevant is '.'
* If there is no decimal point, return NULL (which will result in same
* behavior as if FM hadn't been specified).
- * ----------
*/
static char *
-get_last_relevant_decnum(char *num)
+get_last_relevant_decnum(const char *num)
{
char *result,
*p = strchr(num, '.');
@@ -5381,12 +5320,11 @@ get_last_relevant_decnum(char *num)
return result;
}
-/* ----------
+/*
* Number extraction for TO_NUMBER()
- * ----------
*/
static void
-NUM_numpart_from_char(NUMProc *Np, int id, int input_len)
+NUM_numpart_from_char(NUMProc *Np, int id, size_t input_len)
{
bool isread = false;
@@ -5420,7 +5358,7 @@ NUM_numpart_from_char(NUMProc *Np, int id, int input_len)
*/
if (IS_LSIGN(Np->Num) && Np->Num->lsign == NUM_LSIGN_PRE)
{
- int x = 0;
+ size_t x = 0;
#ifdef DEBUG_TO_FROM_CHAR
elog(DEBUG_elog_output, "Try read locale pre-sign (%c)", *Np->inout_p);
@@ -5499,7 +5437,7 @@ NUM_numpart_from_char(NUMProc *Np, int id, int input_len)
* Np->decimal is always just "." if we don't have a D format token.
* So we just unconditionally match to Np->decimal.
*/
- int x = strlen(Np->decimal);
+ size_t x = strlen(Np->decimal);
#ifdef DEBUG_TO_FROM_CHAR
elog(DEBUG_elog_output, "Try read decimal point (%c)",
@@ -5538,7 +5476,7 @@ NUM_numpart_from_char(NUMProc *Np, int id, int input_len)
(Np->inout_p + 1) < Np->inout + input_len &&
!isdigit((unsigned char) *(Np->inout_p + 1)))
{
- int x;
+ size_t x;
char *tmp = Np->inout_p++;
#ifdef DEBUG_TO_FROM_CHAR
@@ -5596,9 +5534,8 @@ NUM_numpart_from_char(NUMProc *Np, int id, int input_len)
*(_n)->number == '0' && \
(_n)->Num->post != 0)
-/* ----------
+/*
* Add digit or sign to number-string
- * ----------
*/
static void
NUM_numpart_to_char(NUMProc *Np, int id)
@@ -5791,7 +5728,7 @@ NUM_numpart_to_char(NUMProc *Np, int id)
* Skip over "n" input characters, but only if they aren't numeric data
*/
static void
-NUM_eat_non_data_chars(NUMProc *Np, int n, int input_len)
+NUM_eat_non_data_chars(NUMProc *Np, int n, size_t input_len)
{
while (n-- > 0)
{
@@ -5805,14 +5742,14 @@ NUM_eat_non_data_chars(NUMProc *Np, int n, int input_len)
static char *
NUM_processor(FormatNode *node, NUMDesc *Num, char *inout,
- char *number, int input_len, int to_char_out_pre_spaces,
+ char *number, size_t input_len, int to_char_out_pre_spaces,
int sign, bool is_to_char, Oid collid)
{
FormatNode *n;
NUMProc _Np,
*Np = &_Np;
const char *pattern;
- int pattern_len;
+ size_t pattern_len;
MemSet(Np, 0, sizeof(NUMProc));
@@ -5893,7 +5830,7 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout,
*/
if (Np->last_relevant && Np->Num->zero_end > Np->out_pre_spaces)
{
- int last_zero_pos;
+ size_t last_zero_pos;
char *last_zero;
/* note that Np->number cannot be zero-length here */
@@ -6267,10 +6204,9 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout,
}
}
-/* ----------
+/*
* MACRO: Start part of NUM - for all NUM's to_char variants
* (sorry, but I hate copy same code - macro is better..)
- * ----------
*/
#define NUM_TOCHAR_prepare \
do { \
@@ -6281,13 +6217,12 @@ do { \
format = NUM_cache(len, &Num, fmt, &shouldFree); \
} while (0)
-/* ----------
+/*
* MACRO: Finish part of NUM
- * ----------
*/
#define NUM_TOCHAR_finish \
do { \
- int len; \
+ size_t len; \
\
NUM_processor(format, &Num, VARDATA(result), numstr, 0, out_pre_spaces, sign, true, PG_GET_COLLATION()); \
\
@@ -6303,9 +6238,8 @@ do { \
SET_VARSIZE(result, len + VARHDRSZ); \
} while (0)
-/* -------------------
+/*
* NUMERIC to_number() (convert string to numeric)
- * -------------------
*/
Datum
numeric_to_number(PG_FUNCTION_ARGS)
@@ -6362,9 +6296,8 @@ numeric_to_number(PG_FUNCTION_ARGS)
return result;
}
-/* ------------------
+/*
* NUMERIC to_char()
- * ------------------
*/
Datum
numeric_to_char(PG_FUNCTION_ARGS)
@@ -6434,7 +6367,7 @@ numeric_to_char(PG_FUNCTION_ARGS)
}
else
{
- int numstr_pre_len;
+ size_t numstr_pre_len;
Numeric val = value;
Numeric x;
@@ -6490,9 +6423,8 @@ numeric_to_char(PG_FUNCTION_ARGS)
PG_RETURN_TEXT_P(result);
}
-/* ---------------
+/*
* INT4 to_char()
- * ---------------
*/
Datum
int4_to_char(PG_FUNCTION_ARGS)
@@ -6532,7 +6464,7 @@ int4_to_char(PG_FUNCTION_ARGS)
}
else
{
- int numstr_pre_len;
+ size_t numstr_pre_len;
if (IS_MULTI(&Num))
{
@@ -6584,9 +6516,8 @@ int4_to_char(PG_FUNCTION_ARGS)
PG_RETURN_TEXT_P(result);
}
-/* ---------------
+/*
* INT8 to_char()
- * ---------------
*/
Datum
int8_to_char(PG_FUNCTION_ARGS)
@@ -6642,7 +6573,7 @@ int8_to_char(PG_FUNCTION_ARGS)
}
else
{
- int numstr_pre_len;
+ size_t numstr_pre_len;
if (IS_MULTI(&Num))
{
@@ -6696,9 +6627,8 @@ int8_to_char(PG_FUNCTION_ARGS)
PG_RETURN_TEXT_P(result);
}
-/* -----------------
+/*
* FLOAT4 to_char()
- * -----------------
*/
Datum
float4_to_char(PG_FUNCTION_ARGS)
@@ -6757,7 +6687,7 @@ float4_to_char(PG_FUNCTION_ARGS)
{
float4 val = value;
char *orgnum;
- int numstr_pre_len;
+ size_t numstr_pre_len;
if (IS_MULTI(&Num))
{
@@ -6809,9 +6739,8 @@ float4_to_char(PG_FUNCTION_ARGS)
PG_RETURN_TEXT_P(result);
}
-/* -----------------
+/*
* FLOAT8 to_char()
- * -----------------
*/
Datum
float8_to_char(PG_FUNCTION_ARGS)
@@ -6870,7 +6799,7 @@ float8_to_char(PG_FUNCTION_ARGS)
{
float8 val = value;
char *orgnum;
- int numstr_pre_len;
+ size_t numstr_pre_len;
if (IS_MULTI(&Num))
{
diff --git a/src/backend/utils/adt/jsonpath_scan.l b/src/backend/utils/adt/jsonpath_scan.l
index c7aab83eeb4..8c3a0a9c642 100644
--- a/src/backend/utils/adt/jsonpath_scan.l
+++ b/src/backend/utils/adt/jsonpath_scan.l
@@ -574,7 +574,7 @@ hexval(char c, int *result, struct Node *escontext, yyscan_t yyscanner)
/* Add given unicode character to scanstring */
static bool
-addUnicodeChar(int ch, struct Node *escontext, yyscan_t yyscanner)
+addUnicodeChar(char32_t ch, struct Node *escontext, yyscan_t yyscanner)
{
if (ch == 0)
{
@@ -607,7 +607,7 @@ addUnicodeChar(int ch, struct Node *escontext, yyscan_t yyscanner)
/* Add unicode character, processing any surrogate pairs */
static bool
-addUnicode(int ch, int *hi_surrogate, struct Node *escontext, yyscan_t yyscanner)
+addUnicode(char32_t ch, int *hi_surrogate, struct Node *escontext, yyscan_t yyscanner)
{
if (is_utf16_surrogate_first(ch))
{
@@ -655,7 +655,7 @@ parseUnicode(char *s, int l, struct Node *escontext, yyscan_t yyscanner)
for (i = 2; i < l; i += 2) /* skip '\u' */
{
- int ch = 0;
+ char32_t ch = 0;
int j,
si;
diff --git a/src/backend/utils/adt/pg_locale_builtin.c b/src/backend/utils/adt/pg_locale_builtin.c
index 3dc611b50e1..1021e0d129b 100644
--- a/src/backend/utils/adt/pg_locale_builtin.c
+++ b/src/backend/utils/adt/pg_locale_builtin.c
@@ -15,7 +15,6 @@
#include "catalog/pg_collation.h"
#include "common/unicode_case.h"
#include "common/unicode_category.h"
-#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "utils/builtins.h"
#include "utils/pg_locale.h"
@@ -36,6 +35,23 @@ struct WordBoundaryState
};
/*
+ * In UTF-8, pg_wchar is guaranteed to be the code point value.
+ */
+static inline char32_t
+to_char32(pg_wchar wc)
+{
+ Assert(GetDatabaseEncoding() == PG_UTF8);
+ return (char32_t) wc;
+}
+
+static inline pg_wchar
+to_pg_wchar(char32_t c32)
+{
+ Assert(GetDatabaseEncoding() == PG_UTF8);
+ return (pg_wchar) c32;
+}
+
+/*
* Simple word boundary iterator that draws boundaries each time the result of
* pg_u_isalnum() changes.
*/
@@ -47,7 +63,7 @@ initcap_wbnext(void *state)
while (wbstate->offset < wbstate->len &&
wbstate->str[wbstate->offset] != '\0')
{
- pg_wchar u = utf8_to_unicode((unsigned char *) wbstate->str +
+ char32_t u = utf8_to_unicode((unsigned char *) wbstate->str +
wbstate->offset);
bool curr_alnum = pg_u_isalnum(u, wbstate->posix);
@@ -112,61 +128,61 @@ strfold_builtin(char *dest, size_t destsize, const char *src, ssize_t srclen,
static bool
wc_isdigit_builtin(pg_wchar wc, pg_locale_t locale)
{
- return pg_u_isdigit(wc, !locale->builtin.casemap_full);
+ return pg_u_isdigit(to_char32(wc), !locale->builtin.casemap_full);
}
static bool
wc_isalpha_builtin(pg_wchar wc, pg_locale_t locale)
{
- return pg_u_isalpha(wc);
+ return pg_u_isalpha(to_char32(wc));
}
static bool
wc_isalnum_builtin(pg_wchar wc, pg_locale_t locale)
{
- return pg_u_isalnum(wc, !locale->builtin.casemap_full);
+ return pg_u_isalnum(to_char32(wc), !locale->builtin.casemap_full);
}
static bool
wc_isupper_builtin(pg_wchar wc, pg_locale_t locale)
{
- return pg_u_isupper(wc);
+ return pg_u_isupper(to_char32(wc));
}
static bool
wc_islower_builtin(pg_wchar wc, pg_locale_t locale)
{
- return pg_u_islower(wc);
+ return pg_u_islower(to_char32(wc));
}
static bool
wc_isgraph_builtin(pg_wchar wc, pg_locale_t locale)
{
- return pg_u_isgraph(wc);
+ return pg_u_isgraph(to_char32(wc));
}
static bool
wc_isprint_builtin(pg_wchar wc, pg_locale_t locale)
{
- return pg_u_isprint(wc);
+ return pg_u_isprint(to_char32(wc));
}
static bool
wc_ispunct_builtin(pg_wchar wc, pg_locale_t locale)
{
- return pg_u_ispunct(wc, !locale->builtin.casemap_full);
+ return pg_u_ispunct(to_char32(wc), !locale->builtin.casemap_full);
}
static bool
wc_isspace_builtin(pg_wchar wc, pg_locale_t locale)
{
- return pg_u_isspace(wc);
+ return pg_u_isspace(to_char32(wc));
}
static bool
wc_isxdigit_builtin(pg_wchar wc, pg_locale_t locale)
{
- return pg_u_isxdigit(wc, !locale->builtin.casemap_full);
+ return pg_u_isxdigit(to_char32(wc), !locale->builtin.casemap_full);
}
static bool
@@ -179,13 +195,13 @@ char_is_cased_builtin(char ch, pg_locale_t locale)
static pg_wchar
wc_toupper_builtin(pg_wchar wc, pg_locale_t locale)
{
- return unicode_uppercase_simple(wc);
+ return to_pg_wchar(unicode_uppercase_simple(to_char32(wc)));
}
static pg_wchar
wc_tolower_builtin(pg_wchar wc, pg_locale_t locale)
{
- return unicode_lowercase_simple(wc);
+ return to_pg_wchar(unicode_lowercase_simple(to_char32(wc)));
}
static const struct ctype_methods ctype_methods_builtin = {
diff --git a/src/backend/utils/adt/pg_locale_icu.c b/src/backend/utils/adt/pg_locale_icu.c
index 05bad202669..f5a0cc8fe41 100644
--- a/src/backend/utils/adt/pg_locale_icu.c
+++ b/src/backend/utils/adt/pg_locale_icu.c
@@ -128,6 +128,11 @@ char_is_cased_icu(char ch, pg_locale_t locale)
(ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
}
+/*
+ * XXX: many of the functions below rely on casts directly from pg_wchar to
+ * UChar32, which is correct for the UTF-8 encoding, but not in general.
+ */
+
static pg_wchar
toupper_icu(pg_wchar wc, pg_locale_t locale)
{
diff --git a/src/backend/utils/adt/pg_locale_libc.c b/src/backend/utils/adt/pg_locale_libc.c
index 7ae778dc296..9c7fcd1fc7a 100644
--- a/src/backend/utils/adt/pg_locale_libc.c
+++ b/src/backend/utils/adt/pg_locale_libc.c
@@ -45,8 +45,7 @@
*
* 2. When working in UTF8 encoding, we use the <wctype.h> functions.
* This assumes that every platform uses Unicode codepoints directly
- * as the wchar_t representation of Unicode. (XXX: ICU makes this assumption
- * even for non-UTF8 encodings, which may be a problem.) On some platforms
+ * as the wchar_t representation of Unicode. On some platforms
* wchar_t is only 16 bits wide, so we have to punt for codepoints > 0xFFFF.
*
* 3. In all other encodings, we use the <ctype.h> functions for pg_wchar
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 1fe33df2756..a710508979e 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -1637,7 +1637,7 @@ static Datum
pg_stat_wal_build_tuple(PgStat_WalCounters wal_counters,
TimestampTz stat_reset_timestamp)
{
-#define PG_STAT_WAL_COLS 5
+#define PG_STAT_WAL_COLS 6
TupleDesc tupdesc;
Datum values[PG_STAT_WAL_COLS] = {0};
bool nulls[PG_STAT_WAL_COLS] = {0};
@@ -1651,9 +1651,11 @@ pg_stat_wal_build_tuple(PgStat_WalCounters wal_counters,
INT8OID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "wal_bytes",
NUMERICOID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 4, "wal_buffers_full",
+ TupleDescInitEntry(tupdesc, (AttrNumber) 4, "wal_fpi_bytes",
+ NUMERICOID, -1, 0);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 5, "wal_buffers_full",
INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 5, "stats_reset",
+ TupleDescInitEntry(tupdesc, (AttrNumber) 6, "stats_reset",
TIMESTAMPTZOID, -1, 0);
BlessTupleDesc(tupdesc);
@@ -1669,12 +1671,18 @@ pg_stat_wal_build_tuple(PgStat_WalCounters wal_counters,
ObjectIdGetDatum(0),
Int32GetDatum(-1));
- values[3] = Int64GetDatum(wal_counters.wal_buffers_full);
+ snprintf(buf, sizeof buf, UINT64_FORMAT, wal_counters.wal_fpi_bytes);
+ values[3] = DirectFunctionCall3(numeric_in,
+ CStringGetDatum(buf),
+ ObjectIdGetDatum(0),
+ Int32GetDatum(-1));
+
+ values[4] = Int64GetDatum(wal_counters.wal_buffers_full);
if (stat_reset_timestamp != 0)
- values[4] = TimestampTzGetDatum(stat_reset_timestamp);
+ values[5] = TimestampTzGetDatum(stat_reset_timestamp);
else
- nulls[4] = true;
+ nulls[5] = true;
/* Returns the record as Datum */
PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls)));
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index e5e066a5537..cb23ad52782 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -6575,6 +6575,13 @@ get_actual_variable_range(PlannerInfo *root, VariableStatData *vardata,
continue;
/*
+ * get_actual_variable_endpoint uses the index-only-scan machinery, so
+ * ignore indexes that can't use it on their first column.
+ */
+ if (!index->canreturn[0])
+ continue;
+
+ /*
* The first index column must match the desired variable, sortop, and
* collation --- but we can use a descending-order index.
*/
diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c
index 2c398cd9e5c..8d735786e51 100644
--- a/src/backend/utils/adt/varlena.c
+++ b/src/backend/utils/adt/varlena.c
@@ -5419,12 +5419,12 @@ unicode_assigned(PG_FUNCTION_ARGS)
ereport(ERROR,
(errmsg("Unicode categorization can only be performed if server encoding is UTF8")));
- /* convert to pg_wchar */
+ /* convert to char32_t */
size = pg_mbstrlen_with_len(VARDATA_ANY(input), VARSIZE_ANY_EXHDR(input));
p = (unsigned char *) VARDATA_ANY(input);
for (int i = 0; i < size; i++)
{
- pg_wchar uchar = utf8_to_unicode(p);
+ char32_t uchar = utf8_to_unicode(p);
int category = unicode_category(uchar);
if (category == PG_U_UNASSIGNED)
@@ -5443,24 +5443,24 @@ unicode_normalize_func(PG_FUNCTION_ARGS)
char *formstr = text_to_cstring(PG_GETARG_TEXT_PP(1));
UnicodeNormalizationForm form;
int size;
- pg_wchar *input_chars;
- pg_wchar *output_chars;
+ char32_t *input_chars;
+ char32_t *output_chars;
unsigned char *p;
text *result;
int i;
form = unicode_norm_form_from_string(formstr);
- /* convert to pg_wchar */
+ /* convert to char32_t */
size = pg_mbstrlen_with_len(VARDATA_ANY(input), VARSIZE_ANY_EXHDR(input));
- input_chars = palloc((size + 1) * sizeof(pg_wchar));
+ input_chars = palloc((size + 1) * sizeof(char32_t));
p = (unsigned char *) VARDATA_ANY(input);
for (i = 0; i < size; i++)
{
input_chars[i] = utf8_to_unicode(p);
p += pg_utf_mblen(p);
}
- input_chars[i] = (pg_wchar) '\0';
+ input_chars[i] = (char32_t) '\0';
Assert((char *) p == VARDATA_ANY(input) + VARSIZE_ANY_EXHDR(input));
/* action */
@@ -5468,7 +5468,7 @@ unicode_normalize_func(PG_FUNCTION_ARGS)
/* convert back to UTF-8 string */
size = 0;
- for (pg_wchar *wp = output_chars; *wp; wp++)
+ for (char32_t *wp = output_chars; *wp; wp++)
{
unsigned char buf[4];
@@ -5480,7 +5480,7 @@ unicode_normalize_func(PG_FUNCTION_ARGS)
SET_VARSIZE(result, size + VARHDRSZ);
p = (unsigned char *) VARDATA_ANY(result);
- for (pg_wchar *wp = output_chars; *wp; wp++)
+ for (char32_t *wp = output_chars; *wp; wp++)
{
unicode_to_utf8(*wp, p);
p += pg_utf_mblen(p);
@@ -5509,8 +5509,8 @@ unicode_is_normalized(PG_FUNCTION_ARGS)
char *formstr = text_to_cstring(PG_GETARG_TEXT_PP(1));
UnicodeNormalizationForm form;
int size;
- pg_wchar *input_chars;
- pg_wchar *output_chars;
+ char32_t *input_chars;
+ char32_t *output_chars;
unsigned char *p;
int i;
UnicodeNormalizationQC quickcheck;
@@ -5519,16 +5519,16 @@ unicode_is_normalized(PG_FUNCTION_ARGS)
form = unicode_norm_form_from_string(formstr);
- /* convert to pg_wchar */
+ /* convert to char32_t */
size = pg_mbstrlen_with_len(VARDATA_ANY(input), VARSIZE_ANY_EXHDR(input));
- input_chars = palloc((size + 1) * sizeof(pg_wchar));
+ input_chars = palloc((size + 1) * sizeof(char32_t));
p = (unsigned char *) VARDATA_ANY(input);
for (i = 0; i < size; i++)
{
input_chars[i] = utf8_to_unicode(p);
p += pg_utf_mblen(p);
}
- input_chars[i] = (pg_wchar) '\0';
+ input_chars[i] = (char32_t) '\0';
Assert((char *) p == VARDATA_ANY(input) + VARSIZE_ANY_EXHDR(input));
/* quick check (see UAX #15) */
@@ -5542,11 +5542,11 @@ unicode_is_normalized(PG_FUNCTION_ARGS)
output_chars = unicode_normalize(form, input_chars);
output_size = 0;
- for (pg_wchar *wp = output_chars; *wp; wp++)
+ for (char32_t *wp = output_chars; *wp; wp++)
output_size++;
result = (size == output_size) &&
- (memcmp(input_chars, output_chars, size * sizeof(pg_wchar)) == 0);
+ (memcmp(input_chars, output_chars, size * sizeof(char32_t)) == 0);
PG_RETURN_BOOL(result);
}
@@ -5602,7 +5602,7 @@ unistr(PG_FUNCTION_ARGS)
int len;
StringInfoData str;
text *result;
- pg_wchar pair_first = 0;
+ char16_t pair_first = 0;
char cbuf[MAX_UNICODE_EQUIVALENT_STRING + 1];
instr = VARDATA_ANY(input_text);
@@ -5626,7 +5626,7 @@ unistr(PG_FUNCTION_ARGS)
else if ((len >= 5 && isxdigits_n(instr + 1, 4)) ||
(len >= 6 && instr[1] == 'u' && isxdigits_n(instr + 2, 4)))
{
- pg_wchar unicode;
+ char32_t unicode;
int offset = instr[1] == 'u' ? 2 : 1;
unicode = hexval_n(instr + offset, 4);
@@ -5662,7 +5662,7 @@ unistr(PG_FUNCTION_ARGS)
}
else if (len >= 8 && instr[1] == '+' && isxdigits_n(instr + 2, 6))
{
- pg_wchar unicode;
+ char32_t unicode;
unicode = hexval_n(instr + 2, 6);
@@ -5697,7 +5697,7 @@ unistr(PG_FUNCTION_ARGS)
}
else if (len >= 10 && instr[1] == 'U' && isxdigits_n(instr + 2, 8))
{
- pg_wchar unicode;
+ char32_t unicode;
unicode = hexval_n(instr + 2, 8);
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 2b798b823ea..915d0bc9084 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -4658,12 +4658,6 @@ CheckNNConstraintFetch(Relation relation)
break;
}
- check[found].ccenforced = conform->conenforced;
- check[found].ccvalid = conform->convalidated;
- check[found].ccnoinherit = conform->connoinherit;
- check[found].ccname = MemoryContextStrdup(CacheMemoryContext,
- NameStr(conform->conname));
-
/* Grab and test conbin is actually set */
val = fastgetattr(htup,
Anum_pg_constraint_conbin,
@@ -4676,7 +4670,13 @@ CheckNNConstraintFetch(Relation relation)
/* detoast and convert to cstring in caller's context */
char *s = TextDatumGetCString(val);
+ check[found].ccenforced = conform->conenforced;
+ check[found].ccvalid = conform->convalidated;
+ check[found].ccnoinherit = conform->connoinherit;
+ check[found].ccname = MemoryContextStrdup(CacheMemoryContext,
+ NameStr(conform->conname));
check[found].ccbin = MemoryContextStrdup(CacheMemoryContext, s);
+
pfree(s);
found++;
}
diff --git a/src/backend/utils/mb/mbutils.c b/src/backend/utils/mb/mbutils.c
index 886ecbad871..fb629ed5c8f 100644
--- a/src/backend/utils/mb/mbutils.c
+++ b/src/backend/utils/mb/mbutils.c
@@ -862,7 +862,7 @@ perform_default_encoding_conversion(const char *src, int len,
* may call this outside any transaction, or in an aborted transaction.
*/
void
-pg_unicode_to_server(pg_wchar c, unsigned char *s)
+pg_unicode_to_server(char32_t c, unsigned char *s)
{
unsigned char c_as_utf8[MAX_MULTIBYTE_CHAR_LEN + 1];
int c_as_utf8_len;
@@ -924,7 +924,7 @@ pg_unicode_to_server(pg_wchar c, unsigned char *s)
* but simply return false on conversion failure.
*/
bool
-pg_unicode_to_server_noerror(pg_wchar c, unsigned char *s)
+pg_unicode_to_server_noerror(char32_t c, unsigned char *s)
{
unsigned char c_as_utf8[MAX_MULTIBYTE_CHAR_LEN + 1];
int c_as_utf8_len;
diff --git a/src/backend/utils/misc/gen_guc_tables.pl b/src/backend/utils/misc/gen_guc_tables.pl
index b187259bf1e..3efde02bab8 100644
--- a/src/backend/utils/misc/gen_guc_tables.pl
+++ b/src/backend/utils/misc/gen_guc_tables.pl
@@ -25,10 +25,7 @@ my $parse = Catalog::ParseData($input_fname);
open my $ofh, '>', $output_fname or die;
print_boilerplate($ofh, $output_fname, 'GUC tables');
-foreach my $type (qw(bool int real string enum))
-{
- print_one_table($ofh, $type);
-}
+print_table($ofh);
close $ofh;
@@ -41,56 +38,52 @@ sub dquote
return q{"} . $s =~ s/"/\\"/gr . q{"};
}
-# Print GUC table for one type.
-sub print_one_table
+# Print GUC table.
+sub print_table
{
- my ($ofh, $type) = @_;
- my $Type = ucfirst $type;
+ my ($ofh) = @_;
print $ofh "\n\n";
- print $ofh "struct config_${type} ConfigureNames${Type}[] =\n";
+ print $ofh "struct config_generic ConfigureNames[] =\n";
print $ofh "{\n";
foreach my $entry (@{$parse})
{
- next if $entry->{type} ne $type;
-
print $ofh "#ifdef $entry->{ifdef}\n" if $entry->{ifdef};
print $ofh "\t{\n";
- print $ofh "\t\t{\n";
- printf $ofh "\t\t\t.name = %s,\n", dquote($entry->{name});
- printf $ofh "\t\t\t.context = %s,\n", $entry->{context};
- printf $ofh "\t\t\t.group = %s,\n", $entry->{group};
- printf $ofh "\t\t\t.short_desc = gettext_noop(%s),\n",
+ printf $ofh "\t\t.name = %s,\n", dquote($entry->{name});
+ printf $ofh "\t\t.context = %s,\n", $entry->{context};
+ printf $ofh "\t\t.group = %s,\n", $entry->{group};
+ printf $ofh "\t\t.short_desc = gettext_noop(%s),\n",
dquote($entry->{short_desc});
- printf $ofh "\t\t\t.long_desc = gettext_noop(%s),\n",
+ printf $ofh "\t\t.long_desc = gettext_noop(%s),\n",
dquote($entry->{long_desc})
if $entry->{long_desc};
- printf $ofh "\t\t\t.flags = %s,\n", $entry->{flags}
- if $entry->{flags};
- printf $ofh "\t\t\t.vartype = %s,\n", ('PGC_' . uc($type));
- print $ofh "\t\t},\n";
- printf $ofh "\t\t.variable = &%s,\n", $entry->{variable};
- printf $ofh "\t\t.boot_val = %s,\n", $entry->{boot_val};
- printf $ofh "\t\t.min = %s,\n", $entry->{min}
+ printf $ofh "\t\t.flags = %s,\n", $entry->{flags} if $entry->{flags};
+ printf $ofh "\t\t.vartype = %s,\n", ('PGC_' . uc($entry->{type}));
+ printf $ofh "\t\t._%s = {\n", $entry->{type};
+ printf $ofh "\t\t\t.variable = &%s,\n", $entry->{variable};
+ printf $ofh "\t\t\t.boot_val = %s,\n", $entry->{boot_val};
+ printf $ofh "\t\t\t.min = %s,\n", $entry->{min}
if $entry->{type} eq 'int' || $entry->{type} eq 'real';
- printf $ofh "\t\t.max = %s,\n", $entry->{max}
+ printf $ofh "\t\t\t.max = %s,\n", $entry->{max}
if $entry->{type} eq 'int' || $entry->{type} eq 'real';
- printf $ofh "\t\t.options = %s,\n", $entry->{options}
+ printf $ofh "\t\t\t.options = %s,\n", $entry->{options}
if $entry->{type} eq 'enum';
- printf $ofh "\t\t.check_hook = %s,\n", $entry->{check_hook}
+ printf $ofh "\t\t\t.check_hook = %s,\n", $entry->{check_hook}
if $entry->{check_hook};
- printf $ofh "\t\t.assign_hook = %s,\n", $entry->{assign_hook}
+ printf $ofh "\t\t\t.assign_hook = %s,\n", $entry->{assign_hook}
if $entry->{assign_hook};
- printf $ofh "\t\t.show_hook = %s,\n", $entry->{show_hook}
+ printf $ofh "\t\t\t.show_hook = %s,\n", $entry->{show_hook}
if $entry->{show_hook};
+ print $ofh "\t\t},\n";
print $ofh "\t},\n";
print $ofh "#endif\n" if $entry->{ifdef};
print $ofh "\n";
}
print $ofh "\t/* End-of-list marker */\n";
- print $ofh "\t{{0}}\n";
+ print $ofh "\t{0}\n";
print $ofh "};\n";
return;
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index a82286cc98a..679846da42c 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -245,12 +245,12 @@ static void ReportGUCOption(struct config_generic *record);
static void set_config_sourcefile(const char *name, char *sourcefile,
int sourceline);
static void reapply_stacked_values(struct config_generic *variable,
- struct config_string *pHolder,
+ struct config_generic *pHolder,
GucStack *stack,
const char *curvalue,
GucContext curscontext, GucSource cursource,
Oid cursrole);
-static void free_placeholder(struct config_string *pHolder);
+static void free_placeholder(struct config_generic *pHolder);
static bool validate_option_array_item(const char *name, const char *value,
bool skipIfNoPermissions);
static void write_auto_conf_file(int fd, const char *filename, ConfigVariable *head);
@@ -261,15 +261,15 @@ static bool assignable_custom_variable_name(const char *name, bool skip_errors,
int elevel);
static void do_serialize(char **destptr, Size *maxbytes,
const char *fmt,...) pg_attribute_printf(3, 4);
-static bool call_bool_check_hook(const struct config_bool *conf, bool *newval,
+static bool call_bool_check_hook(const struct config_generic *conf, bool *newval,
void **extra, GucSource source, int elevel);
-static bool call_int_check_hook(const struct config_int *conf, int *newval,
+static bool call_int_check_hook(const struct config_generic *conf, int *newval,
void **extra, GucSource source, int elevel);
-static bool call_real_check_hook(const struct config_real *conf, double *newval,
+static bool call_real_check_hook(const struct config_generic *conf, double *newval,
void **extra, GucSource source, int elevel);
-static bool call_string_check_hook(const struct config_string *conf, char **newval,
+static bool call_string_check_hook(const struct config_generic *conf, char **newval,
void **extra, GucSource source, int elevel);
-static bool call_enum_check_hook(const struct config_enum *conf, int *newval,
+static bool call_enum_check_hook(const struct config_generic *conf, int *newval,
void **extra, GucSource source, int elevel);
@@ -703,13 +703,13 @@ guc_free(void *ptr)
* Detect whether strval is referenced anywhere in a GUC string item
*/
static bool
-string_field_used(struct config_string *conf, char *strval)
+string_field_used(struct config_generic *conf, char *strval)
{
- if (strval == *(conf->variable) ||
- strval == conf->reset_val ||
- strval == conf->boot_val)
+ if (strval == *(conf->_string.variable) ||
+ strval == conf->_string.reset_val ||
+ strval == conf->_string.boot_val)
return true;
- for (GucStack *stack = conf->gen.stack; stack; stack = stack->prev)
+ for (GucStack *stack = conf->stack; stack; stack = stack->prev)
{
if (strval == stack->prior.val.stringval ||
strval == stack->masked.val.stringval)
@@ -724,7 +724,7 @@ string_field_used(struct config_string *conf, char *strval)
* states).
*/
static void
-set_string_field(struct config_string *conf, char **field, char *newval)
+set_string_field(struct config_generic *conf, char **field, char *newval)
{
char *oldval = *field;
@@ -787,25 +787,19 @@ set_stack_value(struct config_generic *gconf, config_var_value *val)
switch (gconf->vartype)
{
case PGC_BOOL:
- val->val.boolval =
- *((struct config_bool *) gconf)->variable;
+ val->val.boolval = *gconf->_bool.variable;
break;
case PGC_INT:
- val->val.intval =
- *((struct config_int *) gconf)->variable;
+ val->val.intval = *gconf->_int.variable;
break;
case PGC_REAL:
- val->val.realval =
- *((struct config_real *) gconf)->variable;
+ val->val.realval = *gconf->_real.variable;
break;
case PGC_STRING:
- set_string_field((struct config_string *) gconf,
- &(val->val.stringval),
- *((struct config_string *) gconf)->variable);
+ set_string_field(gconf, &(val->val.stringval), *gconf->_string.variable);
break;
case PGC_ENUM:
- val->val.enumval =
- *((struct config_enum *) gconf)->variable;
+ val->val.enumval = *gconf->_enum.variable;
break;
}
set_extra_field(gconf, &(val->extra), gconf->extra);
@@ -827,7 +821,7 @@ discard_stack_value(struct config_generic *gconf, config_var_value *val)
/* no need to do anything */
break;
case PGC_STRING:
- set_string_field((struct config_string *) gconf,
+ set_string_field(gconf,
&(val->val.stringval),
NULL);
break;
@@ -892,19 +886,7 @@ build_guc_variables(void)
/*
* Count all the built-in variables.
*/
- for (int i = 0; ConfigureNamesBool[i].gen.name; i++)
- num_vars++;
-
- for (int i = 0; ConfigureNamesInt[i].gen.name; i++)
- num_vars++;
-
- for (int i = 0; ConfigureNamesReal[i].gen.name; i++)
- num_vars++;
-
- for (int i = 0; ConfigureNamesString[i].gen.name; i++)
- num_vars++;
-
- for (int i = 0; ConfigureNamesEnum[i].gen.name; i++)
+ for (int i = 0; ConfigureNames[i].name; i++)
num_vars++;
/*
@@ -922,57 +904,9 @@ build_guc_variables(void)
&hash_ctl,
HASH_ELEM | HASH_FUNCTION | HASH_COMPARE | HASH_CONTEXT);
- for (int i = 0; ConfigureNamesBool[i].gen.name; i++)
- {
- struct config_generic *gucvar = &ConfigureNamesBool[i].gen;
-
- hentry = (GUCHashEntry *) hash_search(guc_hashtab,
- &gucvar->name,
- HASH_ENTER,
- &found);
- Assert(!found);
- hentry->gucvar = gucvar;
- }
-
- for (int i = 0; ConfigureNamesInt[i].gen.name; i++)
- {
- struct config_generic *gucvar = &ConfigureNamesInt[i].gen;
-
- hentry = (GUCHashEntry *) hash_search(guc_hashtab,
- &gucvar->name,
- HASH_ENTER,
- &found);
- Assert(!found);
- hentry->gucvar = gucvar;
- }
-
- for (int i = 0; ConfigureNamesReal[i].gen.name; i++)
- {
- struct config_generic *gucvar = &ConfigureNamesReal[i].gen;
-
- hentry = (GUCHashEntry *) hash_search(guc_hashtab,
- &gucvar->name,
- HASH_ENTER,
- &found);
- Assert(!found);
- hentry->gucvar = gucvar;
- }
-
- for (int i = 0; ConfigureNamesString[i].gen.name; i++)
- {
- struct config_generic *gucvar = &ConfigureNamesString[i].gen;
-
- hentry = (GUCHashEntry *) hash_search(guc_hashtab,
- &gucvar->name,
- HASH_ENTER,
- &found);
- Assert(!found);
- hentry->gucvar = gucvar;
- }
-
- for (int i = 0; ConfigureNamesEnum[i].gen.name; i++)
+ for (int i = 0; ConfigureNames[i].name; i++)
{
- struct config_generic *gucvar = &ConfigureNamesEnum[i].gen;
+ struct config_generic *gucvar = &ConfigureNames[i];
hentry = (GUCHashEntry *) hash_search(guc_hashtab,
&gucvar->name,
@@ -1122,44 +1056,42 @@ assignable_custom_variable_name(const char *name, bool skip_errors, int elevel)
static struct config_generic *
add_placeholder_variable(const char *name, int elevel)
{
- size_t sz = sizeof(struct config_string) + sizeof(char *);
- struct config_string *var;
- struct config_generic *gen;
+ size_t sz = sizeof(struct config_generic) + sizeof(char *);
+ struct config_generic *var;
- var = (struct config_string *) guc_malloc(elevel, sz);
+ var = (struct config_generic *) guc_malloc(elevel, sz);
if (var == NULL)
return NULL;
memset(var, 0, sz);
- gen = &var->gen;
- gen->name = guc_strdup(elevel, name);
- if (gen->name == NULL)
+ var->name = guc_strdup(elevel, name);
+ if (var->name == NULL)
{
guc_free(var);
return NULL;
}
- gen->context = PGC_USERSET;
- gen->group = CUSTOM_OPTIONS;
- gen->short_desc = "GUC placeholder variable";
- gen->flags = GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE | GUC_CUSTOM_PLACEHOLDER;
- gen->vartype = PGC_STRING;
+ var->context = PGC_USERSET;
+ var->group = CUSTOM_OPTIONS;
+ var->short_desc = "GUC placeholder variable";
+ var->flags = GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE | GUC_CUSTOM_PLACEHOLDER;
+ var->vartype = PGC_STRING;
/*
* The char* is allocated at the end of the struct since we have no
* 'static' place to point to. Note that the current value, as well as
* the boot and reset values, start out NULL.
*/
- var->variable = (char **) (var + 1);
+ var->_string.variable = (char **) (var + 1);
- if (!add_guc_variable((struct config_generic *) var, elevel))
+ if (!add_guc_variable(var, elevel))
{
- guc_free(unconstify(char *, gen->name));
+ guc_free(unconstify(char *, var->name));
guc_free(var);
return NULL;
}
- return gen;
+ return var;
}
/*
@@ -1385,62 +1317,62 @@ check_GUC_init(const struct config_generic *gconf)
{
case PGC_BOOL:
{
- const struct config_bool *conf = (const struct config_bool *) gconf;
+ const struct config_bool *conf = &gconf->_bool;
if (*conf->variable && !conf->boot_val)
{
elog(LOG, "GUC (PGC_BOOL) %s, boot_val=%d, C-var=%d",
- conf->gen.name, conf->boot_val, *conf->variable);
+ gconf->name, conf->boot_val, *conf->variable);
return false;
}
break;
}
case PGC_INT:
{
- const struct config_int *conf = (const struct config_int *) gconf;
+ const struct config_int *conf = &gconf->_int;
if (*conf->variable != 0 && *conf->variable != conf->boot_val)
{
elog(LOG, "GUC (PGC_INT) %s, boot_val=%d, C-var=%d",
- conf->gen.name, conf->boot_val, *conf->variable);
+ gconf->name, conf->boot_val, *conf->variable);
return false;
}
break;
}
case PGC_REAL:
{
- const struct config_real *conf = (const struct config_real *) gconf;
+ const struct config_real *conf = &gconf->_real;
if (*conf->variable != 0.0 && *conf->variable != conf->boot_val)
{
elog(LOG, "GUC (PGC_REAL) %s, boot_val=%g, C-var=%g",
- conf->gen.name, conf->boot_val, *conf->variable);
+ gconf->name, conf->boot_val, *conf->variable);
return false;
}
break;
}
case PGC_STRING:
{
- const struct config_string *conf = (const struct config_string *) gconf;
+ const struct config_string *conf = &gconf->_string;
if (*conf->variable != NULL &&
(conf->boot_val == NULL ||
strcmp(*conf->variable, conf->boot_val) != 0))
{
elog(LOG, "GUC (PGC_STRING) %s, boot_val=%s, C-var=%s",
- conf->gen.name, conf->boot_val ? conf->boot_val : "<null>", *conf->variable);
+ gconf->name, conf->boot_val ? conf->boot_val : "<null>", *conf->variable);
return false;
}
break;
}
case PGC_ENUM:
{
- const struct config_enum *conf = (const struct config_enum *) gconf;
+ const struct config_enum *conf = &gconf->_enum;
if (*conf->variable != conf->boot_val)
{
elog(LOG, "GUC (PGC_ENUM) %s, boot_val=%d, C-var=%d",
- conf->gen.name, conf->boot_val, *conf->variable);
+ gconf->name, conf->boot_val, *conf->variable);
return false;
}
break;
@@ -1607,13 +1539,13 @@ InitializeOneGUCOption(struct config_generic *gconf)
{
case PGC_BOOL:
{
- struct config_bool *conf = (struct config_bool *) gconf;
+ struct config_bool *conf = &gconf->_bool;
bool newval = conf->boot_val;
- if (!call_bool_check_hook(conf, &newval, &extra,
+ if (!call_bool_check_hook(gconf, &newval, &extra,
PGC_S_DEFAULT, LOG))
elog(FATAL, "failed to initialize %s to %d",
- conf->gen.name, (int) newval);
+ gconf->name, (int) newval);
if (conf->assign_hook)
conf->assign_hook(newval, extra);
*conf->variable = conf->reset_val = newval;
@@ -1621,15 +1553,15 @@ InitializeOneGUCOption(struct config_generic *gconf)
}
case PGC_INT:
{
- struct config_int *conf = (struct config_int *) gconf;
+ struct config_int *conf = &gconf->_int;
int newval = conf->boot_val;
Assert(newval >= conf->min);
Assert(newval <= conf->max);
- if (!call_int_check_hook(conf, &newval, &extra,
+ if (!call_int_check_hook(gconf, &newval, &extra,
PGC_S_DEFAULT, LOG))
elog(FATAL, "failed to initialize %s to %d",
- conf->gen.name, newval);
+ gconf->name, newval);
if (conf->assign_hook)
conf->assign_hook(newval, extra);
*conf->variable = conf->reset_val = newval;
@@ -1637,15 +1569,15 @@ InitializeOneGUCOption(struct config_generic *gconf)
}
case PGC_REAL:
{
- struct config_real *conf = (struct config_real *) gconf;
+ struct config_real *conf = &gconf->_real;
double newval = conf->boot_val;
Assert(newval >= conf->min);
Assert(newval <= conf->max);
- if (!call_real_check_hook(conf, &newval, &extra,
+ if (!call_real_check_hook(gconf, &newval, &extra,
PGC_S_DEFAULT, LOG))
elog(FATAL, "failed to initialize %s to %g",
- conf->gen.name, newval);
+ gconf->name, newval);
if (conf->assign_hook)
conf->assign_hook(newval, extra);
*conf->variable = conf->reset_val = newval;
@@ -1653,7 +1585,7 @@ InitializeOneGUCOption(struct config_generic *gconf)
}
case PGC_STRING:
{
- struct config_string *conf = (struct config_string *) gconf;
+ struct config_string *conf = &gconf->_string;
char *newval;
/* non-NULL boot_val must always get strdup'd */
@@ -1662,10 +1594,10 @@ InitializeOneGUCOption(struct config_generic *gconf)
else
newval = NULL;
- if (!call_string_check_hook(conf, &newval, &extra,
+ if (!call_string_check_hook(gconf, &newval, &extra,
PGC_S_DEFAULT, LOG))
elog(FATAL, "failed to initialize %s to \"%s\"",
- conf->gen.name, newval ? newval : "");
+ gconf->name, newval ? newval : "");
if (conf->assign_hook)
conf->assign_hook(newval, extra);
*conf->variable = conf->reset_val = newval;
@@ -1673,13 +1605,13 @@ InitializeOneGUCOption(struct config_generic *gconf)
}
case PGC_ENUM:
{
- struct config_enum *conf = (struct config_enum *) gconf;
+ struct config_enum *conf = &gconf->_enum;
int newval = conf->boot_val;
- if (!call_enum_check_hook(conf, &newval, &extra,
+ if (!call_enum_check_hook(gconf, &newval, &extra,
PGC_S_DEFAULT, LOG))
elog(FATAL, "failed to initialize %s to %d",
- conf->gen.name, newval);
+ gconf->name, newval);
if (conf->assign_hook)
conf->assign_hook(newval, extra);
*conf->variable = conf->reset_val = newval;
@@ -1726,7 +1658,7 @@ SelectConfigFiles(const char *userDoption, const char *progname)
char *fname;
bool fname_is_malloced;
struct stat stat_buf;
- struct config_string *data_directory_rec;
+ struct config_generic *data_directory_rec;
/* configdir is -D option, or $PGDATA if no -D */
if (userDoption)
@@ -1806,10 +1738,10 @@ SelectConfigFiles(const char *userDoption, const char *progname)
* Note: SetDataDir will copy and absolute-ize its argument, so we don't
* have to.
*/
- data_directory_rec = (struct config_string *)
+ data_directory_rec =
find_option("data_directory", false, false, PANIC);
- if (*data_directory_rec->variable)
- SetDataDir(*data_directory_rec->variable);
+ if (*data_directory_rec->_string.variable)
+ SetDataDir(*data_directory_rec->_string.variable);
else if (configdir)
SetDataDir(configdir);
else
@@ -1971,62 +1903,62 @@ ResetAllOptions(void)
{
case PGC_BOOL:
{
- struct config_bool *conf = (struct config_bool *) gconf;
+ struct config_bool *conf = &gconf->_bool;
if (conf->assign_hook)
conf->assign_hook(conf->reset_val,
- conf->gen.reset_extra);
+ gconf->reset_extra);
*conf->variable = conf->reset_val;
- set_extra_field(&conf->gen, &conf->gen.extra,
- conf->gen.reset_extra);
+ set_extra_field(gconf, &gconf->extra,
+ gconf->reset_extra);
break;
}
case PGC_INT:
{
- struct config_int *conf = (struct config_int *) gconf;
+ struct config_int *conf = &gconf->_int;
if (conf->assign_hook)
conf->assign_hook(conf->reset_val,
- conf->gen.reset_extra);
+ gconf->reset_extra);
*conf->variable = conf->reset_val;
- set_extra_field(&conf->gen, &conf->gen.extra,
- conf->gen.reset_extra);
+ set_extra_field(gconf, &gconf->extra,
+ gconf->reset_extra);
break;
}
case PGC_REAL:
{
- struct config_real *conf = (struct config_real *) gconf;
+ struct config_real *conf = &gconf->_real;
if (conf->assign_hook)
conf->assign_hook(conf->reset_val,
- conf->gen.reset_extra);
+ gconf->reset_extra);
*conf->variable = conf->reset_val;
- set_extra_field(&conf->gen, &conf->gen.extra,
- conf->gen.reset_extra);
+ set_extra_field(gconf, &gconf->extra,
+ gconf->reset_extra);
break;
}
case PGC_STRING:
{
- struct config_string *conf = (struct config_string *) gconf;
+ struct config_string *conf = &gconf->_string;
if (conf->assign_hook)
conf->assign_hook(conf->reset_val,
- conf->gen.reset_extra);
- set_string_field(conf, conf->variable, conf->reset_val);
- set_extra_field(&conf->gen, &conf->gen.extra,
- conf->gen.reset_extra);
+ gconf->reset_extra);
+ set_string_field(gconf, conf->variable, conf->reset_val);
+ set_extra_field(gconf, &gconf->extra,
+ gconf->reset_extra);
break;
}
case PGC_ENUM:
{
- struct config_enum *conf = (struct config_enum *) gconf;
+ struct config_enum *conf = &gconf->_enum;
if (conf->assign_hook)
conf->assign_hook(conf->reset_val,
- conf->gen.reset_extra);
+ gconf->reset_extra);
*conf->variable = conf->reset_val;
- set_extra_field(&conf->gen, &conf->gen.extra,
- conf->gen.reset_extra);
+ set_extra_field(gconf, &gconf->extra,
+ gconf->reset_extra);
break;
}
}
@@ -2346,17 +2278,17 @@ AtEOXact_GUC(bool isCommit, int nestLevel)
{
case PGC_BOOL:
{
- struct config_bool *conf = (struct config_bool *) gconf;
+ struct config_bool *conf = &gconf->_bool;
bool newval = newvalue.val.boolval;
void *newextra = newvalue.extra;
if (*conf->variable != newval ||
- conf->gen.extra != newextra)
+ gconf->extra != newextra)
{
if (conf->assign_hook)
conf->assign_hook(newval, newextra);
*conf->variable = newval;
- set_extra_field(&conf->gen, &conf->gen.extra,
+ set_extra_field(gconf, &gconf->extra,
newextra);
changed = true;
}
@@ -2364,17 +2296,17 @@ AtEOXact_GUC(bool isCommit, int nestLevel)
}
case PGC_INT:
{
- struct config_int *conf = (struct config_int *) gconf;
+ struct config_int *conf = &gconf->_int;
int newval = newvalue.val.intval;
void *newextra = newvalue.extra;
if (*conf->variable != newval ||
- conf->gen.extra != newextra)
+ gconf->extra != newextra)
{
if (conf->assign_hook)
conf->assign_hook(newval, newextra);
*conf->variable = newval;
- set_extra_field(&conf->gen, &conf->gen.extra,
+ set_extra_field(gconf, &gconf->extra,
newextra);
changed = true;
}
@@ -2382,17 +2314,17 @@ AtEOXact_GUC(bool isCommit, int nestLevel)
}
case PGC_REAL:
{
- struct config_real *conf = (struct config_real *) gconf;
+ struct config_real *conf = &gconf->_real;
double newval = newvalue.val.realval;
void *newextra = newvalue.extra;
if (*conf->variable != newval ||
- conf->gen.extra != newextra)
+ gconf->extra != newextra)
{
if (conf->assign_hook)
conf->assign_hook(newval, newextra);
*conf->variable = newval;
- set_extra_field(&conf->gen, &conf->gen.extra,
+ set_extra_field(gconf, &gconf->extra,
newextra);
changed = true;
}
@@ -2400,17 +2332,17 @@ AtEOXact_GUC(bool isCommit, int nestLevel)
}
case PGC_STRING:
{
- struct config_string *conf = (struct config_string *) gconf;
+ struct config_string *conf = &gconf->_string;
char *newval = newvalue.val.stringval;
void *newextra = newvalue.extra;
if (*conf->variable != newval ||
- conf->gen.extra != newextra)
+ gconf->extra != newextra)
{
if (conf->assign_hook)
conf->assign_hook(newval, newextra);
- set_string_field(conf, conf->variable, newval);
- set_extra_field(&conf->gen, &conf->gen.extra,
+ set_string_field(gconf, conf->variable, newval);
+ set_extra_field(gconf, &gconf->extra,
newextra);
changed = true;
}
@@ -2421,23 +2353,23 @@ AtEOXact_GUC(bool isCommit, int nestLevel)
* we have type-specific code anyway, might as
* well inline it.
*/
- set_string_field(conf, &stack->prior.val.stringval, NULL);
- set_string_field(conf, &stack->masked.val.stringval, NULL);
+ set_string_field(gconf, &stack->prior.val.stringval, NULL);
+ set_string_field(gconf, &stack->masked.val.stringval, NULL);
break;
}
case PGC_ENUM:
{
- struct config_enum *conf = (struct config_enum *) gconf;
+ struct config_enum *conf = &gconf->_enum;
int newval = newvalue.val.enumval;
void *newextra = newvalue.extra;
if (*conf->variable != newval ||
- conf->gen.extra != newextra)
+ gconf->extra != newextra)
{
if (conf->assign_hook)
conf->assign_hook(newval, newextra);
*conf->variable = newval;
- set_extra_field(&conf->gen, &conf->gen.extra,
+ set_extra_field(gconf, &gconf->extra,
newextra);
changed = true;
}
@@ -2960,16 +2892,16 @@ parse_real(const char *value, double *result, int flags, const char **hintmsg)
* allocated for modification.
*/
const char *
-config_enum_lookup_by_value(const struct config_enum *record, int val)
+config_enum_lookup_by_value(const struct config_generic *record, int val)
{
- for (const struct config_enum_entry *entry = record->options; entry && entry->name; entry++)
+ for (const struct config_enum_entry *entry = record->_enum.options; entry && entry->name; entry++)
{
if (entry->val == val)
return entry->name;
}
elog(ERROR, "could not find enum option %d for %s",
- val, record->gen.name);
+ val, record->name);
return NULL; /* silence compiler */
}
@@ -3070,41 +3002,39 @@ parse_and_validate_value(const struct config_generic *record,
{
case PGC_BOOL:
{
- const struct config_bool *conf = (const struct config_bool *) record;
-
if (!parse_bool(value, &newval->boolval))
{
ereport(elevel,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("parameter \"%s\" requires a Boolean value",
- conf->gen.name)));
+ record->name)));
return false;
}
- if (!call_bool_check_hook(conf, &newval->boolval, newextra,
+ if (!call_bool_check_hook(record, &newval->boolval, newextra,
source, elevel))
return false;
}
break;
case PGC_INT:
{
- const struct config_int *conf = (const struct config_int *) record;
+ const struct config_int *conf = &record->_int;
const char *hintmsg;
if (!parse_int(value, &newval->intval,
- conf->gen.flags, &hintmsg))
+ record->flags, &hintmsg))
{
ereport(elevel,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid value for parameter \"%s\": \"%s\"",
- conf->gen.name, value),
+ record->name, value),
hintmsg ? errhint("%s", _(hintmsg)) : 0));
return false;
}
if (newval->intval < conf->min || newval->intval > conf->max)
{
- const char *unit = get_config_unit_name(conf->gen.flags);
+ const char *unit = get_config_unit_name(record->flags);
const char *unitspace;
if (unit)
@@ -3116,36 +3046,36 @@ parse_and_validate_value(const struct config_generic *record,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("%d%s%s is outside the valid range for parameter \"%s\" (%d%s%s .. %d%s%s)",
newval->intval, unitspace, unit,
- conf->gen.name,
+ record->name,
conf->min, unitspace, unit,
conf->max, unitspace, unit)));
return false;
}
- if (!call_int_check_hook(conf, &newval->intval, newextra,
+ if (!call_int_check_hook(record, &newval->intval, newextra,
source, elevel))
return false;
}
break;
case PGC_REAL:
{
- const struct config_real *conf = (const struct config_real *) record;
+ const struct config_real *conf = &record->_real;
const char *hintmsg;
if (!parse_real(value, &newval->realval,
- conf->gen.flags, &hintmsg))
+ record->flags, &hintmsg))
{
ereport(elevel,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid value for parameter \"%s\": \"%s\"",
- conf->gen.name, value),
+ record->name, value),
hintmsg ? errhint("%s", _(hintmsg)) : 0));
return false;
}
if (newval->realval < conf->min || newval->realval > conf->max)
{
- const char *unit = get_config_unit_name(conf->gen.flags);
+ const char *unit = get_config_unit_name(record->flags);
const char *unitspace;
if (unit)
@@ -3157,21 +3087,19 @@ parse_and_validate_value(const struct config_generic *record,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("%g%s%s is outside the valid range for parameter \"%s\" (%g%s%s .. %g%s%s)",
newval->realval, unitspace, unit,
- conf->gen.name,
+ record->name,
conf->min, unitspace, unit,
conf->max, unitspace, unit)));
return false;
}
- if (!call_real_check_hook(conf, &newval->realval, newextra,
+ if (!call_real_check_hook(record, &newval->realval, newextra,
source, elevel))
return false;
}
break;
case PGC_STRING:
{
- const struct config_string *conf = (const struct config_string *) record;
-
/*
* The value passed by the caller could be transient, so we
* always strdup it.
@@ -3184,12 +3112,12 @@ parse_and_validate_value(const struct config_generic *record,
* The only built-in "parsing" check we have is to apply
* truncation if GUC_IS_NAME.
*/
- if (conf->gen.flags & GUC_IS_NAME)
+ if (record->flags & GUC_IS_NAME)
truncate_identifier(newval->stringval,
strlen(newval->stringval),
true);
- if (!call_string_check_hook(conf, &newval->stringval, newextra,
+ if (!call_string_check_hook(record, &newval->stringval, newextra,
source, elevel))
{
guc_free(newval->stringval);
@@ -3200,7 +3128,7 @@ parse_and_validate_value(const struct config_generic *record,
break;
case PGC_ENUM:
{
- const struct config_enum *conf = (const struct config_enum *) record;
+ const struct config_enum *conf = &record->_enum;
if (!config_enum_lookup_by_name(conf, value, &newval->enumval))
{
@@ -3213,7 +3141,7 @@ parse_and_validate_value(const struct config_generic *record,
ereport(elevel,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid value for parameter \"%s\": \"%s\"",
- conf->gen.name, value),
+ record->name, value),
hintmsg ? errhint("%s", _(hintmsg)) : 0));
if (hintmsg)
@@ -3221,7 +3149,7 @@ parse_and_validate_value(const struct config_generic *record,
return false;
}
- if (!call_enum_check_hook(conf, &newval->enumval, newextra,
+ if (!call_enum_check_hook(record, &newval->enumval, newextra,
source, elevel))
return false;
}
@@ -3639,7 +3567,7 @@ set_config_with_handle(const char *name, config_handle *handle,
{
case PGC_BOOL:
{
- struct config_bool *conf = (struct config_bool *) record;
+ struct config_bool *conf = &record->_bool;
#define newval (newval_union.boolval)
@@ -3653,23 +3581,23 @@ set_config_with_handle(const char *name, config_handle *handle,
else if (source == PGC_S_DEFAULT)
{
newval = conf->boot_val;
- if (!call_bool_check_hook(conf, &newval, &newextra,
+ if (!call_bool_check_hook(record, &newval, &newextra,
source, elevel))
return 0;
}
else
{
newval = conf->reset_val;
- newextra = conf->gen.reset_extra;
- source = conf->gen.reset_source;
- context = conf->gen.reset_scontext;
- srole = conf->gen.reset_srole;
+ newextra = record->reset_extra;
+ source = record->reset_source;
+ context = record->reset_scontext;
+ srole = record->reset_srole;
}
if (prohibitValueChange)
{
/* Release newextra, unless it's reset_extra */
- if (newextra && !extra_field_used(&conf->gen, newextra))
+ if (newextra && !extra_field_used(record, newextra))
guc_free(newextra);
if (*conf->variable != newval)
@@ -3678,7 +3606,7 @@ set_config_with_handle(const char *name, config_handle *handle,
ereport(elevel,
(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
errmsg("parameter \"%s\" cannot be changed without restarting the server",
- conf->gen.name)));
+ record->name)));
return 0;
}
record->status &= ~GUC_PENDING_RESTART;
@@ -3689,34 +3617,34 @@ set_config_with_handle(const char *name, config_handle *handle,
{
/* Save old value to support transaction abort */
if (!makeDefault)
- push_old_value(&conf->gen, action);
+ push_old_value(record, action);
if (conf->assign_hook)
conf->assign_hook(newval, newextra);
*conf->variable = newval;
- set_extra_field(&conf->gen, &conf->gen.extra,
+ set_extra_field(record, &record->extra,
newextra);
- set_guc_source(&conf->gen, source);
- conf->gen.scontext = context;
- conf->gen.srole = srole;
+ set_guc_source(record, source);
+ record->scontext = context;
+ record->srole = srole;
}
if (makeDefault)
{
- if (conf->gen.reset_source <= source)
+ if (record->reset_source <= source)
{
conf->reset_val = newval;
- set_extra_field(&conf->gen, &conf->gen.reset_extra,
+ set_extra_field(record, &record->reset_extra,
newextra);
- conf->gen.reset_source = source;
- conf->gen.reset_scontext = context;
- conf->gen.reset_srole = srole;
+ record->reset_source = source;
+ record->reset_scontext = context;
+ record->reset_srole = srole;
}
- for (GucStack *stack = conf->gen.stack; stack; stack = stack->prev)
+ for (GucStack *stack = record->stack; stack; stack = stack->prev)
{
if (stack->source <= source)
{
stack->prior.val.boolval = newval;
- set_extra_field(&conf->gen, &stack->prior.extra,
+ set_extra_field(record, &stack->prior.extra,
newextra);
stack->source = source;
stack->scontext = context;
@@ -3726,7 +3654,7 @@ set_config_with_handle(const char *name, config_handle *handle,
}
/* Perhaps we didn't install newextra anywhere */
- if (newextra && !extra_field_used(&conf->gen, newextra))
+ if (newextra && !extra_field_used(record, newextra))
guc_free(newextra);
break;
@@ -3735,7 +3663,7 @@ set_config_with_handle(const char *name, config_handle *handle,
case PGC_INT:
{
- struct config_int *conf = (struct config_int *) record;
+ struct config_int *conf = &record->_int;
#define newval (newval_union.intval)
@@ -3749,23 +3677,23 @@ set_config_with_handle(const char *name, config_handle *handle,
else if (source == PGC_S_DEFAULT)
{
newval = conf->boot_val;
- if (!call_int_check_hook(conf, &newval, &newextra,
+ if (!call_int_check_hook(record, &newval, &newextra,
source, elevel))
return 0;
}
else
{
newval = conf->reset_val;
- newextra = conf->gen.reset_extra;
- source = conf->gen.reset_source;
- context = conf->gen.reset_scontext;
- srole = conf->gen.reset_srole;
+ newextra = record->reset_extra;
+ source = record->reset_source;
+ context = record->reset_scontext;
+ srole = record->reset_srole;
}
if (prohibitValueChange)
{
/* Release newextra, unless it's reset_extra */
- if (newextra && !extra_field_used(&conf->gen, newextra))
+ if (newextra && !extra_field_used(record, newextra))
guc_free(newextra);
if (*conf->variable != newval)
@@ -3774,7 +3702,7 @@ set_config_with_handle(const char *name, config_handle *handle,
ereport(elevel,
(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
errmsg("parameter \"%s\" cannot be changed without restarting the server",
- conf->gen.name)));
+ record->name)));
return 0;
}
record->status &= ~GUC_PENDING_RESTART;
@@ -3785,34 +3713,34 @@ set_config_with_handle(const char *name, config_handle *handle,
{
/* Save old value to support transaction abort */
if (!makeDefault)
- push_old_value(&conf->gen, action);
+ push_old_value(record, action);
if (conf->assign_hook)
conf->assign_hook(newval, newextra);
*conf->variable = newval;
- set_extra_field(&conf->gen, &conf->gen.extra,
+ set_extra_field(record, &record->extra,
newextra);
- set_guc_source(&conf->gen, source);
- conf->gen.scontext = context;
- conf->gen.srole = srole;
+ set_guc_source(record, source);
+ record->scontext = context;
+ record->srole = srole;
}
if (makeDefault)
{
- if (conf->gen.reset_source <= source)
+ if (record->reset_source <= source)
{
conf->reset_val = newval;
- set_extra_field(&conf->gen, &conf->gen.reset_extra,
+ set_extra_field(record, &record->reset_extra,
newextra);
- conf->gen.reset_source = source;
- conf->gen.reset_scontext = context;
- conf->gen.reset_srole = srole;
+ record->reset_source = source;
+ record->reset_scontext = context;
+ record->reset_srole = srole;
}
- for (GucStack *stack = conf->gen.stack; stack; stack = stack->prev)
+ for (GucStack *stack = record->stack; stack; stack = stack->prev)
{
if (stack->source <= source)
{
stack->prior.val.intval = newval;
- set_extra_field(&conf->gen, &stack->prior.extra,
+ set_extra_field(record, &stack->prior.extra,
newextra);
stack->source = source;
stack->scontext = context;
@@ -3822,7 +3750,7 @@ set_config_with_handle(const char *name, config_handle *handle,
}
/* Perhaps we didn't install newextra anywhere */
- if (newextra && !extra_field_used(&conf->gen, newextra))
+ if (newextra && !extra_field_used(record, newextra))
guc_free(newextra);
break;
@@ -3831,7 +3759,7 @@ set_config_with_handle(const char *name, config_handle *handle,
case PGC_REAL:
{
- struct config_real *conf = (struct config_real *) record;
+ struct config_real *conf = &record->_real;
#define newval (newval_union.realval)
@@ -3845,23 +3773,23 @@ set_config_with_handle(const char *name, config_handle *handle,
else if (source == PGC_S_DEFAULT)
{
newval = conf->boot_val;
- if (!call_real_check_hook(conf, &newval, &newextra,
+ if (!call_real_check_hook(record, &newval, &newextra,
source, elevel))
return 0;
}
else
{
newval = conf->reset_val;
- newextra = conf->gen.reset_extra;
- source = conf->gen.reset_source;
- context = conf->gen.reset_scontext;
- srole = conf->gen.reset_srole;
+ newextra = record->reset_extra;
+ source = record->reset_source;
+ context = record->reset_scontext;
+ srole = record->reset_srole;
}
if (prohibitValueChange)
{
/* Release newextra, unless it's reset_extra */
- if (newextra && !extra_field_used(&conf->gen, newextra))
+ if (newextra && !extra_field_used(record, newextra))
guc_free(newextra);
if (*conf->variable != newval)
@@ -3870,7 +3798,7 @@ set_config_with_handle(const char *name, config_handle *handle,
ereport(elevel,
(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
errmsg("parameter \"%s\" cannot be changed without restarting the server",
- conf->gen.name)));
+ record->name)));
return 0;
}
record->status &= ~GUC_PENDING_RESTART;
@@ -3881,34 +3809,34 @@ set_config_with_handle(const char *name, config_handle *handle,
{
/* Save old value to support transaction abort */
if (!makeDefault)
- push_old_value(&conf->gen, action);
+ push_old_value(record, action);
if (conf->assign_hook)
conf->assign_hook(newval, newextra);
*conf->variable = newval;
- set_extra_field(&conf->gen, &conf->gen.extra,
+ set_extra_field(record, &record->extra,
newextra);
- set_guc_source(&conf->gen, source);
- conf->gen.scontext = context;
- conf->gen.srole = srole;
+ set_guc_source(record, source);
+ record->scontext = context;
+ record->srole = srole;
}
if (makeDefault)
{
- if (conf->gen.reset_source <= source)
+ if (record->reset_source <= source)
{
conf->reset_val = newval;
- set_extra_field(&conf->gen, &conf->gen.reset_extra,
+ set_extra_field(record, &record->reset_extra,
newextra);
- conf->gen.reset_source = source;
- conf->gen.reset_scontext = context;
- conf->gen.reset_srole = srole;
+ record->reset_source = source;
+ record->reset_scontext = context;
+ record->reset_srole = srole;
}
- for (GucStack *stack = conf->gen.stack; stack; stack = stack->prev)
+ for (GucStack *stack = record->stack; stack; stack = stack->prev)
{
if (stack->source <= source)
{
stack->prior.val.realval = newval;
- set_extra_field(&conf->gen, &stack->prior.extra,
+ set_extra_field(record, &stack->prior.extra,
newextra);
stack->source = source;
stack->scontext = context;
@@ -3918,7 +3846,7 @@ set_config_with_handle(const char *name, config_handle *handle,
}
/* Perhaps we didn't install newextra anywhere */
- if (newextra && !extra_field_used(&conf->gen, newextra))
+ if (newextra && !extra_field_used(record, newextra))
guc_free(newextra);
break;
@@ -3927,7 +3855,7 @@ set_config_with_handle(const char *name, config_handle *handle,
case PGC_STRING:
{
- struct config_string *conf = (struct config_string *) record;
+ struct config_string *conf = &record->_string;
GucContext orig_context = context;
GucSource orig_source = source;
Oid orig_srole = srole;
@@ -3953,7 +3881,7 @@ set_config_with_handle(const char *name, config_handle *handle,
else
newval = NULL;
- if (!call_string_check_hook(conf, &newval, &newextra,
+ if (!call_string_check_hook(record, &newval, &newextra,
source, elevel))
{
guc_free(newval);
@@ -3967,10 +3895,10 @@ set_config_with_handle(const char *name, config_handle *handle,
* guc.c's control
*/
newval = conf->reset_val;
- newextra = conf->gen.reset_extra;
- source = conf->gen.reset_source;
- context = conf->gen.reset_scontext;
- srole = conf->gen.reset_srole;
+ newextra = record->reset_extra;
+ source = record->reset_source;
+ context = record->reset_scontext;
+ srole = record->reset_srole;
}
if (prohibitValueChange)
@@ -3983,10 +3911,10 @@ set_config_with_handle(const char *name, config_handle *handle,
strcmp(*conf->variable, newval) != 0);
/* Release newval, unless it's reset_val */
- if (newval && !string_field_used(conf, newval))
+ if (newval && !string_field_used(record, newval))
guc_free(newval);
/* Release newextra, unless it's reset_extra */
- if (newextra && !extra_field_used(&conf->gen, newextra))
+ if (newextra && !extra_field_used(record, newextra))
guc_free(newextra);
if (newval_different)
@@ -3995,7 +3923,7 @@ set_config_with_handle(const char *name, config_handle *handle,
ereport(elevel,
(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
errmsg("parameter \"%s\" cannot be changed without restarting the server",
- conf->gen.name)));
+ record->name)));
return 0;
}
record->status &= ~GUC_PENDING_RESTART;
@@ -4006,16 +3934,16 @@ set_config_with_handle(const char *name, config_handle *handle,
{
/* Save old value to support transaction abort */
if (!makeDefault)
- push_old_value(&conf->gen, action);
+ push_old_value(record, action);
if (conf->assign_hook)
conf->assign_hook(newval, newextra);
- set_string_field(conf, conf->variable, newval);
- set_extra_field(&conf->gen, &conf->gen.extra,
+ set_string_field(record, conf->variable, newval);
+ set_extra_field(record, &record->extra,
newextra);
- set_guc_source(&conf->gen, source);
- conf->gen.scontext = context;
- conf->gen.srole = srole;
+ set_guc_source(record, source);
+ record->scontext = context;
+ record->srole = srole;
/*
* Ugly hack: during SET session_authorization, forcibly
@@ -4042,7 +3970,7 @@ set_config_with_handle(const char *name, config_handle *handle,
* that.
*/
if (!is_reload &&
- strcmp(conf->gen.name, "session_authorization") == 0)
+ strcmp(record->name, "session_authorization") == 0)
(void) set_config_with_handle("role", NULL,
value ? "none" : NULL,
orig_context,
@@ -4058,22 +3986,22 @@ set_config_with_handle(const char *name, config_handle *handle,
if (makeDefault)
{
- if (conf->gen.reset_source <= source)
+ if (record->reset_source <= source)
{
- set_string_field(conf, &conf->reset_val, newval);
- set_extra_field(&conf->gen, &conf->gen.reset_extra,
+ set_string_field(record, &conf->reset_val, newval);
+ set_extra_field(record, &record->reset_extra,
newextra);
- conf->gen.reset_source = source;
- conf->gen.reset_scontext = context;
- conf->gen.reset_srole = srole;
+ record->reset_source = source;
+ record->reset_scontext = context;
+ record->reset_srole = srole;
}
- for (GucStack *stack = conf->gen.stack; stack; stack = stack->prev)
+ for (GucStack *stack = record->stack; stack; stack = stack->prev)
{
if (stack->source <= source)
{
- set_string_field(conf, &stack->prior.val.stringval,
+ set_string_field(record, &stack->prior.val.stringval,
newval);
- set_extra_field(&conf->gen, &stack->prior.extra,
+ set_extra_field(record, &stack->prior.extra,
newextra);
stack->source = source;
stack->scontext = context;
@@ -4083,10 +4011,10 @@ set_config_with_handle(const char *name, config_handle *handle,
}
/* Perhaps we didn't install newval anywhere */
- if (newval && !string_field_used(conf, newval))
+ if (newval && !string_field_used(record, newval))
guc_free(newval);
/* Perhaps we didn't install newextra anywhere */
- if (newextra && !extra_field_used(&conf->gen, newextra))
+ if (newextra && !extra_field_used(record, newextra))
guc_free(newextra);
break;
@@ -4095,7 +4023,7 @@ set_config_with_handle(const char *name, config_handle *handle,
case PGC_ENUM:
{
- struct config_enum *conf = (struct config_enum *) record;
+ struct config_enum *conf = &record->_enum;
#define newval (newval_union.enumval)
@@ -4109,23 +4037,23 @@ set_config_with_handle(const char *name, config_handle *handle,
else if (source == PGC_S_DEFAULT)
{
newval = conf->boot_val;
- if (!call_enum_check_hook(conf, &newval, &newextra,
+ if (!call_enum_check_hook(record, &newval, &newextra,
source, elevel))
return 0;
}
else
{
newval = conf->reset_val;
- newextra = conf->gen.reset_extra;
- source = conf->gen.reset_source;
- context = conf->gen.reset_scontext;
- srole = conf->gen.reset_srole;
+ newextra = record->reset_extra;
+ source = record->reset_source;
+ context = record->reset_scontext;
+ srole = record->reset_srole;
}
if (prohibitValueChange)
{
/* Release newextra, unless it's reset_extra */
- if (newextra && !extra_field_used(&conf->gen, newextra))
+ if (newextra && !extra_field_used(record, newextra))
guc_free(newextra);
if (*conf->variable != newval)
@@ -4134,7 +4062,7 @@ set_config_with_handle(const char *name, config_handle *handle,
ereport(elevel,
(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
errmsg("parameter \"%s\" cannot be changed without restarting the server",
- conf->gen.name)));
+ record->name)));
return 0;
}
record->status &= ~GUC_PENDING_RESTART;
@@ -4145,34 +4073,34 @@ set_config_with_handle(const char *name, config_handle *handle,
{
/* Save old value to support transaction abort */
if (!makeDefault)
- push_old_value(&conf->gen, action);
+ push_old_value(record, action);
if (conf->assign_hook)
conf->assign_hook(newval, newextra);
*conf->variable = newval;
- set_extra_field(&conf->gen, &conf->gen.extra,
+ set_extra_field(record, &record->extra,
newextra);
- set_guc_source(&conf->gen, source);
- conf->gen.scontext = context;
- conf->gen.srole = srole;
+ set_guc_source(record, source);
+ record->scontext = context;
+ record->srole = srole;
}
if (makeDefault)
{
- if (conf->gen.reset_source <= source)
+ if (record->reset_source <= source)
{
conf->reset_val = newval;
- set_extra_field(&conf->gen, &conf->gen.reset_extra,
+ set_extra_field(record, &record->reset_extra,
newextra);
- conf->gen.reset_source = source;
- conf->gen.reset_scontext = context;
- conf->gen.reset_srole = srole;
+ record->reset_source = source;
+ record->reset_scontext = context;
+ record->reset_srole = srole;
}
- for (GucStack *stack = conf->gen.stack; stack; stack = stack->prev)
+ for (GucStack *stack = record->stack; stack; stack = stack->prev)
{
if (stack->source <= source)
{
stack->prior.val.enumval = newval;
- set_extra_field(&conf->gen, &stack->prior.extra,
+ set_extra_field(record, &stack->prior.extra,
newextra);
stack->source = source;
stack->scontext = context;
@@ -4182,7 +4110,7 @@ set_config_with_handle(const char *name, config_handle *handle,
}
/* Perhaps we didn't install newextra anywhere */
- if (newextra && !extra_field_used(&conf->gen, newextra))
+ if (newextra && !extra_field_used(record, newextra))
guc_free(newextra);
break;
@@ -4296,25 +4224,25 @@ GetConfigOption(const char *name, bool missing_ok, bool restrict_privileged)
switch (record->vartype)
{
case PGC_BOOL:
- return *((struct config_bool *) record)->variable ? "on" : "off";
+ return *record->_bool.variable ? "on" : "off";
case PGC_INT:
snprintf(buffer, sizeof(buffer), "%d",
- *((struct config_int *) record)->variable);
+ *record->_int.variable);
return buffer;
case PGC_REAL:
snprintf(buffer, sizeof(buffer), "%g",
- *((struct config_real *) record)->variable);
+ *record->_real.variable);
return buffer;
case PGC_STRING:
- return *((struct config_string *) record)->variable ?
- *((struct config_string *) record)->variable : "";
+ return *record->_string.variable ?
+ *record->_string.variable : "";
case PGC_ENUM:
- return config_enum_lookup_by_value((struct config_enum *) record,
- *((struct config_enum *) record)->variable);
+ return config_enum_lookup_by_value(record,
+ *record->_enum.variable);
}
return NULL;
}
@@ -4344,25 +4272,25 @@ GetConfigOptionResetString(const char *name)
switch (record->vartype)
{
case PGC_BOOL:
- return ((struct config_bool *) record)->reset_val ? "on" : "off";
+ return record->_bool.reset_val ? "on" : "off";
case PGC_INT:
snprintf(buffer, sizeof(buffer), "%d",
- ((struct config_int *) record)->reset_val);
+ record->_int.reset_val);
return buffer;
case PGC_REAL:
snprintf(buffer, sizeof(buffer), "%g",
- ((struct config_real *) record)->reset_val);
+ record->_real.reset_val);
return buffer;
case PGC_STRING:
- return ((struct config_string *) record)->reset_val ?
- ((struct config_string *) record)->reset_val : "";
+ return record->_string.reset_val ?
+ record->_string.reset_val : "";
case PGC_ENUM:
- return config_enum_lookup_by_value((struct config_enum *) record,
- ((struct config_enum *) record)->reset_val);
+ return config_enum_lookup_by_value(record,
+ record->_enum.reset_val);
}
return NULL;
}
@@ -4802,8 +4730,7 @@ init_custom_variable(const char *name,
const char *long_desc,
GucContext context,
int flags,
- enum config_type type,
- size_t sz)
+ enum config_type type)
{
struct config_generic *gen;
@@ -4839,8 +4766,8 @@ init_custom_variable(const char *name,
context = PGC_SUSET;
/* As above, an OOM here is FATAL */
- gen = (struct config_generic *) guc_malloc(FATAL, sz);
- memset(gen, 0, sz);
+ gen = (struct config_generic *) guc_malloc(FATAL, sizeof(struct config_generic));
+ memset(gen, 0, sizeof(struct config_generic));
gen->name = guc_strdup(FATAL, name);
gen->context = context;
@@ -4862,7 +4789,7 @@ define_custom_variable(struct config_generic *variable)
{
const char *name = variable->name;
GUCHashEntry *hentry;
- struct config_string *pHolder;
+ struct config_generic *pHolder;
/* Check mapping between initial and default value */
Assert(check_GUC_init(variable));
@@ -4894,7 +4821,7 @@ define_custom_variable(struct config_generic *variable)
errmsg("attempt to redefine parameter \"%s\"", name)));
Assert(hentry->gucvar->vartype == PGC_STRING);
- pHolder = (struct config_string *) hentry->gucvar;
+ pHolder = hentry->gucvar;
/*
* First, set the variable to its default value. We must do this even
@@ -4913,7 +4840,7 @@ define_custom_variable(struct config_generic *variable)
/*
* Remove the placeholder from any lists it's in, too.
*/
- RemoveGUCFromLists(&pHolder->gen);
+ RemoveGUCFromLists(pHolder);
/*
* Assign the string value(s) stored in the placeholder to the real
@@ -4927,25 +4854,25 @@ define_custom_variable(struct config_generic *variable)
*/
/* First, apply the reset value if any */
- if (pHolder->reset_val)
- (void) set_config_option_ext(name, pHolder->reset_val,
- pHolder->gen.reset_scontext,
- pHolder->gen.reset_source,
- pHolder->gen.reset_srole,
+ if (pHolder->_string.reset_val)
+ (void) set_config_option_ext(name, pHolder->_string.reset_val,
+ pHolder->reset_scontext,
+ pHolder->reset_source,
+ pHolder->reset_srole,
GUC_ACTION_SET, true, WARNING, false);
/* That should not have resulted in stacking anything */
Assert(variable->stack == NULL);
/* Now, apply current and stacked values, in the order they were stacked */
- reapply_stacked_values(variable, pHolder, pHolder->gen.stack,
- *(pHolder->variable),
- pHolder->gen.scontext, pHolder->gen.source,
- pHolder->gen.srole);
+ reapply_stacked_values(variable, pHolder, pHolder->stack,
+ *(pHolder->_string.variable),
+ pHolder->scontext, pHolder->source,
+ pHolder->srole);
/* Also copy over any saved source-location information */
- if (pHolder->gen.sourcefile)
- set_config_sourcefile(name, pHolder->gen.sourcefile,
- pHolder->gen.sourceline);
+ if (pHolder->sourcefile)
+ set_config_sourcefile(name, pHolder->sourcefile,
+ pHolder->sourceline);
/* Now we can free the no-longer-referenced placeholder variable */
free_placeholder(pHolder);
@@ -4960,7 +4887,7 @@ define_custom_variable(struct config_generic *variable)
*/
static void
reapply_stacked_values(struct config_generic *variable,
- struct config_string *pHolder,
+ struct config_generic *pHolder,
GucStack *stack,
const char *curvalue,
GucContext curscontext, GucSource cursource,
@@ -5030,10 +4957,10 @@ reapply_stacked_values(struct config_generic *variable,
* this is to be just a transactional assignment. (We leak the stack
* entry.)
*/
- if (curvalue != pHolder->reset_val ||
- curscontext != pHolder->gen.reset_scontext ||
- cursource != pHolder->gen.reset_source ||
- cursrole != pHolder->gen.reset_srole)
+ if (curvalue != pHolder->_string.reset_val ||
+ curscontext != pHolder->reset_scontext ||
+ cursource != pHolder->reset_source ||
+ cursrole != pHolder->reset_srole)
{
(void) set_config_option_ext(name, curvalue,
curscontext, cursource, cursrole,
@@ -5055,14 +4982,14 @@ reapply_stacked_values(struct config_generic *variable,
* doesn't seem worth spending much code on.
*/
static void
-free_placeholder(struct config_string *pHolder)
+free_placeholder(struct config_generic *pHolder)
{
/* Placeholders are always STRING type, so free their values */
- Assert(pHolder->gen.vartype == PGC_STRING);
- set_string_field(pHolder, pHolder->variable, NULL);
- set_string_field(pHolder, &pHolder->reset_val, NULL);
+ Assert(pHolder->vartype == PGC_STRING);
+ set_string_field(pHolder, pHolder->_string.variable, NULL);
+ set_string_field(pHolder, &pHolder->_string.reset_val, NULL);
- guc_free(unconstify(char *, pHolder->gen.name));
+ guc_free(unconstify(char *, pHolder->name));
guc_free(pHolder);
}
@@ -5081,18 +5008,16 @@ DefineCustomBoolVariable(const char *name,
GucBoolAssignHook assign_hook,
GucShowHook show_hook)
{
- struct config_bool *var;
-
- var = (struct config_bool *)
- init_custom_variable(name, short_desc, long_desc, context, flags,
- PGC_BOOL, sizeof(struct config_bool));
- var->variable = valueAddr;
- var->boot_val = bootValue;
- var->reset_val = bootValue;
- var->check_hook = check_hook;
- var->assign_hook = assign_hook;
- var->show_hook = show_hook;
- define_custom_variable(&var->gen);
+ struct config_generic *var;
+
+ var = init_custom_variable(name, short_desc, long_desc, context, flags, PGC_BOOL);
+ var->_bool.variable = valueAddr;
+ var->_bool.boot_val = bootValue;
+ var->_bool.reset_val = bootValue;
+ var->_bool.check_hook = check_hook;
+ var->_bool.assign_hook = assign_hook;
+ var->_bool.show_hook = show_hook;
+ define_custom_variable(var);
}
void
@@ -5109,20 +5034,18 @@ DefineCustomIntVariable(const char *name,
GucIntAssignHook assign_hook,
GucShowHook show_hook)
{
- struct config_int *var;
-
- var = (struct config_int *)
- init_custom_variable(name, short_desc, long_desc, context, flags,
- PGC_INT, sizeof(struct config_int));
- var->variable = valueAddr;
- var->boot_val = bootValue;
- var->reset_val = bootValue;
- var->min = minValue;
- var->max = maxValue;
- var->check_hook = check_hook;
- var->assign_hook = assign_hook;
- var->show_hook = show_hook;
- define_custom_variable(&var->gen);
+ struct config_generic *var;
+
+ var = init_custom_variable(name, short_desc, long_desc, context, flags, PGC_INT);
+ var->_int.variable = valueAddr;
+ var->_int.boot_val = bootValue;
+ var->_int.reset_val = bootValue;
+ var->_int.min = minValue;
+ var->_int.max = maxValue;
+ var->_int.check_hook = check_hook;
+ var->_int.assign_hook = assign_hook;
+ var->_int.show_hook = show_hook;
+ define_custom_variable(var);
}
void
@@ -5139,20 +5062,18 @@ DefineCustomRealVariable(const char *name,
GucRealAssignHook assign_hook,
GucShowHook show_hook)
{
- struct config_real *var;
-
- var = (struct config_real *)
- init_custom_variable(name, short_desc, long_desc, context, flags,
- PGC_REAL, sizeof(struct config_real));
- var->variable = valueAddr;
- var->boot_val = bootValue;
- var->reset_val = bootValue;
- var->min = minValue;
- var->max = maxValue;
- var->check_hook = check_hook;
- var->assign_hook = assign_hook;
- var->show_hook = show_hook;
- define_custom_variable(&var->gen);
+ struct config_generic *var;
+
+ var = init_custom_variable(name, short_desc, long_desc, context, flags, PGC_REAL);
+ var->_real.variable = valueAddr;
+ var->_real.boot_val = bootValue;
+ var->_real.reset_val = bootValue;
+ var->_real.min = minValue;
+ var->_real.max = maxValue;
+ var->_real.check_hook = check_hook;
+ var->_real.assign_hook = assign_hook;
+ var->_real.show_hook = show_hook;
+ define_custom_variable(var);
}
void
@@ -5167,17 +5088,15 @@ DefineCustomStringVariable(const char *name,
GucStringAssignHook assign_hook,
GucShowHook show_hook)
{
- struct config_string *var;
-
- var = (struct config_string *)
- init_custom_variable(name, short_desc, long_desc, context, flags,
- PGC_STRING, sizeof(struct config_string));
- var->variable = valueAddr;
- var->boot_val = bootValue;
- var->check_hook = check_hook;
- var->assign_hook = assign_hook;
- var->show_hook = show_hook;
- define_custom_variable(&var->gen);
+ struct config_generic *var;
+
+ var = init_custom_variable(name, short_desc, long_desc, context, flags, PGC_STRING);
+ var->_string.variable = valueAddr;
+ var->_string.boot_val = bootValue;
+ var->_string.check_hook = check_hook;
+ var->_string.assign_hook = assign_hook;
+ var->_string.show_hook = show_hook;
+ define_custom_variable(var);
}
void
@@ -5193,19 +5112,17 @@ DefineCustomEnumVariable(const char *name,
GucEnumAssignHook assign_hook,
GucShowHook show_hook)
{
- struct config_enum *var;
-
- var = (struct config_enum *)
- init_custom_variable(name, short_desc, long_desc, context, flags,
- PGC_ENUM, sizeof(struct config_enum));
- var->variable = valueAddr;
- var->boot_val = bootValue;
- var->reset_val = bootValue;
- var->options = options;
- var->check_hook = check_hook;
- var->assign_hook = assign_hook;
- var->show_hook = show_hook;
- define_custom_variable(&var->gen);
+ struct config_generic *var;
+
+ var = init_custom_variable(name, short_desc, long_desc, context, flags, PGC_ENUM);
+ var->_enum.variable = valueAddr;
+ var->_enum.boot_val = bootValue;
+ var->_enum.reset_val = bootValue;
+ var->_enum.options = options;
+ var->_enum.check_hook = check_hook;
+ var->_enum.assign_hook = assign_hook;
+ var->_enum.show_hook = show_hook;
+ define_custom_variable(var);
}
/*
@@ -5251,7 +5168,7 @@ MarkGUCPrefixReserved(const char *className)
/* Remove it from any lists it's in, too */
RemoveGUCFromLists(var);
/* And free it */
- free_placeholder((struct config_string *) var);
+ free_placeholder(var);
}
}
@@ -5304,7 +5221,7 @@ get_explain_guc_options(int *num)
{
case PGC_BOOL:
{
- struct config_bool *lconf = (struct config_bool *) conf;
+ struct config_bool *lconf = &conf->_bool;
modified = (lconf->boot_val != *(lconf->variable));
}
@@ -5312,7 +5229,7 @@ get_explain_guc_options(int *num)
case PGC_INT:
{
- struct config_int *lconf = (struct config_int *) conf;
+ struct config_int *lconf = &conf->_int;
modified = (lconf->boot_val != *(lconf->variable));
}
@@ -5320,7 +5237,7 @@ get_explain_guc_options(int *num)
case PGC_REAL:
{
- struct config_real *lconf = (struct config_real *) conf;
+ struct config_real *lconf = &conf->_real;
modified = (lconf->boot_val != *(lconf->variable));
}
@@ -5328,7 +5245,7 @@ get_explain_guc_options(int *num)
case PGC_STRING:
{
- struct config_string *lconf = (struct config_string *) conf;
+ struct config_string *lconf = &conf->_string;
if (lconf->boot_val == NULL &&
*lconf->variable == NULL)
@@ -5343,7 +5260,7 @@ get_explain_guc_options(int *num)
case PGC_ENUM:
{
- struct config_enum *lconf = (struct config_enum *) conf;
+ struct config_enum *lconf = &conf->_enum;
modified = (lconf->boot_val != *(lconf->variable));
}
@@ -5412,7 +5329,7 @@ ShowGUCOption(const struct config_generic *record, bool use_units)
{
case PGC_BOOL:
{
- const struct config_bool *conf = (const struct config_bool *) record;
+ const struct config_bool *conf = &record->_bool;
if (conf->show_hook)
val = conf->show_hook();
@@ -5423,7 +5340,7 @@ ShowGUCOption(const struct config_generic *record, bool use_units)
case PGC_INT:
{
- const struct config_int *conf = (const struct config_int *) record;
+ const struct config_int *conf = &record->_int;
if (conf->show_hook)
val = conf->show_hook();
@@ -5452,7 +5369,7 @@ ShowGUCOption(const struct config_generic *record, bool use_units)
case PGC_REAL:
{
- const struct config_real *conf = (const struct config_real *) record;
+ const struct config_real *conf = &record->_real;
if (conf->show_hook)
val = conf->show_hook();
@@ -5477,7 +5394,7 @@ ShowGUCOption(const struct config_generic *record, bool use_units)
case PGC_STRING:
{
- const struct config_string *conf = (const struct config_string *) record;
+ const struct config_string *conf = &record->_string;
if (conf->show_hook)
val = conf->show_hook();
@@ -5490,12 +5407,12 @@ ShowGUCOption(const struct config_generic *record, bool use_units)
case PGC_ENUM:
{
- const struct config_enum *conf = (const struct config_enum *) record;
+ const struct config_enum *conf = &record->_enum;
if (conf->show_hook)
val = conf->show_hook();
else
- val = config_enum_lookup_by_value(conf, *conf->variable);
+ val = config_enum_lookup_by_value(record, *conf->variable);
}
break;
@@ -5535,7 +5452,7 @@ write_one_nondefault_variable(FILE *fp, struct config_generic *gconf)
{
case PGC_BOOL:
{
- struct config_bool *conf = (struct config_bool *) gconf;
+ struct config_bool *conf = &gconf->_bool;
if (*conf->variable)
fprintf(fp, "true");
@@ -5546,7 +5463,7 @@ write_one_nondefault_variable(FILE *fp, struct config_generic *gconf)
case PGC_INT:
{
- struct config_int *conf = (struct config_int *) gconf;
+ struct config_int *conf = &gconf->_int;
fprintf(fp, "%d", *conf->variable);
}
@@ -5554,7 +5471,7 @@ write_one_nondefault_variable(FILE *fp, struct config_generic *gconf)
case PGC_REAL:
{
- struct config_real *conf = (struct config_real *) gconf;
+ struct config_real *conf = &gconf->_real;
fprintf(fp, "%.17g", *conf->variable);
}
@@ -5562,7 +5479,7 @@ write_one_nondefault_variable(FILE *fp, struct config_generic *gconf)
case PGC_STRING:
{
- struct config_string *conf = (struct config_string *) gconf;
+ struct config_string *conf = &gconf->_string;
if (*conf->variable)
fprintf(fp, "%s", *conf->variable);
@@ -5571,10 +5488,10 @@ write_one_nondefault_variable(FILE *fp, struct config_generic *gconf)
case PGC_ENUM:
{
- struct config_enum *conf = (struct config_enum *) gconf;
+ struct config_enum *conf = &gconf->_enum;
fprintf(fp, "%s",
- config_enum_lookup_by_value(conf, *conf->variable));
+ config_enum_lookup_by_value(gconf, *conf->variable));
}
break;
}
@@ -5809,7 +5726,7 @@ estimate_variable_size(struct config_generic *gconf)
case PGC_INT:
{
- struct config_int *conf = (struct config_int *) gconf;
+ struct config_int *conf = &gconf->_int;
/*
* Instead of getting the exact display length, use max
@@ -5838,7 +5755,7 @@ estimate_variable_size(struct config_generic *gconf)
case PGC_STRING:
{
- struct config_string *conf = (struct config_string *) gconf;
+ struct config_string *conf = &gconf->_string;
/*
* If the value is NULL, we transmit it as an empty string.
@@ -5854,9 +5771,9 @@ estimate_variable_size(struct config_generic *gconf)
case PGC_ENUM:
{
- struct config_enum *conf = (struct config_enum *) gconf;
+ struct config_enum *conf = &gconf->_enum;
- valsize = strlen(config_enum_lookup_by_value(conf, *conf->variable));
+ valsize = strlen(config_enum_lookup_by_value(gconf, *conf->variable));
}
break;
}
@@ -5975,7 +5892,7 @@ serialize_variable(char **destptr, Size *maxbytes,
{
case PGC_BOOL:
{
- struct config_bool *conf = (struct config_bool *) gconf;
+ struct config_bool *conf = &gconf->_bool;
do_serialize(destptr, maxbytes,
(*conf->variable ? "true" : "false"));
@@ -5984,7 +5901,7 @@ serialize_variable(char **destptr, Size *maxbytes,
case PGC_INT:
{
- struct config_int *conf = (struct config_int *) gconf;
+ struct config_int *conf = &gconf->_int;
do_serialize(destptr, maxbytes, "%d", *conf->variable);
}
@@ -5992,7 +5909,7 @@ serialize_variable(char **destptr, Size *maxbytes,
case PGC_REAL:
{
- struct config_real *conf = (struct config_real *) gconf;
+ struct config_real *conf = &gconf->_real;
do_serialize(destptr, maxbytes, "%.*e",
REALTYPE_PRECISION, *conf->variable);
@@ -6001,7 +5918,7 @@ serialize_variable(char **destptr, Size *maxbytes,
case PGC_STRING:
{
- struct config_string *conf = (struct config_string *) gconf;
+ struct config_string *conf = &gconf->_string;
/* NULL becomes empty string, see estimate_variable_size() */
do_serialize(destptr, maxbytes, "%s",
@@ -6011,10 +5928,10 @@ serialize_variable(char **destptr, Size *maxbytes,
case PGC_ENUM:
{
- struct config_enum *conf = (struct config_enum *) gconf;
+ struct config_enum *conf = &gconf->_enum;
do_serialize(destptr, maxbytes, "%s",
- config_enum_lookup_by_value(conf, *conf->variable));
+ config_enum_lookup_by_value(gconf, *conf->variable));
}
break;
}
@@ -6199,7 +6116,7 @@ RestoreGUCState(void *gucstate)
break;
case PGC_STRING:
{
- struct config_string *conf = (struct config_string *) gconf;
+ struct config_string *conf = &gconf->_string;
guc_free(*conf->variable);
if (conf->reset_val && conf->reset_val != *conf->variable)
@@ -6710,11 +6627,11 @@ GUC_check_errcode(int sqlerrcode)
*/
static bool
-call_bool_check_hook(const struct config_bool *conf, bool *newval, void **extra,
+call_bool_check_hook(const struct config_generic *conf, bool *newval, void **extra,
GucSource source, int elevel)
{
/* Quick success if no hook */
- if (!conf->check_hook)
+ if (!conf->_bool.check_hook)
return true;
/* Reset variables that might be set by hook */
@@ -6723,14 +6640,14 @@ call_bool_check_hook(const struct config_bool *conf, bool *newval, void **extra,
GUC_check_errdetail_string = NULL;
GUC_check_errhint_string = NULL;
- if (!conf->check_hook(newval, extra, source))
+ if (!conf->_bool.check_hook(newval, extra, source))
{
ereport(elevel,
(errcode(GUC_check_errcode_value),
GUC_check_errmsg_string ?
errmsg_internal("%s", GUC_check_errmsg_string) :
errmsg("invalid value for parameter \"%s\": %d",
- conf->gen.name, (int) *newval),
+ conf->name, (int) *newval),
GUC_check_errdetail_string ?
errdetail_internal("%s", GUC_check_errdetail_string) : 0,
GUC_check_errhint_string ?
@@ -6744,11 +6661,11 @@ call_bool_check_hook(const struct config_bool *conf, bool *newval, void **extra,
}
static bool
-call_int_check_hook(const struct config_int *conf, int *newval, void **extra,
+call_int_check_hook(const struct config_generic *conf, int *newval, void **extra,
GucSource source, int elevel)
{
/* Quick success if no hook */
- if (!conf->check_hook)
+ if (!conf->_int.check_hook)
return true;
/* Reset variables that might be set by hook */
@@ -6757,14 +6674,14 @@ call_int_check_hook(const struct config_int *conf, int *newval, void **extra,
GUC_check_errdetail_string = NULL;
GUC_check_errhint_string = NULL;
- if (!conf->check_hook(newval, extra, source))
+ if (!conf->_int.check_hook(newval, extra, source))
{
ereport(elevel,
(errcode(GUC_check_errcode_value),
GUC_check_errmsg_string ?
errmsg_internal("%s", GUC_check_errmsg_string) :
errmsg("invalid value for parameter \"%s\": %d",
- conf->gen.name, *newval),
+ conf->name, *newval),
GUC_check_errdetail_string ?
errdetail_internal("%s", GUC_check_errdetail_string) : 0,
GUC_check_errhint_string ?
@@ -6778,11 +6695,11 @@ call_int_check_hook(const struct config_int *conf, int *newval, void **extra,
}
static bool
-call_real_check_hook(const struct config_real *conf, double *newval, void **extra,
+call_real_check_hook(const struct config_generic *conf, double *newval, void **extra,
GucSource source, int elevel)
{
/* Quick success if no hook */
- if (!conf->check_hook)
+ if (!conf->_real.check_hook)
return true;
/* Reset variables that might be set by hook */
@@ -6791,14 +6708,14 @@ call_real_check_hook(const struct config_real *conf, double *newval, void **extr
GUC_check_errdetail_string = NULL;
GUC_check_errhint_string = NULL;
- if (!conf->check_hook(newval, extra, source))
+ if (!conf->_real.check_hook(newval, extra, source))
{
ereport(elevel,
(errcode(GUC_check_errcode_value),
GUC_check_errmsg_string ?
errmsg_internal("%s", GUC_check_errmsg_string) :
errmsg("invalid value for parameter \"%s\": %g",
- conf->gen.name, *newval),
+ conf->name, *newval),
GUC_check_errdetail_string ?
errdetail_internal("%s", GUC_check_errdetail_string) : 0,
GUC_check_errhint_string ?
@@ -6812,13 +6729,13 @@ call_real_check_hook(const struct config_real *conf, double *newval, void **extr
}
static bool
-call_string_check_hook(const struct config_string *conf, char **newval, void **extra,
+call_string_check_hook(const struct config_generic *conf, char **newval, void **extra,
GucSource source, int elevel)
{
volatile bool result = true;
/* Quick success if no hook */
- if (!conf->check_hook)
+ if (!conf->_string.check_hook)
return true;
/*
@@ -6834,14 +6751,14 @@ call_string_check_hook(const struct config_string *conf, char **newval, void **e
GUC_check_errdetail_string = NULL;
GUC_check_errhint_string = NULL;
- if (!conf->check_hook(newval, extra, source))
+ if (!conf->_string.check_hook(newval, extra, source))
{
ereport(elevel,
(errcode(GUC_check_errcode_value),
GUC_check_errmsg_string ?
errmsg_internal("%s", GUC_check_errmsg_string) :
errmsg("invalid value for parameter \"%s\": \"%s\"",
- conf->gen.name, *newval ? *newval : ""),
+ conf->name, *newval ? *newval : ""),
GUC_check_errdetail_string ?
errdetail_internal("%s", GUC_check_errdetail_string) : 0,
GUC_check_errhint_string ?
@@ -6862,11 +6779,11 @@ call_string_check_hook(const struct config_string *conf, char **newval, void **e
}
static bool
-call_enum_check_hook(const struct config_enum *conf, int *newval, void **extra,
+call_enum_check_hook(const struct config_generic *conf, int *newval, void **extra,
GucSource source, int elevel)
{
/* Quick success if no hook */
- if (!conf->check_hook)
+ if (!conf->_enum.check_hook)
return true;
/* Reset variables that might be set by hook */
@@ -6875,14 +6792,14 @@ call_enum_check_hook(const struct config_enum *conf, int *newval, void **extra,
GUC_check_errdetail_string = NULL;
GUC_check_errhint_string = NULL;
- if (!conf->check_hook(newval, extra, source))
+ if (!conf->_enum.check_hook(newval, extra, source))
{
ereport(elevel,
(errcode(GUC_check_errcode_value),
GUC_check_errmsg_string ?
errmsg_internal("%s", GUC_check_errmsg_string) :
errmsg("invalid value for parameter \"%s\": \"%s\"",
- conf->gen.name,
+ conf->name,
config_enum_lookup_by_value(conf, *newval)),
GUC_check_errdetail_string ?
errdetail_internal("%s", GUC_check_errdetail_string) : 0,
diff --git a/src/backend/utils/misc/guc_funcs.c b/src/backend/utils/misc/guc_funcs.c
index d7a822e1462..4f58fa3d4e0 100644
--- a/src/backend/utils/misc/guc_funcs.c
+++ b/src/backend/utils/misc/guc_funcs.c
@@ -629,7 +629,7 @@ GetConfigOptionValues(const struct config_generic *conf, const char **values)
{
case PGC_BOOL:
{
- const struct config_bool *lconf = (const struct config_bool *) conf;
+ const struct config_bool *lconf = &conf->_bool;
/* min_val */
values[9] = NULL;
@@ -650,7 +650,7 @@ GetConfigOptionValues(const struct config_generic *conf, const char **values)
case PGC_INT:
{
- const struct config_int *lconf = (const struct config_int *) conf;
+ const struct config_int *lconf = &conf->_int;
/* min_val */
snprintf(buffer, sizeof(buffer), "%d", lconf->min);
@@ -675,7 +675,7 @@ GetConfigOptionValues(const struct config_generic *conf, const char **values)
case PGC_REAL:
{
- const struct config_real *lconf = (const struct config_real *) conf;
+ const struct config_real *lconf = &conf->_real;
/* min_val */
snprintf(buffer, sizeof(buffer), "%g", lconf->min);
@@ -700,7 +700,7 @@ GetConfigOptionValues(const struct config_generic *conf, const char **values)
case PGC_STRING:
{
- const struct config_string *lconf = (const struct config_string *) conf;
+ const struct config_string *lconf = &conf->_string;
/* min_val */
values[9] = NULL;
@@ -727,7 +727,7 @@ GetConfigOptionValues(const struct config_generic *conf, const char **values)
case PGC_ENUM:
{
- const struct config_enum *lconf = (const struct config_enum *) conf;
+ const struct config_enum *lconf = &conf->_enum;
/* min_val */
values[9] = NULL;
@@ -745,11 +745,11 @@ GetConfigOptionValues(const struct config_generic *conf, const char **values)
"{\"", "\"}", "\",\"");
/* boot_val */
- values[12] = pstrdup(config_enum_lookup_by_value(lconf,
+ values[12] = pstrdup(config_enum_lookup_by_value(conf,
lconf->boot_val));
/* reset_val */
- values[13] = pstrdup(config_enum_lookup_by_value(lconf,
+ values[13] = pstrdup(config_enum_lookup_by_value(conf,
lconf->reset_val));
}
break;
diff --git a/src/backend/utils/misc/help_config.c b/src/backend/utils/misc/help_config.c
index 86812ac881f..2810715693c 100644
--- a/src/backend/utils/misc/help_config.c
+++ b/src/backend/utils/misc/help_config.c
@@ -23,23 +23,8 @@
#include "utils/help_config.h"
-/*
- * This union allows us to mix the numerous different types of structs
- * that we are organizing.
- */
-typedef union
-{
- struct config_generic generic;
- struct config_bool _bool;
- struct config_real real;
- struct config_int integer;
- struct config_string string;
- struct config_enum _enum;
-} mixedStruct;
-
-
-static void printMixedStruct(mixedStruct *structToPrint);
-static bool displayStruct(mixedStruct *structToDisplay);
+static void printMixedStruct(const struct config_generic *structToPrint);
+static bool displayStruct(const struct config_generic *structToDisplay);
void
@@ -55,7 +40,7 @@ GucInfoMain(void)
for (int i = 0; i < numOpts; i++)
{
- mixedStruct *var = (mixedStruct *) guc_vars[i];
+ const struct config_generic *var = guc_vars[i];
if (displayStruct(var))
printMixedStruct(var);
@@ -70,11 +55,11 @@ GucInfoMain(void)
* should be displayed to the user.
*/
static bool
-displayStruct(mixedStruct *structToDisplay)
+displayStruct(const struct config_generic *structToDisplay)
{
- return !(structToDisplay->generic.flags & (GUC_NO_SHOW_ALL |
- GUC_NOT_IN_SAMPLE |
- GUC_DISALLOW_IN_FILE));
+ return !(structToDisplay->flags & (GUC_NO_SHOW_ALL |
+ GUC_NOT_IN_SAMPLE |
+ GUC_DISALLOW_IN_FILE));
}
@@ -83,14 +68,14 @@ displayStruct(mixedStruct *structToDisplay)
* a different format, depending on what the user wants to see.
*/
static void
-printMixedStruct(mixedStruct *structToPrint)
+printMixedStruct(const struct config_generic *structToPrint)
{
printf("%s\t%s\t%s\t",
- structToPrint->generic.name,
- GucContext_Names[structToPrint->generic.context],
- _(config_group_names[structToPrint->generic.group]));
+ structToPrint->name,
+ GucContext_Names[structToPrint->context],
+ _(config_group_names[structToPrint->group]));
- switch (structToPrint->generic.vartype)
+ switch (structToPrint->vartype)
{
case PGC_BOOL:
@@ -101,26 +86,26 @@ printMixedStruct(mixedStruct *structToPrint)
case PGC_INT:
printf("INTEGER\t%d\t%d\t%d\t",
- structToPrint->integer.reset_val,
- structToPrint->integer.min,
- structToPrint->integer.max);
+ structToPrint->_int.reset_val,
+ structToPrint->_int.min,
+ structToPrint->_int.max);
break;
case PGC_REAL:
printf("REAL\t%g\t%g\t%g\t",
- structToPrint->real.reset_val,
- structToPrint->real.min,
- structToPrint->real.max);
+ structToPrint->_real.reset_val,
+ structToPrint->_real.min,
+ structToPrint->_real.max);
break;
case PGC_STRING:
printf("STRING\t%s\t\t\t",
- structToPrint->string.boot_val ? structToPrint->string.boot_val : "");
+ structToPrint->_string.boot_val ? structToPrint->_string.boot_val : "");
break;
case PGC_ENUM:
printf("ENUM\t%s\t\t\t",
- config_enum_lookup_by_value(&structToPrint->_enum,
+ config_enum_lookup_by_value(structToPrint,
structToPrint->_enum.boot_val));
break;
@@ -130,6 +115,6 @@ printMixedStruct(mixedStruct *structToPrint)
}
printf("%s\t%s\n",
- (structToPrint->generic.short_desc == NULL) ? "" : _(structToPrint->generic.short_desc),
- (structToPrint->generic.long_desc == NULL) ? "" : _(structToPrint->generic.long_desc));
+ (structToPrint->short_desc == NULL) ? "" : _(structToPrint->short_desc),
+ (structToPrint->long_desc == NULL) ? "" : _(structToPrint->long_desc));
}
diff --git a/src/bin/pg_verifybackup/pg_verifybackup.c b/src/bin/pg_verifybackup/pg_verifybackup.c
index 5e6c13bb921..8d5befa947f 100644
--- a/src/bin/pg_verifybackup/pg_verifybackup.c
+++ b/src/bin/pg_verifybackup/pg_verifybackup.c
@@ -1228,7 +1228,7 @@ parse_required_wal(verifier_context *context, char *pg_waldump_path,
* context says we should.
*/
void
-report_backup_error(verifier_context *context, const char *pg_restrict fmt,...)
+report_backup_error(verifier_context *context, const char *restrict fmt,...)
{
va_list ap;
@@ -1245,7 +1245,7 @@ report_backup_error(verifier_context *context, const char *pg_restrict fmt,...)
* Report a fatal error and exit
*/
void
-report_fatal_error(const char *pg_restrict fmt,...)
+report_fatal_error(const char *restrict fmt,...)
{
va_list ap;
diff --git a/src/bin/pg_verifybackup/pg_verifybackup.h b/src/bin/pg_verifybackup/pg_verifybackup.h
index 8cb6f9c53ad..3bdae62b822 100644
--- a/src/bin/pg_verifybackup/pg_verifybackup.h
+++ b/src/bin/pg_verifybackup/pg_verifybackup.h
@@ -96,9 +96,9 @@ typedef struct verifier_context
} verifier_context;
extern void report_backup_error(verifier_context *context,
- const char *pg_restrict fmt,...)
+ const char *restrict fmt,...)
pg_attribute_printf(2, 3);
-pg_noreturn extern void report_fatal_error(const char *pg_restrict fmt,...)
+pg_noreturn extern void report_fatal_error(const char *restrict fmt,...)
pg_attribute_printf(1, 2);
extern bool should_ignore_relpath(verifier_context *context,
const char *relpath);
diff --git a/src/bin/psql/prompt.c b/src/bin/psql/prompt.c
index b08d7328fbf..59a2ceee07a 100644
--- a/src/bin/psql/prompt.c
+++ b/src/bin/psql/prompt.c
@@ -34,6 +34,7 @@
* %P - pipeline status: on, off or abort
* %> - database server port number
* %n - database user name
+ * %S - search_path
* %s - service
* %/ - current database
* %~ - like %/ but "~" when database name equals user name
@@ -167,6 +168,16 @@ get_prompt(promptStatus_t status, ConditionalStack cstack)
if (pset.db)
strlcpy(buf, session_username(), sizeof(buf));
break;
+ /* search_path */
+ case 'S':
+ if (pset.db)
+ {
+ const char *sp = PQparameterStatus(pset.db, "search_path");
+
+ /* Use ? for versions that don't report search_path. */
+ strlcpy(buf, sp ? sp : "?", sizeof(buf));
+ }
+ break;
/* service name */
case 's':
{
diff --git a/src/common/logging.c b/src/common/logging.c
index 125a172af80..7319a5b4e20 100644
--- a/src/common/logging.c
+++ b/src/common/logging.c
@@ -206,7 +206,7 @@ pg_logging_set_locus_callback(void (*cb) (const char **filename, uint64 *lineno)
void
pg_log_generic(enum pg_log_level level, enum pg_log_part part,
- const char *pg_restrict fmt,...)
+ const char *restrict fmt,...)
{
va_list ap;
@@ -217,7 +217,7 @@ pg_log_generic(enum pg_log_level level, enum pg_log_part part,
void
pg_log_generic_v(enum pg_log_level level, enum pg_log_part part,
- const char *pg_restrict fmt, va_list ap)
+ const char *restrict fmt, va_list ap)
{
int save_errno = errno;
const char *filename = NULL;
diff --git a/src/common/saslprep.c b/src/common/saslprep.c
index 97beb47940b..101e8d65a4d 100644
--- a/src/common/saslprep.c
+++ b/src/common/saslprep.c
@@ -47,7 +47,7 @@
/* Prototypes for local functions */
static int codepoint_range_cmp(const void *a, const void *b);
-static bool is_code_in_table(pg_wchar code, const pg_wchar *map, int mapsize);
+static bool is_code_in_table(char32_t code, const char32_t *map, int mapsize);
static int pg_utf8_string_len(const char *source);
/*
@@ -64,7 +64,7 @@ static int pg_utf8_string_len(const char *source);
*
* These are all mapped to the ASCII space character (U+00A0).
*/
-static const pg_wchar non_ascii_space_ranges[] =
+static const char32_t non_ascii_space_ranges[] =
{
0x00A0, 0x00A0,
0x1680, 0x1680,
@@ -79,7 +79,7 @@ static const pg_wchar non_ascii_space_ranges[] =
*
* If any of these appear in the input, they are removed.
*/
-static const pg_wchar commonly_mapped_to_nothing_ranges[] =
+static const char32_t commonly_mapped_to_nothing_ranges[] =
{
0x00AD, 0x00AD,
0x034F, 0x034F,
@@ -114,7 +114,7 @@ static const pg_wchar commonly_mapped_to_nothing_ranges[] =
* tables, so one code might originate from multiple source tables.
* Adjacent ranges have also been merged together, to save space.
*/
-static const pg_wchar prohibited_output_ranges[] =
+static const char32_t prohibited_output_ranges[] =
{
0x0000, 0x001F, /* C.2.1 */
0x007F, 0x00A0, /* C.1.2, C.2.1, C.2.2 */
@@ -155,7 +155,7 @@ static const pg_wchar prohibited_output_ranges[] =
};
/* A.1 Unassigned code points in Unicode 3.2 */
-static const pg_wchar unassigned_codepoint_ranges[] =
+static const char32_t unassigned_codepoint_ranges[] =
{
0x0221, 0x0221,
0x0234, 0x024F,
@@ -556,7 +556,7 @@ static const pg_wchar unassigned_codepoint_ranges[] =
};
/* D.1 Characters with bidirectional property "R" or "AL" */
-static const pg_wchar RandALCat_codepoint_ranges[] =
+static const char32_t RandALCat_codepoint_ranges[] =
{
0x05BE, 0x05BE,
0x05C0, 0x05C0,
@@ -595,7 +595,7 @@ static const pg_wchar RandALCat_codepoint_ranges[] =
};
/* D.2 Characters with bidirectional property "L" */
-static const pg_wchar LCat_codepoint_ranges[] =
+static const char32_t LCat_codepoint_ranges[] =
{
0x0041, 0x005A,
0x0061, 0x007A,
@@ -968,8 +968,8 @@ static const pg_wchar LCat_codepoint_ranges[] =
static int
codepoint_range_cmp(const void *a, const void *b)
{
- const pg_wchar *key = (const pg_wchar *) a;
- const pg_wchar *range = (const pg_wchar *) b;
+ const char32_t *key = (const char32_t *) a;
+ const char32_t *range = (const char32_t *) b;
if (*key < range[0])
return -1; /* less than lower bound */
@@ -980,14 +980,14 @@ codepoint_range_cmp(const void *a, const void *b)
}
static bool
-is_code_in_table(pg_wchar code, const pg_wchar *map, int mapsize)
+is_code_in_table(char32_t code, const char32_t *map, int mapsize)
{
Assert(mapsize % 2 == 0);
if (code < map[0] || code > map[mapsize - 1])
return false;
- if (bsearch(&code, map, mapsize / 2, sizeof(pg_wchar) * 2,
+ if (bsearch(&code, map, mapsize / 2, sizeof(char32_t) * 2,
codepoint_range_cmp))
return true;
else
@@ -1046,8 +1046,8 @@ pg_utf8_string_len(const char *source)
pg_saslprep_rc
pg_saslprep(const char *input, char **output)
{
- pg_wchar *input_chars = NULL;
- pg_wchar *output_chars = NULL;
+ char32_t *input_chars = NULL;
+ char32_t *output_chars = NULL;
int input_size;
char *result;
int result_size;
@@ -1055,7 +1055,7 @@ pg_saslprep(const char *input, char **output)
int i;
bool contains_RandALCat;
unsigned char *p;
- pg_wchar *wp;
+ char32_t *wp;
/* Ensure we return *output as NULL on failure */
*output = NULL;
@@ -1080,10 +1080,10 @@ pg_saslprep(const char *input, char **output)
input_size = pg_utf8_string_len(input);
if (input_size < 0)
return SASLPREP_INVALID_UTF8;
- if (input_size >= MaxAllocSize / sizeof(pg_wchar))
+ if (input_size >= MaxAllocSize / sizeof(char32_t))
goto oom;
- input_chars = ALLOC((input_size + 1) * sizeof(pg_wchar));
+ input_chars = ALLOC((input_size + 1) * sizeof(char32_t));
if (!input_chars)
goto oom;
@@ -1093,7 +1093,7 @@ pg_saslprep(const char *input, char **output)
input_chars[i] = utf8_to_unicode(p);
p += pg_utf_mblen(p);
}
- input_chars[i] = (pg_wchar) '\0';
+ input_chars[i] = (char32_t) '\0';
/*
* The steps below correspond to the steps listed in [RFC3454], Section
@@ -1107,7 +1107,7 @@ pg_saslprep(const char *input, char **output)
count = 0;
for (i = 0; i < input_size; i++)
{
- pg_wchar code = input_chars[i];
+ char32_t code = input_chars[i];
if (IS_CODE_IN_TABLE(code, non_ascii_space_ranges))
input_chars[count++] = 0x0020;
@@ -1118,7 +1118,7 @@ pg_saslprep(const char *input, char **output)
else
input_chars[count++] = code;
}
- input_chars[count] = (pg_wchar) '\0';
+ input_chars[count] = (char32_t) '\0';
input_size = count;
if (input_size == 0)
@@ -1138,7 +1138,7 @@ pg_saslprep(const char *input, char **output)
*/
for (i = 0; i < input_size; i++)
{
- pg_wchar code = input_chars[i];
+ char32_t code = input_chars[i];
if (IS_CODE_IN_TABLE(code, prohibited_output_ranges))
goto prohibited;
@@ -1170,7 +1170,7 @@ pg_saslprep(const char *input, char **output)
contains_RandALCat = false;
for (i = 0; i < input_size; i++)
{
- pg_wchar code = input_chars[i];
+ char32_t code = input_chars[i];
if (IS_CODE_IN_TABLE(code, RandALCat_codepoint_ranges))
{
@@ -1181,12 +1181,12 @@ pg_saslprep(const char *input, char **output)
if (contains_RandALCat)
{
- pg_wchar first = input_chars[0];
- pg_wchar last = input_chars[input_size - 1];
+ char32_t first = input_chars[0];
+ char32_t last = input_chars[input_size - 1];
for (i = 0; i < input_size; i++)
{
- pg_wchar code = input_chars[i];
+ char32_t code = input_chars[i];
if (IS_CODE_IN_TABLE(code, LCat_codepoint_ranges))
goto prohibited;
diff --git a/src/common/string.c b/src/common/string.c
index d8a3129c3ba..95c7c07d502 100644
--- a/src/common/string.c
+++ b/src/common/string.c
@@ -47,7 +47,7 @@ pg_str_endswith(const char *str, const char *end)
* strtoint --- just like strtol, but returns int not long
*/
int
-strtoint(const char *pg_restrict str, char **pg_restrict endptr, int base)
+strtoint(const char *restrict str, char **restrict endptr, int base)
{
long val;
diff --git a/src/common/unicode/case_test.c b/src/common/unicode/case_test.c
index fdfb62e8552..00d4f85e5a5 100644
--- a/src/common/unicode/case_test.c
+++ b/src/common/unicode/case_test.c
@@ -24,6 +24,7 @@
#include "common/unicode_case.h"
#include "common/unicode_category.h"
#include "common/unicode_version.h"
+#include "mb/pg_wchar.h"
/* enough to hold largest source or result string, including NUL */
#define BUFSZ 256
@@ -54,7 +55,7 @@ initcap_wbnext(void *state)
while (wbstate->offset < wbstate->len &&
wbstate->str[wbstate->offset] != '\0')
{
- pg_wchar u = utf8_to_unicode((unsigned char *) wbstate->str +
+ char32_t u = utf8_to_unicode((unsigned char *) wbstate->str +
wbstate->offset);
bool curr_alnum = pg_u_isalnum(u, wbstate->posix);
@@ -77,16 +78,16 @@ initcap_wbnext(void *state)
#ifdef USE_ICU
static void
-icu_test_simple(pg_wchar code)
+icu_test_simple(char32_t code)
{
- pg_wchar lower = unicode_lowercase_simple(code);
- pg_wchar title = unicode_titlecase_simple(code);
- pg_wchar upper = unicode_uppercase_simple(code);
- pg_wchar fold = unicode_casefold_simple(code);
- pg_wchar iculower = u_tolower(code);
- pg_wchar icutitle = u_totitle(code);
- pg_wchar icuupper = u_toupper(code);
- pg_wchar icufold = u_foldCase(code, U_FOLD_CASE_DEFAULT);
+ char32_t lower = unicode_lowercase_simple(code);
+ char32_t title = unicode_titlecase_simple(code);
+ char32_t upper = unicode_uppercase_simple(code);
+ char32_t fold = unicode_casefold_simple(code);
+ char32_t iculower = u_tolower(code);
+ char32_t icutitle = u_totitle(code);
+ char32_t icuupper = u_toupper(code);
+ char32_t icufold = u_foldCase(code, U_FOLD_CASE_DEFAULT);
if (lower != iculower || title != icutitle || upper != icuupper ||
fold != icufold)
@@ -172,7 +173,7 @@ test_icu(void)
int successful = 0;
int skipped_mismatch = 0;
- for (pg_wchar code = 0; code <= 0x10ffff; code++)
+ for (char32_t code = 0; code <= 0x10ffff; code++)
{
pg_unicode_category category = unicode_category(code);
diff --git a/src/common/unicode/category_test.c b/src/common/unicode/category_test.c
index 5d37ba39196..1e8c1f7905f 100644
--- a/src/common/unicode/category_test.c
+++ b/src/common/unicode/category_test.c
@@ -22,6 +22,7 @@
#include "common/unicode_category.h"
#include "common/unicode_version.h"
+#include "mb/pg_wchar.h"
static int pg_unicode_version = 0;
#ifdef USE_ICU
@@ -59,7 +60,7 @@ icu_test()
int pg_skipped_codepoints = 0;
int icu_skipped_codepoints = 0;
- for (pg_wchar code = 0; code <= 0x10ffff; code++)
+ for (char32_t code = 0; code <= 0x10ffff; code++)
{
uint8_t pg_category = unicode_category(code);
uint8_t icu_category = u_charType(code);
diff --git a/src/common/unicode/generate-norm_test_table.pl b/src/common/unicode/generate-norm_test_table.pl
index 1b401be9409..1a8b908ff33 100644
--- a/src/common/unicode/generate-norm_test_table.pl
+++ b/src/common/unicode/generate-norm_test_table.pl
@@ -47,8 +47,8 @@ print $OUTPUT <<HEADER;
typedef struct
{
int linenum;
- pg_wchar input[50];
- pg_wchar output[4][50];
+ char32_t input[50];
+ char32_t output[4][50];
} pg_unicode_test;
/* test table */
diff --git a/src/common/unicode/generate-unicode_case_table.pl b/src/common/unicode/generate-unicode_case_table.pl
index 5d9ddd62803..f71eb25c94e 100644
--- a/src/common/unicode/generate-unicode_case_table.pl
+++ b/src/common/unicode/generate-unicode_case_table.pl
@@ -270,7 +270,6 @@ print $OT <<"EOS";
*/
#include "common/unicode_case.h"
-#include "mb/pg_wchar.h"
/*
* The maximum number of codepoints that can result from case mapping
@@ -297,7 +296,7 @@ typedef enum
typedef struct
{
int16 conditions;
- pg_wchar map[NCaseKind][MAX_CASE_EXPANSION];
+ char32_t map[NCaseKind][MAX_CASE_EXPANSION];
} pg_special_case;
/*
@@ -430,7 +429,7 @@ foreach my $kind ('lower', 'title', 'upper', 'fold')
* The entry case_map_${kind}[case_index(codepoint)] is the mapping for the
* given codepoint.
*/
-static const pg_wchar case_map_$kind\[$index\] =
+static const char32_t case_map_$kind\[$index\] =
{
EOS
@@ -502,7 +501,7 @@ print $OT <<"EOS";
* the offset into the mapping tables.
*/
static inline uint16
-case_index(pg_wchar cp)
+case_index(char32_t cp)
{
/* Fast path for codepoints < $fastpath_limit */
if (cp < $fastpath_limit)
diff --git a/src/common/unicode/generate-unicode_category_table.pl b/src/common/unicode/generate-unicode_category_table.pl
index abab5cd9696..7e094b13720 100644
--- a/src/common/unicode/generate-unicode_category_table.pl
+++ b/src/common/unicode/generate-unicode_category_table.pl
@@ -366,15 +366,15 @@ print $OT <<"EOS";
*/
typedef struct
{
- uint32 first; /* Unicode codepoint */
- uint32 last; /* Unicode codepoint */
+ char32_t first; /* Unicode codepoint */
+ char32_t last; /* Unicode codepoint */
uint8 category; /* General Category */
} pg_category_range;
typedef struct
{
- uint32 first; /* Unicode codepoint */
- uint32 last; /* Unicode codepoint */
+ char32_t first; /* Unicode codepoint */
+ char32_t last; /* Unicode codepoint */
} pg_unicode_range;
typedef struct
diff --git a/src/common/unicode/norm_test.c b/src/common/unicode/norm_test.c
index 25bc59463f2..058817f1719 100644
--- a/src/common/unicode/norm_test.c
+++ b/src/common/unicode/norm_test.c
@@ -20,7 +20,7 @@
#include "norm_test_table.h"
static char *
-print_wchar_str(const pg_wchar *s)
+print_wchar_str(const char32_t *s)
{
#define BUF_DIGITS 50
static char buf[BUF_DIGITS * 11 + 1];
@@ -41,7 +41,7 @@ print_wchar_str(const pg_wchar *s)
}
static int
-pg_wcscmp(const pg_wchar *s1, const pg_wchar *s2)
+pg_wcscmp(const char32_t *s1, const char32_t *s2)
{
for (;;)
{
@@ -65,7 +65,7 @@ main(int argc, char **argv)
{
for (int form = 0; form < 4; form++)
{
- pg_wchar *result;
+ char32_t *result;
result = unicode_normalize(form, test->input);
diff --git a/src/common/unicode_case.c b/src/common/unicode_case.c
index 073faf6a0d5..e5e494db43c 100644
--- a/src/common/unicode_case.c
+++ b/src/common/unicode_case.c
@@ -30,7 +30,7 @@ enum CaseMapResult
/*
* Map for each case kind.
*/
-static const pg_wchar *const casekind_map[NCaseKind] =
+static const char32_t *const casekind_map[NCaseKind] =
{
[CaseLower] = case_map_lower,
[CaseTitle] = case_map_title,
@@ -38,42 +38,42 @@ static const pg_wchar *const casekind_map[NCaseKind] =
[CaseFold] = case_map_fold,
};
-static pg_wchar find_case_map(pg_wchar ucs, const pg_wchar *map);
+static char32_t find_case_map(char32_t ucs, const char32_t *map);
static size_t convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
CaseKind str_casekind, bool full, WordBoundaryNext wbnext,
void *wbstate);
-static enum CaseMapResult casemap(pg_wchar u1, CaseKind casekind, bool full,
+static enum CaseMapResult casemap(char32_t u1, CaseKind casekind, bool full,
const char *src, size_t srclen, size_t srcoff,
- pg_wchar *simple, const pg_wchar **special);
+ char32_t *simple, const char32_t **special);
-pg_wchar
-unicode_lowercase_simple(pg_wchar code)
+char32_t
+unicode_lowercase_simple(char32_t code)
{
- pg_wchar cp = find_case_map(code, case_map_lower);
+ char32_t cp = find_case_map(code, case_map_lower);
return cp != 0 ? cp : code;
}
-pg_wchar
-unicode_titlecase_simple(pg_wchar code)
+char32_t
+unicode_titlecase_simple(char32_t code)
{
- pg_wchar cp = find_case_map(code, case_map_title);
+ char32_t cp = find_case_map(code, case_map_title);
return cp != 0 ? cp : code;
}
-pg_wchar
-unicode_uppercase_simple(pg_wchar code)
+char32_t
+unicode_uppercase_simple(char32_t code)
{
- pg_wchar cp = find_case_map(code, case_map_upper);
+ char32_t cp = find_case_map(code, case_map_upper);
return cp != 0 ? cp : code;
}
-pg_wchar
-unicode_casefold_simple(pg_wchar code)
+char32_t
+unicode_casefold_simple(char32_t code)
{
- pg_wchar cp = find_case_map(code, case_map_fold);
+ char32_t cp = find_case_map(code, case_map_fold);
return cp != 0 ? cp : code;
}
@@ -231,10 +231,10 @@ convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
while ((srclen < 0 || srcoff < srclen) && src[srcoff] != '\0')
{
- pg_wchar u1 = utf8_to_unicode((unsigned char *) src + srcoff);
+ char32_t u1 = utf8_to_unicode((unsigned char *) src + srcoff);
int u1len = unicode_utf8len(u1);
- pg_wchar simple = 0;
- const pg_wchar *special = NULL;
+ char32_t simple = 0;
+ const char32_t *special = NULL;
enum CaseMapResult casemap_result;
if (str_casekind == CaseTitle)
@@ -265,8 +265,8 @@ convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
case CASEMAP_SIMPLE:
{
/* replace with single character */
- pg_wchar u2 = simple;
- pg_wchar u2len = unicode_utf8len(u2);
+ char32_t u2 = simple;
+ char32_t u2len = unicode_utf8len(u2);
Assert(special == NULL);
if (result_len + u2len <= dstsize)
@@ -280,7 +280,7 @@ convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
Assert(simple == 0);
for (int i = 0; i < MAX_CASE_EXPANSION && special[i]; i++)
{
- pg_wchar u2 = special[i];
+ char32_t u2 = special[i];
size_t u2len = unicode_utf8len(u2);
if (result_len + u2len <= dstsize)
@@ -320,7 +320,7 @@ check_final_sigma(const unsigned char *str, size_t len, size_t offset)
{
if ((str[i] & 0x80) == 0 || (str[i] & 0xC0) == 0xC0)
{
- pg_wchar curr = utf8_to_unicode(str + i);
+ char32_t curr = utf8_to_unicode(str + i);
if (pg_u_prop_case_ignorable(curr))
continue;
@@ -344,7 +344,7 @@ check_final_sigma(const unsigned char *str, size_t len, size_t offset)
{
if ((str[i] & 0x80) == 0 || (str[i] & 0xC0) == 0xC0)
{
- pg_wchar curr = utf8_to_unicode(str + i);
+ char32_t curr = utf8_to_unicode(str + i);
if (pg_u_prop_case_ignorable(curr))
continue;
@@ -394,9 +394,9 @@ check_special_conditions(int conditions, const char *str, size_t len,
* character without modification.
*/
static enum CaseMapResult
-casemap(pg_wchar u1, CaseKind casekind, bool full,
+casemap(char32_t u1, CaseKind casekind, bool full,
const char *src, size_t srclen, size_t srcoff,
- pg_wchar *simple, const pg_wchar **special)
+ char32_t *simple, const char32_t **special)
{
uint16 idx;
@@ -434,8 +434,8 @@ casemap(pg_wchar u1, CaseKind casekind, bool full,
* Find entry in simple case map.
* If the entry does not exist, 0 will be returned.
*/
-static pg_wchar
-find_case_map(pg_wchar ucs, const pg_wchar *map)
+static char32_t
+find_case_map(char32_t ucs, const char32_t *map)
{
/* Fast path for codepoints < 0x80 */
if (ucs < 0x80)
diff --git a/src/common/unicode_category.c b/src/common/unicode_category.c
index 4136c4d4f92..aab667a7bb4 100644
--- a/src/common/unicode_category.c
+++ b/src/common/unicode_category.c
@@ -1,7 +1,7 @@
/*-------------------------------------------------------------------------
* unicode_category.c
* Determine general category and character properties of Unicode
- * characters. Encoding must be UTF8, where we assume that the pg_wchar
+ * characters. Encoding must be UTF8, where we assume that the char32_t
* representation is a code point.
*
* Portions Copyright (c) 2017-2025, PostgreSQL Global Development Group
@@ -76,13 +76,13 @@
#define PG_U_CHARACTER_TAB 0x09
static bool range_search(const pg_unicode_range *tbl, size_t size,
- pg_wchar code);
+ char32_t code);
/*
* Unicode general category for the given codepoint.
*/
pg_unicode_category
-unicode_category(pg_wchar code)
+unicode_category(char32_t code)
{
int min = 0;
int mid;
@@ -108,7 +108,7 @@ unicode_category(pg_wchar code)
}
bool
-pg_u_prop_alphabetic(pg_wchar code)
+pg_u_prop_alphabetic(char32_t code)
{
if (code < 0x80)
return unicode_opt_ascii[code].properties & PG_U_PROP_ALPHABETIC;
@@ -119,7 +119,7 @@ pg_u_prop_alphabetic(pg_wchar code)
}
bool
-pg_u_prop_lowercase(pg_wchar code)
+pg_u_prop_lowercase(char32_t code)
{
if (code < 0x80)
return unicode_opt_ascii[code].properties & PG_U_PROP_LOWERCASE;
@@ -130,7 +130,7 @@ pg_u_prop_lowercase(pg_wchar code)
}
bool
-pg_u_prop_uppercase(pg_wchar code)
+pg_u_prop_uppercase(char32_t code)
{
if (code < 0x80)
return unicode_opt_ascii[code].properties & PG_U_PROP_UPPERCASE;
@@ -141,7 +141,7 @@ pg_u_prop_uppercase(pg_wchar code)
}
bool
-pg_u_prop_cased(pg_wchar code)
+pg_u_prop_cased(char32_t code)
{
uint32 category_mask;
@@ -156,7 +156,7 @@ pg_u_prop_cased(pg_wchar code)
}
bool
-pg_u_prop_case_ignorable(pg_wchar code)
+pg_u_prop_case_ignorable(char32_t code)
{
if (code < 0x80)
return unicode_opt_ascii[code].properties & PG_U_PROP_CASE_IGNORABLE;
@@ -167,7 +167,7 @@ pg_u_prop_case_ignorable(pg_wchar code)
}
bool
-pg_u_prop_white_space(pg_wchar code)
+pg_u_prop_white_space(char32_t code)
{
if (code < 0x80)
return unicode_opt_ascii[code].properties & PG_U_PROP_WHITE_SPACE;
@@ -178,7 +178,7 @@ pg_u_prop_white_space(pg_wchar code)
}
bool
-pg_u_prop_hex_digit(pg_wchar code)
+pg_u_prop_hex_digit(char32_t code)
{
if (code < 0x80)
return unicode_opt_ascii[code].properties & PG_U_PROP_HEX_DIGIT;
@@ -189,7 +189,7 @@ pg_u_prop_hex_digit(pg_wchar code)
}
bool
-pg_u_prop_join_control(pg_wchar code)
+pg_u_prop_join_control(char32_t code)
{
if (code < 0x80)
return unicode_opt_ascii[code].properties & PG_U_PROP_JOIN_CONTROL;
@@ -208,7 +208,7 @@ pg_u_prop_join_control(pg_wchar code)
*/
bool
-pg_u_isdigit(pg_wchar code, bool posix)
+pg_u_isdigit(char32_t code, bool posix)
{
if (posix)
return ('0' <= code && code <= '9');
@@ -217,19 +217,19 @@ pg_u_isdigit(pg_wchar code, bool posix)
}
bool
-pg_u_isalpha(pg_wchar code)
+pg_u_isalpha(char32_t code)
{
return pg_u_prop_alphabetic(code);
}
bool
-pg_u_isalnum(pg_wchar code, bool posix)
+pg_u_isalnum(char32_t code, bool posix)
{
return pg_u_isalpha(code) || pg_u_isdigit(code, posix);
}
bool
-pg_u_isword(pg_wchar code)
+pg_u_isword(char32_t code)
{
uint32 category_mask = PG_U_CATEGORY_MASK(unicode_category(code));
@@ -240,32 +240,32 @@ pg_u_isword(pg_wchar code)
}
bool
-pg_u_isupper(pg_wchar code)
+pg_u_isupper(char32_t code)
{
return pg_u_prop_uppercase(code);
}
bool
-pg_u_islower(pg_wchar code)
+pg_u_islower(char32_t code)
{
return pg_u_prop_lowercase(code);
}
bool
-pg_u_isblank(pg_wchar code)
+pg_u_isblank(char32_t code)
{
return code == PG_U_CHARACTER_TAB ||
unicode_category(code) == PG_U_SPACE_SEPARATOR;
}
bool
-pg_u_iscntrl(pg_wchar code)
+pg_u_iscntrl(char32_t code)
{
return unicode_category(code) == PG_U_CONTROL;
}
bool
-pg_u_isgraph(pg_wchar code)
+pg_u_isgraph(char32_t code)
{
uint32 category_mask = PG_U_CATEGORY_MASK(unicode_category(code));
@@ -276,7 +276,7 @@ pg_u_isgraph(pg_wchar code)
}
bool
-pg_u_isprint(pg_wchar code)
+pg_u_isprint(char32_t code)
{
pg_unicode_category category = unicode_category(code);
@@ -287,7 +287,7 @@ pg_u_isprint(pg_wchar code)
}
bool
-pg_u_ispunct(pg_wchar code, bool posix)
+pg_u_ispunct(char32_t code, bool posix)
{
uint32 category_mask;
@@ -308,13 +308,13 @@ pg_u_ispunct(pg_wchar code, bool posix)
}
bool
-pg_u_isspace(pg_wchar code)
+pg_u_isspace(char32_t code)
{
return pg_u_prop_white_space(code);
}
bool
-pg_u_isxdigit(pg_wchar code, bool posix)
+pg_u_isxdigit(char32_t code, bool posix)
{
if (posix)
return (('0' <= code && code <= '9') ||
@@ -478,7 +478,7 @@ unicode_category_abbrev(pg_unicode_category category)
* given table.
*/
static bool
-range_search(const pg_unicode_range *tbl, size_t size, pg_wchar code)
+range_search(const pg_unicode_range *tbl, size_t size, char32_t code)
{
int min = 0;
int mid;
diff --git a/src/common/unicode_norm.c b/src/common/unicode_norm.c
index 6654b4cbc49..489d99cd5ab 100644
--- a/src/common/unicode_norm.c
+++ b/src/common/unicode_norm.c
@@ -69,7 +69,7 @@ conv_compare(const void *p1, const void *p2)
* lookup, while the frontend version uses a binary search.
*/
static const pg_unicode_decomposition *
-get_code_entry(pg_wchar code)
+get_code_entry(char32_t code)
{
#ifndef FRONTEND
int h;
@@ -109,7 +109,7 @@ get_code_entry(pg_wchar code)
* Get the combining class of the given codepoint.
*/
static uint8
-get_canonical_class(pg_wchar code)
+get_canonical_class(char32_t code)
{
const pg_unicode_decomposition *entry = get_code_entry(code);
@@ -130,15 +130,15 @@ get_canonical_class(pg_wchar code)
* Note: the returned pointer can point to statically allocated buffer, and
* is only valid until next call to this function!
*/
-static const pg_wchar *
+static const char32_t *
get_code_decomposition(const pg_unicode_decomposition *entry, int *dec_size)
{
- static pg_wchar x;
+ static char32_t x;
if (DECOMPOSITION_IS_INLINE(entry))
{
Assert(DECOMPOSITION_SIZE(entry) == 1);
- x = (pg_wchar) entry->dec_index;
+ x = (char32_t) entry->dec_index;
*dec_size = 1;
return &x;
}
@@ -156,7 +156,7 @@ get_code_decomposition(const pg_unicode_decomposition *entry, int *dec_size)
* are, in turn, decomposable.
*/
static int
-get_decomposed_size(pg_wchar code, bool compat)
+get_decomposed_size(char32_t code, bool compat)
{
const pg_unicode_decomposition *entry;
int size = 0;
@@ -318,7 +318,7 @@ recompose_code(uint32 start, uint32 code, uint32 *result)
* in the array result.
*/
static void
-decompose_code(pg_wchar code, bool compat, pg_wchar **result, int *current)
+decompose_code(char32_t code, bool compat, char32_t **result, int *current)
{
const pg_unicode_decomposition *entry;
int i;
@@ -337,7 +337,7 @@ decompose_code(pg_wchar code, bool compat, pg_wchar **result, int *current)
v,
tindex,
sindex;
- pg_wchar *res = *result;
+ char32_t *res = *result;
sindex = code - SBASE;
l = LBASE + sindex / (VCOUNT * TCOUNT);
@@ -369,7 +369,7 @@ decompose_code(pg_wchar code, bool compat, pg_wchar **result, int *current)
if (entry == NULL || DECOMPOSITION_SIZE(entry) == 0 ||
(!compat && DECOMPOSITION_IS_COMPAT(entry)))
{
- pg_wchar *res = *result;
+ char32_t *res = *result;
res[*current] = code;
(*current)++;
@@ -382,7 +382,7 @@ decompose_code(pg_wchar code, bool compat, pg_wchar **result, int *current)
decomp = get_code_decomposition(entry, &dec_size);
for (i = 0; i < dec_size; i++)
{
- pg_wchar lcode = (pg_wchar) decomp[i];
+ char32_t lcode = (char32_t) decomp[i];
/* Leave if no more decompositions */
decompose_code(lcode, compat, result, current);
@@ -398,17 +398,17 @@ decompose_code(pg_wchar code, bool compat, pg_wchar **result, int *current)
* malloc. Or NULL if we run out of memory. In backend, the returned
* string is palloc'd instead, and OOM is reported with ereport().
*/
-pg_wchar *
-unicode_normalize(UnicodeNormalizationForm form, const pg_wchar *input)
+char32_t *
+unicode_normalize(UnicodeNormalizationForm form, const char32_t *input)
{
bool compat = (form == UNICODE_NFKC || form == UNICODE_NFKD);
bool recompose = (form == UNICODE_NFC || form == UNICODE_NFKC);
- pg_wchar *decomp_chars;
- pg_wchar *recomp_chars;
+ char32_t *decomp_chars;
+ char32_t *recomp_chars;
int decomp_size,
current_size;
int count;
- const pg_wchar *p;
+ const char32_t *p;
/* variables for recomposition */
int last_class;
@@ -425,7 +425,7 @@ unicode_normalize(UnicodeNormalizationForm form, const pg_wchar *input)
for (p = input; *p; p++)
decomp_size += get_decomposed_size(*p, compat);
- decomp_chars = (pg_wchar *) ALLOC((decomp_size + 1) * sizeof(pg_wchar));
+ decomp_chars = (char32_t *) ALLOC((decomp_size + 1) * sizeof(char32_t));
if (decomp_chars == NULL)
return NULL;
@@ -448,9 +448,9 @@ unicode_normalize(UnicodeNormalizationForm form, const pg_wchar *input)
*/
for (count = 1; count < decomp_size; count++)
{
- pg_wchar prev = decomp_chars[count - 1];
- pg_wchar next = decomp_chars[count];
- pg_wchar tmp;
+ char32_t prev = decomp_chars[count - 1];
+ char32_t next = decomp_chars[count];
+ char32_t tmp;
const uint8 prevClass = get_canonical_class(prev);
const uint8 nextClass = get_canonical_class(next);
@@ -487,7 +487,7 @@ unicode_normalize(UnicodeNormalizationForm form, const pg_wchar *input)
* longer than the decomposed one, so make the allocation of the output
* string based on that assumption.
*/
- recomp_chars = (pg_wchar *) ALLOC((decomp_size + 1) * sizeof(pg_wchar));
+ recomp_chars = (char32_t *) ALLOC((decomp_size + 1) * sizeof(char32_t));
if (!recomp_chars)
{
FREE(decomp_chars);
@@ -501,9 +501,9 @@ unicode_normalize(UnicodeNormalizationForm form, const pg_wchar *input)
for (count = 1; count < decomp_size; count++)
{
- pg_wchar ch = decomp_chars[count];
+ char32_t ch = decomp_chars[count];
int ch_class = get_canonical_class(ch);
- pg_wchar composite;
+ char32_t composite;
if (last_class < ch_class &&
recompose_code(starter_ch, ch, &composite))
@@ -524,7 +524,7 @@ unicode_normalize(UnicodeNormalizationForm form, const pg_wchar *input)
recomp_chars[target_pos++] = ch;
}
}
- recomp_chars[target_pos] = (pg_wchar) '\0';
+ recomp_chars[target_pos] = (char32_t) '\0';
FREE(decomp_chars);
@@ -540,7 +540,7 @@ unicode_normalize(UnicodeNormalizationForm form, const pg_wchar *input)
#ifndef FRONTEND
static const pg_unicode_normprops *
-qc_hash_lookup(pg_wchar ch, const pg_unicode_norminfo *norminfo)
+qc_hash_lookup(char32_t ch, const pg_unicode_norminfo *norminfo)
{
int h;
uint32 hashkey;
@@ -571,7 +571,7 @@ qc_hash_lookup(pg_wchar ch, const pg_unicode_norminfo *norminfo)
* Look up the normalization quick check character property
*/
static UnicodeNormalizationQC
-qc_is_allowed(UnicodeNormalizationForm form, pg_wchar ch)
+qc_is_allowed(UnicodeNormalizationForm form, char32_t ch)
{
const pg_unicode_normprops *found = NULL;
@@ -595,7 +595,7 @@ qc_is_allowed(UnicodeNormalizationForm form, pg_wchar ch)
}
UnicodeNormalizationQC
-unicode_is_normalized_quickcheck(UnicodeNormalizationForm form, const pg_wchar *input)
+unicode_is_normalized_quickcheck(UnicodeNormalizationForm form, const char32_t *input)
{
uint8 lastCanonicalClass = 0;
UnicodeNormalizationQC result = UNICODE_NORM_QC_YES;
@@ -610,9 +610,9 @@ unicode_is_normalized_quickcheck(UnicodeNormalizationForm form, const pg_wchar *
if (form == UNICODE_NFD || form == UNICODE_NFKD)
return UNICODE_NORM_QC_MAYBE;
- for (const pg_wchar *p = input; *p; p++)
+ for (const char32_t *p = input; *p; p++)
{
- pg_wchar ch = *p;
+ char32_t ch = *p;
uint8 canonicalClass;
UnicodeNormalizationQC check;
diff --git a/src/fe_utils/mbprint.c b/src/fe_utils/mbprint.c
index eb3eeee9925..abffdbe18a2 100644
--- a/src/fe_utils/mbprint.c
+++ b/src/fe_utils/mbprint.c
@@ -49,20 +49,20 @@ pg_get_utf8_id(void)
*
* No error checks here, c must point to a long-enough string.
*/
-static pg_wchar
+static char32_t
utf8_to_unicode(const unsigned char *c)
{
if ((*c & 0x80) == 0)
- return (pg_wchar) c[0];
+ return (char32_t) c[0];
else if ((*c & 0xe0) == 0xc0)
- return (pg_wchar) (((c[0] & 0x1f) << 6) |
+ return (char32_t) (((c[0] & 0x1f) << 6) |
(c[1] & 0x3f));
else if ((*c & 0xf0) == 0xe0)
- return (pg_wchar) (((c[0] & 0x0f) << 12) |
+ return (char32_t) (((c[0] & 0x0f) << 12) |
((c[1] & 0x3f) << 6) |
(c[2] & 0x3f));
else if ((*c & 0xf8) == 0xf0)
- return (pg_wchar) (((c[0] & 0x07) << 18) |
+ return (char32_t) (((c[0] & 0x07) << 18) |
((c[1] & 0x3f) << 12) |
((c[2] & 0x3f) << 6) |
(c[3] & 0x3f));
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index d12798be3d8..a12757e46e5 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -202,6 +202,7 @@ extern XLogRecPtr XLogInsertRecord(struct XLogRecData *rdata,
XLogRecPtr fpw_lsn,
uint8 flags,
int num_fpi,
+ uint64 fpi_bytes,
bool topxid_included);
extern void XLogFlush(XLogRecPtr record);
extern bool XLogBackgroundFlush(void);
diff --git a/src/include/c.h b/src/include/c.h
index 9ab5e617995..757dfff4782 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -93,8 +93,6 @@
/* ----------------------------------------------------------------
* Section 1: compiler characteristics
- *
- * type prefixes (const, signed, volatile, inline) are handled in pg_config.h.
* ----------------------------------------------------------------
*/
@@ -109,6 +107,12 @@
#endif
/*
+ * Previously used PostgreSQL-specific spelling, for backward compatibility
+ * for extensions.
+ */
+#define pg_restrict restrict
+
+/*
* Attribute macros
*
* GCC: https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
@@ -1372,6 +1376,29 @@ typedef intptr_t sigjmp_buf[5];
/* /port compatibility functions */
#include "port.h"
+/*
+ * char16_t and char32_t
+ * Unicode code points.
+ *
+ * uchar.h should always be available in C11, but it's not available on
+ * Mac. However, these types are keywords in C++11, so when using C++, we
+ * can't redefine the types.
+ *
+ * XXX: when uchar.h is available everywhere, we can remove this check and
+ * just include uchar.h unconditionally.
+ *
+ * XXX: this section is out of place because uchar.h needs to be included
+ * after port.h, due to an interaction with win32_port.h in some cases.
+ */
+#ifdef HAVE_UCHAR_H
+#include <uchar.h>
+#else
+#ifndef __cplusplus
+typedef uint16_t char16_t;
+typedef uint32_t char32_t;
+#endif
+#endif
+
/* IWYU pragma: end_exports */
#endif /* C_H */
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index 1b0b16a343f..18e95179ab6 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -57,6 +57,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 202510221
+#define CATALOG_VERSION_NO 202510281
#endif
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index eecb43ec6f0..9121a382f76 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -6029,16 +6029,16 @@
{ oid => '1136', descr => 'statistics: information about WAL activity',
proname => 'pg_stat_get_wal', proisstrict => 'f', provolatile => 's',
proparallel => 'r', prorettype => 'record', proargtypes => '',
- proallargtypes => '{int8,int8,numeric,int8,timestamptz}',
- proargmodes => '{o,o,o,o,o}',
- proargnames => '{wal_records,wal_fpi,wal_bytes,wal_buffers_full,stats_reset}',
+ proallargtypes => '{int8,int8,numeric,numeric,int8,timestamptz}',
+ proargmodes => '{o,o,o,o,o,o}',
+ proargnames => '{wal_records,wal_fpi,wal_bytes,wal_fpi_bytes,wal_buffers_full,stats_reset}',
prosrc => 'pg_stat_get_wal' },
{ oid => '6313', descr => 'statistics: backend WAL activity',
proname => 'pg_stat_get_backend_wal', provolatile => 'v', proparallel => 'r',
prorettype => 'record', proargtypes => 'int4',
- proallargtypes => '{int4,int8,int8,numeric,int8,timestamptz}',
- proargmodes => '{i,o,o,o,o,o}',
- proargnames => '{backend_pid,wal_records,wal_fpi,wal_bytes,wal_buffers_full,stats_reset}',
+ proallargtypes => '{int4,int8,int8,numeric,numeric,int8,timestamptz}',
+ proargmodes => '{i,o,o,o,o,o,o}',
+ proargnames => '{backend_pid,wal_records,wal_fpi,wal_bytes,wal_fpi_bytes,wal_buffers_full,stats_reset}',
prosrc => 'pg_stat_get_backend_wal' },
{ oid => '6248', descr => 'statistics: information about WAL prefetching',
proname => 'pg_stat_get_recovery_prefetch', prorows => '1', proretset => 't',
diff --git a/src/include/common/logging.h b/src/include/common/logging.h
index 81529ee8f29..2e0333dc009 100644
--- a/src/include/common/logging.h
+++ b/src/include/common/logging.h
@@ -93,10 +93,10 @@ void pg_logging_set_pre_callback(void (*cb) (void));
void pg_logging_set_locus_callback(void (*cb) (const char **filename, uint64 *lineno));
void pg_log_generic(enum pg_log_level level, enum pg_log_part part,
- const char *pg_restrict fmt,...)
+ const char *restrict fmt,...)
pg_attribute_printf(3, 4);
void pg_log_generic_v(enum pg_log_level level, enum pg_log_part part,
- const char *pg_restrict fmt, va_list ap)
+ const char *restrict fmt, va_list ap)
pg_attribute_printf(3, 0);
/*
diff --git a/src/include/common/string.h b/src/include/common/string.h
index 55ed8774364..32a97c24b22 100644
--- a/src/include/common/string.h
+++ b/src/include/common/string.h
@@ -25,7 +25,7 @@ typedef struct PromptInterruptContext
/* functions in src/common/string.c */
extern bool pg_str_endswith(const char *str, const char *end);
-extern int strtoint(const char *pg_restrict str, char **pg_restrict endptr,
+extern int strtoint(const char *restrict str, char **restrict endptr,
int base);
extern char *pg_clean_ascii(const char *str, int alloc_flags);
extern int pg_strip_crlf(char *str);
diff --git a/src/include/common/unicode_case.h b/src/include/common/unicode_case.h
index 41e2c1f4b33..6bcffd349c2 100644
--- a/src/include/common/unicode_case.h
+++ b/src/include/common/unicode_case.h
@@ -14,14 +14,12 @@
#ifndef UNICODE_CASE_H
#define UNICODE_CASE_H
-#include "mb/pg_wchar.h"
-
typedef size_t (*WordBoundaryNext) (void *wbstate);
-pg_wchar unicode_lowercase_simple(pg_wchar code);
-pg_wchar unicode_titlecase_simple(pg_wchar code);
-pg_wchar unicode_uppercase_simple(pg_wchar code);
-pg_wchar unicode_casefold_simple(pg_wchar code);
+char32_t unicode_lowercase_simple(char32_t code);
+char32_t unicode_titlecase_simple(char32_t code);
+char32_t unicode_uppercase_simple(char32_t code);
+char32_t unicode_casefold_simple(char32_t code);
size_t unicode_strlower(char *dst, size_t dstsize, const char *src,
ssize_t srclen, bool full);
size_t unicode_strtitle(char *dst, size_t dstsize, const char *src,
diff --git a/src/include/common/unicode_case_table.h b/src/include/common/unicode_case_table.h
index d5311786582..0a14fb2d97b 100644
--- a/src/include/common/unicode_case_table.h
+++ b/src/include/common/unicode_case_table.h
@@ -18,7 +18,6 @@
*/
#include "common/unicode_case.h"
-#include "mb/pg_wchar.h"
/*
* The maximum number of codepoints that can result from case mapping
@@ -45,7 +44,7 @@ typedef enum
typedef struct
{
int16 conditions;
- pg_wchar map[NCaseKind][MAX_CASE_EXPANSION];
+ char32_t map[NCaseKind][MAX_CASE_EXPANSION];
} pg_special_case;
/*
@@ -166,7 +165,7 @@ static const pg_special_case special_case[106] =
* The entry case_map_lower[case_index(codepoint)] is the mapping for the
* given codepoint.
*/
-static const pg_wchar case_map_lower[1704] =
+static const char32_t case_map_lower[1704] =
{
0x000000, /* reserved */
0x000000, /* U+000000 */
@@ -1879,7 +1878,7 @@ static const pg_wchar case_map_lower[1704] =
* The entry case_map_title[case_index(codepoint)] is the mapping for the
* given codepoint.
*/
-static const pg_wchar case_map_title[1704] =
+static const char32_t case_map_title[1704] =
{
0x000000, /* reserved */
0x000000, /* U+000000 */
@@ -3592,7 +3591,7 @@ static const pg_wchar case_map_title[1704] =
* The entry case_map_upper[case_index(codepoint)] is the mapping for the
* given codepoint.
*/
-static const pg_wchar case_map_upper[1704] =
+static const char32_t case_map_upper[1704] =
{
0x000000, /* reserved */
0x000000, /* U+000000 */
@@ -5305,7 +5304,7 @@ static const pg_wchar case_map_upper[1704] =
* The entry case_map_fold[case_index(codepoint)] is the mapping for the
* given codepoint.
*/
-static const pg_wchar case_map_fold[1704] =
+static const char32_t case_map_fold[1704] =
{
0x000000, /* reserved */
0x000000, /* U+000000 */
@@ -13522,7 +13521,7 @@ static const uint16 case_map[4778] =
* the offset into the mapping tables.
*/
static inline uint16
-case_index(pg_wchar cp)
+case_index(char32_t cp)
{
/* Fast path for codepoints < 0x0588 */
if (cp < 0x0588)
diff --git a/src/include/common/unicode_category.h b/src/include/common/unicode_category.h
index 8fd8b67a416..684143d3c8a 100644
--- a/src/include/common/unicode_category.h
+++ b/src/include/common/unicode_category.h
@@ -14,8 +14,6 @@
#ifndef UNICODE_CATEGORY_H
#define UNICODE_CATEGORY_H
-#include "mb/pg_wchar.h"
-
/*
* Unicode General Category Values
*
@@ -61,31 +59,31 @@ typedef enum pg_unicode_category
PG_U_FINAL_PUNCTUATION = 29 /* Pf */
} pg_unicode_category;
-extern pg_unicode_category unicode_category(pg_wchar code);
+extern pg_unicode_category unicode_category(char32_t code);
extern const char *unicode_category_string(pg_unicode_category category);
extern const char *unicode_category_abbrev(pg_unicode_category category);
-extern bool pg_u_prop_alphabetic(pg_wchar code);
-extern bool pg_u_prop_lowercase(pg_wchar code);
-extern bool pg_u_prop_uppercase(pg_wchar code);
-extern bool pg_u_prop_cased(pg_wchar code);
-extern bool pg_u_prop_case_ignorable(pg_wchar code);
-extern bool pg_u_prop_white_space(pg_wchar code);
-extern bool pg_u_prop_hex_digit(pg_wchar code);
-extern bool pg_u_prop_join_control(pg_wchar code);
+extern bool pg_u_prop_alphabetic(char32_t code);
+extern bool pg_u_prop_lowercase(char32_t code);
+extern bool pg_u_prop_uppercase(char32_t code);
+extern bool pg_u_prop_cased(char32_t code);
+extern bool pg_u_prop_case_ignorable(char32_t code);
+extern bool pg_u_prop_white_space(char32_t code);
+extern bool pg_u_prop_hex_digit(char32_t code);
+extern bool pg_u_prop_join_control(char32_t code);
-extern bool pg_u_isdigit(pg_wchar code, bool posix);
-extern bool pg_u_isalpha(pg_wchar code);
-extern bool pg_u_isalnum(pg_wchar code, bool posix);
-extern bool pg_u_isword(pg_wchar code);
-extern bool pg_u_isupper(pg_wchar code);
-extern bool pg_u_islower(pg_wchar code);
-extern bool pg_u_isblank(pg_wchar code);
-extern bool pg_u_iscntrl(pg_wchar code);
-extern bool pg_u_isgraph(pg_wchar code);
-extern bool pg_u_isprint(pg_wchar code);
-extern bool pg_u_ispunct(pg_wchar code, bool posix);
-extern bool pg_u_isspace(pg_wchar code);
-extern bool pg_u_isxdigit(pg_wchar code, bool posix);
+extern bool pg_u_isdigit(char32_t code, bool posix);
+extern bool pg_u_isalpha(char32_t code);
+extern bool pg_u_isalnum(char32_t code, bool posix);
+extern bool pg_u_isword(char32_t code);
+extern bool pg_u_isupper(char32_t code);
+extern bool pg_u_islower(char32_t code);
+extern bool pg_u_isblank(char32_t code);
+extern bool pg_u_iscntrl(char32_t code);
+extern bool pg_u_isgraph(char32_t code);
+extern bool pg_u_isprint(char32_t code);
+extern bool pg_u_ispunct(char32_t code, bool posix);
+extern bool pg_u_isspace(char32_t code);
+extern bool pg_u_isxdigit(char32_t code, bool posix);
#endif /* UNICODE_CATEGORY_H */
diff --git a/src/include/common/unicode_category_table.h b/src/include/common/unicode_category_table.h
index 95a1c65da7e..466a41b72b0 100644
--- a/src/include/common/unicode_category_table.h
+++ b/src/include/common/unicode_category_table.h
@@ -20,15 +20,15 @@
*/
typedef struct
{
- uint32 first; /* Unicode codepoint */
- uint32 last; /* Unicode codepoint */
+ char32_t first; /* Unicode codepoint */
+ char32_t last; /* Unicode codepoint */
uint8 category; /* General Category */
} pg_category_range;
typedef struct
{
- uint32 first; /* Unicode codepoint */
- uint32 last; /* Unicode codepoint */
+ char32_t first; /* Unicode codepoint */
+ char32_t last; /* Unicode codepoint */
} pg_unicode_range;
typedef struct
diff --git a/src/include/common/unicode_norm.h b/src/include/common/unicode_norm.h
index 5bc3b79e78e..516c192cc4c 100644
--- a/src/include/common/unicode_norm.h
+++ b/src/include/common/unicode_norm.h
@@ -14,8 +14,6 @@
#ifndef UNICODE_NORM_H
#define UNICODE_NORM_H
-#include "mb/pg_wchar.h"
-
typedef enum
{
UNICODE_NFC = 0,
@@ -32,8 +30,8 @@ typedef enum
UNICODE_NORM_QC_MAYBE = -1,
} UnicodeNormalizationQC;
-extern pg_wchar *unicode_normalize(UnicodeNormalizationForm form, const pg_wchar *input);
+extern char32_t *unicode_normalize(UnicodeNormalizationForm form, const char32_t *input);
-extern UnicodeNormalizationQC unicode_is_normalized_quickcheck(UnicodeNormalizationForm form, const pg_wchar *input);
+extern UnicodeNormalizationQC unicode_is_normalized_quickcheck(UnicodeNormalizationForm form, const char32_t *input);
#endif /* UNICODE_NORM_H */
diff --git a/src/include/executor/instrument.h b/src/include/executor/instrument.h
index 03653ab6c6c..ffe470f2b84 100644
--- a/src/include/executor/instrument.h
+++ b/src/include/executor/instrument.h
@@ -53,6 +53,7 @@ typedef struct WalUsage
int64 wal_records; /* # of WAL records produced */
int64 wal_fpi; /* # of WAL full page images produced */
uint64 wal_bytes; /* size of WAL records produced */
+ uint64 wal_fpi_bytes; /* size of WAL full page images produced */
int64 wal_buffers_full; /* # of times the WAL buffers became full */
} WalUsage;
diff --git a/src/include/libpq/pqformat.h b/src/include/libpq/pqformat.h
index 55442caf0e4..127a74e299a 100644
--- a/src/include/libpq/pqformat.h
+++ b/src/include/libpq/pqformat.h
@@ -34,7 +34,7 @@ extern void pq_sendfloat8(StringInfo buf, float8 f);
* Append a [u]int8 to a StringInfo buffer, which already has enough space
* preallocated.
*
- * The use of pg_restrict allows the compiler to optimize the code based on
+ * The use of restrict allows the compiler to optimize the code based on
* the assumption that buf, buf->len, buf->data and *buf->data don't
* overlap. Without the annotation buf->len etc cannot be kept in a register
* over subsequent pq_writeintN calls.
@@ -43,7 +43,7 @@ extern void pq_sendfloat8(StringInfo buf, float8 f);
* overly picky and demanding a * before a restrict.
*/
static inline void
-pq_writeint8(StringInfoData *pg_restrict buf, uint8 i)
+pq_writeint8(StringInfoData *restrict buf, uint8 i)
{
uint8 ni = i;
@@ -57,7 +57,7 @@ pq_writeint8(StringInfoData *pg_restrict buf, uint8 i)
* preallocated.
*/
static inline void
-pq_writeint16(StringInfoData *pg_restrict buf, uint16 i)
+pq_writeint16(StringInfoData *restrict buf, uint16 i)
{
uint16 ni = pg_hton16(i);
@@ -71,7 +71,7 @@ pq_writeint16(StringInfoData *pg_restrict buf, uint16 i)
* preallocated.
*/
static inline void
-pq_writeint32(StringInfoData *pg_restrict buf, uint32 i)
+pq_writeint32(StringInfoData *restrict buf, uint32 i)
{
uint32 ni = pg_hton32(i);
@@ -85,7 +85,7 @@ pq_writeint32(StringInfoData *pg_restrict buf, uint32 i)
* preallocated.
*/
static inline void
-pq_writeint64(StringInfoData *pg_restrict buf, uint64 i)
+pq_writeint64(StringInfoData *restrict buf, uint64 i)
{
uint64 ni = pg_hton64(i);
@@ -105,7 +105,7 @@ pq_writeint64(StringInfoData *pg_restrict buf, uint64 i)
* sent to the frontend.
*/
static inline void
-pq_writestring(StringInfoData *pg_restrict buf, const char *pg_restrict str)
+pq_writestring(StringInfoData *restrict buf, const char *restrict str)
{
int slen = strlen(str);
char *p;
diff --git a/src/include/mb/pg_wchar.h b/src/include/mb/pg_wchar.h
index 4b4a9974b75..4d84bdc81e4 100644
--- a/src/include/mb/pg_wchar.h
+++ b/src/include/mb/pg_wchar.h
@@ -532,25 +532,25 @@ typedef uint32 (*utf_local_conversion_func) (uint32 code);
* Some handy functions for Unicode-specific tests.
*/
static inline bool
-is_valid_unicode_codepoint(pg_wchar c)
+is_valid_unicode_codepoint(char32_t c)
{
return (c > 0 && c <= 0x10FFFF);
}
static inline bool
-is_utf16_surrogate_first(pg_wchar c)
+is_utf16_surrogate_first(char32_t c)
{
return (c >= 0xD800 && c <= 0xDBFF);
}
static inline bool
-is_utf16_surrogate_second(pg_wchar c)
+is_utf16_surrogate_second(char32_t c)
{
return (c >= 0xDC00 && c <= 0xDFFF);
}
-static inline pg_wchar
-surrogate_pair_to_codepoint(pg_wchar first, pg_wchar second)
+static inline char32_t
+surrogate_pair_to_codepoint(char16_t first, char16_t second)
{
return ((first & 0x3FF) << 10) + 0x10000 + (second & 0x3FF);
}
@@ -561,20 +561,20 @@ surrogate_pair_to_codepoint(pg_wchar first, pg_wchar second)
*
* No error checks here, c must point to a long-enough string.
*/
-static inline pg_wchar
+static inline char32_t
utf8_to_unicode(const unsigned char *c)
{
if ((*c & 0x80) == 0)
- return (pg_wchar) c[0];
+ return (char32_t) c[0];
else if ((*c & 0xe0) == 0xc0)
- return (pg_wchar) (((c[0] & 0x1f) << 6) |
+ return (char32_t) (((c[0] & 0x1f) << 6) |
(c[1] & 0x3f));
else if ((*c & 0xf0) == 0xe0)
- return (pg_wchar) (((c[0] & 0x0f) << 12) |
+ return (char32_t) (((c[0] & 0x0f) << 12) |
((c[1] & 0x3f) << 6) |
(c[2] & 0x3f));
else if ((*c & 0xf8) == 0xf0)
- return (pg_wchar) (((c[0] & 0x07) << 18) |
+ return (char32_t) (((c[0] & 0x07) << 18) |
((c[1] & 0x3f) << 12) |
((c[2] & 0x3f) << 6) |
(c[3] & 0x3f));
@@ -588,7 +588,7 @@ utf8_to_unicode(const unsigned char *c)
* unicode_utf8len(c) bytes available.
*/
static inline unsigned char *
-unicode_to_utf8(pg_wchar c, unsigned char *utf8string)
+unicode_to_utf8(char32_t c, unsigned char *utf8string)
{
if (c <= 0x7F)
{
@@ -620,7 +620,7 @@ unicode_to_utf8(pg_wchar c, unsigned char *utf8string)
* Number of bytes needed to represent the given char in UTF8.
*/
static inline int
-unicode_utf8len(pg_wchar c)
+unicode_utf8len(char32_t c)
{
if (c <= 0x7F)
return 1;
@@ -676,8 +676,8 @@ extern int pg_valid_server_encoding(const char *name);
extern bool is_encoding_supported_by_icu(int encoding);
extern const char *get_encoding_name_for_icu(int encoding);
-extern unsigned char *unicode_to_utf8(pg_wchar c, unsigned char *utf8string);
-extern pg_wchar utf8_to_unicode(const unsigned char *c);
+extern unsigned char *unicode_to_utf8(char32_t c, unsigned char *utf8string);
+extern char32_t utf8_to_unicode(const unsigned char *c);
extern bool pg_utf8_islegal(const unsigned char *source, int length);
extern int pg_utf_mblen(const unsigned char *s);
extern int pg_mule_mblen(const unsigned char *s);
@@ -739,8 +739,8 @@ extern char *pg_server_to_client(const char *s, int len);
extern char *pg_any_to_server(const char *s, int len, int encoding);
extern char *pg_server_to_any(const char *s, int len, int encoding);
-extern void pg_unicode_to_server(pg_wchar c, unsigned char *s);
-extern bool pg_unicode_to_server_noerror(pg_wchar c, unsigned char *s);
+extern void pg_unicode_to_server(char32_t c, unsigned char *s);
+extern bool pg_unicode_to_server_noerror(char32_t c, unsigned char *s);
extern unsigned short BIG5toCNS(unsigned short big5, unsigned char *lc);
extern unsigned short CNStoBIG5(unsigned short cns, unsigned char lc);
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index c4dc5d72bdb..f52f14cc566 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -463,6 +463,9 @@
/* Define to 1 if you have the <termios.h> header file. */
#undef HAVE_TERMIOS_H
+/* Define to 1 if you have the <uchar.h> header file. */
+#undef HAVE_UCHAR_H
+
/* Define to 1 if curl_global_init() is guaranteed to be thread-safe. */
#undef HAVE_THREADSAFE_CURL_GLOBAL_INIT
@@ -796,10 +799,6 @@
#undef inline
#endif
-/* Define to keyword to use for C99 restrict support, or to nothing if not
- supported */
-#undef pg_restrict
-
/* Define to the equivalent of the C99 'restrict' keyword, or to
nothing if this is not supported. Do not define if restrict is
supported directly. */
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index bc8077cbae6..7ae503e71a2 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -212,7 +212,7 @@ typedef struct PgStat_TableXactStatus
* ------------------------------------------------------------
*/
-#define PGSTAT_FILE_FORMAT_ID 0x01A5BCB9
+#define PGSTAT_FILE_FORMAT_ID 0x01A5BCBA
typedef struct PgStat_ArchiverStats
{
@@ -473,6 +473,7 @@ typedef struct PgStat_WalCounters
PgStat_Counter wal_records;
PgStat_Counter wal_fpi;
uint64 wal_bytes;
+ uint64 wal_fpi_bytes;
PgStat_Counter wal_buffers_full;
} PgStat_WalCounters;
diff --git a/src/include/replication/worker_internal.h b/src/include/replication/worker_internal.h
index ae352f6e691..e23fa9a4514 100644
--- a/src/include/replication/worker_internal.h
+++ b/src/include/replication/worker_internal.h
@@ -254,7 +254,8 @@ extern PGDLLIMPORT bool InitializingApplyWorker;
extern PGDLLIMPORT List *table_states_not_ready;
extern void logicalrep_worker_attach(int slot);
-extern LogicalRepWorker *logicalrep_worker_find(Oid subid, Oid relid,
+extern LogicalRepWorker *logicalrep_worker_find(LogicalRepWorkerType wtype,
+ Oid subid, Oid relid,
bool only_running);
extern List *logicalrep_workers_find(Oid subid, bool only_running,
bool acquire_lock);
@@ -263,9 +264,11 @@ extern bool logicalrep_worker_launch(LogicalRepWorkerType wtype,
Oid userid, Oid relid,
dsm_handle subworker_dsm,
bool retain_dead_tuples);
-extern void logicalrep_worker_stop(Oid subid, Oid relid);
+extern void logicalrep_worker_stop(LogicalRepWorkerType wtype, Oid subid,
+ Oid relid);
extern void logicalrep_pa_worker_stop(ParallelApplyWorkerInfo *winfo);
-extern void logicalrep_worker_wakeup(Oid subid, Oid relid);
+extern void logicalrep_worker_wakeup(LogicalRepWorkerType wtype, Oid subid,
+ Oid relid);
extern void logicalrep_worker_wakeup_ptr(LogicalRepWorker *worker);
extern int logicalrep_sync_worker_count(Oid subid);
diff --git a/src/include/utils/guc_tables.h b/src/include/utils/guc_tables.h
index 3de3d809545..bbfcc633014 100644
--- a/src/include/utils/guc_tables.h
+++ b/src/include/utils/guc_tables.h
@@ -132,6 +132,84 @@ typedef struct guc_stack
config_var_value masked; /* SET value in a GUC_SET_LOCAL entry */
} GucStack;
+
+/* GUC records for specific variable types */
+
+struct config_bool
+{
+ /* constant fields, must be set correctly in initial value: */
+ bool *variable;
+ bool boot_val;
+ GucBoolCheckHook check_hook;
+ GucBoolAssignHook assign_hook;
+ GucShowHook show_hook;
+ /* variable fields, initialized at runtime: */
+ bool reset_val;
+};
+
+struct config_int
+{
+ /* constant fields, must be set correctly in initial value: */
+ int *variable;
+ int boot_val;
+ int min;
+ int max;
+ GucIntCheckHook check_hook;
+ GucIntAssignHook assign_hook;
+ GucShowHook show_hook;
+ /* variable fields, initialized at runtime: */
+ int reset_val;
+};
+
+struct config_real
+{
+ /* constant fields, must be set correctly in initial value: */
+ double *variable;
+ double boot_val;
+ double min;
+ double max;
+ GucRealCheckHook check_hook;
+ GucRealAssignHook assign_hook;
+ GucShowHook show_hook;
+ /* variable fields, initialized at runtime: */
+ double reset_val;
+};
+
+/*
+ * A note about string GUCs: the boot_val is allowed to be NULL, which leads
+ * to the reset_val and the actual variable value (*variable) also being NULL.
+ * However, there is no way to set a NULL value subsequently using
+ * set_config_option or any other GUC API. Also, GUC APIs such as SHOW will
+ * display a NULL value as an empty string. Callers that choose to use a NULL
+ * boot_val should overwrite the setting later in startup, or else be careful
+ * that NULL doesn't have semantics that are visibly different from an empty
+ * string.
+ */
+struct config_string
+{
+ /* constant fields, must be set correctly in initial value: */
+ char **variable;
+ const char *boot_val;
+ GucStringCheckHook check_hook;
+ GucStringAssignHook assign_hook;
+ GucShowHook show_hook;
+ /* variable fields, initialized at runtime: */
+ char *reset_val;
+};
+
+struct config_enum
+{
+ /* constant fields, must be set correctly in initial value: */
+ int *variable;
+ int boot_val;
+ const struct config_enum_entry *options;
+ GucEnumCheckHook check_hook;
+ GucEnumAssignHook assign_hook;
+ GucShowHook show_hook;
+ /* variable fields, initialized at runtime: */
+ int reset_val;
+};
+
/*
* Generic fields applicable to all types of variables
*
@@ -200,6 +278,16 @@ struct config_generic
char *sourcefile; /* file current setting is from (NULL if not
* set in config file) */
int sourceline; /* line in source file */
+
+ /* fields for specific variable types */
+ union
+ {
+ struct config_bool _bool;
+ struct config_int _int;
+ struct config_real _real;
+ struct config_string _string;
+ struct config_enum _enum;
+ };
};
/* bit values in status field */
@@ -212,100 +300,14 @@ struct config_generic
#define GUC_NEEDS_REPORT 0x0004 /* new value must be reported to client */
-/* GUC records for specific variable types */
-
-struct config_bool
-{
- struct config_generic gen;
- /* constant fields, must be set correctly in initial value: */
- bool *variable;
- bool boot_val;
- GucBoolCheckHook check_hook;
- GucBoolAssignHook assign_hook;
- GucShowHook show_hook;
- /* variable fields, initialized at runtime: */
- bool reset_val;
-};
-
-struct config_int
-{
- struct config_generic gen;
- /* constant fields, must be set correctly in initial value: */
- int *variable;
- int boot_val;
- int min;
- int max;
- GucIntCheckHook check_hook;
- GucIntAssignHook assign_hook;
- GucShowHook show_hook;
- /* variable fields, initialized at runtime: */
- int reset_val;
-};
-
-struct config_real
-{
- struct config_generic gen;
- /* constant fields, must be set correctly in initial value: */
- double *variable;
- double boot_val;
- double min;
- double max;
- GucRealCheckHook check_hook;
- GucRealAssignHook assign_hook;
- GucShowHook show_hook;
- /* variable fields, initialized at runtime: */
- double reset_val;
-};
-
-/*
- * A note about string GUCs: the boot_val is allowed to be NULL, which leads
- * to the reset_val and the actual variable value (*variable) also being NULL.
- * However, there is no way to set a NULL value subsequently using
- * set_config_option or any other GUC API. Also, GUC APIs such as SHOW will
- * display a NULL value as an empty string. Callers that choose to use a NULL
- * boot_val should overwrite the setting later in startup, or else be careful
- * that NULL doesn't have semantics that are visibly different from an empty
- * string.
- */
-struct config_string
-{
- struct config_generic gen;
- /* constant fields, must be set correctly in initial value: */
- char **variable;
- const char *boot_val;
- GucStringCheckHook check_hook;
- GucStringAssignHook assign_hook;
- GucShowHook show_hook;
- /* variable fields, initialized at runtime: */
- char *reset_val;
-};
-
-struct config_enum
-{
- struct config_generic gen;
- /* constant fields, must be set correctly in initial value: */
- int *variable;
- int boot_val;
- const struct config_enum_entry *options;
- GucEnumCheckHook check_hook;
- GucEnumAssignHook assign_hook;
- GucShowHook show_hook;
- /* variable fields, initialized at runtime: */
- int reset_val;
-};
-
/* constant tables corresponding to enums above and in guc.h */
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[];
-/* data arrays defining all the built-in GUC variables */
-extern PGDLLIMPORT struct config_bool ConfigureNamesBool[];
-extern PGDLLIMPORT struct config_int ConfigureNamesInt[];
-extern PGDLLIMPORT struct config_real ConfigureNamesReal[];
-extern PGDLLIMPORT struct config_string ConfigureNamesString[];
-extern PGDLLIMPORT struct config_enum ConfigureNamesEnum[];
+/* data array defining all the built-in GUC variables */
+extern PGDLLIMPORT struct config_generic ConfigureNames[];
/* lookup GUC variables, returning config_generic pointers */
extern struct config_generic *find_option(const char *name,
@@ -326,7 +328,7 @@ extern struct config_generic **get_guc_variables(int *num_vars);
extern void build_guc_variables(void);
/* search in enum options */
-extern const char *config_enum_lookup_by_value(const struct config_enum *record, int val);
+extern const char *config_enum_lookup_by_value(const struct config_generic *record, int val);
extern bool config_enum_lookup_by_name(const struct config_enum *record,
const char *value, int *retval);
extern char *config_enum_get_options(const struct config_enum *record,
diff --git a/src/interfaces/libpq/t/006_service.pl b/src/interfaces/libpq/t/006_service.pl
index 797e6232b8f..29a70629b44 100644
--- a/src/interfaces/libpq/t/006_service.pl
+++ b/src/interfaces/libpq/t/006_service.pl
@@ -22,18 +22,14 @@ $dummy_node->init;
my $td = PostgreSQL::Test::Utils::tempdir;
-# Windows vs non-Windows: CRLF vs LF for the file's newline, relying on
-# the fact that libpq uses fgets() when reading the lines of a service file.
-my $newline = $windows_os ? "\r\n" : "\n";
-
# Create the set of service files used in the tests.
# File that includes a valid service name, and uses a decomposed connection
# string for its contents, split on spaces.
my $srvfile_valid = "$td/pg_service_valid.conf";
-append_to_file($srvfile_valid, "[my_srv]" . $newline);
+append_to_file($srvfile_valid, "[my_srv]\n");
foreach my $param (split(/\s+/, $node->connstr))
{
- append_to_file($srvfile_valid, $param . $newline);
+ append_to_file($srvfile_valid, $param . "\n");
}
# File defined with no contents, used as default value for PGSERVICEFILE,
@@ -51,14 +47,14 @@ my $srvfile_missing = "$td/pg_service_missing.conf";
my $srvfile_nested = "$td/pg_service_nested.conf";
copy($srvfile_valid, $srvfile_nested)
or die "Could not copy $srvfile_valid to $srvfile_nested: $!";
-append_to_file($srvfile_nested, 'service=invalid_srv' . $newline);
+append_to_file($srvfile_nested, "service=invalid_srv\n");
# Service file with nested "servicefile" defined.
my $srvfile_nested_2 = "$td/pg_service_nested_2.conf";
copy($srvfile_valid, $srvfile_nested_2)
or die "Could not copy $srvfile_valid to $srvfile_nested_2: $!";
append_to_file($srvfile_nested_2,
- 'servicefile=' . $srvfile_default . $newline);
+ 'servicefile=' . $srvfile_default . "\n");
# Set the fallback directory lookup of the service file to the temporary
# directory of this test. PGSYSCONFDIR is used if the service file
diff --git a/src/test/ldap/t/003_ldap_connection_param_lookup.pl b/src/test/ldap/t/003_ldap_connection_param_lookup.pl
index 8c1e1caf992..abcb6d22a8b 100644
--- a/src/test/ldap/t/003_ldap_connection_param_lookup.pl
+++ b/src/test/ldap/t/003_ldap_connection_param_lookup.pl
@@ -44,31 +44,21 @@ $ldap->ldapadd_file('authdata.ldif');
$ldap->ldapsetpw('uid=test1,dc=example,dc=net', 'secret1');
$ldap->ldapsetpw('uid=test2,dc=example,dc=net', 'secret2');
-# Windows vs non-Windows: CRLF vs LF for the file's newline, relying on
-# the fact that libpq uses fgets() when reading the lines of a service file.
-my $newline = $windows_os ? "\r\n" : "\n";
-
my $td = PostgreSQL::Test::Utils::tempdir;
# create ldap file based on postgres connection info
my $ldif_valid = "$td/connection_params.ldif";
-append_to_file($ldif_valid, "version:1");
-append_to_file($ldif_valid, $newline);
-append_to_file($ldif_valid, "dn:cn=mydatabase,dc=example,dc=net");
-append_to_file($ldif_valid, $newline);
-append_to_file($ldif_valid, "changetype:add");
-append_to_file($ldif_valid, $newline);
-append_to_file($ldif_valid, "objectclass:top");
-append_to_file($ldif_valid, $newline);
-append_to_file($ldif_valid, "objectclass:device");
-append_to_file($ldif_valid, $newline);
-append_to_file($ldif_valid, "cn:mydatabase");
-append_to_file($ldif_valid, $newline);
-append_to_file($ldif_valid, "description:host=");
-append_to_file($ldif_valid, $node->host);
-append_to_file($ldif_valid, $newline);
-append_to_file($ldif_valid, "description:port=");
-append_to_file($ldif_valid, $node->port);
+append_to_file(
+ $ldif_valid, qq{
+version:1
+dn:cn=mydatabase,dc=example,dc=net
+changetype:add
+objectclass:top
+objectclass:device
+cn:mydatabase
+description:host=} . $node->host . qq{
+description:port=} . $node->port . qq{
+});
$ldap->ldapadd_file($ldif_valid);
@@ -86,12 +76,11 @@ note "setting up PostgreSQL instance";
# File that includes a valid service name, that uses a decomposed
# connection string for its contents, split on spaces.
my $srvfile_valid = "$td/pg_service_valid.conf";
-append_to_file($srvfile_valid, "[my_srv]");
-append_to_file($srvfile_valid, $newline);
-append_to_file($srvfile_valid, "ldap://localhost:");
-append_to_file($srvfile_valid, $ldap_port);
-append_to_file($srvfile_valid,
- "/dc=example,dc=net?description?one?(cn=mydatabase)");
+append_to_file(
+ $srvfile_valid, qq{
+[my_srv]
+ldap://localhost:$ldap_port/dc=example,dc=net?description?one?(cn=mydatabase)
+});
# File defined with no contents, used as default value for
# PGSERVICEFILE, so that no lookup is attempted in the user's home
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 16753b2e4c0..77e25ca029e 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -2306,9 +2306,10 @@ pg_stat_user_tables| SELECT relid,
pg_stat_wal| SELECT wal_records,
wal_fpi,
wal_bytes,
+ wal_fpi_bytes,
wal_buffers_full,
stats_reset
- FROM pg_stat_get_wal() w(wal_records, wal_fpi, wal_bytes, wal_buffers_full, stats_reset);
+ FROM pg_stat_get_wal() w(wal_records, wal_fpi, wal_bytes, wal_fpi_bytes, wal_buffers_full, stats_reset);
pg_stat_wal_receiver| SELECT pid,
status,
receive_start_lsn,
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index bb4e1b37005..df88c78fe3a 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -3505,6 +3505,8 @@ cb_cleanup_dir
cb_options
cb_tablespace
cb_tablespace_mapping
+char16_t
+char32_t
check_agg_arguments_context
check_function_callback
check_network_data
@@ -3808,7 +3810,6 @@ memoize_iterator
metastring
missing_cache_key
mix_data_t
-mixedStruct
mode_t
movedb_failure_params
multirange_bsearch_comparison