summaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/access/brin/brin_minmax_multi.c2
-rw-r--r--src/backend/access/common/tidstore.c2
-rw-r--r--src/backend/access/gin/ginget.c2
-rw-r--r--src/backend/access/gin/ginpostinglist.c4
-rw-r--r--src/backend/access/hash/hashsort.c2
-rw-r--r--src/backend/access/hash/hashutil.c2
-rw-r--r--src/backend/access/heap/heapam.c34
-rw-r--r--src/backend/access/heap/heaptoast.c4
-rw-r--r--src/backend/access/nbtree/nbtdedup.c2
-rw-r--r--src/backend/access/nbtree/nbtpreprocesskeys.c4
-rw-r--r--src/backend/access/nbtree/nbtsearch.c4
-rw-r--r--src/backend/access/nbtree/nbtsort.c6
-rw-r--r--src/backend/access/nbtree/nbtsplitloc.c4
-rw-r--r--src/backend/access/spgist/spgdoinsert.c2
-rw-r--r--src/backend/access/spgist/spgtextproc.c2
-rw-r--r--src/backend/access/spgist/spgutils.c2
-rw-r--r--src/backend/access/spgist/spgvacuum.c2
-rw-r--r--src/backend/access/transam/xlog.c2
-rw-r--r--src/backend/access/transam/xloginsert.c15
-rw-r--r--src/backend/catalog/indexing.c6
-rw-r--r--src/backend/catalog/pg_constraint.c10
-rw-r--r--src/backend/catalog/system_views.sql1
-rw-r--r--src/backend/commands/explain.c8
-rw-r--r--src/backend/commands/subscriptioncmds.c4
-rw-r--r--src/backend/executor/execGrouping.c74
-rw-r--r--src/backend/executor/execIndexing.c8
-rw-r--r--src/backend/executor/execPartition.c14
-rw-r--r--src/backend/executor/instrument.c2
-rw-r--r--src/backend/executor/nodeAgg.c32
-rw-r--r--src/backend/executor/nodeIndexscan.c4
-rw-r--r--src/backend/executor/nodeRecursiveunion.c25
-rw-r--r--src/backend/executor/nodeSetOp.c26
-rw-r--r--src/backend/executor/nodeSubplan.c17
-rw-r--r--src/backend/executor/spi.c12
-rw-r--r--src/backend/nodes/tidbitmap.c2
-rw-r--r--src/backend/optimizer/path/joinpath.c21
-rw-r--r--src/backend/parser/parser.c8
-rw-r--r--src/backend/parser/scan.l8
-rw-r--r--src/backend/partitioning/partbounds.c6
-rw-r--r--src/backend/partitioning/partprune.c8
-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/replication/slot.c70
-rw-r--r--src/backend/statistics/attribute_stats.c4
-rw-r--r--src/backend/storage/lmgr/predicate.c8
-rw-r--r--src/backend/storage/page/itemptr.c4
-rw-r--r--src/backend/tcop/pquery.c37
-rw-r--r--src/backend/tsearch/ts_selfuncs.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/array_selfuncs.c48
-rw-r--r--src/backend/utils/adt/arrayfuncs.c10
-rw-r--r--src/backend/utils/adt/formatting.c778
-rw-r--r--src/backend/utils/adt/json.c6
-rw-r--r--src/backend/utils/adt/jsonfuncs.c28
-rw-r--r--src/backend/utils/adt/jsonpath_scan.l6
-rw-r--r--src/backend/utils/adt/multirangetypes_selfuncs.c16
-rw-r--r--src/backend/utils/adt/network_selfuncs.c20
-rw-r--r--src/backend/utils/adt/orderedsetaggs.c4
-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/rangetypes_selfuncs.c16
-rw-r--r--src/backend/utils/adt/selfuncs.c7
-rw-r--r--src/backend/utils/adt/tid.c6
-rw-r--r--src/backend/utils/adt/tsvector_op.c12
-rw-r--r--src/backend/utils/adt/varlena.c40
-rw-r--r--src/backend/utils/adt/xml.c4
-rw-r--r--src/backend/utils/cache/catcache.c14
-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/backend/utils/mmgr/aset.c6
-rw-r--r--src/backend/utils/sort/tuplesortvariants.c2
80 files changed, 1290 insertions, 1382 deletions
diff --git a/src/backend/access/brin/brin_minmax_multi.c b/src/backend/access/brin/brin_minmax_multi.c
index c87f1b9cd7e..f8a11444d66 100644
--- a/src/backend/access/brin/brin_minmax_multi.c
+++ b/src/backend/access/brin/brin_minmax_multi.c
@@ -276,7 +276,7 @@ static int compare_values(const void *a, const void *b, void *arg);
* function (which should be BTLessStrategyNumber).
*/
static void
-AssertArrayOrder(FmgrInfo *cmp, Oid colloid, Datum *values, int nvalues)
+AssertArrayOrder(FmgrInfo *cmp, Oid colloid, const Datum *values, int nvalues)
{
int i;
Datum lt;
diff --git a/src/backend/access/common/tidstore.c b/src/backend/access/common/tidstore.c
index 5bd75fb499c..fb807d9fe59 100644
--- a/src/backend/access/common/tidstore.c
+++ b/src/backend/access/common/tidstore.c
@@ -418,7 +418,7 @@ TidStoreSetBlockOffsets(TidStore *ts, BlockNumber blkno, OffsetNumber *offsets,
/* Return true if the given TID is present in the TidStore */
bool
-TidStoreIsMember(TidStore *ts, ItemPointer tid)
+TidStoreIsMember(TidStore *ts, const ItemPointerData *tid)
{
int wordnum;
int bitnum;
diff --git a/src/backend/access/gin/ginget.c b/src/backend/access/gin/ginget.c
index 656299b1b52..0d4108d05a3 100644
--- a/src/backend/access/gin/ginget.c
+++ b/src/backend/access/gin/ginget.c
@@ -489,7 +489,7 @@ restartScanEntry:
static int
entryIndexByFrequencyCmp(const void *a1, const void *a2, void *arg)
{
- const GinScanKey key = (const GinScanKey) arg;
+ const GinScanKeyData *key = arg;
int i1 = *(const int *) a1;
int i2 = *(const int *) a2;
uint32 n1 = key->scanEntry[i1]->predictNumberResult;
diff --git a/src/backend/access/gin/ginpostinglist.c b/src/backend/access/gin/ginpostinglist.c
index 48eadec87b0..1bf061803da 100644
--- a/src/backend/access/gin/ginpostinglist.c
+++ b/src/backend/access/gin/ginpostinglist.c
@@ -84,7 +84,7 @@
#define MaxBytesPerInteger 7
static inline uint64
-itemptr_to_uint64(const ItemPointer iptr)
+itemptr_to_uint64(const ItemPointerData *iptr)
{
uint64 val;
@@ -194,7 +194,7 @@ decode_varbyte(unsigned char **ptr)
* byte at the end, if any, is zero.
*/
GinPostingList *
-ginCompressPostingList(const ItemPointer ipd, int nipd, int maxsize,
+ginCompressPostingList(const ItemPointerData *ipd, int nipd, int maxsize,
int *nwritten)
{
uint64 prev;
diff --git a/src/backend/access/hash/hashsort.c b/src/backend/access/hash/hashsort.c
index 6e8c0e68a92..92ae3cf53f5 100644
--- a/src/backend/access/hash/hashsort.c
+++ b/src/backend/access/hash/hashsort.c
@@ -106,7 +106,7 @@ _h_spooldestroy(HSpool *hspool)
* spool an index entry into the sort file.
*/
void
-_h_spool(HSpool *hspool, ItemPointer self, const Datum *values, const bool *isnull)
+_h_spool(HSpool *hspool, const ItemPointerData *self, const Datum *values, const bool *isnull)
{
tuplesort_putindextuplevalues(hspool->sortstate, hspool->index,
self, values, isnull);
diff --git a/src/backend/access/hash/hashutil.c b/src/backend/access/hash/hashutil.c
index 66c39f60654..f41233fcd07 100644
--- a/src/backend/access/hash/hashutil.c
+++ b/src/backend/access/hash/hashutil.c
@@ -316,7 +316,7 @@ _hash_get_indextuple_hashkey(IndexTuple itup)
*/
bool
_hash_convert_tuple(Relation index,
- Datum *user_values, bool *user_isnull,
+ const Datum *user_values, const bool *user_isnull,
Datum *index_values, bool *index_isnull)
{
uint32 hashkey;
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 568696333c2..36fee9c994e 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -63,7 +63,7 @@ static XLogRecPtr log_heap_update(Relation reln, Buffer oldbuf,
bool all_visible_cleared, bool new_all_visible_cleared);
#ifdef USE_ASSERT_CHECKING
static void check_lock_if_inplace_updateable_rel(Relation relation,
- ItemPointer otid,
+ const ItemPointerData *otid,
HeapTuple newtup);
static void check_inplace_rel_lock(HeapTuple oldtup);
#endif
@@ -72,7 +72,7 @@ static Bitmapset *HeapDetermineColumnsInfo(Relation relation,
Bitmapset *external_cols,
HeapTuple oldtup, HeapTuple newtup,
bool *has_external);
-static bool heap_acquire_tuplock(Relation relation, ItemPointer tid,
+static bool heap_acquire_tuplock(Relation relation, const ItemPointerData *tid,
LockTupleMode mode, LockWaitPolicy wait_policy,
bool *have_tuple_lock);
static inline BlockNumber heapgettup_advance_block(HeapScanDesc scan,
@@ -86,7 +86,7 @@ static void compute_new_xmax_infomask(TransactionId xmax, uint16 old_infomask,
TransactionId *result_xmax, uint16 *result_infomask,
uint16 *result_infomask2);
static TM_Result heap_lock_updated_tuple(Relation rel, HeapTuple tuple,
- ItemPointer ctid, TransactionId xid,
+ const ItemPointerData *ctid, TransactionId xid,
LockTupleMode mode);
static void GetMultiXactIdHintBits(MultiXactId multi, uint16 *new_infomask,
uint16 *new_infomask2);
@@ -95,7 +95,7 @@ static TransactionId MultiXactIdGetUpdateXid(TransactionId xmax,
static bool DoesMultiXactIdConflict(MultiXactId multi, uint16 infomask,
LockTupleMode lockmode, bool *current_is_member);
static void MultiXactIdWait(MultiXactId multi, MultiXactStatus status, uint16 infomask,
- Relation rel, ItemPointer ctid, XLTW_Oper oper,
+ Relation rel, const ItemPointerData *ctid, XLTW_Oper oper,
int *remaining);
static bool ConditionalMultiXactIdWait(MultiXactId multi, MultiXactStatus status,
uint16 infomask, Relation rel, int *remaining,
@@ -2786,7 +2786,7 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask)
* generated by another transaction).
*/
TM_Result
-heap_delete(Relation relation, ItemPointer tid,
+heap_delete(Relation relation, const ItemPointerData *tid,
CommandId cid, Snapshot crosscheck, bool wait,
TM_FailureData *tmfd, bool changingPart)
{
@@ -3209,7 +3209,7 @@ l1:
* via ereport().
*/
void
-simple_heap_delete(Relation relation, ItemPointer tid)
+simple_heap_delete(Relation relation, const ItemPointerData *tid)
{
TM_Result result;
TM_FailureData tmfd;
@@ -3255,7 +3255,7 @@ simple_heap_delete(Relation relation, ItemPointer tid)
* generated by another transaction).
*/
TM_Result
-heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
+heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup,
CommandId cid, Snapshot crosscheck, bool wait,
TM_FailureData *tmfd, LockTupleMode *lockmode,
TU_UpdateIndexes *update_indexes)
@@ -4238,7 +4238,7 @@ l2:
*/
static void
check_lock_if_inplace_updateable_rel(Relation relation,
- ItemPointer otid,
+ const ItemPointerData *otid,
HeapTuple newtup)
{
/* LOCKTAG_TUPLE acceptable for any catalog */
@@ -4499,7 +4499,7 @@ HeapDetermineColumnsInfo(Relation relation,
* via ereport().
*/
void
-simple_heap_update(Relation relation, ItemPointer otid, HeapTuple tup,
+simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup,
TU_UpdateIndexes *update_indexes)
{
TM_Result result;
@@ -5285,7 +5285,7 @@ out_unlocked:
* wait_policy is Skip.
*/
static bool
-heap_acquire_tuplock(Relation relation, ItemPointer tid, LockTupleMode mode,
+heap_acquire_tuplock(Relation relation, const ItemPointerData *tid, LockTupleMode mode,
LockWaitPolicy wait_policy, bool *have_tuple_lock)
{
if (*have_tuple_lock)
@@ -5706,7 +5706,7 @@ test_lockmode_for_conflict(MultiXactStatus status, TransactionId xid,
* version as well.
*/
static TM_Result
-heap_lock_updated_tuple_rec(Relation rel, ItemPointer tid, TransactionId xid,
+heap_lock_updated_tuple_rec(Relation rel, const ItemPointerData *tid, TransactionId xid,
LockTupleMode mode)
{
TM_Result result;
@@ -6051,7 +6051,7 @@ out_unlocked:
* levels, because that would lead to a serializability failure.
*/
static TM_Result
-heap_lock_updated_tuple(Relation rel, HeapTuple tuple, ItemPointer ctid,
+heap_lock_updated_tuple(Relation rel, HeapTuple tuple, const ItemPointerData *ctid,
TransactionId xid, LockTupleMode mode)
{
/*
@@ -6096,7 +6096,7 @@ heap_lock_updated_tuple(Relation rel, HeapTuple tuple, ItemPointer ctid,
* An explicit confirmation WAL record also makes logical decoding simpler.
*/
void
-heap_finish_speculative(Relation relation, ItemPointer tid)
+heap_finish_speculative(Relation relation, const ItemPointerData *tid)
{
Buffer buffer;
Page page;
@@ -6183,7 +6183,7 @@ heap_finish_speculative(Relation relation, ItemPointer tid)
* confirmation records.
*/
void
-heap_abort_speculative(Relation relation, ItemPointer tid)
+heap_abort_speculative(Relation relation, const ItemPointerData *tid)
{
TransactionId xid = GetCurrentTransactionId();
ItemId lp;
@@ -7705,7 +7705,7 @@ DoesMultiXactIdConflict(MultiXactId multi, uint16 infomask,
static bool
Do_MultiXactIdWait(MultiXactId multi, MultiXactStatus status,
uint16 infomask, bool nowait,
- Relation rel, ItemPointer ctid, XLTW_Oper oper,
+ Relation rel, const ItemPointerData *ctid, XLTW_Oper oper,
int *remaining, bool logLockFailure)
{
bool result = true;
@@ -7782,7 +7782,7 @@ Do_MultiXactIdWait(MultiXactId multi, MultiXactStatus status,
*/
static void
MultiXactIdWait(MultiXactId multi, MultiXactStatus status, uint16 infomask,
- Relation rel, ItemPointer ctid, XLTW_Oper oper,
+ Relation rel, const ItemPointerData *ctid, XLTW_Oper oper,
int *remaining)
{
(void) Do_MultiXactIdWait(multi, status, infomask, false,
@@ -8068,7 +8068,7 @@ index_delete_prefetch_buffer(Relation rel,
static inline void
index_delete_check_htid(TM_IndexDeleteOp *delstate,
Page page, OffsetNumber maxoff,
- ItemPointer htid, TM_IndexStatus *istatus)
+ const ItemPointerData *htid, TM_IndexStatus *istatus)
{
OffsetNumber indexpagehoffnum = ItemPointerGetOffsetNumber(htid);
ItemId iid;
diff --git a/src/backend/access/heap/heaptoast.c b/src/backend/access/heap/heaptoast.c
index cb1e57030f6..e148c9be482 100644
--- a/src/backend/access/heap/heaptoast.c
+++ b/src/backend/access/heap/heaptoast.c
@@ -561,8 +561,8 @@ toast_flatten_tuple_to_datum(HeapTupleHeader tup,
*/
HeapTuple
toast_build_flattened_tuple(TupleDesc tupleDesc,
- Datum *values,
- bool *isnull)
+ const Datum *values,
+ const bool *isnull)
{
HeapTuple new_tuple;
int numAttrs = tupleDesc->natts;
diff --git a/src/backend/access/nbtree/nbtdedup.c b/src/backend/access/nbtree/nbtdedup.c
index 07e63962f81..a746de45dd3 100644
--- a/src/backend/access/nbtree/nbtdedup.c
+++ b/src/backend/access/nbtree/nbtdedup.c
@@ -859,7 +859,7 @@ _bt_singleval_fillfactor(Page page, BTDedupState state, Size newitemsz)
* returned posting list tuple (they must be included in htids array.)
*/
IndexTuple
-_bt_form_posting(IndexTuple base, ItemPointer htids, int nhtids)
+_bt_form_posting(IndexTuple base, const ItemPointerData *htids, int nhtids)
{
uint32 keysize,
newsize;
diff --git a/src/backend/access/nbtree/nbtpreprocesskeys.c b/src/backend/access/nbtree/nbtpreprocesskeys.c
index 7b7d7860d8f..a871bf62cab 100644
--- a/src/backend/access/nbtree/nbtpreprocesskeys.c
+++ b/src/backend/access/nbtree/nbtpreprocesskeys.c
@@ -67,7 +67,7 @@ static int _bt_num_array_keys(IndexScanDesc scan, Oid *skip_eq_ops_out,
int *numSkipArrayKeys_out);
static Datum _bt_find_extreme_element(IndexScanDesc scan, ScanKey skey,
Oid elemtype, StrategyNumber strat,
- Datum *elems, int nelems);
+ const Datum *elems, int nelems);
static void _bt_setup_array_cmp(IndexScanDesc scan, ScanKey skey, Oid elemtype,
FmgrInfo *orderproc, FmgrInfo **sortprocp);
static int _bt_sort_array_elements(ScanKey skey, FmgrInfo *sortproc,
@@ -2569,7 +2569,7 @@ _bt_num_array_keys(IndexScanDesc scan, Oid *skip_eq_ops_out,
static Datum
_bt_find_extreme_element(IndexScanDesc scan, ScanKey skey, Oid elemtype,
StrategyNumber strat,
- Datum *elems, int nelems)
+ const Datum *elems, int nelems)
{
Relation rel = scan->indexRelation;
Oid cmp_op;
diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c
index d69798795b4..7ae2bc8b66a 100644
--- a/src/backend/access/nbtree/nbtsearch.c
+++ b/src/backend/access/nbtree/nbtsearch.c
@@ -37,7 +37,7 @@ static bool _bt_readpage(IndexScanDesc scan, ScanDirection dir,
static void _bt_saveitem(BTScanOpaque so, int itemIndex,
OffsetNumber offnum, IndexTuple itup);
static int _bt_setuppostingitems(BTScanOpaque so, int itemIndex,
- OffsetNumber offnum, ItemPointer heapTid,
+ OffsetNumber offnum, const ItemPointerData *heapTid,
IndexTuple itup);
static inline void _bt_savepostingitem(BTScanOpaque so, int itemIndex,
OffsetNumber offnum,
@@ -2079,7 +2079,7 @@ _bt_saveitem(BTScanOpaque so, int itemIndex,
*/
static int
_bt_setuppostingitems(BTScanOpaque so, int itemIndex, OffsetNumber offnum,
- ItemPointer heapTid, IndexTuple itup)
+ const ItemPointerData *heapTid, IndexTuple itup)
{
BTScanPosItem *currItem = &so->currPos.items[itemIndex];
diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c
index 313fe66bc96..454adaee7dc 100644
--- a/src/backend/access/nbtree/nbtsort.c
+++ b/src/backend/access/nbtree/nbtsort.c
@@ -257,8 +257,8 @@ typedef struct BTWriteState
static double _bt_spools_heapscan(Relation heap, Relation index,
BTBuildState *buildstate, IndexInfo *indexInfo);
static void _bt_spooldestroy(BTSpool *btspool);
-static void _bt_spool(BTSpool *btspool, ItemPointer self,
- Datum *values, bool *isnull);
+static void _bt_spool(BTSpool *btspool, const ItemPointerData *self,
+ const Datum *values, const bool *isnull);
static void _bt_leafbuild(BTSpool *btspool, BTSpool *btspool2);
static void _bt_build_callback(Relation index, ItemPointer tid, Datum *values,
bool *isnull, bool tupleIsAlive, void *state);
@@ -525,7 +525,7 @@ _bt_spooldestroy(BTSpool *btspool)
* spool an index entry into the sort file.
*/
static void
-_bt_spool(BTSpool *btspool, ItemPointer self, Datum *values, bool *isnull)
+_bt_spool(BTSpool *btspool, const ItemPointerData *self, const Datum *values, const bool *isnull)
{
tuplesort_putindextuplevalues(btspool->sortstate, btspool->index,
self, values, isnull);
diff --git a/src/backend/access/nbtree/nbtsplitloc.c b/src/backend/access/nbtree/nbtsplitloc.c
index b88c396195a..f0082f88c76 100644
--- a/src/backend/access/nbtree/nbtsplitloc.c
+++ b/src/backend/access/nbtree/nbtsplitloc.c
@@ -69,7 +69,7 @@ static void _bt_deltasortsplits(FindSplitData *state, double fillfactormult,
static int _bt_splitcmp(const void *arg1, const void *arg2);
static bool _bt_afternewitemoff(FindSplitData *state, OffsetNumber maxoff,
int leaffillfactor, bool *usemult);
-static bool _bt_adjacenthtid(ItemPointer lowhtid, ItemPointer highhtid);
+static bool _bt_adjacenthtid(const ItemPointerData *lowhtid, const ItemPointerData *highhtid);
static OffsetNumber _bt_bestsplitloc(FindSplitData *state, int perfectpenalty,
bool *newitemonleft, FindSplitStrat strategy);
static int _bt_defaultinterval(FindSplitData *state);
@@ -747,7 +747,7 @@ _bt_afternewitemoff(FindSplitData *state, OffsetNumber maxoff,
* transaction.
*/
static bool
-_bt_adjacenthtid(ItemPointer lowhtid, ItemPointer highhtid)
+_bt_adjacenthtid(const ItemPointerData *lowhtid, const ItemPointerData *highhtid)
{
BlockNumber lowblk,
highblk;
diff --git a/src/backend/access/spgist/spgdoinsert.c b/src/backend/access/spgist/spgdoinsert.c
index e00bd0e2636..4eadb518776 100644
--- a/src/backend/access/spgist/spgdoinsert.c
+++ b/src/backend/access/spgist/spgdoinsert.c
@@ -1908,7 +1908,7 @@ spgSplitNodeAction(Relation index, SpGistState *state,
*/
bool
spgdoinsert(Relation index, SpGistState *state,
- ItemPointer heapPtr, Datum *datums, bool *isnulls)
+ const ItemPointerData *heapPtr, const Datum *datums, const bool *isnulls)
{
bool result = true;
TupleDesc leafDescriptor = state->leafTupDesc;
diff --git a/src/backend/access/spgist/spgtextproc.c b/src/backend/access/spgist/spgtextproc.c
index 73842655f08..91f4ab260c2 100644
--- a/src/backend/access/spgist/spgtextproc.c
+++ b/src/backend/access/spgist/spgtextproc.c
@@ -155,7 +155,7 @@ commonPrefix(const char *a, const char *b, int lena, int lenb)
* On success, *i gets the match location; on failure, it gets where to insert
*/
static bool
-searchChar(Datum *nodeLabels, int nNodes, int16 c, int *i)
+searchChar(const Datum *nodeLabels, int nNodes, int16 c, int *i)
{
int StopLow = 0,
StopHigh = nNodes;
diff --git a/src/backend/access/spgist/spgutils.c b/src/backend/access/spgist/spgutils.c
index 245ec05e4bb..87c31da71a5 100644
--- a/src/backend/access/spgist/spgutils.c
+++ b/src/backend/access/spgist/spgutils.c
@@ -868,7 +868,7 @@ SpGistGetLeafTupleSize(TupleDesc tupleDescriptor,
* Construct a leaf tuple containing the given heap TID and datum values
*/
SpGistLeafTuple
-spgFormLeafTuple(SpGistState *state, ItemPointer heapPtr,
+spgFormLeafTuple(SpGistState *state, const ItemPointerData *heapPtr,
const Datum *datums, const bool *isnulls)
{
SpGistLeafTuple tup;
diff --git a/src/backend/access/spgist/spgvacuum.c b/src/backend/access/spgist/spgvacuum.c
index 8f8a1ad7796..71ef2e5036f 100644
--- a/src/backend/access/spgist/spgvacuum.c
+++ b/src/backend/access/spgist/spgvacuum.c
@@ -61,7 +61,7 @@ typedef struct spgBulkDeleteState
* ensures that scans of the list don't miss items added during the scan.
*/
static void
-spgAddPendingTID(spgBulkDeleteState *bds, ItemPointer tid)
+spgAddPendingTID(spgBulkDeleteState *bds, const ItemPointerData *tid)
{
spgVacPendingItem *pitem;
spgVacPendingItem **listLink;
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/indexing.c b/src/backend/catalog/indexing.c
index 25c4b6bdc87..004c5121000 100644
--- a/src/backend/catalog/indexing.c
+++ b/src/backend/catalog/indexing.c
@@ -310,7 +310,7 @@ CatalogTuplesMultiInsertWithInfo(Relation heapRel, TupleTableSlot **slot,
* (Use CatalogTupleUpdateWithInfo in such cases.)
*/
void
-CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
+CatalogTupleUpdate(Relation heapRel, const ItemPointerData *otid, HeapTuple tup)
{
CatalogIndexState indstate;
TU_UpdateIndexes updateIndexes = TU_All;
@@ -334,7 +334,7 @@ CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
* so that callers needn't trouble over this ... but we don't do so today.
*/
void
-CatalogTupleUpdateWithInfo(Relation heapRel, ItemPointer otid, HeapTuple tup,
+CatalogTupleUpdateWithInfo(Relation heapRel, const ItemPointerData *otid, HeapTuple tup,
CatalogIndexState indstate)
{
TU_UpdateIndexes updateIndexes = TU_All;
@@ -362,7 +362,7 @@ CatalogTupleUpdateWithInfo(Relation heapRel, ItemPointer otid, HeapTuple tup,
* it might be better to do something about caching CatalogIndexState.
*/
void
-CatalogTupleDelete(Relation heapRel, ItemPointer tid)
+CatalogTupleDelete(Relation heapRel, const ItemPointerData *tid)
{
simple_heap_delete(heapRel, tid);
}
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/explain.c b/src/backend/commands/explain.c
index e6edae0845c..7e699f8595e 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -4283,7 +4283,8 @@ show_wal_usage(ExplainState *es, const WalUsage *usage)
{
/* Show only positive counter values. */
if ((usage->wal_records > 0) || (usage->wal_fpi > 0) ||
- (usage->wal_bytes > 0) || (usage->wal_buffers_full > 0))
+ (usage->wal_bytes > 0) || (usage->wal_buffers_full > 0) ||
+ (usage->wal_fpi_bytes > 0))
{
ExplainIndentText(es);
appendStringInfoString(es->str, "WAL:");
@@ -4297,6 +4298,9 @@ show_wal_usage(ExplainState *es, const WalUsage *usage)
if (usage->wal_bytes > 0)
appendStringInfo(es->str, " bytes=%" PRIu64,
usage->wal_bytes);
+ if (usage->wal_fpi_bytes > 0)
+ appendStringInfo(es->str, " fpi bytes=%" PRIu64,
+ usage->wal_fpi_bytes);
if (usage->wal_buffers_full > 0)
appendStringInfo(es->str, " buffers full=%" PRId64,
usage->wal_buffers_full);
@@ -4311,6 +4315,8 @@ show_wal_usage(ExplainState *es, const WalUsage *usage)
usage->wal_fpi, es);
ExplainPropertyUInteger("WAL Bytes", NULL,
usage->wal_bytes, es);
+ ExplainPropertyUInteger("WAL FPI Bytes", NULL,
+ usage->wal_fpi_bytes, es);
ExplainPropertyInteger("WAL Buffers Full", NULL,
usage->wal_buffers_full, es);
}
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/execGrouping.c b/src/backend/executor/execGrouping.c
index 75087204f0c..b4bdaa3c305 100644
--- a/src/backend/executor/execGrouping.c
+++ b/src/backend/executor/execGrouping.c
@@ -20,9 +20,9 @@
#include "miscadmin.h"
#include "utils/lsyscache.h"
-static int TupleHashTableMatch(struct tuplehash_hash *tb, const MinimalTuple tuple1, const MinimalTuple tuple2);
+static int TupleHashTableMatch(struct tuplehash_hash *tb, MinimalTuple tuple1, MinimalTuple tuple2);
static inline uint32 TupleHashTableHash_internal(struct tuplehash_hash *tb,
- const MinimalTuple tuple);
+ MinimalTuple tuple);
static inline TupleHashEntry LookupTupleHashEntry_internal(TupleHashTable hashtable,
TupleTableSlot *slot,
bool *isnew, uint32 hash);
@@ -145,8 +145,8 @@ execTuplesHashPrepare(int numCols,
* collations: collations to use in comparisons
* nbuckets: initial estimate of hashtable size
* additionalsize: size of data that may be stored along with the hash entry
- * metacxt: memory context for long-lived allocation, but not per-entry data
- * tablecxt: memory context in which to store table entries
+ * metacxt: memory context for long-lived data and the simplehash table
+ * tuplescxt: memory context in which to store the hashed tuples themselves
* tempcxt: short-lived context for evaluation hash and comparison functions
* use_variable_hash_iv: if true, adjust hash IV per-parallel-worker
*
@@ -157,11 +157,25 @@ execTuplesHashPrepare(int numCols,
* Note that the keyColIdx, hashfunctions, and collations arrays must be
* allocated in storage that will live as long as the hashtable does.
*
+ * The metacxt and tuplescxt are separate because it's usually desirable for
+ * tuplescxt to be a BumpContext to avoid memory wastage, while metacxt must
+ * support pfree in case the simplehash table needs to be enlarged. (We could
+ * simplify the API of TupleHashTables by managing the tuplescxt internally.
+ * But that would be disadvantageous to nodeAgg.c and nodeSubplan.c, which use
+ * a single tuplescxt for multiple TupleHashTables that are reset together.)
+ *
* LookupTupleHashEntry, FindTupleHashEntry, and related functions may leak
* memory in the tempcxt. It is caller's responsibility to reset that context
* reasonably often, typically once per tuple. (We do it that way, rather
* than managing an extra context within the hashtable, because in many cases
* the caller can specify a tempcxt that it needs to reset per-tuple anyway.)
+ *
+ * We don't currently provide DestroyTupleHashTable functionality; the hash
+ * table will be cleaned up at destruction of the metacxt. (Some callers
+ * bother to delete the tuplescxt explicitly, though it'd be sufficient to
+ * ensure it's a child of the metacxt.) There's not much point in working
+ * harder than this so long as the expression-evaluation infrastructure
+ * behaves similarly.
*/
TupleHashTable
BuildTupleHashTable(PlanState *parent,
@@ -175,7 +189,7 @@ BuildTupleHashTable(PlanState *parent,
long nbuckets,
Size additionalsize,
MemoryContext metacxt,
- MemoryContext tablecxt,
+ MemoryContext tuplescxt,
MemoryContext tempcxt,
bool use_variable_hash_iv)
{
@@ -183,14 +197,24 @@ BuildTupleHashTable(PlanState *parent,
Size entrysize;
Size hash_mem_limit;
MemoryContext oldcontext;
- bool allow_jit;
uint32 hash_iv = 0;
Assert(nbuckets > 0);
+
+ /* tuplescxt must be separate, else ResetTupleHashTable breaks things */
+ Assert(metacxt != tuplescxt);
+
+ /* ensure additionalsize is maxalign'ed */
additionalsize = MAXALIGN(additionalsize);
- entrysize = sizeof(TupleHashEntryData) + additionalsize;
- /* Limit initial table size request to not more than hash_mem */
+ /*
+ * Limit initial table size request to not more than hash_mem.
+ *
+ * XXX this calculation seems pretty misguided, as it counts only overhead
+ * and not the tuples themselves. But we have no knowledge of the
+ * expected tuple width here.
+ */
+ entrysize = sizeof(TupleHashEntryData) + additionalsize;
hash_mem_limit = get_hash_memory_limit() / entrysize;
if (nbuckets > hash_mem_limit)
nbuckets = hash_mem_limit;
@@ -202,7 +226,7 @@ BuildTupleHashTable(PlanState *parent,
hashtable->numCols = numCols;
hashtable->keyColIdx = keyColIdx;
hashtable->tab_collations = collations;
- hashtable->tablecxt = tablecxt;
+ hashtable->tuplescxt = tuplescxt;
hashtable->tempcxt = tempcxt;
hashtable->additionalsize = additionalsize;
hashtable->tableslot = NULL; /* will be made on first lookup */
@@ -230,16 +254,6 @@ BuildTupleHashTable(PlanState *parent,
hashtable->tableslot = MakeSingleTupleTableSlot(CreateTupleDescCopy(inputDesc),
&TTSOpsMinimalTuple);
- /*
- * If the caller fails to make the metacxt different from the tablecxt,
- * allowing JIT would lead to the generated functions to a) live longer
- * than the query or b) be re-generated each time the table is being
- * reset. Therefore prevent JIT from being used in that case, by not
- * providing a parent node (which prevents accessing the JitContext in the
- * EState).
- */
- allow_jit = (metacxt != tablecxt);
-
/* build hash ExprState for all columns */
hashtable->tab_hash_expr = ExecBuildHash32FromAttrs(inputDesc,
inputOps,
@@ -247,7 +261,7 @@ BuildTupleHashTable(PlanState *parent,
collations,
numCols,
keyColIdx,
- allow_jit ? parent : NULL,
+ parent,
hash_iv);
/* build comparator for all columns */
@@ -256,7 +270,7 @@ BuildTupleHashTable(PlanState *parent,
&TTSOpsMinimalTuple,
numCols,
keyColIdx, eqfuncoids, collations,
- allow_jit ? parent : NULL);
+ parent);
/*
* While not pretty, it's ok to not shut down this context, but instead
@@ -273,13 +287,19 @@ BuildTupleHashTable(PlanState *parent,
/*
* Reset contents of the hashtable to be empty, preserving all the non-content
- * state. Note that the tablecxt passed to BuildTupleHashTable() should
- * also be reset, otherwise there will be leaks.
+ * state.
+ *
+ * Note: in usages where several TupleHashTables share a tuplescxt, all must
+ * be reset together, as the first one's reset call will destroy all their
+ * data. The additional reset calls for the rest will redundantly reset the
+ * tuplescxt. But because of mcxt.c's isReset flag, that's cheap enough that
+ * we need not avoid it.
*/
void
ResetTupleHashTable(TupleHashTable hashtable)
{
tuplehash_reset(hashtable->hashtab);
+ MemoryContextReset(hashtable->tuplescxt);
}
/*
@@ -419,7 +439,7 @@ FindTupleHashEntry(TupleHashTable hashtable, TupleTableSlot *slot,
*/
static uint32
TupleHashTableHash_internal(struct tuplehash_hash *tb,
- const MinimalTuple tuple)
+ MinimalTuple tuple)
{
TupleHashTable hashtable = (TupleHashTable) tb->private_data;
uint32 hashkey;
@@ -489,10 +509,10 @@ LookupTupleHashEntry_internal(TupleHashTable hashtable, TupleTableSlot *slot,
/* created new entry */
*isnew = true;
- MemoryContextSwitchTo(hashtable->tablecxt);
+ MemoryContextSwitchTo(hashtable->tuplescxt);
/*
- * Copy the first tuple into the table context, and request
+ * Copy the first tuple into the tuples context, and request
* additionalsize extra bytes before the allocation.
*
* The caller can get a pointer to the additional data with
@@ -517,7 +537,7 @@ LookupTupleHashEntry_internal(TupleHashTable hashtable, TupleTableSlot *slot,
* See whether two tuples (presumably of the same hash value) match
*/
static int
-TupleHashTableMatch(struct tuplehash_hash *tb, const MinimalTuple tuple1, const MinimalTuple tuple2)
+TupleHashTableMatch(struct tuplehash_hash *tb, MinimalTuple tuple1, MinimalTuple tuple2)
{
TupleTableSlot *slot1;
TupleTableSlot *slot2;
diff --git a/src/backend/executor/execIndexing.c b/src/backend/executor/execIndexing.c
index ca33a854278..401606f840a 100644
--- a/src/backend/executor/execIndexing.c
+++ b/src/backend/executor/execIndexing.c
@@ -128,7 +128,7 @@ typedef enum
static bool check_exclusion_or_unique_constraint(Relation heap, Relation index,
IndexInfo *indexInfo,
- ItemPointer tupleid,
+ const ItemPointerData *tupleid,
const Datum *values, const bool *isnull,
EState *estate, bool newIndex,
CEOUC_WAIT_MODE waitMode,
@@ -541,7 +541,7 @@ ExecInsertIndexTuples(ResultRelInfo *resultRelInfo,
bool
ExecCheckIndexConstraints(ResultRelInfo *resultRelInfo, TupleTableSlot *slot,
EState *estate, ItemPointer conflictTid,
- ItemPointer tupleid, List *arbiterIndexes)
+ const ItemPointerData *tupleid, List *arbiterIndexes)
{
int i;
int numIndices;
@@ -703,7 +703,7 @@ ExecCheckIndexConstraints(ResultRelInfo *resultRelInfo, TupleTableSlot *slot,
static bool
check_exclusion_or_unique_constraint(Relation heap, Relation index,
IndexInfo *indexInfo,
- ItemPointer tupleid,
+ const ItemPointerData *tupleid,
const Datum *values, const bool *isnull,
EState *estate, bool newIndex,
CEOUC_WAIT_MODE waitMode,
@@ -955,7 +955,7 @@ retry:
void
check_exclusion_constraint(Relation heap, Relation index,
IndexInfo *indexInfo,
- ItemPointer tupleid,
+ const ItemPointerData *tupleid,
const Datum *values, const bool *isnull,
EState *estate, bool newIndex)
{
diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c
index 1f2da072632..aa12e9ad2ea 100644
--- a/src/backend/executor/execPartition.c
+++ b/src/backend/executor/execPartition.c
@@ -173,11 +173,11 @@ static void FormPartitionKeyDatum(PartitionDispatch pd,
EState *estate,
Datum *values,
bool *isnull);
-static int get_partition_for_tuple(PartitionDispatch pd, Datum *values,
- bool *isnull);
+static int get_partition_for_tuple(PartitionDispatch pd, const Datum *values,
+ const bool *isnull);
static char *ExecBuildSlotPartitionKeyDescription(Relation rel,
- Datum *values,
- bool *isnull,
+ const Datum *values,
+ const bool *isnull,
int maxfieldlen);
static List *adjust_partition_colnos(List *colnos, ResultRelInfo *leaf_part_rri);
static List *adjust_partition_colnos_using_map(List *colnos, AttrMap *attrMap);
@@ -1396,7 +1396,7 @@ FormPartitionKeyDatum(PartitionDispatch pd,
* found or -1 if none found.
*/
static int
-get_partition_for_tuple(PartitionDispatch pd, Datum *values, bool *isnull)
+get_partition_for_tuple(PartitionDispatch pd, const Datum *values, const bool *isnull)
{
int bound_offset = -1;
int part_index = -1;
@@ -1617,8 +1617,8 @@ get_partition_for_tuple(PartitionDispatch pd, Datum *values, bool *isnull)
*/
static char *
ExecBuildSlotPartitionKeyDescription(Relation rel,
- Datum *values,
- bool *isnull,
+ const Datum *values,
+ const bool *isnull,
int maxfieldlen)
{
StringInfoData buf;
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/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index 64643c3943a..759ffeed2e6 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -1457,7 +1457,7 @@ find_cols_walker(Node *node, FindColsContext *context)
* We have a separate hashtable and associated perhash data structure for each
* grouping set for which we're doing hashing.
*
- * The contents of the hash tables always live in the hashcontext's per-tuple
+ * The contents of the hash tables live in the aggstate's hash_tuplescxt
* memory context (there is only one of these for all tables together, since
* they are all reset at the same time).
*/
@@ -1509,7 +1509,7 @@ build_hash_table(AggState *aggstate, int setno, long nbuckets)
{
AggStatePerHash perhash = &aggstate->perhash[setno];
MemoryContext metacxt = aggstate->hash_metacxt;
- MemoryContext tablecxt = aggstate->hash_tablecxt;
+ MemoryContext tuplescxt = aggstate->hash_tuplescxt;
MemoryContext tmpcxt = aggstate->tmpcontext->ecxt_per_tuple_memory;
Size additionalsize;
@@ -1535,7 +1535,7 @@ build_hash_table(AggState *aggstate, int setno, long nbuckets)
nbuckets,
additionalsize,
metacxt,
- tablecxt,
+ tuplescxt,
tmpcxt,
DO_AGGSPLIT_SKIPFINAL(aggstate->aggsplit));
}
@@ -1868,7 +1868,7 @@ hash_agg_check_limits(AggState *aggstate)
uint64 ngroups = aggstate->hash_ngroups_current;
Size meta_mem = MemoryContextMemAllocated(aggstate->hash_metacxt,
true);
- Size entry_mem = MemoryContextMemAllocated(aggstate->hash_tablecxt,
+ Size entry_mem = MemoryContextMemAllocated(aggstate->hash_tuplescxt,
true);
Size tval_mem = MemoryContextMemAllocated(aggstate->hashcontext->ecxt_per_tuple_memory,
true);
@@ -1959,7 +1959,7 @@ hash_agg_update_metrics(AggState *aggstate, bool from_tape, int npartitions)
meta_mem = MemoryContextMemAllocated(aggstate->hash_metacxt, true);
/* memory for hash entries */
- entry_mem = MemoryContextMemAllocated(aggstate->hash_tablecxt, true);
+ entry_mem = MemoryContextMemAllocated(aggstate->hash_tuplescxt, true);
/* memory for byref transition states */
hashkey_mem = MemoryContextMemAllocated(aggstate->hashcontext->ecxt_per_tuple_memory, true);
@@ -2042,11 +2042,11 @@ hash_create_memory(AggState *aggstate)
/* and no smaller than ALLOCSET_DEFAULT_INITSIZE */
maxBlockSize = Max(maxBlockSize, ALLOCSET_DEFAULT_INITSIZE);
- aggstate->hash_tablecxt = BumpContextCreate(aggstate->ss.ps.state->es_query_cxt,
- "HashAgg table context",
- ALLOCSET_DEFAULT_MINSIZE,
- ALLOCSET_DEFAULT_INITSIZE,
- maxBlockSize);
+ aggstate->hash_tuplescxt = BumpContextCreate(aggstate->ss.ps.state->es_query_cxt,
+ "HashAgg hashed tuples",
+ ALLOCSET_DEFAULT_MINSIZE,
+ ALLOCSET_DEFAULT_INITSIZE,
+ maxBlockSize);
}
@@ -2707,7 +2707,6 @@ agg_refill_hash_table(AggState *aggstate)
/* free memory and reset hash tables */
ReScanExprContext(aggstate->hashcontext);
- MemoryContextReset(aggstate->hash_tablecxt);
for (int setno = 0; setno < aggstate->num_hashes; setno++)
ResetTupleHashTable(aggstate->perhash[setno].hashtable);
@@ -4428,18 +4427,18 @@ ExecEndAgg(AggState *node)
hashagg_reset_spill_state(node);
+ /* Release hash tables too */
if (node->hash_metacxt != NULL)
{
MemoryContextDelete(node->hash_metacxt);
node->hash_metacxt = NULL;
}
- if (node->hash_tablecxt != NULL)
+ if (node->hash_tuplescxt != NULL)
{
- MemoryContextDelete(node->hash_tablecxt);
- node->hash_tablecxt = NULL;
+ MemoryContextDelete(node->hash_tuplescxt);
+ node->hash_tuplescxt = NULL;
}
-
for (transno = 0; transno < node->numtrans; transno++)
{
AggStatePerTrans pertrans = &node->pertrans[transno];
@@ -4555,8 +4554,7 @@ ExecReScanAgg(AggState *node)
node->hash_ngroups_current = 0;
ReScanExprContext(node->hashcontext);
- MemoryContextReset(node->hash_tablecxt);
- /* Rebuild an empty hash table */
+ /* Rebuild empty hash table(s) */
build_hash_tables(node);
node->table_filled = false;
/* iterator will be reset when the table is filled */
diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c
index 7fcaa37fe62..f36929deec3 100644
--- a/src/backend/executor/nodeIndexscan.c
+++ b/src/backend/executor/nodeIndexscan.c
@@ -65,7 +65,7 @@ static int cmp_orderbyvals(const Datum *adist, const bool *anulls,
static int reorderqueue_cmp(const pairingheap_node *a,
const pairingheap_node *b, void *arg);
static void reorderqueue_push(IndexScanState *node, TupleTableSlot *slot,
- Datum *orderbyvals, bool *orderbynulls);
+ const Datum *orderbyvals, const bool *orderbynulls);
static HeapTuple reorderqueue_pop(IndexScanState *node);
@@ -458,7 +458,7 @@ reorderqueue_cmp(const pairingheap_node *a, const pairingheap_node *b,
*/
static void
reorderqueue_push(IndexScanState *node, TupleTableSlot *slot,
- Datum *orderbyvals, bool *orderbynulls)
+ const Datum *orderbyvals, const bool *orderbynulls)
{
IndexScanDesc scandesc = node->iss_ScanDesc;
EState *estate = node->ss.ps.state;
diff --git a/src/backend/executor/nodeRecursiveunion.c b/src/backend/executor/nodeRecursiveunion.c
index 40f66fd0680..ebb7919b49b 100644
--- a/src/backend/executor/nodeRecursiveunion.c
+++ b/src/backend/executor/nodeRecursiveunion.c
@@ -53,7 +53,7 @@ build_hash_table(RecursiveUnionState *rustate)
node->numGroups,
0,
rustate->ps.state->es_query_cxt,
- rustate->tableContext,
+ rustate->tuplesContext,
rustate->tempContext,
false);
}
@@ -197,7 +197,7 @@ ExecInitRecursiveUnion(RecursiveUnion *node, EState *estate, int eflags)
rustate->hashfunctions = NULL;
rustate->hashtable = NULL;
rustate->tempContext = NULL;
- rustate->tableContext = NULL;
+ rustate->tuplesContext = NULL;
/* initialize processing state */
rustate->recursing = false;
@@ -209,7 +209,8 @@ ExecInitRecursiveUnion(RecursiveUnion *node, EState *estate, int eflags)
* If hashing, we need a per-tuple memory context for comparisons, and a
* longer-lived context to store the hash table. The table can't just be
* kept in the per-query context because we want to be able to throw it
- * away when rescanning.
+ * away when rescanning. We can use a BumpContext to save storage,
+ * because we will have no need to delete individual table entries.
*/
if (node->numCols > 0)
{
@@ -217,10 +218,10 @@ ExecInitRecursiveUnion(RecursiveUnion *node, EState *estate, int eflags)
AllocSetContextCreate(CurrentMemoryContext,
"RecursiveUnion",
ALLOCSET_DEFAULT_SIZES);
- rustate->tableContext =
- AllocSetContextCreate(CurrentMemoryContext,
- "RecursiveUnion hash table",
- ALLOCSET_DEFAULT_SIZES);
+ rustate->tuplesContext =
+ BumpContextCreate(CurrentMemoryContext,
+ "RecursiveUnion hashed tuples",
+ ALLOCSET_DEFAULT_SIZES);
}
/*
@@ -288,11 +289,11 @@ ExecEndRecursiveUnion(RecursiveUnionState *node)
tuplestore_end(node->working_table);
tuplestore_end(node->intermediate_table);
- /* free subsidiary stuff including hashtable */
+ /* free subsidiary stuff including hashtable data */
if (node->tempContext)
MemoryContextDelete(node->tempContext);
- if (node->tableContext)
- MemoryContextDelete(node->tableContext);
+ if (node->tuplesContext)
+ MemoryContextDelete(node->tuplesContext);
/*
* close down subplans
@@ -328,10 +329,6 @@ ExecReScanRecursiveUnion(RecursiveUnionState *node)
if (outerPlan->chgParam == NULL)
ExecReScan(outerPlan);
- /* Release any hashtable storage */
- if (node->tableContext)
- MemoryContextReset(node->tableContext);
-
/* Empty hashtable if needed */
if (plan->numCols > 0)
ResetTupleHashTable(node->hashtable);
diff --git a/src/backend/executor/nodeSetOp.c b/src/backend/executor/nodeSetOp.c
index 4068481a523..7b223a7ca3a 100644
--- a/src/backend/executor/nodeSetOp.c
+++ b/src/backend/executor/nodeSetOp.c
@@ -106,7 +106,7 @@ build_hash_table(SetOpState *setopstate)
node->numGroups,
sizeof(SetOpStatePerGroupData),
setopstate->ps.state->es_query_cxt,
- setopstate->tableContext,
+ setopstate->tuplesContext,
econtext->ecxt_per_tuple_memory,
false);
}
@@ -589,13 +589,15 @@ ExecInitSetOp(SetOp *node, EState *estate, int eflags)
/*
* If hashing, we also need a longer-lived context to store the hash
* table. The table can't just be kept in the per-query context because
- * we want to be able to throw it away in ExecReScanSetOp.
+ * we want to be able to throw it away in ExecReScanSetOp. We can use a
+ * BumpContext to save storage, because we will have no need to delete
+ * individual table entries.
*/
if (node->strategy == SETOP_HASHED)
- setopstate->tableContext =
- AllocSetContextCreate(CurrentMemoryContext,
- "SetOp hash table",
- ALLOCSET_DEFAULT_SIZES);
+ setopstate->tuplesContext =
+ BumpContextCreate(CurrentMemoryContext,
+ "SetOp hashed tuples",
+ ALLOCSET_DEFAULT_SIZES);
/*
* initialize child nodes
@@ -680,9 +682,9 @@ ExecInitSetOp(SetOp *node, EState *estate, int eflags)
void
ExecEndSetOp(SetOpState *node)
{
- /* free subsidiary stuff including hashtable */
- if (node->tableContext)
- MemoryContextDelete(node->tableContext);
+ /* free subsidiary stuff including hashtable data */
+ if (node->tuplesContext)
+ MemoryContextDelete(node->tuplesContext);
ExecEndNode(outerPlanState(node));
ExecEndNode(innerPlanState(node));
@@ -721,11 +723,7 @@ ExecReScanSetOp(SetOpState *node)
return;
}
- /* Release any hashtable storage */
- if (node->tableContext)
- MemoryContextReset(node->tableContext);
-
- /* And rebuild an empty hashtable */
+ /* Else, we must rebuild the hashtable */
ResetTupleHashTable(node->hashtable);
node->table_filled = false;
}
diff --git a/src/backend/executor/nodeSubplan.c b/src/backend/executor/nodeSubplan.c
index 53fb56f7388..9f6e45bcb0b 100644
--- a/src/backend/executor/nodeSubplan.c
+++ b/src/backend/executor/nodeSubplan.c
@@ -506,7 +506,6 @@ buildSubPlanHash(SubPlanState *node, ExprContext *econtext)
* saves a needless fetch inner op step for the hashing ExprState created
* in BuildTupleHashTable().
*/
- MemoryContextReset(node->hashtablecxt);
node->havehashrows = false;
node->havenullrows = false;
@@ -528,7 +527,7 @@ buildSubPlanHash(SubPlanState *node, ExprContext *econtext)
nbuckets,
0,
node->planstate->state->es_query_cxt,
- node->hashtablecxt,
+ node->tuplesContext,
innerecontext->ecxt_per_tuple_memory,
false);
@@ -557,7 +556,7 @@ buildSubPlanHash(SubPlanState *node, ExprContext *econtext)
nbuckets,
0,
node->planstate->state->es_query_cxt,
- node->hashtablecxt,
+ node->tuplesContext,
innerecontext->ecxt_per_tuple_memory,
false);
}
@@ -838,7 +837,7 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent)
sstate->projRight = NULL;
sstate->hashtable = NULL;
sstate->hashnulls = NULL;
- sstate->hashtablecxt = NULL;
+ sstate->tuplesContext = NULL;
sstate->innerecontext = NULL;
sstate->keyColIdx = NULL;
sstate->tab_eq_funcoids = NULL;
@@ -889,11 +888,11 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent)
*righttlist;
ListCell *l;
- /* We need a memory context to hold the hash table(s) */
- sstate->hashtablecxt =
- AllocSetContextCreate(CurrentMemoryContext,
- "Subplan HashTable Context",
- ALLOCSET_DEFAULT_SIZES);
+ /* We need a memory context to hold the hash table(s)' tuples */
+ sstate->tuplesContext =
+ BumpContextCreate(CurrentMemoryContext,
+ "SubPlan hashed tuples",
+ ALLOCSET_DEFAULT_SIZES);
/* and a short-lived exprcontext for function evaluation */
sstate->innerecontext = CreateExprContext(estate);
diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
index 50fcd023776..653500b38dc 100644
--- a/src/backend/executor/spi.c
+++ b/src/backend/executor/spi.c
@@ -68,7 +68,7 @@ static int _SPI_execute_plan(SPIPlanPtr plan, const SPIExecuteOptions *options,
bool fire_triggers);
static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes,
- Datum *Values, const char *Nulls);
+ const Datum *Values, const char *Nulls);
static int _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount);
@@ -669,7 +669,7 @@ SPI_execute_extended(const char *src,
/* Execute a previously prepared plan */
int
-SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls,
+SPI_execute_plan(SPIPlanPtr plan, const Datum *Values, const char *Nulls,
bool read_only, long tcount)
{
SPIExecuteOptions options;
@@ -771,7 +771,7 @@ SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params,
*/
int
SPI_execute_snapshot(SPIPlanPtr plan,
- Datum *Values, const char *Nulls,
+ const Datum *Values, const char *Nulls,
Snapshot snapshot, Snapshot crosscheck_snapshot,
bool read_only, bool fire_triggers, long tcount)
{
@@ -811,7 +811,7 @@ SPI_execute_snapshot(SPIPlanPtr plan,
int
SPI_execute_with_args(const char *src,
int nargs, Oid *argtypes,
- Datum *Values, const char *Nulls,
+ const Datum *Values, const char *Nulls,
bool read_only, long tcount)
{
int res;
@@ -1443,7 +1443,7 @@ SPI_freetuptable(SPITupleTable *tuptable)
*/
Portal
SPI_cursor_open(const char *name, SPIPlanPtr plan,
- Datum *Values, const char *Nulls,
+ const Datum *Values, const char *Nulls,
bool read_only)
{
Portal portal;
@@ -2847,7 +2847,7 @@ fail:
*/
static ParamListInfo
_SPI_convert_params(int nargs, Oid *argtypes,
- Datum *Values, const char *Nulls)
+ const Datum *Values, const char *Nulls)
{
ParamListInfo paramLI;
diff --git a/src/backend/nodes/tidbitmap.c b/src/backend/nodes/tidbitmap.c
index fac2ba5d0ca..23d97b3a6c8 100644
--- a/src/backend/nodes/tidbitmap.c
+++ b/src/backend/nodes/tidbitmap.c
@@ -364,7 +364,7 @@ tbm_free_shared_area(dsa_area *dsa, dsa_pointer dp)
* TBMIterateResult when any of these tuples are reported out.
*/
void
-tbm_add_tuples(TIDBitmap *tbm, const ItemPointer tids, int ntids,
+tbm_add_tuples(TIDBitmap *tbm, const ItemPointerData *tids, int ntids,
bool recheck)
{
BlockNumber currblk = InvalidBlockNumber;
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c
index 3b9407eb2eb..ea5b6415186 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -2260,10 +2260,20 @@ hash_inner_and_outer(PlannerInfo *root,
/*
* If the joinrel is parallel-safe, we may be able to consider a
- * partial hash join. However, the resulting path must not be
- * parameterized.
+ * partial hash join.
+ *
+ * However, we can't handle JOIN_RIGHT_SEMI, because the hash table is
+ * either a shared hash table or a private hash table per backend. In
+ * the shared case, there is no concurrency protection for the match
+ * flags, so multiple workers could inspect and set the flags
+ * concurrently, potentially producing incorrect results. In the
+ * private case, each worker has its own copy of the hash table, so no
+ * single process has all the match flags.
+ *
+ * Also, the resulting path must not be parameterized.
*/
if (joinrel->consider_parallel &&
+ jointype != JOIN_RIGHT_SEMI &&
outerrel->partial_pathlist != NIL &&
bms_is_empty(joinrel->lateral_relids))
{
@@ -2294,13 +2304,12 @@ hash_inner_and_outer(PlannerInfo *root,
* Normally, given that the joinrel is parallel-safe, the cheapest
* total inner path will also be parallel-safe, but if not, we'll
* have to search for the cheapest safe, unparameterized inner
- * path. If full, right, right-semi or right-anti join, we can't
- * use parallelism (building the hash table in each backend)
- * because no one process has all the match bits.
+ * path. If full, right, or right-anti join, we can't use
+ * parallelism (building the hash table in each backend) because
+ * no one process has all the match bits.
*/
if (jointype == JOIN_FULL ||
jointype == JOIN_RIGHT ||
- jointype == JOIN_RIGHT_SEMI ||
jointype == JOIN_RIGHT_ANTI)
cheapest_safe_inner = NULL;
else if (cheapest_total_inner->parallel_safe)
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/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c
index 822cf4ec451..8ba038c5ef4 100644
--- a/src/backend/partitioning/partbounds.c
+++ b/src/backend/partitioning/partbounds.c
@@ -3555,8 +3555,8 @@ partition_rbound_cmp(int partnatts, FmgrInfo *partsupfunc,
*/
int32
partition_rbound_datum_cmp(FmgrInfo *partsupfunc, Oid *partcollation,
- Datum *rb_datums, PartitionRangeDatumKind *rb_kind,
- Datum *tuple_datums, int n_tuple_datums)
+ const Datum *rb_datums, PartitionRangeDatumKind *rb_kind,
+ const Datum *tuple_datums, int n_tuple_datums)
{
int i;
int32 cmpval = -1;
@@ -3695,7 +3695,7 @@ partition_range_bsearch(int partnatts, FmgrInfo *partsupfunc,
int
partition_range_datum_bsearch(FmgrInfo *partsupfunc, Oid *partcollation,
PartitionBoundInfo boundinfo,
- int nvalues, Datum *values, bool *is_equal)
+ int nvalues, const Datum *values, bool *is_equal)
{
int lo,
hi,
diff --git a/src/backend/partitioning/partprune.c b/src/backend/partitioning/partprune.c
index 48a35f763e9..6fff4034c24 100644
--- a/src/backend/partitioning/partprune.c
+++ b/src/backend/partitioning/partprune.c
@@ -179,13 +179,13 @@ static List *get_steps_using_prefix_recurse(GeneratePruningStepsContext *context
List *step_exprs,
List *step_cmpfns);
static PruneStepResult *get_matching_hash_bounds(PartitionPruneContext *context,
- StrategyNumber opstrategy, Datum *values, int nvalues,
+ StrategyNumber opstrategy, const Datum *values, int nvalues,
FmgrInfo *partsupfunc, Bitmapset *nullkeys);
static PruneStepResult *get_matching_list_bounds(PartitionPruneContext *context,
StrategyNumber opstrategy, Datum value, int nvalues,
FmgrInfo *partsupfunc, Bitmapset *nullkeys);
static PruneStepResult *get_matching_range_bounds(PartitionPruneContext *context,
- StrategyNumber opstrategy, Datum *values, int nvalues,
+ StrategyNumber opstrategy, const Datum *values, int nvalues,
FmgrInfo *partsupfunc, Bitmapset *nullkeys);
static Bitmapset *pull_exec_paramids(Expr *expr);
static bool pull_exec_paramids_walker(Node *node, Bitmapset **context);
@@ -2690,7 +2690,7 @@ get_steps_using_prefix_recurse(GeneratePruningStepsContext *context,
*/
static PruneStepResult *
get_matching_hash_bounds(PartitionPruneContext *context,
- StrategyNumber opstrategy, Datum *values, int nvalues,
+ StrategyNumber opstrategy, const Datum *values, int nvalues,
FmgrInfo *partsupfunc, Bitmapset *nullkeys)
{
PruneStepResult *result = (PruneStepResult *) palloc0(sizeof(PruneStepResult));
@@ -2978,7 +2978,7 @@ get_matching_list_bounds(PartitionPruneContext *context,
*/
static PruneStepResult *
get_matching_range_bounds(PartitionPruneContext *context,
- StrategyNumber opstrategy, Datum *values, int nvalues,
+ StrategyNumber opstrategy, const Datum *values, int nvalues,
FmgrInfo *partsupfunc, Bitmapset *nullkeys)
{
PruneStepResult *result = (PruneStepResult *) palloc0(sizeof(PruneStepResult));
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/replication/slot.c b/src/backend/replication/slot.c
index 1e9f4602c69..6363030808f 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -1746,17 +1746,16 @@ static ReplicationSlotInvalidationCause
DetermineSlotInvalidationCause(uint32 possible_causes, ReplicationSlot *s,
XLogRecPtr oldestLSN, Oid dboid,
TransactionId snapshotConflictHorizon,
- TransactionId initial_effective_xmin,
- TransactionId initial_catalog_effective_xmin,
- XLogRecPtr initial_restart_lsn,
TimestampTz *inactive_since, TimestampTz now)
{
Assert(possible_causes != RS_INVAL_NONE);
if (possible_causes & RS_INVAL_WAL_REMOVED)
{
- if (initial_restart_lsn != InvalidXLogRecPtr &&
- initial_restart_lsn < oldestLSN)
+ XLogRecPtr restart_lsn = s->data.restart_lsn;
+
+ if (restart_lsn != InvalidXLogRecPtr &&
+ restart_lsn < oldestLSN)
return RS_INVAL_WAL_REMOVED;
}
@@ -1766,12 +1765,15 @@ DetermineSlotInvalidationCause(uint32 possible_causes, ReplicationSlot *s,
if (SlotIsLogical(s) &&
(dboid == InvalidOid || dboid == s->data.database))
{
- if (TransactionIdIsValid(initial_effective_xmin) &&
- TransactionIdPrecedesOrEquals(initial_effective_xmin,
+ TransactionId effective_xmin = s->effective_xmin;
+ TransactionId catalog_effective_xmin = s->effective_catalog_xmin;
+
+ if (TransactionIdIsValid(effective_xmin) &&
+ TransactionIdPrecedesOrEquals(effective_xmin,
snapshotConflictHorizon))
return RS_INVAL_HORIZON;
- else if (TransactionIdIsValid(initial_catalog_effective_xmin) &&
- TransactionIdPrecedesOrEquals(initial_catalog_effective_xmin,
+ else if (TransactionIdIsValid(catalog_effective_xmin) &&
+ TransactionIdPrecedesOrEquals(catalog_effective_xmin,
snapshotConflictHorizon))
return RS_INVAL_HORIZON;
}
@@ -1840,11 +1842,6 @@ InvalidatePossiblyObsoleteSlot(uint32 possible_causes,
{
int last_signaled_pid = 0;
bool released_lock = false;
- bool terminated = false;
- TransactionId initial_effective_xmin = InvalidTransactionId;
- TransactionId initial_catalog_effective_xmin = InvalidTransactionId;
- XLogRecPtr initial_restart_lsn = InvalidXLogRecPtr;
- ReplicationSlotInvalidationCause invalidation_cause_prev PG_USED_FOR_ASSERTS_ONLY = RS_INVAL_NONE;
TimestampTz inactive_since = 0;
for (;;)
@@ -1887,42 +1884,12 @@ InvalidatePossiblyObsoleteSlot(uint32 possible_causes,
/* we do nothing if the slot is already invalid */
if (s->data.invalidated == RS_INVAL_NONE)
- {
- /*
- * The slot's mutex will be released soon, and it is possible that
- * those values change since the process holding the slot has been
- * terminated (if any), so record them here to ensure that we
- * would report the correct invalidation cause.
- *
- * Unlike other slot attributes, slot's inactive_since can't be
- * changed until the acquired slot is released or the owning
- * process is terminated. So, the inactive slot can only be
- * invalidated immediately without being terminated.
- */
- if (!terminated)
- {
- initial_restart_lsn = s->data.restart_lsn;
- initial_effective_xmin = s->effective_xmin;
- initial_catalog_effective_xmin = s->effective_catalog_xmin;
- }
-
invalidation_cause = DetermineSlotInvalidationCause(possible_causes,
s, oldestLSN,
dboid,
snapshotConflictHorizon,
- initial_effective_xmin,
- initial_catalog_effective_xmin,
- initial_restart_lsn,
&inactive_since,
now);
- }
-
- /*
- * The invalidation cause recorded previously should not change while
- * the process owning the slot (if any) has been terminated.
- */
- Assert(!(invalidation_cause_prev != RS_INVAL_NONE && terminated &&
- invalidation_cause_prev != invalidation_cause));
/* if there's no invalidation, we're done */
if (invalidation_cause == RS_INVAL_NONE)
@@ -1940,6 +1907,11 @@ InvalidatePossiblyObsoleteSlot(uint32 possible_causes,
* If the slot can be acquired, do so and mark it invalidated
* immediately. Otherwise we'll signal the owning process, below, and
* retry.
+ *
+ * Note: Unlike other slot attributes, slot's inactive_since can't be
+ * changed until the acquired slot is released or the owning process
+ * is terminated. So, the inactive slot can only be invalidated
+ * immediately without being terminated.
*/
if (active_pid == 0)
{
@@ -2014,8 +1986,6 @@ InvalidatePossiblyObsoleteSlot(uint32 possible_causes,
(void) kill(active_pid, SIGTERM);
last_signaled_pid = active_pid;
- terminated = true;
- invalidation_cause_prev = invalidation_cause;
}
/* Wait until the slot is released. */
@@ -2026,6 +1996,14 @@ InvalidatePossiblyObsoleteSlot(uint32 possible_causes,
* Re-acquire lock and start over; we expect to invalidate the
* slot next time (unless another process acquires the slot in the
* meantime).
+ *
+ * Note: It is possible for a slot to advance its restart_lsn or
+ * xmin values sufficiently between when we release the mutex and
+ * when we recheck, moving from a conflicting state to a non
+ * conflicting state. This is intentional and safe: if the slot
+ * has caught up while we're busy here, the resources we were
+ * concerned about (WAL segments or tuples) have not yet been
+ * removed, and there's no reason to invalidate the slot.
*/
LWLockAcquire(ReplicationSlotControlLock, LW_SHARED);
continue;
diff --git a/src/backend/statistics/attribute_stats.c b/src/backend/statistics/attribute_stats.c
index c5df83282e0..401bf571f27 100644
--- a/src/backend/statistics/attribute_stats.c
+++ b/src/backend/statistics/attribute_stats.c
@@ -115,7 +115,7 @@ static void set_stats_slot(Datum *values, bool *nulls, bool *replaces,
Datum stanumbers, bool stanumbers_isnull,
Datum stavalues, bool stavalues_isnull);
static void upsert_pg_statistic(Relation starel, HeapTuple oldtup,
- Datum *values, bool *nulls, bool *replaces);
+ const Datum *values, const bool *nulls, const bool *replaces);
static bool delete_pg_statistic(Oid reloid, AttrNumber attnum, bool stainherit);
static void init_empty_stats_tuple(Oid reloid, int16 attnum, bool inherited,
Datum *values, bool *nulls, bool *replaces);
@@ -819,7 +819,7 @@ set_stats_slot(Datum *values, bool *nulls, bool *replaces,
*/
static void
upsert_pg_statistic(Relation starel, HeapTuple oldtup,
- Datum *values, bool *nulls, bool *replaces)
+ const Datum *values, const bool *nulls, const bool *replaces)
{
HeapTuple newtup;
diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c
index c1d8511ad17..bb807d8c9cd 100644
--- a/src/backend/storage/lmgr/predicate.c
+++ b/src/backend/storage/lmgr/predicate.c
@@ -168,7 +168,7 @@
* PredicateLockRelation(Relation relation, Snapshot snapshot)
* PredicateLockPage(Relation relation, BlockNumber blkno,
* Snapshot snapshot)
- * PredicateLockTID(Relation relation, ItemPointer tid, Snapshot snapshot,
+ * PredicateLockTID(Relation relation, const ItemPointerData *tid, Snapshot snapshot,
* TransactionId tuple_xid)
* PredicateLockPageSplit(Relation relation, BlockNumber oldblkno,
* BlockNumber newblkno)
@@ -180,7 +180,7 @@
* conflict detection (may also trigger rollback)
* CheckForSerializableConflictOut(Relation relation, TransactionId xid,
* Snapshot snapshot)
- * CheckForSerializableConflictIn(Relation relation, ItemPointer tid,
+ * CheckForSerializableConflictIn(Relation relation, const ItemPointerData *tid,
* BlockNumber blkno)
* CheckTableForSerializableConflictIn(Relation relation)
*
@@ -2618,7 +2618,7 @@ PredicateLockPage(Relation relation, BlockNumber blkno, Snapshot snapshot)
* Skip if this is a temporary table.
*/
void
-PredicateLockTID(Relation relation, ItemPointer tid, Snapshot snapshot,
+PredicateLockTID(Relation relation, const ItemPointerData *tid, Snapshot snapshot,
TransactionId tuple_xid)
{
PREDICATELOCKTARGETTAG tag;
@@ -4333,7 +4333,7 @@ CheckTargetForConflictsIn(PREDICATELOCKTARGETTAG *targettag)
* tuple itself.
*/
void
-CheckForSerializableConflictIn(Relation relation, ItemPointer tid, BlockNumber blkno)
+CheckForSerializableConflictIn(Relation relation, const ItemPointerData *tid, BlockNumber blkno)
{
PREDICATELOCKTARGETTAG targettag;
diff --git a/src/backend/storage/page/itemptr.c b/src/backend/storage/page/itemptr.c
index ad658215721..cedb27d6cc5 100644
--- a/src/backend/storage/page/itemptr.c
+++ b/src/backend/storage/page/itemptr.c
@@ -32,7 +32,7 @@ StaticAssertDecl(sizeof(ItemPointerData) == 3 * sizeof(uint16),
* Asserts that the disk item pointers are both valid!
*/
bool
-ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
+ItemPointerEquals(const ItemPointerData *pointer1, const ItemPointerData *pointer2)
{
if (ItemPointerGetBlockNumber(pointer1) ==
ItemPointerGetBlockNumber(pointer2) &&
@@ -48,7 +48,7 @@ ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
* Generic btree-style comparison for item pointers.
*/
int32
-ItemPointerCompare(ItemPointer arg1, ItemPointer arg2)
+ItemPointerCompare(const ItemPointerData *arg1, const ItemPointerData *arg2)
{
/*
* Use ItemPointerGet{Offset,Block}NumberNoCheck to avoid asserting
diff --git a/src/backend/tcop/pquery.c b/src/backend/tcop/pquery.c
index 08791b8f75e..74179139fa9 100644
--- a/src/backend/tcop/pquery.c
+++ b/src/backend/tcop/pquery.c
@@ -165,27 +165,22 @@ ProcessQuery(PlannedStmt *plan,
*/
if (qc)
{
- switch (queryDesc->operation)
- {
- case CMD_SELECT:
- SetQueryCompletion(qc, CMDTAG_SELECT, queryDesc->estate->es_processed);
- break;
- case CMD_INSERT:
- SetQueryCompletion(qc, CMDTAG_INSERT, queryDesc->estate->es_processed);
- break;
- case CMD_UPDATE:
- SetQueryCompletion(qc, CMDTAG_UPDATE, queryDesc->estate->es_processed);
- break;
- case CMD_DELETE:
- SetQueryCompletion(qc, CMDTAG_DELETE, queryDesc->estate->es_processed);
- break;
- case CMD_MERGE:
- SetQueryCompletion(qc, CMDTAG_MERGE, queryDesc->estate->es_processed);
- break;
- default:
- SetQueryCompletion(qc, CMDTAG_UNKNOWN, queryDesc->estate->es_processed);
- break;
- }
+ CommandTag tag;
+
+ if (queryDesc->operation == CMD_SELECT)
+ tag = CMDTAG_SELECT;
+ else if (queryDesc->operation == CMD_INSERT)
+ tag = CMDTAG_INSERT;
+ else if (queryDesc->operation == CMD_UPDATE)
+ tag = CMDTAG_UPDATE;
+ else if (queryDesc->operation == CMD_DELETE)
+ tag = CMDTAG_DELETE;
+ else if (queryDesc->operation == CMD_MERGE)
+ tag = CMDTAG_MERGE;
+ else
+ tag = CMDTAG_UNKNOWN;
+
+ SetQueryCompletion(qc, tag, queryDesc->estate->es_processed);
}
/*
diff --git a/src/backend/tsearch/ts_selfuncs.c b/src/backend/tsearch/ts_selfuncs.c
index 6a71ae6452d..fb367ad74d2 100644
--- a/src/backend/tsearch/ts_selfuncs.c
+++ b/src/backend/tsearch/ts_selfuncs.c
@@ -47,8 +47,8 @@ typedef struct
static Selectivity tsquerysel(VariableStatData *vardata, Datum constval);
static Selectivity mcelem_tsquery_selec(TSQuery query,
- Datum *mcelem, int nmcelem,
- float4 *numbers, int nnumbers);
+ const Datum *mcelem, int nmcelem,
+ const float4 *numbers, int nnumbers);
static Selectivity tsquery_opr_selec(QueryItem *item, char *operand,
TextFreq *lookup, int length, float4 minfreq);
static int compare_lexeme_textfreq(const void *e1, const void *e2);
@@ -204,8 +204,8 @@ tsquerysel(VariableStatData *vardata, Datum constval)
* Extract data from the pg_statistic arrays into useful format.
*/
static Selectivity
-mcelem_tsquery_selec(TSQuery query, Datum *mcelem, int nmcelem,
- float4 *numbers, int nnumbers)
+mcelem_tsquery_selec(TSQuery query, const Datum *mcelem, int nmcelem,
+ const float4 *numbers, int nnumbers)
{
float4 minfreq;
TextFreq *lookup;
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/array_selfuncs.c b/src/backend/utils/adt/array_selfuncs.c
index cf6fbf8652c..4dab35b0057 100644
--- a/src/backend/utils/adt/array_selfuncs.c
+++ b/src/backend/utils/adt/array_selfuncs.c
@@ -39,25 +39,25 @@
static Selectivity calc_arraycontsel(VariableStatData *vardata, Datum constval,
Oid elemtype, Oid operator);
-static Selectivity mcelem_array_selec(ArrayType *array,
+static Selectivity mcelem_array_selec(const ArrayType *array,
TypeCacheEntry *typentry,
- Datum *mcelem, int nmcelem,
- float4 *numbers, int nnumbers,
- float4 *hist, int nhist,
+ const Datum *mcelem, int nmcelem,
+ const float4 *numbers, int nnumbers,
+ const float4 *hist, int nhist,
Oid operator);
-static Selectivity mcelem_array_contain_overlap_selec(Datum *mcelem, int nmcelem,
- float4 *numbers, int nnumbers,
- Datum *array_data, int nitems,
+static Selectivity mcelem_array_contain_overlap_selec(const Datum *mcelem, int nmcelem,
+ const float4 *numbers, int nnumbers,
+ const Datum *array_data, int nitems,
Oid operator, TypeCacheEntry *typentry);
-static Selectivity mcelem_array_contained_selec(Datum *mcelem, int nmcelem,
- float4 *numbers, int nnumbers,
- Datum *array_data, int nitems,
- float4 *hist, int nhist,
+static Selectivity mcelem_array_contained_selec(const Datum *mcelem, int nmcelem,
+ const float4 *numbers, int nnumbers,
+ const Datum *array_data, int nitems,
+ const float4 *hist, int nhist,
Oid operator, TypeCacheEntry *typentry);
static float *calc_hist(const float4 *hist, int nhist, int n);
static float *calc_distr(const float *p, int n, int m, float rest);
static int floor_log2(uint32 n);
-static bool find_next_mcelem(Datum *mcelem, int nmcelem, Datum value,
+static bool find_next_mcelem(const Datum *mcelem, int nmcelem, Datum value,
int *index, TypeCacheEntry *typentry);
static int element_compare(const void *key1, const void *key2, void *arg);
static int float_compare_desc(const void *key1, const void *key2);
@@ -425,10 +425,10 @@ calc_arraycontsel(VariableStatData *vardata, Datum constval,
* mcelem_array_contained_selec depending on the operator.
*/
static Selectivity
-mcelem_array_selec(ArrayType *array, TypeCacheEntry *typentry,
- Datum *mcelem, int nmcelem,
- float4 *numbers, int nnumbers,
- float4 *hist, int nhist,
+mcelem_array_selec(const ArrayType *array, TypeCacheEntry *typentry,
+ const Datum *mcelem, int nmcelem,
+ const float4 *numbers, int nnumbers,
+ const float4 *hist, int nhist,
Oid operator)
{
Selectivity selec;
@@ -518,9 +518,9 @@ mcelem_array_selec(ArrayType *array, TypeCacheEntry *typentry,
* fraction of nonempty arrays in the column.
*/
static Selectivity
-mcelem_array_contain_overlap_selec(Datum *mcelem, int nmcelem,
- float4 *numbers, int nnumbers,
- Datum *array_data, int nitems,
+mcelem_array_contain_overlap_selec(const Datum *mcelem, int nmcelem,
+ const float4 *numbers, int nnumbers,
+ const Datum *array_data, int nitems,
Oid operator, TypeCacheEntry *typentry)
{
Selectivity selec,
@@ -699,10 +699,10 @@ mcelem_array_contain_overlap_selec(Datum *mcelem, int nmcelem,
* ... * fn^on * (1 - fn)^(1 - on), o1, o2, ..., on) | o1 + o2 + .. on = m
*/
static Selectivity
-mcelem_array_contained_selec(Datum *mcelem, int nmcelem,
- float4 *numbers, int nnumbers,
- Datum *array_data, int nitems,
- float4 *hist, int nhist,
+mcelem_array_contained_selec(const Datum *mcelem, int nmcelem,
+ const float4 *numbers, int nnumbers,
+ const Datum *array_data, int nitems,
+ const float4 *hist, int nhist,
Oid operator, TypeCacheEntry *typentry)
{
int mcelem_index,
@@ -1136,7 +1136,7 @@ floor_log2(uint32 n)
* exact match.)
*/
static bool
-find_next_mcelem(Datum *mcelem, int nmcelem, Datum value, int *index,
+find_next_mcelem(const Datum *mcelem, int nmcelem, Datum value, int *index,
TypeCacheEntry *typentry)
{
int l = *index,
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index a8951f55b93..a464349ee33 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -960,8 +960,8 @@ ending_error:
*/
void
CopyArrayEls(ArrayType *array,
- Datum *values,
- bool *nulls,
+ const Datum *values,
+ const bool *nulls,
int nitems,
int typlen,
bool typbyval,
@@ -3629,7 +3629,7 @@ construct_empty_expanded_array(Oid element_type,
* to hard-wire values if the element type is hard-wired.
*/
void
-deconstruct_array(ArrayType *array,
+deconstruct_array(const ArrayType *array,
Oid elmtype,
int elmlen, bool elmbyval, char elmalign,
Datum **elemsp, bool **nullsp, int *nelemsp)
@@ -3695,7 +3695,7 @@ deconstruct_array(ArrayType *array,
* useful when manipulating arrays from/for system catalogs.
*/
void
-deconstruct_array_builtin(ArrayType *array,
+deconstruct_array_builtin(const ArrayType *array,
Oid elmtype,
Datum **elemsp, bool **nullsp, int *nelemsp)
{
@@ -3765,7 +3765,7 @@ deconstruct_array_builtin(ArrayType *array,
* if the array *might* contain a null.
*/
bool
-array_contains_nulls(ArrayType *array)
+array_contains_nulls(const ArrayType *array)
{
int nelems;
bits8 *bitmap;
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 78e19ac39ac..5f7b3114da7 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,46 @@
#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
- * ----------
*/
+
+enum KeySuffixType
+{
+ SUFFTYPE_PREFIX = 1,
+ SUFFTYPE_POSTFIX = 2,
+};
+
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 */
+ enum KeySuffixType 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,36 +146,33 @@ typedef enum
typedef struct
{
const char *name;
- int len;
+ size_t len;
int id;
bool is_digit;
FromCharDateMode date_mode;
} KeyWord;
+enum FormatNodeType
+{
+ NODE_TYPE_END = 1,
+ NODE_TYPE_ACTION = 2,
+ NODE_TYPE_CHAR = 3,
+ NODE_TYPE_SEPARATOR = 4,
+ NODE_TYPE_SPACE = 5,
+};
+
typedef struct
{
- uint8 type; /* NODE_TYPE_XXX, see below */
+ enum FormatNodeType type;
char character[MAX_MULTIBYTE_CHAR_LEN + 1]; /* if type is CHAR */
- uint8 suffix; /* keyword prefix/suffix code, if any */
+ uint8 suffix; /* keyword prefix/suffix code, if any
+ * (DCH_SUFFIX_*) */
const KeyWord *key; /* if type is ACTION */
} FormatNode;
-#define NODE_TYPE_END 1
-#define NODE_TYPE_ACTION 2
-#define NODE_TYPE_CHAR 3
-#define NODE_TYPE_SEPARATOR 4
-#define NODE_TYPE_SPACE 5
-
-#define SUFFTYPE_PREFIX 1
-#define SUFFTYPE_POSTFIX 2
-
-#define CLOCK_24_HOUR 0
-#define CLOCK_12_HOUR 1
-
-/* ----------
+/*
* Full months
- * ----------
*/
static const char *const months_full[] = {
"January", "February", "March", "April", "May", "June", "July",
@@ -184,9 +183,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 +215,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 +241,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 +252,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,40 +285,46 @@ 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
+enum TH_Case
+{
+ TH_UPPER = 1,
+ TH_LOWER = 2,
+};
-/* ----------
+enum NUMDesc_lsign
+{
+ NUM_LSIGN_PRE = -1,
+ NUM_LSIGN_POST = 1,
+ NUM_LSIGN_NONE = 0,
+};
+
+/*
* Number description struct
- * ----------
*/
typedef struct
{
- int pre, /* (count) numbers before decimal */
- post, /* (count) numbers after decimal */
- lsign, /* want locales sign */
- flag, /* number parameters */
- pre_lsign_num, /* tmp value for lsign */
- multi, /* multiplier for 'V' */
- zero_start, /* position of first zero */
- zero_end, /* position of last zero */
- need_locale; /* needs it locale */
+ int pre; /* (count) numbers before decimal */
+ int post; /* (count) numbers after decimal */
+ enum NUMDesc_lsign lsign; /* want locales sign */
+ int flag; /* number parameters (NUM_F_*) */
+ int pre_lsign_num; /* tmp value for lsign */
+ int multi; /* multiplier for 'V' */
+ int zero_start; /* position of first zero */
+ int zero_end; /* position of last zero */
+ bool need_locale; /* needs it locale */
} NUMDesc;
-/* ----------
+/*
* Flags for NUMBER version
- * ----------
*/
#define NUM_F_DECIMAL (1 << 1)
#define NUM_F_LDECIMAL (1 << 2)
@@ -339,13 +341,8 @@ typedef struct
#define NUM_F_MINUS_POST (1 << 13)
#define NUM_F_EEEE (1 << 14)
-#define NUM_LSIGN_PRE (-1)
-#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 +357,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 +373,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,53 +415,49 @@ 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
{
FromCharDateMode mode;
- int hh,
- pm,
- mi,
- ss,
- ssss,
- d, /* stored as 1-7, Sunday = 1, 0 means missing */
- dd,
- ddd,
- mm,
- ms,
- year,
- bc,
- ww,
- w,
- cc,
- j,
- us,
- yysz, /* is it YY or YYYY ? */
- clock, /* 12 or 24 hour clock? */
- tzsign, /* +1, -1, or 0 if no TZH/TZM fields */
- tzh,
- tzm,
- ff; /* fractional precision */
+ int hh;
+ int pm;
+ int mi;
+ int ss;
+ int ssss;
+ int d; /* stored as 1-7, Sunday = 1, 0 means missing */
+ int dd;
+ int ddd;
+ int mm;
+ int ms;
+ int year;
+ int bc;
+ int ww;
+ int w;
+ int cc;
+ int j;
+ int us;
+ int yysz; /* is it YY or YYYY ? */
+ bool clock_12_hour; /* 12 or 24 hour clock? */
+ int tzsign; /* +1, -1, or 0 if no TZH/TZM fields */
+ int tzh;
+ int tzm;
+ int ff; /* fractional precision */
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))
-
struct fmt_tz /* do_to_timestamp's timezone info output */
{
bool has_tz; /* was there any TZ/TZH/TZM field? */
int gmtoffset; /* GMT offset in seconds */
};
-/* ----------
+/*
* Debug
- * ----------
*/
#ifdef DEBUG_TO_FROM_CHAR
#define DEBUG_TMFC(_X) \
@@ -473,7 +465,7 @@ struct fmt_tz /* do_to_timestamp's timezone info output */
(_X)->mode, (_X)->hh, (_X)->pm, (_X)->mi, (_X)->ss, (_X)->ssss, \
(_X)->d, (_X)->dd, (_X)->ddd, (_X)->mm, (_X)->ms, (_X)->year, \
(_X)->bc, (_X)->ww, (_X)->w, (_X)->cc, (_X)->j, (_X)->us, \
- (_X)->yysz, (_X)->clock)
+ (_X)->yysz, (_X)->clock_12_hour)
#define DEBUG_TM(_X) \
elog(DEBUG_elog_output, "TM:\nsec %d\nyear %d\nmin %d\nwday %d\nhour %d\nyday %d\nmday %d\nnisdst %d\nmon %d\n",\
(_X)->tm_sec, (_X)->tm_year,\
@@ -484,13 +476,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,50 +552,74 @@ do { \
* KeyWord definitions
*****************************************************************************/
-/* ----------
+/*
* Suffixes (FormatNode.suffix is an OR of these codes)
- * ----------
*/
-#define DCH_S_FM 0x01
-#define DCH_S_TH 0x02
-#define DCH_S_th 0x04
-#define DCH_S_SP 0x08
-#define DCH_S_TM 0x10
+#define DCH_SUFFIX_FM 0x01
+#define DCH_SUFFIX_TH 0x02
+#define DCH_SUFFIX_th 0x04
+#define DCH_SUFFIX_SP 0x08
+#define DCH_SUFFIX_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)
-#define S_th(_s) (((_s) & DCH_S_th) ? 1 : 0)
-#define S_TH_TYPE(_s) (((_s) & DCH_S_TH) ? TH_UPPER : TH_LOWER)
+static inline bool
+IS_SUFFIX_TH(uint8 _s)
+{
+ return (_s & DCH_SUFFIX_TH);
+}
+
+static inline bool
+IS_SUFFIX_th(uint8 _s)
+{
+ return (_s & DCH_SUFFIX_th);
+}
+
+static inline bool
+IS_SUFFIX_THth(uint8 _s)
+{
+ return IS_SUFFIX_TH(_s) || IS_SUFFIX_th(_s);
+}
+
+static inline enum TH_Case
+SUFFIX_TH_TYPE(uint8 _s)
+{
+ return _s & DCH_SUFFIX_TH ? TH_UPPER : TH_LOWER;
+}
/* Oracle toggles FM behavior, we don't; see docs. */
-#define S_FM(_s) (((_s) & DCH_S_FM) ? 1 : 0)
-#define S_SP(_s) (((_s) & DCH_S_SP) ? 1 : 0)
-#define S_TM(_s) (((_s) & DCH_S_TM) ? 1 : 0)
+static inline bool
+IS_SUFFIX_FM(uint8 _s)
+{
+ return (_s & DCH_SUFFIX_FM);
+}
+
+static inline bool
+IS_SUFFIX_TM(uint8 _s)
+{
+ return (_s & DCH_SUFFIX_TM);
+}
-/* ----------
+/*
* Suffixes definition for DATE-TIME TO/FROM CHAR
- * ----------
*/
#define TM_SUFFIX_LEN 2
static const KeySuffix DCH_suff[] = {
- {"FM", 2, DCH_S_FM, SUFFTYPE_PREFIX},
- {"fm", 2, DCH_S_FM, SUFFTYPE_PREFIX},
- {"TM", TM_SUFFIX_LEN, DCH_S_TM, SUFFTYPE_PREFIX},
- {"tm", 2, DCH_S_TM, SUFFTYPE_PREFIX},
- {"TH", 2, DCH_S_TH, SUFFTYPE_POSTFIX},
- {"th", 2, DCH_S_th, SUFFTYPE_POSTFIX},
- {"SP", 2, DCH_S_SP, SUFFTYPE_POSTFIX},
+ {"FM", 2, DCH_SUFFIX_FM, SUFFTYPE_PREFIX},
+ {"fm", 2, DCH_SUFFIX_FM, SUFFTYPE_PREFIX},
+ {"TM", TM_SUFFIX_LEN, DCH_SUFFIX_TM, SUFFTYPE_PREFIX},
+ {"tm", 2, DCH_SUFFIX_TM, SUFFTYPE_PREFIX},
+ {"TH", 2, DCH_SUFFIX_TH, SUFFTYPE_POSTFIX},
+ {"th", 2, DCH_SUFFIX_th, SUFFTYPE_POSTFIX},
+ {"SP", 2, DCH_SUFFIX_SP, SUFFTYPE_POSTFIX},
/* last */
{NULL, 0, 0, 0}
};
-/* ----------
+/*
* Format-pictures (KeyWord).
*
* The KeyWord field; alphabetic sorted, *BUT* strings alike is sorted
@@ -628,8 +643,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 +807,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 +929,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 +978,8 @@ static const KeyWord NUM_keywords[] = {
};
-/* ----------
+/*
* KeyWords index for DATE-TIME version
- * ----------
*/
static const int DCH_index[KeyWord_INDEX_SIZE] = {
/*
@@ -991,9 +1001,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 +1024,8 @@ static const int NUM_index[KeyWord_INDEX_SIZE] = {
/*---- chars over 126 are skipped ----*/
};
-/* ----------
+/*
* Number processor struct
- * ----------
*/
typedef struct NUMProc
{
@@ -1062,13 +1070,12 @@ 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);
-static const KeySuffix *suff_search(const char *str, const KeySuffix *suf, int type);
+static const KeySuffix *suff_search(const char *str, const KeySuffix *suf, enum KeySuffixType type);
static bool is_separator_char(const char *str);
static void NUMDesc_prepare(NUMDesc *num, FormatNode *n);
static void parse_format(FormatNode *node, const char *str, const KeyWord *kw,
@@ -1084,38 +1091,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, enum TH_Case type);
+static char *str_numth(char *dest, const char *num, enum TH_Case 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 void fill_str(char *str, int c, int max);
+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 +1132,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 +1145,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;
@@ -1156,11 +1162,9 @@ 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)
+suff_search(const char *str, const KeySuffix *suf, enum KeySuffixType 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 +1185,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 +1236,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 +1367,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,14 +1516,13 @@ parse_format(FormatNode *node, const char *str, const KeyWord *kw,
n->suffix = 0;
}
-/* ----------
+/*
* DEBUG: Dump the FormatNode Tree (debug)
- * ----------
*/
#ifdef DEBUG_TO_FROM_CHAR
-#define DUMP_THth(_suf) (S_TH(_suf) ? "TH" : (S_th(_suf) ? "th" : " "))
-#define DUMP_FM(_suf) (S_FM(_suf) ? "FM" : " ")
+#define DUMP_THth(_suf) (IS_SUFFIX_TH(_suf) ? "TH" : (IS_SUFFIX_th(_suf) ? "th" : " "))
+#define DUMP_FM(_suf) (IS_SUFFIX_FM(_suf) ? "FM" : " ")
static void
dump_node(FormatNode *node, int max)
@@ -1554,20 +1555,18 @@ 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, enum TH_Case 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 +1576,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 +1600,11 @@ 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, enum TH_Case type)
{
if (dest != num)
strcpy(dest, num);
@@ -1900,14 +1897,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 +1919,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 +1941,6 @@ char *
asc_initcap(const char *buff, size_t nbytes)
{
char *result;
- char *p;
int wasalnum = false;
if (!buff)
@@ -1954,7 +1948,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,15 +2000,14 @@ 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
- * ----------
+ * If IS_SUFFIX_THth is on, skip two chars, assuming there are two available
*/
#define SKIP_THth(ptr, _suf) \
do { \
- if (S_THth(_suf)) \
+ if (IS_SUFFIX_THth(_suf)) \
{ \
if (*(ptr)) (ptr) += pg_mblen(ptr); \
if (*(ptr)) (ptr) += pg_mblen(ptr); \
@@ -2023,21 +2016,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 +2046,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)
@@ -2065,7 +2055,7 @@ is_next_separator(FormatNode *n)
if (n->type == NODE_TYPE_END)
return false;
- if (n->type == NODE_TYPE_ACTION && S_THth(n->suffix))
+ if (n->type == NODE_TYPE_ACTION && IS_SUFFIX_THth(n->suffix))
return true;
/*
@@ -2116,10 +2106,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))
{
@@ -2150,8 +2140,7 @@ from_char_set_mode(TmFromChar *tmfc, const FromCharDateMode mode,
ereturn(escontext, false,
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
errmsg("invalid combination of date conventions"),
- errhint("Do not mix Gregorian and ISO week date "
- "conventions in a formatting template.")));
+ errhint("Do not mix Gregorian and ISO week date conventions in a formatting template.")));
}
return true;
}
@@ -2174,8 +2163,7 @@ from_char_set_int(int *dest, const int value, const FormatNode *node,
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
errmsg("conflicting values for \"%s\" field in formatting string",
node->key->name),
- errdetail("This value contradicts a previous setting "
- "for the same field type.")));
+ errdetail("This value contradicts a previous setting for the same field type.")));
*dest = value;
return true;
}
@@ -2202,13 +2190,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,9 +2204,9 @@ 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))
+ if (IS_SUFFIX_FM(node->suffix) || is_next_separator(node))
{
/*
* This node is in Fill Mode, or the next node is known to be a
@@ -2243,10 +2231,9 @@ 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.")));
+ errhint("If your source string is not fixed-width, try using the \"FM\" modifier.")));
errno = 0;
result = strtol(copy, &last, 10);
@@ -2257,10 +2244,9 @@ 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.")));
+ errhint("If your source string is not fixed-width, try using the \"FM\" modifier.")));
*src += used;
}
@@ -2317,10 +2303,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 +2316,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 +2356,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 +2371,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 +2390,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 +2443,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 +2457,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))
{
@@ -2491,22 +2471,19 @@ from_char_seq_search(int *dest, const char **src, const char *const *array,
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
errmsg("invalid value \"%s\" for \"%s\"",
copy, node->key->name),
- errdetail("The given value did not match any of "
- "the allowed values for this field.")));
+ errdetail("The given value did not match any of the allowed values for this field.")));
}
*src += len;
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 +2492,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)
{
@@ -2557,40 +2534,40 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
* display time as shown on a 12-hour clock, even for
* intervals
*/
- sprintf(s, "%0*lld", S_FM(n->suffix) ? 0 : (tm->tm_hour >= 0) ? 2 : 3,
+ sprintf(s, "%0*lld", IS_SUFFIX_FM(n->suffix) ? 0 : (tm->tm_hour >= 0) ? 2 : 3,
tm->tm_hour % (HOURS_PER_DAY / 2) == 0 ?
(long long) (HOURS_PER_DAY / 2) :
(long long) (tm->tm_hour % (HOURS_PER_DAY / 2)));
- if (S_THth(n->suffix))
- str_numth(s, s, S_TH_TYPE(n->suffix));
+ if (IS_SUFFIX_THth(n->suffix))
+ str_numth(s, s, SUFFIX_TH_TYPE(n->suffix));
s += strlen(s);
break;
case DCH_HH24:
- sprintf(s, "%0*lld", S_FM(n->suffix) ? 0 : (tm->tm_hour >= 0) ? 2 : 3,
+ sprintf(s, "%0*lld", IS_SUFFIX_FM(n->suffix) ? 0 : (tm->tm_hour >= 0) ? 2 : 3,
(long long) tm->tm_hour);
- if (S_THth(n->suffix))
- str_numth(s, s, S_TH_TYPE(n->suffix));
+ if (IS_SUFFIX_THth(n->suffix))
+ str_numth(s, s, SUFFIX_TH_TYPE(n->suffix));
s += strlen(s);
break;
case DCH_MI:
- sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : (tm->tm_min >= 0) ? 2 : 3,
+ sprintf(s, "%0*d", IS_SUFFIX_FM(n->suffix) ? 0 : (tm->tm_min >= 0) ? 2 : 3,
tm->tm_min);
- if (S_THth(n->suffix))
- str_numth(s, s, S_TH_TYPE(n->suffix));
+ if (IS_SUFFIX_THth(n->suffix))
+ str_numth(s, s, SUFFIX_TH_TYPE(n->suffix));
s += strlen(s);
break;
case DCH_SS:
- sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : (tm->tm_sec >= 0) ? 2 : 3,
+ sprintf(s, "%0*d", IS_SUFFIX_FM(n->suffix) ? 0 : (tm->tm_sec >= 0) ? 2 : 3,
tm->tm_sec);
- if (S_THth(n->suffix))
- str_numth(s, s, S_TH_TYPE(n->suffix));
+ if (IS_SUFFIX_THth(n->suffix))
+ str_numth(s, s, SUFFIX_TH_TYPE(n->suffix));
s += strlen(s);
break;
#define DCH_to_char_fsec(frac_fmt, frac_val) \
sprintf(s, frac_fmt, (int) (frac_val)); \
- if (S_THth(n->suffix)) \
- str_numth(s, s, S_TH_TYPE(n->suffix)); \
+ if (IS_SUFFIX_THth(n->suffix)) \
+ str_numth(s, s, SUFFIX_TH_TYPE(n->suffix)); \
s += strlen(s)
case DCH_FF1: /* tenth of second */
@@ -2619,8 +2596,8 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
(long long) (tm->tm_hour * SECS_PER_HOUR +
tm->tm_min * SECS_PER_MINUTE +
tm->tm_sec));
- if (S_THth(n->suffix))
- str_numth(s, s, S_TH_TYPE(n->suffix));
+ if (IS_SUFFIX_THth(n->suffix))
+ str_numth(s, s, SUFFIX_TH_TYPE(n->suffix));
s += strlen(s);
break;
case DCH_tz:
@@ -2660,7 +2637,7 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
INVALID_FOR_INTERVAL;
sprintf(s, "%c%0*d",
(tm->tm_gmtoff >= 0) ? '+' : '-',
- S_FM(n->suffix) ? 0 : 2,
+ IS_SUFFIX_FM(n->suffix) ? 0 : 2,
abs((int) tm->tm_gmtoff) / SECS_PER_HOUR);
s += strlen(s);
if (abs((int) tm->tm_gmtoff) % SECS_PER_HOUR != 0)
@@ -2698,7 +2675,7 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
INVALID_FOR_INTERVAL;
if (!tm->tm_mon)
break;
- if (S_TM(n->suffix))
+ if (IS_SUFFIX_TM(n->suffix))
{
char *str = str_toupper_z(localized_full_months[tm->tm_mon - 1], collid);
@@ -2710,7 +2687,7 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
errmsg("localized string format value too long")));
}
else
- sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9,
+ sprintf(s, "%*s", IS_SUFFIX_FM(n->suffix) ? 0 : -9,
asc_toupper_z(months_full[tm->tm_mon - 1]));
s += strlen(s);
break;
@@ -2718,7 +2695,7 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
INVALID_FOR_INTERVAL;
if (!tm->tm_mon)
break;
- if (S_TM(n->suffix))
+ if (IS_SUFFIX_TM(n->suffix))
{
char *str = str_initcap_z(localized_full_months[tm->tm_mon - 1], collid);
@@ -2730,7 +2707,7 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
errmsg("localized string format value too long")));
}
else
- sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9,
+ sprintf(s, "%*s", IS_SUFFIX_FM(n->suffix) ? 0 : -9,
months_full[tm->tm_mon - 1]);
s += strlen(s);
break;
@@ -2738,7 +2715,7 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
INVALID_FOR_INTERVAL;
if (!tm->tm_mon)
break;
- if (S_TM(n->suffix))
+ if (IS_SUFFIX_TM(n->suffix))
{
char *str = str_tolower_z(localized_full_months[tm->tm_mon - 1], collid);
@@ -2750,7 +2727,7 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
errmsg("localized string format value too long")));
}
else
- sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9,
+ sprintf(s, "%*s", IS_SUFFIX_FM(n->suffix) ? 0 : -9,
asc_tolower_z(months_full[tm->tm_mon - 1]));
s += strlen(s);
break;
@@ -2758,7 +2735,7 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
INVALID_FOR_INTERVAL;
if (!tm->tm_mon)
break;
- if (S_TM(n->suffix))
+ if (IS_SUFFIX_TM(n->suffix))
{
char *str = str_toupper_z(localized_abbrev_months[tm->tm_mon - 1], collid);
@@ -2777,7 +2754,7 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
INVALID_FOR_INTERVAL;
if (!tm->tm_mon)
break;
- if (S_TM(n->suffix))
+ if (IS_SUFFIX_TM(n->suffix))
{
char *str = str_initcap_z(localized_abbrev_months[tm->tm_mon - 1], collid);
@@ -2796,7 +2773,7 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
INVALID_FOR_INTERVAL;
if (!tm->tm_mon)
break;
- if (S_TM(n->suffix))
+ if (IS_SUFFIX_TM(n->suffix))
{
char *str = str_tolower_z(localized_abbrev_months[tm->tm_mon - 1], collid);
@@ -2812,15 +2789,15 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
s += strlen(s);
break;
case DCH_MM:
- sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : (tm->tm_mon >= 0) ? 2 : 3,
+ sprintf(s, "%0*d", IS_SUFFIX_FM(n->suffix) ? 0 : (tm->tm_mon >= 0) ? 2 : 3,
tm->tm_mon);
- if (S_THth(n->suffix))
- str_numth(s, s, S_TH_TYPE(n->suffix));
+ if (IS_SUFFIX_THth(n->suffix))
+ str_numth(s, s, SUFFIX_TH_TYPE(n->suffix));
s += strlen(s);
break;
case DCH_DAY:
INVALID_FOR_INTERVAL;
- if (S_TM(n->suffix))
+ if (IS_SUFFIX_TM(n->suffix))
{
char *str = str_toupper_z(localized_full_days[tm->tm_wday], collid);
@@ -2832,13 +2809,13 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
errmsg("localized string format value too long")));
}
else
- sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9,
+ sprintf(s, "%*s", IS_SUFFIX_FM(n->suffix) ? 0 : -9,
asc_toupper_z(days[tm->tm_wday]));
s += strlen(s);
break;
case DCH_Day:
INVALID_FOR_INTERVAL;
- if (S_TM(n->suffix))
+ if (IS_SUFFIX_TM(n->suffix))
{
char *str = str_initcap_z(localized_full_days[tm->tm_wday], collid);
@@ -2850,13 +2827,13 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
errmsg("localized string format value too long")));
}
else
- sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9,
+ sprintf(s, "%*s", IS_SUFFIX_FM(n->suffix) ? 0 : -9,
days[tm->tm_wday]);
s += strlen(s);
break;
case DCH_day:
INVALID_FOR_INTERVAL;
- if (S_TM(n->suffix))
+ if (IS_SUFFIX_TM(n->suffix))
{
char *str = str_tolower_z(localized_full_days[tm->tm_wday], collid);
@@ -2868,13 +2845,13 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
errmsg("localized string format value too long")));
}
else
- sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9,
+ sprintf(s, "%*s", IS_SUFFIX_FM(n->suffix) ? 0 : -9,
asc_tolower_z(days[tm->tm_wday]));
s += strlen(s);
break;
case DCH_DY:
INVALID_FOR_INTERVAL;
- if (S_TM(n->suffix))
+ if (IS_SUFFIX_TM(n->suffix))
{
char *str = str_toupper_z(localized_abbrev_days[tm->tm_wday], collid);
@@ -2891,7 +2868,7 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
break;
case DCH_Dy:
INVALID_FOR_INTERVAL;
- if (S_TM(n->suffix))
+ if (IS_SUFFIX_TM(n->suffix))
{
char *str = str_initcap_z(localized_abbrev_days[tm->tm_wday], collid);
@@ -2908,7 +2885,7 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
break;
case DCH_dy:
INVALID_FOR_INTERVAL;
- if (S_TM(n->suffix))
+ if (IS_SUFFIX_TM(n->suffix))
{
char *str = str_tolower_z(localized_abbrev_days[tm->tm_wday], collid);
@@ -2925,54 +2902,54 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
break;
case DCH_DDD:
case DCH_IDDD:
- sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : 3,
+ sprintf(s, "%0*d", IS_SUFFIX_FM(n->suffix) ? 0 : 3,
(n->key->id == DCH_DDD) ?
tm->tm_yday :
date2isoyearday(tm->tm_year, tm->tm_mon, tm->tm_mday));
- if (S_THth(n->suffix))
- str_numth(s, s, S_TH_TYPE(n->suffix));
+ if (IS_SUFFIX_THth(n->suffix))
+ str_numth(s, s, SUFFIX_TH_TYPE(n->suffix));
s += strlen(s);
break;
case DCH_DD:
- sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : 2, tm->tm_mday);
- if (S_THth(n->suffix))
- str_numth(s, s, S_TH_TYPE(n->suffix));
+ sprintf(s, "%0*d", IS_SUFFIX_FM(n->suffix) ? 0 : 2, tm->tm_mday);
+ if (IS_SUFFIX_THth(n->suffix))
+ str_numth(s, s, SUFFIX_TH_TYPE(n->suffix));
s += strlen(s);
break;
case DCH_D:
INVALID_FOR_INTERVAL;
sprintf(s, "%d", tm->tm_wday + 1);
- if (S_THth(n->suffix))
- str_numth(s, s, S_TH_TYPE(n->suffix));
+ if (IS_SUFFIX_THth(n->suffix))
+ str_numth(s, s, SUFFIX_TH_TYPE(n->suffix));
s += strlen(s);
break;
case DCH_ID:
INVALID_FOR_INTERVAL;
sprintf(s, "%d", (tm->tm_wday == 0) ? 7 : tm->tm_wday);
- if (S_THth(n->suffix))
- str_numth(s, s, S_TH_TYPE(n->suffix));
+ if (IS_SUFFIX_THth(n->suffix))
+ str_numth(s, s, SUFFIX_TH_TYPE(n->suffix));
s += strlen(s);
break;
case DCH_WW:
- sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : 2,
+ sprintf(s, "%0*d", IS_SUFFIX_FM(n->suffix) ? 0 : 2,
(tm->tm_yday - 1) / 7 + 1);
- if (S_THth(n->suffix))
- str_numth(s, s, S_TH_TYPE(n->suffix));
+ if (IS_SUFFIX_THth(n->suffix))
+ str_numth(s, s, SUFFIX_TH_TYPE(n->suffix));
s += strlen(s);
break;
case DCH_IW:
- sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : 2,
+ sprintf(s, "%0*d", IS_SUFFIX_FM(n->suffix) ? 0 : 2,
date2isoweek(tm->tm_year, tm->tm_mon, tm->tm_mday));
- if (S_THth(n->suffix))
- str_numth(s, s, S_TH_TYPE(n->suffix));
+ if (IS_SUFFIX_THth(n->suffix))
+ str_numth(s, s, SUFFIX_TH_TYPE(n->suffix));
s += strlen(s);
break;
case DCH_Q:
if (!tm->tm_mon)
break;
sprintf(s, "%d", (tm->tm_mon - 1) / 3 + 1);
- if (S_THth(n->suffix))
- str_numth(s, s, S_TH_TYPE(n->suffix));
+ if (IS_SUFFIX_THth(n->suffix))
+ str_numth(s, s, SUFFIX_TH_TYPE(n->suffix));
s += strlen(s);
break;
case DCH_CC:
@@ -2988,25 +2965,25 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
i = tm->tm_year / 100 - 1;
}
if (i <= 99 && i >= -99)
- sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : (i >= 0) ? 2 : 3, i);
+ sprintf(s, "%0*d", IS_SUFFIX_FM(n->suffix) ? 0 : (i >= 0) ? 2 : 3, i);
else
sprintf(s, "%d", i);
- if (S_THth(n->suffix))
- str_numth(s, s, S_TH_TYPE(n->suffix));
+ if (IS_SUFFIX_THth(n->suffix))
+ str_numth(s, s, SUFFIX_TH_TYPE(n->suffix));
s += strlen(s);
break;
case DCH_Y_YYY:
i = ADJUST_YEAR(tm->tm_year, is_interval) / 1000;
sprintf(s, "%d,%03d", i,
ADJUST_YEAR(tm->tm_year, is_interval) - (i * 1000));
- if (S_THth(n->suffix))
- str_numth(s, s, S_TH_TYPE(n->suffix));
+ if (IS_SUFFIX_THth(n->suffix))
+ str_numth(s, s, SUFFIX_TH_TYPE(n->suffix));
s += strlen(s);
break;
case DCH_YYYY:
case DCH_IYYY:
sprintf(s, "%0*d",
- S_FM(n->suffix) ? 0 :
+ IS_SUFFIX_FM(n->suffix) ? 0 :
(ADJUST_YEAR(tm->tm_year, is_interval) >= 0) ? 4 : 5,
(n->key->id == DCH_YYYY ?
ADJUST_YEAR(tm->tm_year, is_interval) :
@@ -3014,14 +2991,14 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
tm->tm_mon,
tm->tm_mday),
is_interval)));
- if (S_THth(n->suffix))
- str_numth(s, s, S_TH_TYPE(n->suffix));
+ if (IS_SUFFIX_THth(n->suffix))
+ str_numth(s, s, SUFFIX_TH_TYPE(n->suffix));
s += strlen(s);
break;
case DCH_YYY:
case DCH_IYY:
sprintf(s, "%0*d",
- S_FM(n->suffix) ? 0 :
+ IS_SUFFIX_FM(n->suffix) ? 0 :
(ADJUST_YEAR(tm->tm_year, is_interval) >= 0) ? 3 : 4,
(n->key->id == DCH_YYY ?
ADJUST_YEAR(tm->tm_year, is_interval) :
@@ -3029,14 +3006,14 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
tm->tm_mon,
tm->tm_mday),
is_interval)) % 1000);
- if (S_THth(n->suffix))
- str_numth(s, s, S_TH_TYPE(n->suffix));
+ if (IS_SUFFIX_THth(n->suffix))
+ str_numth(s, s, SUFFIX_TH_TYPE(n->suffix));
s += strlen(s);
break;
case DCH_YY:
case DCH_IY:
sprintf(s, "%0*d",
- S_FM(n->suffix) ? 0 :
+ IS_SUFFIX_FM(n->suffix) ? 0 :
(ADJUST_YEAR(tm->tm_year, is_interval) >= 0) ? 2 : 3,
(n->key->id == DCH_YY ?
ADJUST_YEAR(tm->tm_year, is_interval) :
@@ -3044,8 +3021,8 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
tm->tm_mon,
tm->tm_mday),
is_interval)) % 100);
- if (S_THth(n->suffix))
- str_numth(s, s, S_TH_TYPE(n->suffix));
+ if (IS_SUFFIX_THth(n->suffix))
+ str_numth(s, s, SUFFIX_TH_TYPE(n->suffix));
s += strlen(s);
break;
case DCH_Y:
@@ -3057,8 +3034,8 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
tm->tm_mon,
tm->tm_mday),
is_interval)) % 10);
- if (S_THth(n->suffix))
- str_numth(s, s, S_TH_TYPE(n->suffix));
+ if (IS_SUFFIX_THth(n->suffix))
+ str_numth(s, s, SUFFIX_TH_TYPE(n->suffix));
s += strlen(s);
break;
case DCH_RM:
@@ -3113,21 +3090,21 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
mon = MONTHS_PER_YEAR - tm->tm_mon;
}
- sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -4,
+ sprintf(s, "%*s", IS_SUFFIX_FM(n->suffix) ? 0 : -4,
months[mon]);
s += strlen(s);
}
break;
case DCH_W:
sprintf(s, "%d", (tm->tm_mday - 1) / 7 + 1);
- if (S_THth(n->suffix))
- str_numth(s, s, S_TH_TYPE(n->suffix));
+ if (IS_SUFFIX_THth(n->suffix))
+ str_numth(s, s, SUFFIX_TH_TYPE(n->suffix));
s += strlen(s);
break;
case DCH_J:
sprintf(s, "%d", date2j(tm->tm_year, tm->tm_mon, tm->tm_mday));
- if (S_THth(n->suffix))
- str_numth(s, s, S_TH_TYPE(n->suffix));
+ if (IS_SUFFIX_THth(n->suffix))
+ str_numth(s, s, SUFFIX_TH_TYPE(n->suffix));
s += strlen(s);
break;
}
@@ -3284,7 +3261,7 @@ DCH_from_char(FormatNode *node, const char *in, TmFromChar *out,
return;
if (!from_char_set_int(&out->pm, value % 2, n, escontext))
return;
- out->clock = CLOCK_12_HOUR;
+ out->clock_12_hour = true;
break;
case DCH_AM:
case DCH_PM:
@@ -3296,13 +3273,13 @@ DCH_from_char(FormatNode *node, const char *in, TmFromChar *out,
return;
if (!from_char_set_int(&out->pm, value % 2, n, escontext))
return;
- out->clock = CLOCK_12_HOUR;
+ out->clock_12_hour = true;
break;
case DCH_HH:
case DCH_HH12:
if (from_char_parse_int_len(&out->hh, &s, 2, n, escontext) < 0)
return;
- out->clock = CLOCK_12_HOUR;
+ out->clock_12_hour = true;
SKIP_THth(s, n->suffix);
break;
case DCH_HH24:
@@ -3389,8 +3366,7 @@ DCH_from_char(FormatNode *node, const char *in, TmFromChar *out,
*/
ereturn(escontext,,
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
- errmsg("invalid value \"%s\" for \"%s\"",
- s, n->key->name),
+ errmsg("invalid value \"%s\" for \"%s\"", s, n->key->name),
errdetail("Time zone abbreviation is not recognized.")));
}
/* otherwise parse it like OF */
@@ -3479,7 +3455,7 @@ DCH_from_char(FormatNode *node, const char *in, TmFromChar *out,
case DCH_Month:
case DCH_month:
if (!from_char_seq_search(&value, &s, months_full,
- S_TM(n->suffix) ? localized_full_months : NULL,
+ IS_SUFFIX_TM(n->suffix) ? localized_full_months : NULL,
collid,
n, escontext))
return;
@@ -3490,7 +3466,7 @@ DCH_from_char(FormatNode *node, const char *in, TmFromChar *out,
case DCH_Mon:
case DCH_mon:
if (!from_char_seq_search(&value, &s, months,
- S_TM(n->suffix) ? localized_abbrev_months : NULL,
+ IS_SUFFIX_TM(n->suffix) ? localized_abbrev_months : NULL,
collid,
n, escontext))
return;
@@ -3506,7 +3482,7 @@ DCH_from_char(FormatNode *node, const char *in, TmFromChar *out,
case DCH_Day:
case DCH_day:
if (!from_char_seq_search(&value, &s, days,
- S_TM(n->suffix) ? localized_full_days : NULL,
+ IS_SUFFIX_TM(n->suffix) ? localized_full_days : NULL,
collid,
n, escontext))
return;
@@ -3518,7 +3494,7 @@ DCH_from_char(FormatNode *node, const char *in, TmFromChar *out,
case DCH_Dy:
case DCH_dy:
if (!from_char_seq_search(&value, &s, days_short,
- S_TM(n->suffix) ? localized_abbrev_days : NULL,
+ IS_SUFFIX_TM(n->suffix) ? localized_abbrev_days : NULL,
collid,
n, escontext))
return;
@@ -3592,8 +3568,7 @@ DCH_from_char(FormatNode *node, const char *in, TmFromChar *out,
if (matched < 2)
ereturn(escontext,,
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
- errmsg("invalid value \"%s\" for \"%s\"",
- s, "Y,YYY")));
+ errmsg("invalid value \"%s\" for \"%s\"", s, "Y,YYY")));
/* years += (millennia * 1000); */
if (pg_mul_s32_overflow(millennia, 1000, &millennia) ||
@@ -3725,10 +3700,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 +3902,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 +3966,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 +4041,8 @@ timestamptz_to_char(PG_FUNCTION_ARGS)
}
-/* -------------------
+/*
* INTERVAL to_char()
- * -------------------
*/
Datum
interval_to_char(PG_FUNCTION_ARGS)
@@ -4107,12 +4079,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 +4119,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)
@@ -4171,8 +4141,7 @@ to_date(PG_FUNCTION_ARGS)
if (!IS_VALID_JULIAN(tm.tm_year, tm.tm_mon, tm.tm_mday))
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
- errmsg("date out of range: \"%s\"",
- text_to_cstring(date_txt))));
+ errmsg("date out of range: \"%s\"", text_to_cstring(date_txt))));
result = date2j(tm.tm_year, tm.tm_mon, tm.tm_mday) - POSTGRES_EPOCH_JDATE;
@@ -4180,8 +4149,7 @@ to_date(PG_FUNCTION_ARGS)
if (!IS_VALID_DATE(result))
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
- errmsg("date out of range: \"%s\"",
- text_to_cstring(date_txt))));
+ errmsg("date out of range: \"%s\"", text_to_cstring(date_txt))));
PG_RETURN_DATEADT(result);
}
@@ -4285,8 +4253,7 @@ parse_datetime(text *date_txt, text *fmt, Oid collid, bool strict,
if (!IS_VALID_JULIAN(tm.tm_year, tm.tm_mon, tm.tm_mday))
ereturn(escontext, (Datum) 0,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
- errmsg("date out of range: \"%s\"",
- text_to_cstring(date_txt))));
+ errmsg("date out of range: \"%s\"", text_to_cstring(date_txt))));
result = date2j(tm.tm_year, tm.tm_mon, tm.tm_mday) -
POSTGRES_EPOCH_JDATE;
@@ -4295,8 +4262,7 @@ parse_datetime(text *date_txt, text *fmt, Oid collid, bool strict,
if (!IS_VALID_DATE(result))
ereturn(escontext, (Datum) 0,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
- errmsg("date out of range: \"%s\"",
- text_to_cstring(date_txt))));
+ errmsg("date out of range: \"%s\"", text_to_cstring(date_txt))));
*typid = DATEOID;
return DateADTGetDatum(result);
@@ -4368,7 +4334,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,12 +4394,12 @@ 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)
{
FormatNode *format = NULL;
- TmFromChar tmfc;
+ TmFromChar tmfc = {0};
int fmt_len;
char *date_str;
int fmask;
@@ -4444,7 +4410,6 @@ do_to_timestamp(text *date_txt, text *fmt, Oid collid, bool std,
date_str = text_to_cstring(date_txt);
- ZERO_tmfc(&tmfc);
ZERO_tm(tm);
*fsec = 0;
tz->has_tz = false;
@@ -4527,14 +4492,13 @@ do_to_timestamp(text *date_txt, text *fmt, Oid collid, bool std,
if (tmfc.hh)
tm->tm_hour = tmfc.hh;
- if (tmfc.clock == CLOCK_12_HOUR)
+ if (tmfc.clock_12_hour)
{
if (tm->tm_hour < 1 || tm->tm_hour > HOURS_PER_DAY / 2)
{
errsave(escontext,
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
- errmsg("hour \"%d\" is invalid for the 12-hour clock",
- tm->tm_hour),
+ errmsg("hour \"%d\" is invalid for the 12-hour clock", tm->tm_hour),
errhint("Use the 24-hour clock, or give an hour between 1 and 12.")));
goto fail;
}
@@ -4860,27 +4824,17 @@ fail:
*********************************************************************/
-static char *
+/*
+ * Fill str with character c max times, and add terminating \0. (So max+1
+ * bytes are written altogether!)
+ */
+static void
fill_str(char *str, int c, int max)
{
memset(str, c, max);
- *(str + max) = '\0';
- return str;
+ str[max] = '\0';
}
-#define zeroize_NUM(_n) \
-do { \
- (_n)->flag = 0; \
- (_n)->lsign = 0; \
- (_n)->pre = 0; \
- (_n)->post = 0; \
- (_n)->pre_lsign_num = 0; \
- (_n)->need_locale = 0; \
- (_n)->multi = 0; \
- (_n)->zero_start = 0; \
- (_n)->zero_end = 0; \
-} while(0)
-
/* This works the same as DCH_prevent_counter_overflow */
static inline void
NUM_prevent_counter_overflow(void)
@@ -4988,7 +4942,7 @@ NUM_cache_fetch(const char *str)
*/
ent = NUM_cache_getnew(str);
- zeroize_NUM(&ent->Num);
+ memset(&ent->Num, 0, sizeof ent->Num);
parse_format(ent->format, str, NUM_keywords,
NULL, NUM_index, NUM_FLAG, &ent->Num);
@@ -4998,12 +4952,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;
@@ -5020,7 +4973,7 @@ NUM_cache(int len, NUMDesc *Num, text *pars_str, bool *shouldFree)
*shouldFree = true;
- zeroize_NUM(Num);
+ memset(Num, 0, sizeof *Num);
parse_format(format, str, NUM_keywords,
NULL, NUM_index, NUM_FLAG, Num);
@@ -5070,8 +5023,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 +5044,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 +5078,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 +5120,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 +5223,8 @@ roman_to_int(NUMProc *Np, int input_len)
}
-/* ----------
+/*
* Locale
- * ----------
*/
static void
NUM_prepare_locale(NUMProc *Np)
@@ -5349,16 +5300,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 +5331,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 +5369,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 +5448,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 +5487,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 +5545,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 +5739,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 +5753,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 +5841,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 +6215,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 +6228,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 +6249,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 +6307,8 @@ numeric_to_number(PG_FUNCTION_ARGS)
return result;
}
-/* ------------------
+/*
* NUMERIC to_char()
- * ------------------
*/
Datum
numeric_to_char(PG_FUNCTION_ARGS)
@@ -6434,7 +6378,7 @@ numeric_to_char(PG_FUNCTION_ARGS)
}
else
{
- int numstr_pre_len;
+ size_t numstr_pre_len;
Numeric val = value;
Numeric x;
@@ -6490,9 +6434,8 @@ numeric_to_char(PG_FUNCTION_ARGS)
PG_RETURN_TEXT_P(result);
}
-/* ---------------
+/*
* INT4 to_char()
- * ---------------
*/
Datum
int4_to_char(PG_FUNCTION_ARGS)
@@ -6532,7 +6475,7 @@ int4_to_char(PG_FUNCTION_ARGS)
}
else
{
- int numstr_pre_len;
+ size_t numstr_pre_len;
if (IS_MULTI(&Num))
{
@@ -6584,9 +6527,8 @@ int4_to_char(PG_FUNCTION_ARGS)
PG_RETURN_TEXT_P(result);
}
-/* ---------------
+/*
* INT8 to_char()
- * ---------------
*/
Datum
int8_to_char(PG_FUNCTION_ARGS)
@@ -6642,7 +6584,7 @@ int8_to_char(PG_FUNCTION_ARGS)
}
else
{
- int numstr_pre_len;
+ size_t numstr_pre_len;
if (IS_MULTI(&Num))
{
@@ -6696,9 +6638,8 @@ int8_to_char(PG_FUNCTION_ARGS)
PG_RETURN_TEXT_P(result);
}
-/* -----------------
+/*
* FLOAT4 to_char()
- * -----------------
*/
Datum
float4_to_char(PG_FUNCTION_ARGS)
@@ -6757,7 +6698,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 +6750,8 @@ float4_to_char(PG_FUNCTION_ARGS)
PG_RETURN_TEXT_P(result);
}
-/* -----------------
+/*
* FLOAT8 to_char()
- * -----------------
*/
Datum
float8_to_char(PG_FUNCTION_ARGS)
@@ -6870,7 +6810,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/json.c b/src/backend/utils/adt/json.c
index 14f5cb498fc..88a612b041d 100644
--- a/src/backend/utils/adt/json.c
+++ b/src/backend/utils/adt/json.c
@@ -89,7 +89,7 @@ typedef struct JsonAggState
static void composite_to_json(Datum composite, StringInfo result,
bool use_line_feeds);
static void array_dim_to_json(StringInfo result, int dim, int ndims, int *dims,
- Datum *vals, bool *nulls, int *valcount,
+ const Datum *vals, const bool *nulls, int *valcount,
JsonTypeCategory tcategory, Oid outfuncoid,
bool use_line_feeds);
static void array_to_json_internal(Datum array, StringInfo result,
@@ -429,8 +429,8 @@ JsonEncodeDateTime(char *buf, Datum value, Oid typid, const int *tzp)
* ourselves recursively to process the next dimension.
*/
static void
-array_dim_to_json(StringInfo result, int dim, int ndims, int *dims, Datum *vals,
- bool *nulls, int *valcount, JsonTypeCategory tcategory,
+array_dim_to_json(StringInfo result, int dim, int ndims, int *dims, const Datum *vals,
+ const bool *nulls, int *valcount, JsonTypeCategory tcategory,
Oid outfuncoid, bool use_line_feeds)
{
int i;
diff --git a/src/backend/utils/adt/jsonfuncs.c b/src/backend/utils/adt/jsonfuncs.c
index c5e1a027956..41862872e8a 100644
--- a/src/backend/utils/adt/jsonfuncs.c
+++ b/src/backend/utils/adt/jsonfuncs.c
@@ -477,16 +477,16 @@ static Datum populate_domain(DomainIOData *io, Oid typid, const char *colname,
/* functions supporting jsonb_delete, jsonb_set and jsonb_concat */
static JsonbValue *IteratorConcat(JsonbIterator **it1, JsonbIterator **it2,
JsonbParseState **state);
-static JsonbValue *setPath(JsonbIterator **it, Datum *path_elems,
- bool *path_nulls, int path_len,
+static JsonbValue *setPath(JsonbIterator **it, const Datum *path_elems,
+ const bool *path_nulls, int path_len,
JsonbParseState **st, int level, JsonbValue *newval,
int op_type);
-static void setPathObject(JsonbIterator **it, Datum *path_elems,
- bool *path_nulls, int path_len, JsonbParseState **st,
+static void setPathObject(JsonbIterator **it, const Datum *path_elems,
+ const bool *path_nulls, int path_len, JsonbParseState **st,
int level,
JsonbValue *newval, uint32 npairs, int op_type);
-static void setPathArray(JsonbIterator **it, Datum *path_elems,
- bool *path_nulls, int path_len, JsonbParseState **st,
+static void setPathArray(JsonbIterator **it, const Datum *path_elems,
+ const bool *path_nulls, int path_len, JsonbParseState **st,
int level,
JsonbValue *newval, uint32 nelems, int op_type);
@@ -1528,7 +1528,7 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text)
}
Datum
-jsonb_get_element(Jsonb *jb, Datum *path, int npath, bool *isnull, bool as_text)
+jsonb_get_element(Jsonb *jb, const Datum *path, int npath, bool *isnull, bool as_text)
{
JsonbContainer *container = &jb->root;
JsonbValue *jbvp = NULL;
@@ -1676,7 +1676,7 @@ jsonb_get_element(Jsonb *jb, Datum *path, int npath, bool *isnull, bool as_text)
}
Datum
-jsonb_set_element(Jsonb *jb, Datum *path, int path_len,
+jsonb_set_element(Jsonb *jb, const Datum *path, int path_len,
JsonbValue *newval)
{
JsonbValue *res;
@@ -1718,8 +1718,8 @@ push_null_elements(JsonbParseState **ps, int num)
* Caller is responsible to make sure such path does not exist yet.
*/
static void
-push_path(JsonbParseState **st, int level, Datum *path_elems,
- bool *path_nulls, int path_len, JsonbValue *newval)
+push_path(JsonbParseState **st, int level, const Datum *path_elems,
+ const bool *path_nulls, int path_len, JsonbValue *newval)
{
/*
* tpath contains expected type of an empty jsonb created at each level
@@ -5201,8 +5201,8 @@ IteratorConcat(JsonbIterator **it1, JsonbIterator **it2,
* whatever bits in op_type are set, or nothing is done.
*/
static JsonbValue *
-setPath(JsonbIterator **it, Datum *path_elems,
- bool *path_nulls, int path_len,
+setPath(JsonbIterator **it, const Datum *path_elems,
+ const bool *path_nulls, int path_len,
JsonbParseState **st, int level, JsonbValue *newval, int op_type)
{
JsonbValue v;
@@ -5283,7 +5283,7 @@ setPath(JsonbIterator **it, Datum *path_elems,
* Object walker for setPath
*/
static void
-setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
+setPathObject(JsonbIterator **it, const Datum *path_elems, const bool *path_nulls,
int path_len, JsonbParseState **st, int level,
JsonbValue *newval, uint32 npairs, int op_type)
{
@@ -5422,7 +5422,7 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
* Array walker for setPath
*/
static void
-setPathArray(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
+setPathArray(JsonbIterator **it, const Datum *path_elems, const bool *path_nulls,
int path_len, JsonbParseState **st, int level,
JsonbValue *newval, uint32 nelems, int op_type)
{
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/multirangetypes_selfuncs.c b/src/backend/utils/adt/multirangetypes_selfuncs.c
index b87bcf3ea30..21f0205d803 100644
--- a/src/backend/utils/adt/multirangetypes_selfuncs.c
+++ b/src/backend/utils/adt/multirangetypes_selfuncs.c
@@ -49,10 +49,10 @@ static float8 get_position(TypeCacheEntry *typcache, const RangeBound *value,
static float8 get_len_position(double value, double hist1, double hist2);
static float8 get_distance(TypeCacheEntry *typcache, const RangeBound *bound1,
const RangeBound *bound2);
-static int length_hist_bsearch(Datum *length_hist_values,
+static int length_hist_bsearch(const Datum *length_hist_values,
int length_hist_nvalues, double value,
bool equal);
-static double calc_length_hist_frac(Datum *length_hist_values,
+static double calc_length_hist_frac(const Datum *length_hist_values,
int length_hist_nvalues, double length1,
double length2, bool equal);
static double calc_hist_selectivity_contained(TypeCacheEntry *typcache,
@@ -60,14 +60,14 @@ static double calc_hist_selectivity_contained(TypeCacheEntry *typcache,
RangeBound *upper,
const RangeBound *hist_lower,
int hist_nvalues,
- Datum *length_hist_values,
+ const Datum *length_hist_values,
int length_hist_nvalues);
static double calc_hist_selectivity_contains(TypeCacheEntry *typcache,
const RangeBound *lower,
const RangeBound *upper,
const RangeBound *hist_lower,
int hist_nvalues,
- Datum *length_hist_values,
+ const Datum *length_hist_values,
int length_hist_nvalues);
/*
@@ -765,7 +765,7 @@ rbound_bsearch(TypeCacheEntry *typcache, const RangeBound *value, const RangeBou
* given length, returns -1.
*/
static int
-length_hist_bsearch(Datum *length_hist_values, int length_hist_nvalues,
+length_hist_bsearch(const Datum *length_hist_values, int length_hist_nvalues,
double value, bool equal)
{
int lower = -1,
@@ -963,7 +963,7 @@ get_distance(TypeCacheEntry *typcache, const RangeBound *bound1, const RangeBoun
* 'equal' is true).
*/
static double
-calc_length_hist_frac(Datum *length_hist_values, int length_hist_nvalues,
+calc_length_hist_frac(const Datum *length_hist_values, int length_hist_nvalues,
double length1, double length2, bool equal)
{
double frac;
@@ -1131,7 +1131,7 @@ static double
calc_hist_selectivity_contained(TypeCacheEntry *typcache,
const RangeBound *lower, RangeBound *upper,
const RangeBound *hist_lower, int hist_nvalues,
- Datum *length_hist_values, int length_hist_nvalues)
+ const Datum *length_hist_values, int length_hist_nvalues)
{
int i,
upper_index;
@@ -1252,7 +1252,7 @@ static double
calc_hist_selectivity_contains(TypeCacheEntry *typcache,
const RangeBound *lower, const RangeBound *upper,
const RangeBound *hist_lower, int hist_nvalues,
- Datum *length_hist_values, int length_hist_nvalues)
+ const Datum *length_hist_values, int length_hist_nvalues)
{
int i,
lower_index;
diff --git a/src/backend/utils/adt/network_selfuncs.c b/src/backend/utils/adt/network_selfuncs.c
index 940cdafa546..d08f40e0332 100644
--- a/src/backend/utils/adt/network_selfuncs.c
+++ b/src/backend/utils/adt/network_selfuncs.c
@@ -48,17 +48,17 @@ static Selectivity networkjoinsel_inner(Oid operator,
static Selectivity networkjoinsel_semi(Oid operator,
VariableStatData *vardata1, VariableStatData *vardata2);
static Selectivity mcv_population(float4 *mcv_numbers, int mcv_nvalues);
-static Selectivity inet_hist_value_sel(Datum *values, int nvalues,
+static Selectivity inet_hist_value_sel(const Datum *values, int nvalues,
Datum constvalue, int opr_codenum);
static Selectivity inet_mcv_join_sel(Datum *mcv1_values,
float4 *mcv1_numbers, int mcv1_nvalues, Datum *mcv2_values,
float4 *mcv2_numbers, int mcv2_nvalues, Oid operator);
-static Selectivity inet_mcv_hist_sel(Datum *mcv_values, float4 *mcv_numbers,
- int mcv_nvalues, Datum *hist_values, int hist_nvalues,
+static Selectivity inet_mcv_hist_sel(const Datum *mcv_values, float4 *mcv_numbers,
+ int mcv_nvalues, const Datum *hist_values, int hist_nvalues,
int opr_codenum);
-static Selectivity inet_hist_inclusion_join_sel(Datum *hist1_values,
+static Selectivity inet_hist_inclusion_join_sel(const Datum *hist1_values,
int hist1_nvalues,
- Datum *hist2_values, int hist2_nvalues,
+ const Datum *hist2_values, int hist2_nvalues,
int opr_codenum);
static Selectivity inet_semi_join_sel(Datum lhs_value,
bool mcv_exists, Datum *mcv_values, int mcv_nvalues,
@@ -601,7 +601,7 @@ mcv_population(float4 *mcv_numbers, int mcv_nvalues)
* better option than not considering these buckets at all.
*/
static Selectivity
-inet_hist_value_sel(Datum *values, int nvalues, Datum constvalue,
+inet_hist_value_sel(const Datum *values, int nvalues, Datum constvalue,
int opr_codenum)
{
Selectivity match = 0.0;
@@ -702,8 +702,8 @@ inet_mcv_join_sel(Datum *mcv1_values, float4 *mcv1_numbers, int mcv1_nvalues,
* the histogram.
*/
static Selectivity
-inet_mcv_hist_sel(Datum *mcv_values, float4 *mcv_numbers, int mcv_nvalues,
- Datum *hist_values, int hist_nvalues,
+inet_mcv_hist_sel(const Datum *mcv_values, float4 *mcv_numbers, int mcv_nvalues,
+ const Datum *hist_values, int hist_nvalues,
int opr_codenum)
{
Selectivity selec = 0.0;
@@ -739,8 +739,8 @@ inet_mcv_hist_sel(Datum *mcv_values, float4 *mcv_numbers, int mcv_nvalues,
* average? That would at least avoid non-commutative estimation results.
*/
static Selectivity
-inet_hist_inclusion_join_sel(Datum *hist1_values, int hist1_nvalues,
- Datum *hist2_values, int hist2_nvalues,
+inet_hist_inclusion_join_sel(const Datum *hist1_values, int hist1_nvalues,
+ const Datum *hist2_values, int hist2_nvalues,
int opr_codenum)
{
double match = 0.0;
diff --git a/src/backend/utils/adt/orderedsetaggs.c b/src/backend/utils/adt/orderedsetaggs.c
index c41b191be62..2121cc05f28 100644
--- a/src/backend/utils/adt/orderedsetaggs.c
+++ b/src/backend/utils/adt/orderedsetaggs.c
@@ -660,8 +660,8 @@ pct_info_cmp(const void *pa, const void *pb)
*/
static struct pct_info *
setup_pct_info(int num_percentiles,
- Datum *percentiles_datum,
- bool *percentiles_null,
+ const Datum *percentiles_datum,
+ const bool *percentiles_null,
int64 rowcount,
bool continuous)
{
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/rangetypes_selfuncs.c b/src/backend/utils/adt/rangetypes_selfuncs.c
index d126abc5a82..d85252cafb2 100644
--- a/src/backend/utils/adt/rangetypes_selfuncs.c
+++ b/src/backend/utils/adt/rangetypes_selfuncs.c
@@ -46,18 +46,18 @@ static float8 get_position(TypeCacheEntry *typcache, const RangeBound *value,
static float8 get_len_position(double value, double hist1, double hist2);
static float8 get_distance(TypeCacheEntry *typcache, const RangeBound *bound1,
const RangeBound *bound2);
-static int length_hist_bsearch(Datum *length_hist_values,
+static int length_hist_bsearch(const Datum *length_hist_values,
int length_hist_nvalues, double value, bool equal);
-static double calc_length_hist_frac(Datum *length_hist_values,
+static double calc_length_hist_frac(const Datum *length_hist_values,
int length_hist_nvalues, double length1, double length2, bool equal);
static double calc_hist_selectivity_contained(TypeCacheEntry *typcache,
const RangeBound *lower, RangeBound *upper,
const RangeBound *hist_lower, int hist_nvalues,
- Datum *length_hist_values, int length_hist_nvalues);
+ const Datum *length_hist_values, int length_hist_nvalues);
static double calc_hist_selectivity_contains(TypeCacheEntry *typcache,
const RangeBound *lower, const RangeBound *upper,
const RangeBound *hist_lower, int hist_nvalues,
- Datum *length_hist_values, int length_hist_nvalues);
+ const Datum *length_hist_values, int length_hist_nvalues);
/*
* Returns a default selectivity estimate for given operator, when we don't
@@ -654,7 +654,7 @@ rbound_bsearch(TypeCacheEntry *typcache, const RangeBound *value, const RangeBou
* given length, returns -1.
*/
static int
-length_hist_bsearch(Datum *length_hist_values, int length_hist_nvalues,
+length_hist_bsearch(const Datum *length_hist_values, int length_hist_nvalues,
double value, bool equal)
{
int lower = -1,
@@ -852,7 +852,7 @@ get_distance(TypeCacheEntry *typcache, const RangeBound *bound1, const RangeBoun
* 'equal' is true).
*/
static double
-calc_length_hist_frac(Datum *length_hist_values, int length_hist_nvalues,
+calc_length_hist_frac(const Datum *length_hist_values, int length_hist_nvalues,
double length1, double length2, bool equal)
{
double frac;
@@ -1018,7 +1018,7 @@ static double
calc_hist_selectivity_contained(TypeCacheEntry *typcache,
const RangeBound *lower, RangeBound *upper,
const RangeBound *hist_lower, int hist_nvalues,
- Datum *length_hist_values, int length_hist_nvalues)
+ const Datum *length_hist_values, int length_hist_nvalues)
{
int i,
upper_index;
@@ -1139,7 +1139,7 @@ static double
calc_hist_selectivity_contains(TypeCacheEntry *typcache,
const RangeBound *lower, const RangeBound *upper,
const RangeBound *hist_lower, int hist_nvalues,
- Datum *length_hist_values, int length_hist_nvalues)
+ const Datum *length_hist_values, int length_hist_nvalues)
{
int i,
lower_index;
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/tid.c b/src/backend/utils/adt/tid.c
index 39dab3e42df..0cfb0bd3735 100644
--- a/src/backend/utils/adt/tid.c
+++ b/src/backend/utils/adt/tid.c
@@ -42,7 +42,7 @@
#define DELIM ','
#define NTIDARGS 2
-static ItemPointer currtid_for_view(Relation viewrel, ItemPointer tid);
+static ItemPointer currtid_for_view(Relation viewrel, const ItemPointerData *tid);
/* ----------------------------------------------------------------
* tidin
@@ -293,7 +293,7 @@ hashtidextended(PG_FUNCTION_ARGS)
* relation "rel".
*/
static ItemPointer
-currtid_internal(Relation rel, ItemPointer tid)
+currtid_internal(Relation rel, const ItemPointerData *tid)
{
ItemPointer result;
AclResult aclresult;
@@ -335,7 +335,7 @@ currtid_internal(Relation rel, ItemPointer tid)
* correspond to the CTID of a base relation.
*/
static ItemPointer
-currtid_for_view(Relation viewrel, ItemPointer tid)
+currtid_for_view(Relation viewrel, const ItemPointerData *tid)
{
TupleDesc att = RelationGetDescr(viewrel);
RuleLock *rulelock;
diff --git a/src/backend/utils/adt/tsvector_op.c b/src/backend/utils/adt/tsvector_op.c
index 0625da9532f..c752cbe5463 100644
--- a/src/backend/utils/adt/tsvector_op.c
+++ b/src/backend/utils/adt/tsvector_op.c
@@ -75,7 +75,7 @@ static bool TS_execute_locations_recurse(QueryItem *curitem,
void *arg,
TSExecuteCallback chkcond,
List **locations);
-static int tsvector_bsearch(const TSVector tsv, char *lexeme, int lexeme_len);
+static int tsvector_bsearch(const TSVectorData *tsv, char *lexeme, int lexeme_len);
static Datum tsvector_update_trigger(PG_FUNCTION_ARGS, bool config_column);
@@ -83,7 +83,7 @@ static Datum tsvector_update_trigger(PG_FUNCTION_ARGS, bool config_column);
* Order: haspos, len, word, for all positions (pos, weight)
*/
static int
-silly_cmp_tsvector(const TSVector a, const TSVector b)
+silly_cmp_tsvector(const TSVectorData *a, const TSVectorData *b)
{
if (VARSIZE(a) < VARSIZE(b))
return -1;
@@ -95,8 +95,8 @@ silly_cmp_tsvector(const TSVector a, const TSVector b)
return 1;
else
{
- WordEntry *aptr = ARRPTR(a);
- WordEntry *bptr = ARRPTR(b);
+ const WordEntry *aptr = ARRPTR(a);
+ const WordEntry *bptr = ARRPTR(b);
int i = 0;
int res;
@@ -397,9 +397,9 @@ add_pos(TSVector src, WordEntry *srcptr,
* found.
*/
static int
-tsvector_bsearch(const TSVector tsv, char *lexeme, int lexeme_len)
+tsvector_bsearch(const TSVectorData *tsv, char *lexeme, int lexeme_len)
{
- WordEntry *arrin = ARRPTR(tsv);
+ const WordEntry *arrin = ARRPTR(tsv);
int StopLow = 0,
StopHigh = tsv->size,
StopMiddle,
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/adt/xml.c b/src/backend/utils/adt/xml.c
index 66b44183695..35c915573a1 100644
--- a/src/backend/utils/adt/xml.c
+++ b/src/backend/utils/adt/xml.c
@@ -891,8 +891,8 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
xmltype *
xmlelement(XmlExpr *xexpr,
- Datum *named_argvalue, bool *named_argnull,
- Datum *argvalue, bool *argnull)
+ const Datum *named_argvalue, const bool *named_argnull,
+ const Datum *argvalue, const bool *argnull)
{
#ifdef USE_LIBXML
xmltype *result;
diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 509d9c6c7b4..30ac1bd91be 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -117,10 +117,10 @@ static CatCTup *CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp,
static void ReleaseCatCacheWithOwner(HeapTuple tuple, ResourceOwner resowner);
static void ReleaseCatCacheListWithOwner(CatCList *list, ResourceOwner resowner);
-static void CatCacheFreeKeys(TupleDesc tupdesc, int nkeys, int *attnos,
- Datum *keys);
-static void CatCacheCopyKeys(TupleDesc tupdesc, int nkeys, int *attnos,
- Datum *srckeys, Datum *dstkeys);
+static void CatCacheFreeKeys(TupleDesc tupdesc, int nkeys, const int *attnos,
+ const Datum *keys);
+static void CatCacheCopyKeys(TupleDesc tupdesc, int nkeys, const int *attnos,
+ const Datum *srckeys, Datum *dstkeys);
/*
@@ -2279,7 +2279,7 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments,
* Helper routine that frees keys stored in the keys array.
*/
static void
-CatCacheFreeKeys(TupleDesc tupdesc, int nkeys, int *attnos, Datum *keys)
+CatCacheFreeKeys(TupleDesc tupdesc, int nkeys, const int *attnos, const Datum *keys)
{
int i;
@@ -2301,8 +2301,8 @@ CatCacheFreeKeys(TupleDesc tupdesc, int nkeys, int *attnos, Datum *keys)
* context.
*/
static void
-CatCacheCopyKeys(TupleDesc tupdesc, int nkeys, int *attnos,
- Datum *srckeys, Datum *dstkeys)
+CatCacheCopyKeys(TupleDesc tupdesc, int nkeys, const int *attnos,
+ const Datum *srckeys, Datum *dstkeys)
{
int i;
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/backend/utils/mmgr/aset.c b/src/backend/utils/mmgr/aset.c
index d5ae1bdd3cd..bcd09c07533 100644
--- a/src/backend/utils/mmgr/aset.c
+++ b/src/backend/utils/mmgr/aset.c
@@ -1668,9 +1668,9 @@ AllocSetCheck(MemoryContext context)
prevblock = block, block = block->next)
{
char *bpoz = ((char *) block) + ALLOC_BLOCKHDRSZ;
- long blk_used = block->freeptr - bpoz;
- long blk_data = 0;
- long nchunks = 0;
+ Size blk_used = block->freeptr - bpoz;
+ Size blk_data = 0;
+ Size nchunks = 0;
bool has_external_chunk = false;
if (IsKeeperBlock(set, block))
diff --git a/src/backend/utils/sort/tuplesortvariants.c b/src/backend/utils/sort/tuplesortvariants.c
index 890cdbe1204..41ac4afbf49 100644
--- a/src/backend/utils/sort/tuplesortvariants.c
+++ b/src/backend/utils/sort/tuplesortvariants.c
@@ -816,7 +816,7 @@ tuplesort_putheaptuple(Tuplesortstate *state, HeapTuple tup)
*/
void
tuplesort_putindextuplevalues(Tuplesortstate *state, Relation rel,
- ItemPointer self, const Datum *values,
+ const ItemPointerData *self, const Datum *values,
const bool *isnull)
{
SortTuple stup;