diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c
index 257c7da8568..4a69a81b9fb 100644
--- a/src/backend/catalog/pg_type.c
+++ b/src/backend/catalog/pg_type.c
@@ -948,7 +948,7 @@ char *
 makeMultirangeTypeName(const char *rangeTypeName, Oid typeNamespace)
 {
 	char	   *buf;
-	char	   *rangestr;
+	const char *rangestr;
 
 	/*
 	 * If the range type name contains "range" then change that to
diff --git a/src/backend/tsearch/spell.c b/src/backend/tsearch/spell.c
index 146801885d7..0dab31f0ddb 100644
--- a/src/backend/tsearch/spell.c
+++ b/src/backend/tsearch/spell.c
@@ -2320,7 +2320,7 @@ CheckCompoundAffixes(CMPDAffix **ptr, const char *word, int len, bool CheckInPla
 	}
 	else
 	{
-		char	   *affbegin;
+		const char *affbegin;
 
 		while ((*ptr)->affix)
 		{
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 5bfeda2ffde..c3cb022a400 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -1046,8 +1046,9 @@ typedef struct NUMProc
 	char	   *number,			/* string with number	*/
 			   *number_p,		/* pointer to current number position */
 			   *inout,			/* in / out buffer	*/
-			   *inout_p,		/* pointer to current inout position */
-			   *last_relevant,	/* last relevant number after decimal point */
+			   *inout_p;		/* pointer to current inout position */
+
+	const char *last_relevant,	/* last relevant number after decimal point */
 
 			   *L_negative_sign,	/* Locale */
 			   *L_positive_sign,
@@ -1118,7 +1119,7 @@ static FormatNode *NUM_cache(int len, NUMDesc *Num, const text *pars_str, bool *
 static char *int_to_roman(int number);
 static int	roman_to_int(NUMProc *Np, size_t input_len);
 static void NUM_prepare_locale(NUMProc *Np);
-static char *get_last_relevant_decnum(const char *num);
+static const 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,
@@ -5297,10 +5298,10 @@ NUM_prepare_locale(NUMProc *Np)
  * If there is no decimal point, return NULL (which will result in same
  * behavior as if FM hadn't been specified).
  */
-static char *
+static const char *
 get_last_relevant_decnum(const char *num)
 {
-	char	   *result,
+	const char *result,
 			   *p = strchr(num, '.');
 
 #ifdef DEBUG_TO_FROM_CHAR
diff --git a/src/backend/utils/adt/xid8funcs.c b/src/backend/utils/adt/xid8funcs.c
index a211a107767..4b3f7a69b3b 100644
--- a/src/backend/utils/adt/xid8funcs.c
+++ b/src/backend/utils/adt/xid8funcs.c
@@ -194,7 +194,7 @@ is_visible_fxid(FullTransactionId value, const pg_snapshot *snap)
 #ifdef USE_BSEARCH_IF_NXIP_GREATER
 	else if (snap->nxip > USE_BSEARCH_IF_NXIP_GREATER)
 	{
-		void	   *res;
+		const void *res;
 
 		res = bsearch(&value, snap->xip, snap->nxip, sizeof(FullTransactionId),
 					  cmp_fxid);
diff --git a/src/bin/pg_waldump/pg_waldump.c b/src/bin/pg_waldump/pg_waldump.c
index c6d6ba79e44..1c1ccf59f65 100644
--- a/src/bin/pg_waldump/pg_waldump.c
+++ b/src/bin/pg_waldump/pg_waldump.c
@@ -160,7 +160,7 @@ create_fullpage_directory(char *path)
 static void
 split_path(const char *path, char **dir, char **fname)
 {
-	char	   *sep;
+	const char *sep;
 
 	/* split filepath into directory & filename */
 	sep = strrchr(path, '/');
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 68774a59efd..00593fab5e1 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -6254,7 +6254,7 @@ findBuiltin(const char *name)
 static int
 parseScriptWeight(const char *option, char **script)
 {
-	char	   *sep;
+	const char *sep;
 	int			weight;
 
 	if ((sep = strrchr(option, WSEP)))
diff --git a/src/common/compression.c b/src/common/compression.c
index 4c3c9fd7b50..eb434542fbd 100644
--- a/src/common/compression.c
+++ b/src/common/compression.c
@@ -425,7 +425,7 @@ validate_compress_specification(pg_compress_specification *spec)
 void
 parse_compress_options(const char *option, char **algorithm, char **detail)
 {
-	char	   *sep;
+	const char *sep;
 	char	   *endp;
 	long		result;
 
diff --git a/src/interfaces/ecpg/pgtypeslib/datetime.c b/src/interfaces/ecpg/pgtypeslib/datetime.c
index 1b253747fc4..f43343b4594 100644
--- a/src/interfaces/ecpg/pgtypeslib/datetime.c
+++ b/src/interfaces/ecpg/pgtypeslib/datetime.c
@@ -335,8 +335,8 @@ PGTYPESdate_defmt_asc(date * d, const char *fmt, const char *str)
 	 */
 	int			token[3][2];
 	int			token_values[3] = {-1, -1, -1};
-	char	   *fmt_token_order;
-	char	   *fmt_ystart,
+	const char *fmt_token_order;
+	const char *fmt_ystart,
 			   *fmt_mstart,
 			   *fmt_dstart;
 	unsigned int i;
diff --git a/src/interfaces/ecpg/preproc/ecpg.trailer b/src/interfaces/ecpg/preproc/ecpg.trailer
index 6f94b832a03..be94ca5bbfa 100644
--- a/src/interfaces/ecpg/preproc/ecpg.trailer
+++ b/src/interfaces/ecpg/preproc/ecpg.trailer
@@ -1975,12 +1975,14 @@ civarind: cvariable indicator
 
 char_civar: char_variable
 	{
-		char	   *ptr = strstr(@1, ".arr");
+		char	   *var = mm_strdup(@1);
+		char	   *ptr = strstr(var, ".arr");
 
 		if (ptr)				/* varchar, we need the struct name here, not
 								 * the struct element */
 			*ptr = '\0';
-		add_variable_to_head(&argsinsert, find_variable(@1), &no_indicator);
+		add_variable_to_head(&argsinsert, find_variable(var), &no_indicator);
+		@$ = var;
 	}
 	;
 
diff --git a/src/interfaces/ecpg/preproc/variable.c b/src/interfaces/ecpg/preproc/variable.c
index 2c67e33e92e..350e780c000 100644
--- a/src/interfaces/ecpg/preproc/variable.c
+++ b/src/interfaces/ecpg/preproc/variable.c
@@ -6,6 +6,19 @@
 
 static struct variable *allvariables = NULL;
 
+/* this probably belongs in util.c, but for now it's only needed here */
+static char *
+mm_nstrdup(const char *in, size_t len)
+{
+	char	   *out;
+
+	out = mm_alloc(len + 1);
+	memcpy(out, in, len);
+	out[len] = '\0';
+
+	return out;
+}
+
 struct variable *
 new_variable(const char *name, struct ECPGtype *type, int brace_level)
 {
@@ -22,17 +35,11 @@ new_variable(const char *name, struct ECPGtype *type, int brace_level)
 }
 
 static struct variable *
-find_struct_member(const char *name, char *str, struct ECPGstruct_member *members, int brace_level)
+find_struct_member(const char *name, const char *str,
+				   struct ECPGstruct_member *members, int brace_level)
 {
-	char	   *next = strpbrk(++str, ".-["),
-			   *end,
-				c = '\0';
-
-	if (next != NULL)
-	{
-		c = *next;
-		*next = '\0';
-	}
+	const char *next = strpbrk(++str, ".-["),
+			   *end;
 
 	for (; members; members = members->next)
 	{
@@ -54,8 +61,7 @@ find_struct_member(const char *name, char *str, struct ECPGstruct_member *member
 			}
 			else
 			{
-				*next = c;
-				if (c == '[')
+				if (*next == '[')
 				{
 					int			count;
 
@@ -123,25 +129,24 @@ find_struct_member(const char *name, char *str, struct ECPGstruct_member *member
 }
 
 static struct variable *
-find_struct(const char *name, char *next, char *end)
+find_struct(const char *name, const char *next, const char *end)
 {
+	char	   *prefix;
 	struct variable *p;
-	char		c = *next;
 
 	/* first get the mother structure entry */
-	*next = '\0';
-	p = find_variable(name);
+	prefix = mm_nstrdup(name, next - name);
+	p = find_variable(prefix);
 
-	if (c == '-')
+	if (*next == '-')
 	{
 		if (p->type->type != ECPGt_array)
-			mmfatal(PARSE_ERROR, "variable \"%s\" is not a pointer", name);
+			mmfatal(PARSE_ERROR, "variable \"%s\" is not a pointer", prefix);
 
 		if (p->type->u.element->type != ECPGt_struct && p->type->u.element->type != ECPGt_union)
-			mmfatal(PARSE_ERROR, "variable \"%s\" is not a pointer to a structure or a union", name);
+			mmfatal(PARSE_ERROR, "variable \"%s\" is not a pointer to a structure or a union", prefix);
 
-		/* restore the name, we will need it later */
-		*next = c;
+		free(prefix);
 
 		return find_struct_member(name, ++end, p->type->u.element->u.members, p->brace_level);
 	}
@@ -150,23 +155,21 @@ find_struct(const char *name, char *next, char *end)
 		if (next == end)
 		{
 			if (p->type->type != ECPGt_struct && p->type->type != ECPGt_union)
-				mmfatal(PARSE_ERROR, "variable \"%s\" is neither a structure nor a union", name);
+				mmfatal(PARSE_ERROR, "variable \"%s\" is neither a structure nor a union", prefix);
 
-			/* restore the name, we will need it later */
-			*next = c;
+			free(prefix);
 
 			return find_struct_member(name, end, p->type->u.members, p->brace_level);
 		}
 		else
 		{
 			if (p->type->type != ECPGt_array)
-				mmfatal(PARSE_ERROR, "variable \"%s\" is not an array", name);
+				mmfatal(PARSE_ERROR, "variable \"%s\" is not an array", prefix);
 
 			if (p->type->u.element->type != ECPGt_struct && p->type->u.element->type != ECPGt_union)
-				mmfatal(PARSE_ERROR, "variable \"%s\" is not a pointer to a structure or a union", name);
+				mmfatal(PARSE_ERROR, "variable \"%s\" is not a pointer to a structure or a union", prefix);
 
-			/* restore the name, we will need it later */
-			*next = c;
+			free(prefix);
 
 			return find_struct_member(name, end, p->type->u.element->u.members, p->brace_level);
 		}
@@ -192,7 +195,7 @@ find_simple(const char *name)
 struct variable *
 find_variable(const char *name)
 {
-	char	   *next,
+	const char *next,
 			   *end;
 	struct variable *p;
 	int			count;
@@ -227,15 +230,14 @@ find_variable(const char *name)
 				p = find_struct(name, next, end);
 			else
 			{
-				char		c = *next;
+				char	   *prefix = mm_nstrdup(name, next - name);
 
-				*next = '\0';
-				p = find_simple(name);
+				p = find_simple(prefix);
 				if (p == NULL)
-					mmfatal(PARSE_ERROR, "variable \"%s\" is not declared", name);
+					mmfatal(PARSE_ERROR, "variable \"%s\" is not declared", prefix);
 				if (p->type->type != ECPGt_array)
-					mmfatal(PARSE_ERROR, "variable \"%s\" is not a pointer", name);
-				*next = c;
+					mmfatal(PARSE_ERROR, "variable \"%s\" is not a pointer", prefix);
+				free(prefix);
 				switch (p->type->u.element->type)
 				{
 					case ECPGt_array:
diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c
index efc41fca2ba..58d41207605 100644
--- a/src/test/regress/pg_regress.c
+++ b/src/test/regress/pg_regress.c
@@ -693,7 +693,7 @@ static
 const char *
 get_expectfile(const char *testname, const char *file)
 {
-	char	   *file_type;
+	const char *file_type;
 	_resultmap *rm;
 
 	/*
diff --git a/src/timezone/zic.c b/src/timezone/zic.c
index a8c1de9910d..8dcc7b337a7 100644
--- a/src/timezone/zic.c
+++ b/src/timezone/zic.c
@@ -2620,7 +2620,7 @@ doabbr(char *abbr, struct zone const *zp, char const *letters,
 	   bool isdst, zic_t save, bool doquotes)
 {
 	char	   *cp;
-	char	   *slashp;
+	char const *slashp;
 	size_t		len;
 	char const *format = zp->z_format;
 
