>From 89f0348747b356eaccf5edc2f85bf47d0a35c4f4 Mon Sep 17 00:00:00 2001
From: Oskari Saarenmaa <os@ohmu.fi>
Date: Fri, 20 Dec 2013 18:38:10 +0200
Subject: [PATCH] Make various variables read-only (const)

This allows the variables to be moved from .data to .rodata section which
means that more data can be shared by processes and makes sure that nothing
can accidentally overwrite the read-only definitions.  On a x86-64 Linux
system this moves roughly 9 kilobytes of previously writable data to the
read-only data segment in the backend and 4 kilobytes in libpq.
---
 src/backend/access/common/reloptions.c | 31 ++++------------
 src/backend/catalog/objectaddress.c    |  4 +-
 src/backend/commands/conversioncmds.c  |  2 +-
 src/backend/commands/createas.c        |  3 +-
 src/backend/commands/tablecmds.c       |  8 ++--
 src/backend/optimizer/path/costsize.c  |  2 +-
 src/backend/regex/regc_lex.c           |  4 +-
 src/backend/regex/regcomp.c            |  2 +-
 src/backend/regex/regerror.c           |  6 +--
 src/backend/tcop/utility.c             |  3 +-
 src/backend/tsearch/wparser_def.c      |  4 +-
 src/backend/utils/adt/datetime.c       |  6 +--
 src/backend/utils/adt/formatting.c     | 67 +++++++++++++++-------------------
 src/backend/utils/adt/tsrank.c         | 16 ++++----
 src/backend/utils/mb/encnames.c        | 31 ++++++++--------
 src/backend/utils/mb/mbutils.c         |  8 ++--
 src/backend/utils/mb/wchar.c           |  2 +-
 src/common/relpath.c                   |  8 ++--
 src/include/access/reloptions.h        |  5 +--
 src/include/common/relpath.h           |  3 +-
 src/include/mb/pg_wchar.h              | 18 ++++-----
 src/include/optimizer/cost.h           |  2 +-
 src/include/utils/datetime.h           |  2 +
 src/port/chklocale.c                   |  8 ++--
 24 files changed, 108 insertions(+), 137 deletions(-)

diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c
index 31941e9..5ec617b 100644
--- a/src/backend/access/common/reloptions.c
+++ b/src/backend/access/common/reloptions.c
@@ -564,18 +564,17 @@ add_string_reloption(bits32 kinds, char *name, char *desc, char *default_val,
  * If ignoreOids is true, then we should ignore any occurrence of "oids"
  * in the list (it will be or has been handled by interpretOidsOption()).
  *
- * Note that this is not responsible for determining whether the options
- * are valid, but it does check that namespaces for all the options given are
- * listed in validnsps.  The NULL namespace is always valid and need not be
- * explicitly listed.  Passing a NULL pointer means that only the NULL
- * namespace is valid.
+ * Note that this is not responsible for determining whether the options are
+ * valid, but it does check that namespaces for all the options given
+ * matches validnsp.  The NULL namespace is always valid.  Passing a NULL
+ * valinsp means that only the NULL namespace is valid.
  *
  * Both oldOptions and the result are text arrays (or NULL for "default"),
  * but we declare them as Datums to avoid including array.h in reloptions.h.
  */
 Datum
-transformRelOptions(Datum oldOptions, List *defList, char *namspace,
-					char *validnsps[], bool ignoreOids, bool isReset)
+transformRelOptions(Datum oldOptions, List *defList, const char *namspace,
+					const char *validnsp, bool ignoreOids, bool isReset)
 {
 	Datum		result;
 	ArrayBuildState *astate;
@@ -667,23 +666,7 @@ transformRelOptions(Datum oldOptions, List *defList, char *namspace,
 			 */
 			if (def->defnamespace != NULL)
 			{
-				bool		valid = false;
-				int			i;
-
-				if (validnsps)
-				{
-					for (i = 0; validnsps[i]; i++)
-					{
-						if (pg_strcasecmp(def->defnamespace,
-										  validnsps[i]) == 0)
-						{
-							valid = true;
-							break;
-						}
-					}
-				}
-
-				if (!valid)
+				if (!validnsp || pg_strcasecmp(def->defnamespace, validnsp))
 					ereport(ERROR,
 							(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 							 errmsg("unrecognized parameter namespace \"%s\"",
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index 9011190..dce69c7 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -81,7 +81,7 @@
  * This array provides a common part of system object structure; to help
  * consolidate routines to handle various kind of object classes.
  */
-typedef struct
+typedef const struct
 {
 	Oid			class_oid;		/* oid of catalog */
 	Oid			oid_index_oid;	/* oid of index on system oid column */
@@ -101,7 +101,7 @@ typedef struct
 										 * class? */
 } ObjectPropertyType;
 
-static ObjectPropertyType ObjectProperty[] =
+static const ObjectPropertyType ObjectProperty[] =
 {
 	{
 		CastRelationId,
diff --git a/src/backend/commands/conversioncmds.c b/src/backend/commands/conversioncmds.c
index 84ab434..3938106 100644
--- a/src/backend/commands/conversioncmds.c
+++ b/src/backend/commands/conversioncmds.c
@@ -46,7 +46,7 @@ CreateConversionCommand(CreateConversionStmt *stmt)
 	const char *from_encoding_name = stmt->for_encoding_name;
 	const char *to_encoding_name = stmt->to_encoding_name;
 	List	   *func_name = stmt->func_name;
-	static Oid	funcargs[] = {INT4OID, INT4OID, CSTRINGOID, INTERNALOID, INT4OID};
+	static const Oid	funcargs[] = {INT4OID, INT4OID, CSTRINGOID, INTERNALOID, INT4OID};
 	char		result[1];
 
 	/* Convert list of names to a name and namespace */
diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c
index 9c1fd2c..7cbacf6 100644
--- a/src/backend/commands/createas.c
+++ b/src/backend/commands/createas.c
@@ -264,7 +264,6 @@ intorel_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
 	Datum		toast_options;
 	ListCell   *lc;
 	int			attnum;
-	static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
 
 	Assert(into != NULL);		/* else somebody forgot to set it */
 
@@ -368,7 +367,7 @@ intorel_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
 	toast_options = transformRelOptions((Datum) 0,
 										create->options,
 										"toast",
-										validnsps,
+										"toast",
 										true, false);
 
 	(void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true);
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index b9cd88d..e1aa759 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -448,7 +448,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId)
 	Datum		reloptions;
 	ListCell   *listptr;
 	AttrNumber	attnum;
-	static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
 	Oid			ofTypeId;
 
 	/*
@@ -529,7 +528,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId)
 	/*
 	 * Parse and validate reloptions, if any.
 	 */
-	reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps,
+	reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, "toast",
 									 true, false);
 
 	(void) heap_reloptions(relkind, reloptions, true);
@@ -8745,7 +8744,6 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation,
 	Datum		repl_val[Natts_pg_class];
 	bool		repl_null[Natts_pg_class];
 	bool		repl_repl[Natts_pg_class];
-	static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
 
 	if (defList == NIL && operation != AT_ReplaceRelOptions)
 		return;					/* nothing to do */
@@ -8776,7 +8774,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation,
 
 	/* Generate new proposed reloptions (text array) */
 	newOptions = transformRelOptions(isnull ? (Datum) 0 : datum,
-									 defList, NULL, validnsps, false,
+									 defList, NULL, "toast", false,
 									 operation == AT_ResetRelOptions);
 
 	/* Validate */
@@ -8894,7 +8892,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation,
 		}
 
 		newOptions = transformRelOptions(isnull ? (Datum) 0 : datum,
-										 defList, "toast", validnsps, false,
+										 defList, "toast", "toast", false,
 										 operation == AT_ResetRelOptions);
 
 		(void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true);
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index 50f0852..95fc427 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -104,7 +104,7 @@ double		cpu_operator_cost = DEFAULT_CPU_OPERATOR_COST;
 
 int			effective_cache_size = -1;
 
-Cost		disable_cost = 1.0e10;
+const Cost		disable_cost = 1.0e10;
 
 bool		enable_seqscan = true;
 bool		enable_indexscan = true;
diff --git a/src/backend/regex/regc_lex.c b/src/backend/regex/regc_lex.c
index 3360cfb..7f03df1 100644
--- a/src/backend/regex/regc_lex.c
+++ b/src/backend/regex/regc_lex.c
@@ -716,10 +716,10 @@ static int						/* not actually used, but convenient for RETV */
 lexescape(struct vars * v)
 {
 	chr			c;
-	static chr	alert[] = {
+	static const chr	alert[] = {
 		CHR('a'), CHR('l'), CHR('e'), CHR('r'), CHR('t')
 	};
-	static chr	esc[] = {
+	static const chr	esc[] = {
 		CHR('E'), CHR('S'), CHR('C')
 	};
 	const chr  *save;
diff --git a/src/backend/regex/regcomp.c b/src/backend/regex/regcomp.c
index b5988a2..ca1ccc5 100644
--- a/src/backend/regex/regcomp.c
+++ b/src/backend/regex/regcomp.c
@@ -274,7 +274,7 @@ struct vars
 
 
 /* static function list */
-static struct fns functions = {
+static const struct fns functions = {
 	rfree,						/* regfree insides */
 };
 
diff --git a/src/backend/regex/regerror.c b/src/backend/regex/regerror.c
index f6a3f26..4b2573e 100644
--- a/src/backend/regex/regerror.c
+++ b/src/backend/regex/regerror.c
@@ -34,10 +34,10 @@
 #include "regex/regguts.h"
 
 /* unknown-error explanation */
-static char unk[] = "*** unknown regex error code 0x%x ***";
+static const char unk[] = "*** unknown regex error code 0x%x ***";
 
 /* struct to map among codes, code names, and explanations */
-static struct rerr
+static const struct rerr
 {
 	int			code;
 	const char *name;
@@ -62,7 +62,7 @@ pg_regerror(int errcode,		/* error code, or REG_ATOI or REG_ITOA */
 			char *errbuf,		/* result buffer (unless errbuf_size==0) */
 			size_t errbuf_size) /* available space in errbuf, can be 0 */
 {
-	struct rerr *r;
+	const struct rerr *r;
 	const char *msg;
 	char		convbuf[sizeof(unk) + 50];		/* 50 = plenty for int */
 	size_t		len;
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index dca4503..10ba5a2 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -937,7 +937,6 @@ ProcessUtilitySlow(Node *parsetree,
 						if (IsA(stmt, CreateStmt))
 						{
 							Datum		toast_options;
-							static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
 
 							/* Create the table itself */
 							relOid = DefineRelation((CreateStmt *) stmt,
@@ -957,7 +956,7 @@ ProcessUtilitySlow(Node *parsetree,
 							toast_options = transformRelOptions((Datum) 0,
 											  ((CreateStmt *) stmt)->options,
 																"toast",
-																validnsps,
+																"toast",
 																true,
 																false);
 							(void) heap_reloptions(RELKIND_TOASTVALUE,
diff --git a/src/backend/tsearch/wparser_def.c b/src/backend/tsearch/wparser_def.c
index cb2f8eb..f822abe 100644
--- a/src/backend/tsearch/wparser_def.c
+++ b/src/backend/tsearch/wparser_def.c
@@ -789,7 +789,7 @@ p_isspecial(TParser *prs)
 	 */
 	if (GetDatabaseEncoding() == PG_UTF8 && prs->usewide)
 	{
-		static pg_wchar strange_letter[] = {
+		static const pg_wchar strange_letter[] = {
 			/*
 			 * use binary search, so elements should be ordered
 			 */
@@ -1023,7 +1023,7 @@ p_isspecial(TParser *prs)
 			0xAA34,				/* CHAM CONSONANT SIGN RA */
 			0xAA4D				/* CHAM CONSONANT SIGN FINAL H */
 		};
-		pg_wchar   *StopLow = strange_letter,
+		const pg_wchar   *StopLow = strange_letter,
 				   *StopHigh = strange_letter + lengthof(strange_letter),
 				   *StopMiddle;
 		pg_wchar	c;
diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c
index 1c8291c..c43d419 100644
--- a/src/backend/utils/adt/datetime.c
+++ b/src/backend/utils/adt/datetime.c
@@ -59,10 +59,10 @@ const int	day_tab[2][13] =
 	{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0}
 };
 
-char	   *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
+const char	   *const months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL};
 
-char	   *days[] = {"Sunday", "Monday", "Tuesday", "Wednesday",
+const char	   *const days[] = {"Sunday", "Monday", "Tuesday", "Wednesday",
 "Thursday", "Friday", "Saturday", NULL};
 
 
@@ -186,7 +186,7 @@ static const datetkn datetktbl[] = {
 
 static int	szdatetktbl = sizeof datetktbl / sizeof datetktbl[0];
 
-static datetkn deltatktbl[] = {
+static const datetkn deltatktbl[] = {
 	/* text, token, lexval */
 	{"@", IGNORE_DTF, 0},		/* postgres relative prefix */
 	{DAGO, AGO, 0},				/* "ago" indicates negative time offset */
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 946f3e2..5e58571 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -122,13 +122,6 @@
 
 
 /* ----------
- * External (defined in PgSQL datetime.c (timestamp utils))
- * ----------
- */
-extern char *months[],			/* month abbreviation	*/
-		   *days[];				/* full days		*/
-
-/* ----------
  * Format parser structs
  * ----------
  */
@@ -188,12 +181,12 @@ struct FormatNode
  * Full months
  * ----------
  */
-static char *months_full[] = {
+static const char *const months_full[] = {
 	"January", "February", "March", "April", "May", "June", "July",
 	"August", "September", "October", "November", "December", NULL
 };
 
-static char *days_short[] = {
+static const char *const days_short[] = {
 	"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL
 };
 
@@ -226,8 +219,8 @@ static char *days_short[] = {
  * matches for BC have an odd index.  So the boolean value for BC is given by
  * taking the array index of the match, modulo 2.
  */
-static char *adbc_strings[] = {ad_STR, bc_STR, AD_STR, BC_STR, NULL};
-static char *adbc_strings_long[] = {a_d_STR, b_c_STR, A_D_STR, B_C_STR, NULL};
+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
@@ -253,8 +246,8 @@ static char *adbc_strings_long[] = {a_d_STR, b_c_STR, A_D_STR, B_C_STR, NULL};
  * matches for PM have an odd index.  So the boolean value for PM is given by
  * taking the array index of the match, modulo 2.
  */
-static char *ampm_strings[] = {am_STR, pm_STR, AM_STR, PM_STR, NULL};
-static char *ampm_strings_long[] = {a_m_STR, p_m_STR, A_M_STR, P_M_STR, NULL};
+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
@@ -262,26 +255,26 @@ static char *ampm_strings_long[] = {a_m_STR, p_m_STR, A_M_STR, P_M_STR, NULL};
  *	'VIII' must have higher precedence than 'V')
  * ----------
  */
-static char *rm_months_upper[] =
+static const char *const rm_months_upper[] =
 {"XII", "XI", "X", "IX", "VIII", "VII", "VI", "V", "IV", "III", "II", "I", NULL};
 
-static char *rm_months_lower[] =
+static const char *const rm_months_lower[] =
 {"xii", "xi", "x", "ix", "viii", "vii", "vi", "v", "iv", "iii", "ii", "i", NULL};
 
 /* ----------
  * Roman numbers
  * ----------
  */
-static char *rm1[] = {"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", NULL};
-static char *rm10[] = {"X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC", NULL};
-static char *rm100[] = {"C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM", NULL};
+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};
+static const char *const rm100[] = {"C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM", NULL};
 
 /* ----------
  * Ordinal postfixes
  * ----------
  */
-static char *numTH[] = {"ST", "ND", "RD", "TH", NULL};
-static char *numth[] = {"st", "nd", "rd", "th", NULL};
+static const char *const numTH[] = {"ST", "ND", "RD", "TH", NULL};
+static const char *const numth[] = {"st", "nd", "rd", "th", NULL};
 
 /* ----------
  * Flags & Options:
@@ -525,7 +518,7 @@ do { \
  * Suffixes definition for DATE-TIME TO/FROM CHAR
  * ----------
  */
-static KeySuffix DCH_suff[] = {
+static const KeySuffix DCH_suff[] = {
 	{"FM", 2, DCH_S_FM, SUFFTYPE_PREFIX},
 	{"fm", 2, DCH_S_FM, SUFFTYPE_PREFIX},
 	{"TM", 2, DCH_S_TM, SUFFTYPE_PREFIX},
@@ -950,10 +943,10 @@ typedef struct NUMProc
  */
 static const KeyWord *index_seq_search(char *str, const KeyWord *kw,
 				 const int *index);
-static KeySuffix *suff_search(char *str, KeySuffix *suf, int type);
+static const KeySuffix *suff_search(char *str, const KeySuffix *suf, int type);
 static void NUMDesc_prepare(NUMDesc *num, FormatNode *n);
 static void parse_format(FormatNode *node, char *str, const KeyWord *kw,
-			 KeySuffix *suf, const int *index, int ver, NUMDesc *Num);
+			 const KeySuffix *suf, const int *index, int ver, NUMDesc *Num);
 
 static void DCH_to_char(FormatNode *node, bool is_interval,
 			TmToChar *in, char *out, Oid collid);
@@ -964,7 +957,7 @@ static void dump_index(const KeyWord *k, const int *index);
 static void dump_node(FormatNode *node, int max);
 #endif
 
-static char *get_th(char *num, int type);
+static const char *get_th(char *num, int type);
 static char *str_numth(char *dest, char *num, int type);
 static int	adjust_partial_year_to_2020(int year);
 static int	strspace_len(char *str);
@@ -973,8 +966,8 @@ static void from_char_set_mode(TmFromChar *tmfc, const FromCharDateMode mode);
 static void from_char_set_int(int *dest, const int value, const FormatNode *node);
 static int	from_char_parse_int_len(int *dest, char **src, const int len, FormatNode *node);
 static int	from_char_parse_int(int *dest, char **src, FormatNode *node);
-static int	seq_search(char *name, char **array, int type, int max, int *len);
-static int	from_char_seq_search(int *dest, char **src, char **array, int type, int max, FormatNode *node);
+static int	seq_search(char *name, const char *const *array, int type, int max, int *len);
+static int	from_char_seq_search(int *dest, char **src, const char *const *array, int type, int max, FormatNode *node);
 static void do_to_timestamp(text *date_txt, text *fmt,
 				struct pg_tm * tm, fsec_t *fsec);
 static char *fill_str(char *str, int c, int max);
@@ -1024,10 +1017,10 @@ index_seq_search(char *str, const KeyWord *kw, const int *index)
 	return NULL;
 }
 
-static KeySuffix *
-suff_search(char *str, KeySuffix *suf, int type)
+static const KeySuffix *
+suff_search(char *str, const KeySuffix *suf, int type)
 {
-	KeySuffix  *s;
+	const KeySuffix  *s;
 
 	for (s = suf; s->name != NULL; s++)
 	{
@@ -1237,9 +1230,9 @@ NUMDesc_prepare(NUMDesc *num, FormatNode *n)
  */
 static void
 parse_format(FormatNode *node, char *str, const KeyWord *kw,
-			 KeySuffix *suf, const int *index, int ver, NUMDesc *Num)
+			 const KeySuffix *suf, const int *index, int ver, NUMDesc *Num)
 {
-	KeySuffix  *s;
+	const KeySuffix  *s;
 	FormatNode *n;
 	int			node_set = 0,
 				suffix,
@@ -1401,7 +1394,7 @@ dump_node(FormatNode *node, int max)
  * type --> 0 upper, 1 lower
  * ----------
  */
-static char *
+static const char *
 get_th(char *num, int type)
 {
 	int			len = strlen(num),
@@ -2268,11 +2261,11 @@ from_char_parse_int(int *dest, char **src, FormatNode *node)
  * ----------
  */
 static int
-seq_search(char *name, char **array, int type, int max, int *len)
+seq_search(char *name, const char *const *array, int type, int max, int *len)
 {
-	char	   *p,
-			   *n,
-			  **a;
+	const char		*p,
+				*const *a;
+	char			*n;
 	int			last,
 				i;
 
@@ -2346,7 +2339,7 @@ seq_search(char *name, char **array, int type, int max, int *len)
  * If the string doesn't match, throw an error.
  */
 static int
-from_char_seq_search(int *dest, char **src, char **array, int type, int max,
+from_char_seq_search(int *dest, char **src, const char *const *array, int type, int max,
 					 FormatNode *node)
 {
 	int			len;
diff --git a/src/backend/utils/adt/tsrank.c b/src/backend/utils/adt/tsrank.c
index 1dbe47e..cb6112a 100644
--- a/src/backend/utils/adt/tsrank.c
+++ b/src/backend/utils/adt/tsrank.c
@@ -20,7 +20,7 @@
 #include "miscadmin.h"
 
 
-static float weights[] = {0.1f, 0.2f, 0.4f, 1.0f};
+static const float weights[] = {0.1f, 0.2f, 0.4f, 1.0f};
 
 #define wpos(wep)	( w[ WEP_GETWEIGHT(wep) ] )
 
@@ -33,8 +33,8 @@ static float weights[] = {0.1f, 0.2f, 0.4f, 1.0f};
 #define RANK_NORM_RDIVRPLUS1	0x20
 #define DEF_NORM_METHOD			RANK_NO_NORM
 
-static float calc_rank_or(float *w, TSVector t, TSQuery q);
-static float calc_rank_and(float *w, TSVector t, TSQuery q);
+static float calc_rank_or(const float *w, TSVector t, TSQuery q);
+static float calc_rank_and(const float *w, TSVector t, TSQuery q);
 
 /*
  * Returns a weight of a word collocation
@@ -202,7 +202,7 @@ static WordEntryPosVector POSNULL = {
 };
 
 static float
-calc_rank_and(float *w, TSVector t, TSQuery q)
+calc_rank_and(const float *w, TSVector t, TSQuery q)
 {
 	WordEntryPosVector **pos;
 	int			i,
@@ -278,7 +278,7 @@ calc_rank_and(float *w, TSVector t, TSQuery q)
 }
 
 static float
-calc_rank_or(float *w, TSVector t, TSQuery q)
+calc_rank_or(const float *w, TSVector t, TSQuery q)
 {
 	WordEntry  *entry,
 			   *firstentry;
@@ -347,7 +347,7 @@ calc_rank_or(float *w, TSVector t, TSQuery q)
 }
 
 static float
-calc_rank(float *w, TSVector t, TSQuery q, int32 method)
+calc_rank(const float *w, TSVector t, TSQuery q, int32 method)
 {
 	QueryItem  *item = GETQUERY(q);
 	float		res = 0.0;
@@ -387,7 +387,7 @@ calc_rank(float *w, TSVector t, TSQuery q, int32 method)
 	return res;
 }
 
-static float *
+static const float *
 getWeights(ArrayType *win)
 {
 	static float ws[lengthof(weights)];
@@ -723,7 +723,7 @@ get_docrep(TSVector txt, QueryRepresentation *qr, int *doclen)
 }
 
 static float4
-calc_rank_cd(float4 *arrdata, TSVector txt, TSQuery query, int method)
+calc_rank_cd(const float4 *arrdata, TSVector txt, TSQuery query, int method)
 {
 	DocRepresentation *doc;
 	int			len,
diff --git a/src/backend/utils/mb/encnames.c b/src/backend/utils/mb/encnames.c
index 772d4a5..23b2215 100644
--- a/src/backend/utils/mb/encnames.c
+++ b/src/backend/utils/mb/encnames.c
@@ -29,7 +29,7 @@
  * Karel Zak, Aug 2001
  * ----------
  */
-pg_encname	pg_encname_tbl[] =
+const pg_encname	pg_encname_tbl[] =
 {
 	{
 		"abc", PG_WIN1258
@@ -285,14 +285,11 @@ pg_encname	pg_encname_tbl[] =
 	},							/* alias for UHC */
 	{
 		"windows950", PG_BIG5
-	},							/* alias for BIG5 */
-	{
-		NULL, 0
-	}							/* last */
+	}							/* alias for BIG5 */
 };
 
-unsigned int pg_encname_tbl_sz = \
-sizeof(pg_encname_tbl) / sizeof(pg_encname_tbl[0]) - 1;
+const unsigned int pg_encname_tbl_sz = \
+sizeof(pg_encname_tbl) / sizeof(pg_encname_tbl[0]);
 
 /* ----------
  * These are "official" encoding names.
@@ -300,11 +297,15 @@ sizeof(pg_encname_tbl) / sizeof(pg_encname_tbl[0]) - 1;
  * ----------
  */
 #ifndef WIN32
-#define DEF_ENC2NAME(name, codepage) { #name, PG_##name }
+/* The extra NUL-terminator will make sure a warning is raised if the
+ * storage space for name is too small, otherwise when strlen(name) ==
+ * sizeof(pg_enc2name.name) the NUL-terminator would be silently dropped.
+ */
+#define DEF_ENC2NAME(name, codepage) { #name "\0", PG_##name }
 #else
 #define DEF_ENC2NAME(name, codepage) { #name, PG_##name, codepage }
 #endif
-pg_enc2name pg_enc2name_tbl[] =
+const pg_enc2name pg_enc2name_tbl[] =
 {
 	DEF_ENC2NAME(SQL_ASCII, 0),
 	DEF_ENC2NAME(EUC_JP, 20932),
@@ -356,7 +357,7 @@ pg_enc2name pg_enc2name_tbl[] =
  * This covers all encodings except MULE_INTERNAL, which is alien to gettext.
  * ----------
  */
-pg_enc2gettext pg_enc2gettext_tbl[] =
+const pg_enc2gettext pg_enc2gettext_tbl[] =
 {
 	{PG_SQL_ASCII, "US-ASCII"},
 	{PG_UTF8, "UTF-8"},
@@ -399,7 +400,7 @@ pg_enc2gettext pg_enc2gettext_tbl[] =
 	{PG_GB18030, "GB18030"},
 	{PG_JOHAB, "JOHAB"},
 	{PG_SHIFT_JIS_2004, "SHIFT_JISX0213"},
-	{0, NULL}
+	{0, ""}
 };
 
 
@@ -469,11 +470,11 @@ clean_encoding_name(const char *key, char *newkey)
  * Search encoding by encoding name
  * ----------
  */
-pg_encname *
+const pg_encname *
 pg_char_to_encname_struct(const char *name)
 {
 	unsigned int nel = pg_encname_tbl_sz;
-	pg_encname *base = pg_encname_tbl,
+	const pg_encname *base = pg_encname_tbl,
 			   *last = base + nel - 1,
 			   *position;
 	int			result;
@@ -521,7 +522,7 @@ pg_char_to_encname_struct(const char *name)
 int
 pg_char_to_encoding(const char *name)
 {
-	pg_encname *p;
+	const pg_encname *p;
 
 	if (!name)
 		return -1;
@@ -545,7 +546,7 @@ pg_encoding_to_char(int encoding)
 {
 	if (PG_VALID_ENCODING(encoding))
 	{
-		pg_enc2name *p = &pg_enc2name_tbl[encoding];
+		const pg_enc2name *p = &pg_enc2name_tbl[encoding];
 
 		Assert(encoding == p->encoding);
 		return p->name;
diff --git a/src/backend/utils/mb/mbutils.c b/src/backend/utils/mb/mbutils.c
index 6d1cd8e..bb5d63b 100644
--- a/src/backend/utils/mb/mbutils.c
+++ b/src/backend/utils/mb/mbutils.c
@@ -55,9 +55,9 @@ static FmgrInfo *ToClientConvProc = NULL;
 /*
  * These variables track the currently-selected encodings.
  */
-static pg_enc2name *ClientEncoding = &pg_enc2name_tbl[PG_SQL_ASCII];
-static pg_enc2name *DatabaseEncoding = &pg_enc2name_tbl[PG_SQL_ASCII];
-static pg_enc2name *MessageEncoding = &pg_enc2name_tbl[PG_SQL_ASCII];
+static const pg_enc2name *ClientEncoding = &pg_enc2name_tbl[PG_SQL_ASCII];
+static const pg_enc2name *DatabaseEncoding = &pg_enc2name_tbl[PG_SQL_ASCII];
+static const pg_enc2name *MessageEncoding = &pg_enc2name_tbl[PG_SQL_ASCII];
 
 /*
  * During backend startup we can't set client encoding because we (a)
@@ -903,7 +903,7 @@ raw_pg_bind_textdomain_codeset(const char *domainname, int encoding)
 	bool		elog_ok = (CurrentMemoryContext != NULL);
 	int			i;
 
-	for (i = 0; pg_enc2gettext_tbl[i].name != NULL; i++)
+	for (i = 0; *pg_enc2gettext_tbl[i].name; i++)
 	{
 		if (pg_enc2gettext_tbl[i].encoding == encoding)
 		{
diff --git a/src/backend/utils/mb/wchar.c b/src/backend/utils/mb/wchar.c
index 45bc3c1..6d03a10 100644
--- a/src/backend/utils/mb/wchar.c
+++ b/src/backend/utils/mb/wchar.c
@@ -1720,7 +1720,7 @@ pg_eucjp_increment(unsigned char *charptr, int length)
  * XXX must be sorted by the same order as enum pg_enc (in mb/pg_wchar.h)
  *-------------------------------------------------------------------
  */
-pg_wchar_tbl pg_wchar_table[] = {
+const pg_wchar_tbl pg_wchar_table[] = {
 	{pg_ascii2wchar_with_len, pg_wchar2single_with_len, pg_ascii_mblen, pg_ascii_dsplen, pg_ascii_verifier, 1}, /* PG_SQL_ASCII */
 	{pg_eucjp2wchar_with_len, pg_wchar2euc_with_len, pg_eucjp_mblen, pg_eucjp_dsplen, pg_eucjp_verifier, 3},	/* PG_EUC_JP */
 	{pg_euccn2wchar_with_len, pg_wchar2euc_with_len, pg_euccn_mblen, pg_euccn_dsplen, pg_euccn_verifier, 2},	/* PG_EUC_CN */
diff --git a/src/common/relpath.c b/src/common/relpath.c
index 737003a..177eaf5 100644
--- a/src/common/relpath.c
+++ b/src/common/relpath.c
@@ -20,16 +20,14 @@
 #include "common/relpath.h"
 #include "storage/backendid.h"
 
-#define FORKNAMECHARS	4		/* max chars for a fork name */
-
 /*
  * Lookup table of fork name by fork number.
  *
  * If you add a new entry, remember to update the errhint below, and the
- * documentation for pg_relation_size(). Also keep FORKNAMECHARS above
- * up-to-date.
+ * documentation for pg_relation_size(). Also keep FORKNAMECHARS in
+ * src/include/common/relpath.h up-to-date.
  */
-const char *forkNames[] = {
+const char forkNames[][FORKNAMECHARS+1] = {
 	"main",						/* MAIN_FORKNUM */
 	"fsm",						/* FSM_FORKNUM */
 	"vm",						/* VISIBILITYMAP_FORKNUM */
diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h
index 5a4664b..e02e15a 100644
--- a/src/include/access/reloptions.h
+++ b/src/include/access/reloptions.h
@@ -51,9 +51,6 @@ typedef enum relopt_kind
 	RELOPT_KIND_MAX = (1 << 30)
 } relopt_kind;
 
-/* reloption namespaces allowed for heaps -- currently only TOAST */
-#define HEAP_RELOPT_NAMESPACES { "toast", NULL }
-
 /* generic struct to hold shared data */
 typedef struct relopt_gen
 {
@@ -251,7 +248,7 @@ extern void add_string_reloption(bits32 kinds, char *name, char *desc,
 					 char *default_val, validate_string_relopt validator);
 
 extern Datum transformRelOptions(Datum oldOptions, List *defList,
-					char *namspace, char *validnsps[],
+					const char *namspace, const char *validnsp,
 					bool ignoreOids, bool isReset);
 extern List *untransformRelOptions(Datum options);
 extern bytea *extractRelOptions(HeapTuple tuple, TupleDesc tupdesc,
diff --git a/src/include/common/relpath.h b/src/include/common/relpath.h
index fec7e06..d1001f0 100644
--- a/src/include/common/relpath.h
+++ b/src/include/common/relpath.h
@@ -21,11 +21,12 @@
 #include "storage/relfilenode.h"
 
 
+#define FORKNAMECHARS		4		/* max chars for a fork name */
 #define OIDCHARS		10		/* max chars printed by %u */
 #define TABLESPACE_VERSION_DIRECTORY	"PG_" PG_MAJORVERSION "_" \
 									CppAsString2(CATALOG_VERSION_NO)
 
-extern const char *forkNames[];
+extern const char forkNames[][FORKNAMECHARS+1];
 extern int	forkname_chars(const char *str, ForkNumber *fork);
 extern char *relpathbackend(RelFileNode rnode, BackendId backend,
 			   ForkNumber forknum);
diff --git a/src/include/mb/pg_wchar.h b/src/include/mb/pg_wchar.h
index d255c64..5dc472c 100644
--- a/src/include/mb/pg_wchar.h
+++ b/src/include/mb/pg_wchar.h
@@ -307,12 +307,12 @@ typedef enum pg_enc
  */
 typedef struct pg_encname
 {
-	char	   *name;
+	char		name[16];
 	pg_enc		encoding;
 } pg_encname;
 
-extern pg_encname pg_encname_tbl[];
-extern unsigned int pg_encname_tbl_sz;
+extern const pg_encname pg_encname_tbl[];
+extern const unsigned int pg_encname_tbl_sz;
 
 /*
  * Careful:
@@ -322,14 +322,14 @@ extern unsigned int pg_encname_tbl_sz;
  */
 typedef struct pg_enc2name
 {
-	char	   *name;
+	char		name[16];
 	pg_enc		encoding;
 #ifdef WIN32
 	unsigned	codepage;		/* codepage for WIN32 */
 #endif
 } pg_enc2name;
 
-extern pg_enc2name pg_enc2name_tbl[];
+extern const pg_enc2name pg_enc2name_tbl[];
 
 /*
  * Encoding names for gettext
@@ -337,10 +337,10 @@ extern pg_enc2name pg_enc2name_tbl[];
 typedef struct pg_enc2gettext
 {
 	pg_enc		encoding;
-	const char *name;
+	char		name[16];
 } pg_enc2gettext;
 
-extern pg_enc2gettext pg_enc2gettext_tbl[];
+extern const pg_enc2gettext pg_enc2gettext_tbl[];
 
 /*
  * pg_wchar stuff
@@ -373,7 +373,7 @@ typedef struct
 	int			maxmblen;		/* max bytes for a char in this encoding */
 } pg_wchar_tbl;
 
-extern pg_wchar_tbl pg_wchar_table[];
+extern const pg_wchar_tbl pg_wchar_table[];
 
 /*
  * UTF-8 to local code conversion map
@@ -441,7 +441,7 @@ extern int	pg_valid_server_encoding_id(int encoding);
  * Remaining functions are not considered part of libpq's API, though many
  * of them do exist inside libpq.
  */
-extern pg_encname *pg_char_to_encname_struct(const char *name);
+extern const pg_encname *pg_char_to_encname_struct(const char *name);
 
 extern int	pg_mb2wchar(const char *from, pg_wchar *to);
 extern int	pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len);
diff --git a/src/include/optimizer/cost.h b/src/include/optimizer/cost.h
index 444ab740..756c04c 100644
--- a/src/include/optimizer/cost.h
+++ b/src/include/optimizer/cost.h
@@ -49,7 +49,7 @@ extern PGDLLIMPORT double cpu_tuple_cost;
 extern PGDLLIMPORT double cpu_index_tuple_cost;
 extern PGDLLIMPORT double cpu_operator_cost;
 extern PGDLLIMPORT int effective_cache_size;
-extern Cost disable_cost;
+extern const Cost disable_cost;
 extern bool enable_seqscan;
 extern bool enable_indexscan;
 extern bool enable_indexonlyscan;
diff --git a/src/include/utils/datetime.h b/src/include/utils/datetime.h
index 4e59e44..45e3cec 100644
--- a/src/include/utils/datetime.h
+++ b/src/include/utils/datetime.h
@@ -247,6 +247,8 @@ do { \
  * Include check for leap year.
  */
 
+extern const char *const months[];		/* month abbreviation	*/
+extern const char *const days[];		/* full days		*/
 extern const int day_tab[2][13];
 
 #define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
diff --git a/src/port/chklocale.c b/src/port/chklocale.c
index 3c9d7ab..962575e 100644
--- a/src/port/chklocale.c
+++ b/src/port/chklocale.c
@@ -40,7 +40,7 @@
 struct encoding_match
 {
 	enum pg_enc pg_enc_code;
-	const char *system_enc_name;
+	const char system_enc_name[16];
 };
 
 static const struct encoding_match encoding_match_list[] = {
@@ -185,7 +185,7 @@ static const struct encoding_match encoding_match_list[] = {
 
 	{PG_SQL_ASCII, "US-ASCII"},
 
-	{PG_SQL_ASCII, NULL}		/* end marker */
+	{PG_SQL_ASCII, ""}		/* end marker */
 };
 
 #ifdef WIN32
@@ -251,7 +251,7 @@ pg_codepage_to_encoding(UINT cp)
 	sprintf(sys, "CP%u", cp);
 
 	/* Check the table */
-	for (i = 0; encoding_match_list[i].system_enc_name; i++)
+	for (i = 0; *encoding_match_list[i].system_enc_name; i++)
 		if (pg_strcasecmp(sys, encoding_match_list[i].system_enc_name) == 0)
 			return encoding_match_list[i].pg_enc_code;
 
@@ -347,7 +347,7 @@ pg_get_encoding_from_locale(const char *ctype, bool write_message)
 		return -1;				/* out of memory; unlikely */
 
 	/* Check the table */
-	for (i = 0; encoding_match_list[i].system_enc_name; i++)
+	for (i = 0; *encoding_match_list[i].system_enc_name; i++)
 	{
 		if (pg_strcasecmp(sys, encoding_match_list[i].system_enc_name) == 0)
 		{
-- 
1.8.4.2

