diff options
Diffstat (limited to 'src/backend/utils')
30 files changed, 979 insertions, 1107 deletions
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;  | 
