From 2d53f9f890c48e0780bc5823e87ba698a5c32909 Mon Sep 17 00:00:00 2001
From: Maxim Orlov <m.orlov@postgrespro.ru>
Date: Fri, 11 Mar 2022 11:34:26 +0300
Subject: [PATCH v3] Support 64-bit integer GUCs

Author: Alexander Korotkov <aekorotkov@gmail.com>
Author: Teodor Sigaev <teodor@sigaev.ru>
Author: Nikita Glukhov <n.gluhov@postgrespro.ru>
Author: Maxim Orlov <orlovmg@gmail.com>
Author: Pavel Borisov <pashkin.elfe@gmail.com>
Author: Yura Sokolov <y.sokolov@postgrespro.ru> <funny.falcon@gmail.com>
Author: Aleksander Alekseev <aleksander@timescale.com>
Reviewed-by: Li Japin <japinli@hotmail.com>
Discussion: https://postgr.es/m/CAJ7c6TMvPz8q+nC=JoKniy7yxPzQYcCTnNFYmsDP-nnWsAOJ2g@mail.gmail.com
---
 src/backend/access/common/reloptions.c        | 129 ++++--
 src/backend/postmaster/autovacuum.c           |   6 +-
 src/backend/utils/misc/guc.c                  | 418 ++++++++++++++++++
 src/backend/utils/misc/guc_funcs.c            |  25 ++
 src/backend/utils/misc/guc_tables.c           |  64 +--
 src/include/access/reloptions.h               |  13 +
 src/include/postmaster/autovacuum.h           |   6 +-
 src/include/utils/guc.h                       |  17 +
 src/include/utils/guc_tables.h                |  19 +
 src/include/utils/rel.h                       |   6 +-
 .../modules/delay_execution/delay_execution.c |  28 +-
 .../expected/partition-addition.out           |   6 +-
 .../expected/partition-removal-1.out          |  28 +-
 .../specs/partition-addition.spec             |   6 +-
 .../specs/partition-removal-1.spec            |   6 +-
 15 files changed, 674 insertions(+), 103 deletions(-)

diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c
index 49fd35bfc5..b989442942 100644
--- a/src/backend/access/common/reloptions.c
+++ b/src/backend/access/common/reloptions.c
@@ -222,33 +222,6 @@ static relopt_int intRelOpts[] =
 		},
 		SPGIST_DEFAULT_FILLFACTOR, SPGIST_MIN_FILLFACTOR, 100
 	},
-	{
-		{
-			"autovacuum_vacuum_threshold",
-			"Minimum number of tuple updates or deletes prior to vacuum",
-			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
-			ShareUpdateExclusiveLock
-		},
-		-1, 0, INT_MAX
-	},
-	{
-		{
-			"autovacuum_vacuum_insert_threshold",
-			"Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums",
-			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
-			ShareUpdateExclusiveLock
-		},
-		-2, -1, INT_MAX
-	},
-	{
-		{
-			"autovacuum_analyze_threshold",
-			"Minimum number of tuple inserts, updates or deletes prior to analyze",
-			RELOPT_KIND_HEAP,
-			ShareUpdateExclusiveLock
-		},
-		-1, 0, INT_MAX
-	},
 	{
 		{
 			"autovacuum_vacuum_cost_limit",
@@ -380,7 +353,39 @@ static relopt_int intRelOpts[] =
 		},
 		-1, 0, 1024
 	},
+	/* list terminator */
+	{{NULL}}
+};
 
+static relopt_int64 int64RelOpts[] =
+{
+	{
+		{
+			"autovacuum_vacuum_threshold",
+			"Minimum number of tuple updates or deletes prior to vacuum",
+			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
+			ShareUpdateExclusiveLock
+		},
+		INT64CONST(-1), INT64CONST(0), PG_INT64_MAX
+	},
+	{
+		{
+			"autovacuum_vacuum_insert_threshold",
+			"Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums",
+			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
+			ShareUpdateExclusiveLock
+		},
+		INT64CONST(-2), INT64CONST(-1), PG_INT64_MAX
+	},
+	{
+		{
+			"autovacuum_analyze_threshold",
+			"Minimum number of tuple inserts, updates or deletes prior to analyze",
+			RELOPT_KIND_HEAP,
+			ShareUpdateExclusiveLock
+		},
+		INT64CONST(-1), INT64CONST(0), PG_INT64_MAX
+	},
 	/* list terminator */
 	{{NULL}}
 };
@@ -595,6 +600,12 @@ initialize_reloptions(void)
 								   intRelOpts[i].gen.lockmode));
 		j++;
 	}
+	for (i = 0; int64RelOpts[i].gen.name; i++)
+	{
+		Assert(DoLockModesConflict(int64RelOpts[i].gen.lockmode,
+								   int64RelOpts[i].gen.lockmode));
+		j++;
+	}
 	for (i = 0; realRelOpts[i].gen.name; i++)
 	{
 		Assert(DoLockModesConflict(realRelOpts[i].gen.lockmode,
@@ -637,6 +648,14 @@ initialize_reloptions(void)
 		j++;
 	}
 
+	for (i = 0; int64RelOpts[i].gen.name; i++)
+	{
+		relOpts[j] = &int64RelOpts[i].gen;
+		relOpts[j]->type = RELOPT_TYPE_INT64;
+		relOpts[j]->namelen = strlen(relOpts[j]->name);
+		j++;
+	}
+
 	for (i = 0; realRelOpts[i].gen.name; i++)
 	{
 		relOpts[j] = &realRelOpts[i].gen;
@@ -792,6 +811,9 @@ allocate_reloption(bits32 kinds, int type, const char *name, const char *desc,
 		case RELOPT_TYPE_INT:
 			size = sizeof(relopt_int);
 			break;
+		case RELOPT_TYPE_INT64:
+			size = sizeof(relopt_int64);
+			break;
 		case RELOPT_TYPE_REAL:
 			size = sizeof(relopt_real);
 			break;
@@ -946,6 +968,26 @@ init_real_reloption(bits32 kinds, const char *name, const char *desc,
 	return newoption;
 }
 
+/*
+ * add_int64_reloption
+ *		Add a new 64-bit integer reloption
+ */
+void
+add_int64_reloption(bits32 kinds, const char *name, char *desc,
+					int64 default_val, int64 min_val, int64 max_val,
+					LOCKMODE lockmode)
+{
+	relopt_int64 *newoption;
+
+	newoption = (relopt_int64 *) allocate_reloption(kinds, RELOPT_TYPE_INT64,
+													name, desc, lockmode);
+	newoption->default_val = default_val;
+	newoption->min = min_val;
+	newoption->max = max_val;
+
+	add_reloption((relopt_gen *) newoption);
+}
+
 /*
  * add_real_reloption
  *		Add a new float reloption
@@ -1617,6 +1659,28 @@ parse_one_reloption(relopt_value *option, char *text_str, int text_len,
 									   optint->min, optint->max)));
 			}
 			break;
+		case RELOPT_TYPE_INT64:
+			{
+				relopt_int64 *optint = (relopt_int64 *) option->gen;
+
+				parsed = parse_int64(value, &option->values.int64_val, 0, NULL);
+				if (validate && !parsed)
+					ereport(ERROR,
+							(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+							 errmsg("invalid value for 64-bit integer option \"%s\": %s",
+									option->gen->name, value)));
+				if (validate && (option->values.int64_val < optint->min ||
+								 option->values.int64_val > optint->max))
+					ereport(ERROR,
+							(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+							 errmsg("value %s out of bounds for option \"%s\"",
+									value, option->gen->name),
+							 errdetail("Valid values are between \"%lld"
+									   "\" and \"%lld\".",
+									   (long long ) optint->min,
+									   (long long) optint->max)));
+			}
+			break;
 		case RELOPT_TYPE_REAL:
 			{
 				relopt_real *optreal = (relopt_real *) option->gen;
@@ -1772,6 +1836,11 @@ fillRelOptions(void *rdopts, Size basesize,
 							options[i].values.int_val :
 							((relopt_int *) options[i].gen)->default_val;
 						break;
+					case RELOPT_TYPE_INT64:
+						*(int64 *) itempos = options[i].isset ?
+							options[i].values.int64_val :
+							((relopt_int64 *) options[i].gen)->default_val;
+						break;
 					case RELOPT_TYPE_REAL:
 						*(double *) itempos = options[i].isset ?
 							options[i].values.real_val :
@@ -1841,11 +1910,11 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
 		{"fillfactor", RELOPT_TYPE_INT, offsetof(StdRdOptions, fillfactor)},
 		{"autovacuum_enabled", RELOPT_TYPE_BOOL,
 		offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, enabled)},
-		{"autovacuum_vacuum_threshold", RELOPT_TYPE_INT,
+		{"autovacuum_vacuum_threshold", RELOPT_TYPE_INT64,
 		offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_threshold)},
-		{"autovacuum_vacuum_insert_threshold", RELOPT_TYPE_INT,
+		{"autovacuum_vacuum_insert_threshold", RELOPT_TYPE_INT64,
 		offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_ins_threshold)},
-		{"autovacuum_analyze_threshold", RELOPT_TYPE_INT,
+		{"autovacuum_analyze_threshold", RELOPT_TYPE_INT64,
 		offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, analyze_threshold)},
 		{"autovacuum_vacuum_cost_limit", RELOPT_TYPE_INT,
 		offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_cost_limit)},
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index 7d0877c95e..88c39414a6 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -118,11 +118,11 @@ bool		autovacuum_start_daemon = false;
 int			autovacuum_max_workers;
 int			autovacuum_work_mem = -1;
 int			autovacuum_naptime;
-int			autovacuum_vac_thresh;
+int64		autovacuum_vac_thresh;
 double		autovacuum_vac_scale;
-int			autovacuum_vac_ins_thresh;
+int64		autovacuum_vac_ins_thresh;
 double		autovacuum_vac_ins_scale;
-int			autovacuum_anl_thresh;
+int64		autovacuum_anl_thresh;
 double		autovacuum_anl_scale;
 int			autovacuum_freeze_max_age;
 int			autovacuum_multixact_freeze_max_age;
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 13527fc258..d1e491d22d 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -262,6 +262,8 @@ static bool call_bool_check_hook(struct config_bool *conf, bool *newval,
 								 void **extra, GucSource source, int elevel);
 static bool call_int_check_hook(struct config_int *conf, int *newval,
 								void **extra, GucSource source, int elevel);
+static bool call_int64_check_hook(struct config_int64 *conf, int64 *newval,
+								  void **extra, GucSource source, int elevel);
 static bool call_real_check_hook(struct config_real *conf, double *newval,
 								 void **extra, GucSource source, int elevel);
 static bool call_string_check_hook(struct config_string *conf, char **newval,
@@ -759,6 +761,10 @@ extra_field_used(struct config_generic *gconf, void *extra)
 			if (extra == ((struct config_int *) gconf)->reset_extra)
 				return true;
 			break;
+		case PGC_INT64:
+			if (extra == ((struct config_int64 *) gconf)->reset_extra)
+				return true;
+			break;
 		case PGC_REAL:
 			if (extra == ((struct config_real *) gconf)->reset_extra)
 				return true;
@@ -820,6 +826,10 @@ set_stack_value(struct config_generic *gconf, config_var_value *val)
 			val->val.intval =
 				*((struct config_int *) gconf)->variable;
 			break;
+		case PGC_INT64:
+			val->val.int64val =
+				*((struct config_int64 *) gconf)->variable;
+			break;
 		case PGC_REAL:
 			val->val.realval =
 				*((struct config_real *) gconf)->variable;
@@ -848,6 +858,7 @@ discard_stack_value(struct config_generic *gconf, config_var_value *val)
 	{
 		case PGC_BOOL:
 		case PGC_INT:
+		case PGC_INT64:
 		case PGC_REAL:
 		case PGC_ENUM:
 			/* no need to do anything */
@@ -936,6 +947,14 @@ build_guc_variables(void)
 		num_vars++;
 	}
 
+	for (i = 0; ConfigureNamesInt64[i].gen.name; i++)
+	{
+		struct config_int64 *conf = &ConfigureNamesInt64[i];
+
+		conf->gen.vartype = PGC_INT64;
+		num_vars++;
+	}
+
 	for (i = 0; ConfigureNamesReal[i].gen.name; i++)
 	{
 		struct config_real *conf = &ConfigureNamesReal[i];
@@ -999,6 +1018,18 @@ build_guc_variables(void)
 		hentry->gucvar = gucvar;
 	}
 
+	for (i = 0; ConfigureNamesInt64[i].gen.name; i++)
+	{
+		struct config_generic *gucvar = &ConfigureNamesInt64[i].gen;
+
+		hentry = (GUCHashEntry *) hash_search(guc_hashtab,
+											  &gucvar->name,
+											  HASH_ENTER,
+											  &found);
+		Assert(!found);
+		hentry->gucvar = gucvar;
+	}
+
 	for (i = 0; ConfigureNamesReal[i].gen.name; i++)
 	{
 		struct config_generic *gucvar = &ConfigureNamesReal[i].gen;
@@ -1426,6 +1457,7 @@ check_GUC_name_for_parameter_acl(const char *name)
  * The following validation rules apply for the values:
  * bool - can be false, otherwise must be same as the boot_val
  * int  - can be 0, otherwise must be same as the boot_val
+ * int64 - can be 0, otherwise must be same as the boot_val
  * real - can be 0.0, otherwise must be same as the boot_val
  * string - can be NULL, otherwise must be strcmp equal to the boot_val
  * enum - must be same as the boot_val
@@ -1461,6 +1493,20 @@ check_GUC_init(struct config_generic *gconf)
 				}
 				break;
 			}
+		case PGC_INT64:
+			{
+				struct config_int64 *conf = (struct config_int64 *) gconf;
+
+				if (*conf->variable != 0 && *conf->variable != conf->boot_val)
+				{
+					elog(LOG, "GUC (PGC_INT64) %s, boot_val=%lld, C-var=%lld",
+						 conf->gen.name,
+						 (long long) conf->boot_val,
+						 (long long) *conf->variable);
+					return false;
+				}
+				break;
+			}
 		case PGC_REAL:
 			{
 				struct config_real *conf = (struct config_real *) gconf;
@@ -1691,6 +1737,24 @@ InitializeOneGUCOption(struct config_generic *gconf)
 				conf->gen.extra = conf->reset_extra = extra;
 				break;
 			}
+		case PGC_INT64:
+			{
+				struct config_int64 *conf = (struct config_int64 *) gconf;
+				int64		newval = conf->boot_val;
+				void	   *extra = NULL;
+
+				Assert(newval >= conf->min);
+				Assert(newval <= conf->max);
+				if (!call_int64_check_hook(conf, &newval, &extra,
+										   PGC_S_DEFAULT, LOG))
+					elog(FATAL, "failed to initialize %s to %lld",
+						 conf->gen.name, (long long) newval);
+				if (conf->assign_hook)
+					(*conf->assign_hook) (newval, extra);
+				*conf->variable = conf->reset_val = newval;
+				conf->gen.extra = conf->reset_extra = extra;
+				break;
+			}
 		case PGC_REAL:
 			{
 				struct config_real *conf = (struct config_real *) gconf;
@@ -2041,6 +2105,18 @@ ResetAllOptions(void)
 				{
 					struct config_int *conf = (struct config_int *) gconf;
 
+					if (conf->assign_hook)
+						conf->assign_hook(conf->reset_val,
+										  conf->reset_extra);
+					*conf->variable = conf->reset_val;
+					set_extra_field(&conf->gen, &conf->gen.extra,
+									conf->reset_extra);
+					break;
+				}
+			case PGC_INT64:
+				{
+					struct config_int64 *conf = (struct config_int64 *) gconf;
+
 					if (conf->assign_hook)
 						conf->assign_hook(conf->reset_val,
 										  conf->reset_extra);
@@ -2424,6 +2500,24 @@ AtEOXact_GUC(bool isCommit, int nestLevel)
 							int			newval = newvalue.val.intval;
 							void	   *newextra = newvalue.extra;
 
+							if (*conf->variable != newval ||
+								conf->gen.extra != newextra)
+							{
+								if (conf->assign_hook)
+									conf->assign_hook(newval, newextra);
+								*conf->variable = newval;
+								set_extra_field(&conf->gen, &conf->gen.extra,
+												newextra);
+								changed = true;
+							}
+							break;
+						}
+					case PGC_INT64:
+						{
+							struct config_int64 *conf = (struct config_int64 *) gconf;
+							int64		newval = newvalue.val.int64val;
+							void	   *newextra = newvalue.extra;
+
 							if (*conf->variable != newval ||
 								conf->gen.extra != newextra)
 							{
@@ -2946,6 +3040,71 @@ parse_int(const char *value, int *result, int flags, const char **hintmsg)
 	return true;
 }
 
+/*
+ * Try to parse value as an 64-bit integer.  The accepted format is
+ * decimal number.
+ *
+ * If the string parses okay, return true, else false.
+ * If okay and result is not NULL, return the value in *result.
+ * If not okay and hintmsg is not NULL, *hintmsg is set to a suitable
+ *	HINT message, or NULL if no hint provided.
+ */
+bool
+parse_int64(const char *value, int64 *result, int flags, const char **hintmsg)
+{
+	int64		val;
+	char	   *endptr;
+
+	/* To suppress compiler warnings, always set output params */
+	if (result)
+		*result = 0;
+	if (hintmsg)
+		*hintmsg = NULL;
+
+	/* We assume here that int64 is at least as wide as long */
+	errno = 0;
+	val = strtoi64(value, &endptr, 0);
+
+	if (endptr == value)
+		return false;			/* no HINT for integer syntax error */
+
+	if (errno == ERANGE)
+	{
+		if (hintmsg)
+			*hintmsg = gettext_noop("Value exceeds 64-bit integer range.");
+		return false;
+	}
+
+	/*
+	 * got double format and/or units. For now we attempts parse it as double
+	 * and throw error on 53bit overflow
+	 */
+	if (*endptr != '\0')
+	{
+		double		dval;
+		bool		ok;
+
+		ok = parse_real(value, &dval, flags, hintmsg);
+		if (!ok)
+			return false;
+
+		dval = rint(val);
+
+		if (fabs(dval) >= (double) ((uint64) 1 << 53))
+		{
+			*hintmsg = gettext_noop("Int64 value with units should be positive number < 2^53");
+			return false;
+		}
+
+		val = (int64) dval;
+	}
+
+
+	if (result)
+		*result = val;
+	return true;
+}
+
 /*
  * Try to parse value as a floating point number in the usual format.
  * Optionally, the value can be followed by a unit name if "flags" indicates
@@ -3192,6 +3351,36 @@ parse_and_validate_value(struct config_generic *record,
 					return false;
 			}
 			break;
+		case PGC_INT64:
+			{
+				struct config_int64 *conf = (struct config_int64 *) record;
+				const char *hintmsg;
+
+				if (!parse_int64(value, &newval->int64val, conf->gen.flags, &hintmsg))
+				{
+					ereport(elevel,
+							(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+							 errmsg("invalid value for parameter \"%s\": \"%s\"",
+									name, value),
+							 hintmsg ? errhint("%s", _(hintmsg)) : 0));
+					return false;
+				}
+
+				if (newval->int64val < conf->min || newval->int64val > conf->max)
+				{
+					ereport(elevel,
+							(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+							 errmsg("%lld is outside the valid range for parameter \"%s\" (%lld .. %lld)",
+									(long long) newval->int64val, name,
+									(long long) conf->min, (long long) conf->max)));
+					return false;
+				}
+
+				if (!call_int64_check_hook(conf, &newval->int64val, newextra,
+										   source, elevel))
+					return false;
+			}
+			break;
 		case PGC_REAL:
 			{
 				struct config_real *conf = (struct config_real *) record;
@@ -3895,6 +4084,96 @@ set_config_with_handle(const char *name, config_handle *handle,
 					guc_free(newextra);
 				break;
 
+#undef newval
+			}
+
+		case PGC_INT64:
+			{
+				struct config_int64 *conf = (struct config_int64 *) record;
+
+#define newval (newval_union.int64val)
+
+				if (value)
+				{
+					if (!parse_and_validate_value(record, name, value,
+												  source, elevel,
+												  &newval_union, &newextra))
+						return 0;
+				}
+				else if (source == PGC_S_DEFAULT)
+				{
+					newval = conf->boot_val;
+					if (!call_int64_check_hook(conf, &newval, &newextra,
+											   source, elevel))
+						return 0;
+				}
+				else
+				{
+					newval = conf->reset_val;
+					newextra = conf->reset_extra;
+					source = conf->gen.reset_source;
+					context = conf->gen.reset_scontext;
+				}
+
+				if (prohibitValueChange)
+				{
+					if (*conf->variable != newval)
+					{
+						record->status |= GUC_PENDING_RESTART;
+						ereport(elevel,
+								(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
+								 errmsg("parameter \"%s\" cannot be changed without restarting the server",
+										name)));
+						return 0;
+					}
+					record->status &= ~GUC_PENDING_RESTART;
+					return -1;
+				}
+
+				if (changeVal)
+				{
+					/* Save old value to support transaction abort */
+					if (!makeDefault)
+						push_old_value(&conf->gen, action);
+
+					if (conf->assign_hook)
+						(*conf->assign_hook) (newval, newextra);
+					*conf->variable = newval;
+					set_extra_field(&conf->gen, &conf->gen.extra,
+									newextra);
+					conf->gen.source = source;
+					conf->gen.scontext = context;
+				}
+				if (makeDefault)
+				{
+					GucStack   *stack;
+
+					if (conf->gen.reset_source <= source)
+					{
+						conf->reset_val = newval;
+						set_extra_field(&conf->gen, &conf->reset_extra,
+										newextra);
+						conf->gen.reset_source = source;
+						conf->gen.reset_scontext = context;
+					}
+					for (stack = conf->gen.stack; stack; stack = stack->prev)
+					{
+						if (stack->source <= source)
+						{
+							stack->prior.val.intval = newval;
+							set_extra_field(&conf->gen, &stack->prior.extra,
+											newextra);
+							stack->source = source;
+							stack->scontext = context;
+						}
+					}
+				}
+
+				/* Perhaps we didn't install newextra anywhere */
+				if (newextra && !extra_field_used(&conf->gen, newextra))
+					guc_free(newextra);
+				break;
+
 #undef newval
 			}
 
@@ -4337,6 +4616,11 @@ GetConfigOption(const char *name, bool missing_ok, bool restrict_privileged)
 					 *((struct config_int *) record)->variable);
 			return buffer;
 
+		case PGC_INT64:
+			snprintf(buffer, sizeof(buffer), "%lld",
+					 (long long) *((struct config_int64 *) record)->variable);
+			return buffer;
+
 		case PGC_REAL:
 			snprintf(buffer, sizeof(buffer), "%g",
 					 *((struct config_real *) record)->variable);
@@ -4385,6 +4669,11 @@ GetConfigOptionResetString(const char *name)
 					 ((struct config_int *) record)->reset_val);
 			return buffer;
 
+		case PGC_INT64:
+			snprintf(buffer, sizeof(buffer), "%lld",
+					 (long long) ((struct config_int64 *) record)->reset_val);
+			return buffer;
+
 		case PGC_REAL:
 			snprintf(buffer, sizeof(buffer), "%g",
 					 ((struct config_real *) record)->reset_val);
@@ -5143,6 +5432,36 @@ DefineCustomIntVariable(const char *name,
 	define_custom_variable(&var->gen);
 }
 
+void
+DefineCustomInt64Variable(const char *name,
+						const char *short_desc,
+						const char *long_desc,
+						int64 *valueAddr,
+						int64 bootValue,
+						int64 minValue,
+						int64 maxValue,
+						GucContext context,
+						int flags,
+						GucInt64CheckHook check_hook,
+						GucInt64AssignHook assign_hook,
+						GucShowHook show_hook)
+{
+	struct config_int64 *var;
+
+	var = (struct config_int64 *)
+		init_custom_variable(name, short_desc, long_desc, context, flags,
+							 PGC_INT64, sizeof(struct config_int64));
+	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);
+}
+
 void
 DefineCustomRealVariable(const char *name,
 						 const char *short_desc,
@@ -5336,6 +5655,14 @@ get_explain_guc_options(int *num)
 				}
 				break;
 
+			case PGC_INT64:
+				{
+					struct config_int64 *lconf = (struct config_int64 *) conf;
+
+					modified = (lconf->boot_val != *(lconf->variable));
+				}
+				break;
+
 			case PGC_REAL:
 				{
 					struct config_real *lconf = (struct config_real *) conf;
@@ -5468,6 +5795,21 @@ ShowGUCOption(struct config_generic *record, bool use_units)
 			}
 			break;
 
+		case PGC_INT64:
+			{
+				struct config_int64 *conf = (struct config_int64 *) record;
+
+				if (conf->show_hook)
+					val = (*conf->show_hook) ();
+				else
+				{
+					snprintf(buffer, sizeof(buffer), "%lld",
+							 (long long) *conf->variable);
+					val = buffer;
+				}
+			}
+			break;
+
 		case PGC_REAL:
 			{
 				struct config_real *conf = (struct config_real *) record;
@@ -5570,6 +5912,14 @@ write_one_nondefault_variable(FILE *fp, struct config_generic *gconf)
 			}
 			break;
 
+		case PGC_INT64:
+			{
+				struct config_int64 *conf = (struct config_int64 *) gconf;
+
+				fprintf(fp, "%lld", (long long) *conf->variable);
+			}
+			break;
+
 		case PGC_REAL:
 			{
 				struct config_real *conf = (struct config_real *) gconf;
@@ -5848,6 +6198,24 @@ estimate_variable_size(struct config_generic *gconf)
 			}
 			break;
 
+		case PGC_INT64:
+			{
+				struct config_int64 *conf = (struct config_int64 *) gconf;
+
+				/*
+				 * Instead of getting the exact display length, use max
+				 * length.  Also reduce the max length for typical ranges of
+				 * small values.  Maximum value is 2^63, i.e. 20 chars.
+				 * Include one byte for sign.
+				 */
+#define ABS(x)			((x) >= 0 ? (x) : -(x))
+				if (ABS(*conf->variable) < 1000)
+					valsize = 3 + 1;
+				else
+					valsize = 20 + 1;
+			}
+			break;
+
 		case PGC_REAL:
 			{
 				/*
@@ -6014,6 +6382,14 @@ serialize_variable(char **destptr, Size *maxbytes,
 			}
 			break;
 
+		case PGC_INT64:
+			{
+				struct config_int64 *conf = (struct config_int64 *) gconf;
+
+				do_serialize(destptr, maxbytes, "%lld", (long long) *conf->variable);
+			}
+			break;
+
 		case PGC_REAL:
 			{
 				struct config_real *conf = (struct config_real *) gconf;
@@ -6227,6 +6603,14 @@ RestoreGUCState(void *gucstate)
 				{
 					struct config_int *conf = (struct config_int *) gconf;
 
+					if (conf->reset_extra && conf->reset_extra != gconf->extra)
+						guc_free(conf->reset_extra);
+					break;
+				}
+			case PGC_INT64:
+				{
+					struct config_int64 *conf = (struct config_int64 *) gconf;
+
 					if (conf->reset_extra && conf->reset_extra != gconf->extra)
 						guc_free(conf->reset_extra);
 					break;
@@ -6827,6 +7211,40 @@ call_int_check_hook(struct config_int *conf, int *newval, void **extra,
 	return true;
 }
 
+static bool
+call_int64_check_hook(struct config_int64 *conf, int64 *newval, void **extra,
+					  GucSource source, int elevel)
+{
+	/* Quick success if no hook */
+	if (!conf->check_hook)
+		return true;
+
+	/* Reset variables that might be set by hook */
+	GUC_check_errcode_value = ERRCODE_INVALID_PARAMETER_VALUE;
+	GUC_check_errmsg_string = NULL;
+	GUC_check_errdetail_string = NULL;
+	GUC_check_errhint_string = NULL;
+
+	if (!(*conf->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\": %lld",
+						conf->gen.name, (long long) *newval),
+				 GUC_check_errdetail_string ?
+				 errdetail_internal("%s", GUC_check_errdetail_string) : 0,
+				 GUC_check_errhint_string ?
+				 errhint("%s", GUC_check_errhint_string) : 0));
+		/* Flush any strings created in ErrorContext */
+		FlushErrorState();
+		return false;
+	}
+
+	return true;
+}
+
 static bool
 call_real_check_hook(struct config_real *conf, double *newval, void **extra,
 					 GucSource source, int elevel)
diff --git a/src/backend/utils/misc/guc_funcs.c b/src/backend/utils/misc/guc_funcs.c
index 9c9edd3d2f..d0625d18b3 100644
--- a/src/backend/utils/misc/guc_funcs.c
+++ b/src/backend/utils/misc/guc_funcs.c
@@ -673,6 +673,31 @@ GetConfigOptionValues(struct config_generic *conf, const char **values)
 			}
 			break;
 
+		case PGC_INT64:
+			{
+				struct config_int64 *lconf = (struct config_int64 *) conf;
+
+				/* min_val */
+				snprintf(buffer, sizeof(buffer), "%lld", (long long) lconf->min);
+				values[9] = pstrdup(buffer);
+
+				/* max_val */
+				snprintf(buffer, sizeof(buffer), "%lld", (long long) lconf->max);
+				values[10] = pstrdup(buffer);
+
+				/* enumvals */
+				values[11] = NULL;
+
+				/* boot_val */
+				snprintf(buffer, sizeof(buffer), "%lld", (long long) lconf->boot_val);
+				values[12] = pstrdup(buffer);
+
+				/* reset_val */
+				snprintf(buffer, sizeof(buffer), "%lld", (long long) lconf->reset_val);
+				values[13] = pstrdup(buffer);
+			}
+			break;
+
 		case PGC_REAL:
 			{
 				struct config_real *lconf = (struct config_real *) conf;
diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c
index 686309db58..03edd9f95d 100644
--- a/src/backend/utils/misc/guc_tables.c
+++ b/src/backend/utils/misc/guc_tables.c
@@ -731,6 +731,7 @@ const char *const config_type_names[] =
 {
 	[PGC_BOOL] = "bool",
 	[PGC_INT] = "integer",
+	[PGC_INT64] = "int64",
 	[PGC_REAL] = "real",
 	[PGC_STRING] = "string",
 	[PGC_ENUM] = "enum",
@@ -3397,33 +3398,6 @@ struct config_int ConfigureNamesInt[] =
 		60, 1, INT_MAX / 1000,
 		NULL, NULL, NULL
 	},
-	{
-		{"autovacuum_vacuum_threshold", PGC_SIGHUP, AUTOVACUUM,
-			gettext_noop("Minimum number of tuple updates or deletes prior to vacuum."),
-			NULL
-		},
-		&autovacuum_vac_thresh,
-		50, 0, INT_MAX,
-		NULL, NULL, NULL
-	},
-	{
-		{"autovacuum_vacuum_insert_threshold", PGC_SIGHUP, AUTOVACUUM,
-			gettext_noop("Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums."),
-			NULL
-		},
-		&autovacuum_vac_ins_thresh,
-		1000, -1, INT_MAX,
-		NULL, NULL, NULL
-	},
-	{
-		{"autovacuum_analyze_threshold", PGC_SIGHUP, AUTOVACUUM,
-			gettext_noop("Minimum number of tuple inserts, updates, or deletes prior to analyze."),
-			NULL
-		},
-		&autovacuum_anl_thresh,
-		50, 0, INT_MAX,
-		NULL, NULL, NULL
-	},
 	{
 		/* see varsup.c for why this is PGC_POSTMASTER not PGC_SIGHUP */
 		{"autovacuum_freeze_max_age", PGC_POSTMASTER, AUTOVACUUM,
@@ -3721,6 +3695,42 @@ struct config_int ConfigureNamesInt[] =
 };
 
 
+struct config_int64 ConfigureNamesInt64[] =
+{
+	{
+		{"autovacuum_vacuum_threshold", PGC_SIGHUP, AUTOVACUUM,
+			gettext_noop("Minimum number of tuple updates or deletes prior to vacuum."),
+			NULL
+		},
+		&autovacuum_vac_thresh,
+		INT64CONST(50), INT64CONST(0), PG_INT64_MAX,
+		NULL, NULL, NULL
+	},
+	{
+		{"autovacuum_vacuum_insert_threshold", PGC_SIGHUP, AUTOVACUUM,
+			gettext_noop("Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums."),
+			NULL
+		},
+		&autovacuum_vac_ins_thresh,
+		INT64CONST(1000), INT64CONST(-1), PG_INT64_MAX,
+		NULL, NULL, NULL
+	},
+	{
+		{"autovacuum_analyze_threshold", PGC_SIGHUP, AUTOVACUUM,
+			gettext_noop("Minimum number of tuple inserts, updates, or deletes prior to analyze."),
+			NULL
+		},
+		&autovacuum_anl_thresh,
+		INT64CONST(50), INT64CONST(0), PG_INT64_MAX,
+		NULL, NULL, NULL
+	},
+	/* End-of-list marker */
+	{
+		{NULL, 0, 0, NULL, NULL}, NULL, 0, 0, 0, NULL, NULL, NULL
+	}
+};
+
+
 struct config_real ConfigureNamesReal[] =
 {
 	{
diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h
index df6923c9d5..309c82ebf4 100644
--- a/src/include/access/reloptions.h
+++ b/src/include/access/reloptions.h
@@ -30,6 +30,7 @@ typedef enum relopt_type
 {
 	RELOPT_TYPE_BOOL,
 	RELOPT_TYPE_INT,
+	RELOPT_TYPE_INT64,
 	RELOPT_TYPE_REAL,
 	RELOPT_TYPE_ENUM,
 	RELOPT_TYPE_STRING,
@@ -81,6 +82,7 @@ typedef struct relopt_value
 	{
 		bool		bool_val;
 		int			int_val;
+		int64		int64_val;
 		double		real_val;
 		int			enum_val;
 		char	   *string_val; /* allocated separately */
@@ -102,6 +104,14 @@ typedef struct relopt_int
 	int			max;
 } relopt_int;
 
+typedef struct relopt_int64
+{
+	relopt_gen	gen;
+	int64		default_val;
+	int64		min;
+	int64		max;
+}			relopt_int64;
+
 typedef struct relopt_real
 {
 	relopt_gen	gen;
@@ -185,6 +195,9 @@ extern void add_bool_reloption(bits32 kinds, const char *name, const char *desc,
 extern void add_int_reloption(bits32 kinds, const char *name, const char *desc,
 							  int default_val, int min_val, int max_val,
 							  LOCKMODE lockmode);
+extern void add_int64_reloption(bits32 kinds, const char *name, char *desc,
+								int64 default_val, int64 min_val, int64 max_val,
+								LOCKMODE lockmode);
 extern void add_real_reloption(bits32 kinds, const char *name, const char *desc,
 							   double default_val, double min_val, double max_val,
 							   LOCKMODE lockmode);
diff --git a/src/include/postmaster/autovacuum.h b/src/include/postmaster/autovacuum.h
index cae1e8b329..15f12ce24f 100644
--- a/src/include/postmaster/autovacuum.h
+++ b/src/include/postmaster/autovacuum.h
@@ -31,11 +31,11 @@ extern PGDLLIMPORT bool autovacuum_start_daemon;
 extern PGDLLIMPORT int autovacuum_max_workers;
 extern PGDLLIMPORT int autovacuum_work_mem;
 extern PGDLLIMPORT int autovacuum_naptime;
-extern PGDLLIMPORT int autovacuum_vac_thresh;
+extern PGDLLIMPORT int64 autovacuum_vac_thresh;
 extern PGDLLIMPORT double autovacuum_vac_scale;
-extern PGDLLIMPORT int autovacuum_vac_ins_thresh;
+extern PGDLLIMPORT int64 autovacuum_vac_ins_thresh;
 extern PGDLLIMPORT double autovacuum_vac_ins_scale;
-extern PGDLLIMPORT int autovacuum_anl_thresh;
+extern PGDLLIMPORT int64 autovacuum_anl_thresh;
 extern PGDLLIMPORT double autovacuum_anl_scale;
 extern PGDLLIMPORT int autovacuum_freeze_max_age;
 extern PGDLLIMPORT int autovacuum_multixact_freeze_max_age;
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index 840b0fe57f..0a3fe0b54f 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -178,12 +178,14 @@ struct config_enum_entry
  */
 typedef bool (*GucBoolCheckHook) (bool *newval, void **extra, GucSource source);
 typedef bool (*GucIntCheckHook) (int *newval, void **extra, GucSource source);
+typedef bool (*GucInt64CheckHook) (int64 *newval, void **extra, GucSource source);
 typedef bool (*GucRealCheckHook) (double *newval, void **extra, GucSource source);
 typedef bool (*GucStringCheckHook) (char **newval, void **extra, GucSource source);
 typedef bool (*GucEnumCheckHook) (int *newval, void **extra, GucSource source);
 
 typedef void (*GucBoolAssignHook) (bool newval, void *extra);
 typedef void (*GucIntAssignHook) (int newval, void *extra);
+typedef void (*GucInt64AssignHook) (int64 newval, void *extra);
 typedef void (*GucRealAssignHook) (double newval, void *extra);
 typedef void (*GucStringAssignHook) (const char *newval, void *extra);
 typedef void (*GucEnumAssignHook) (int newval, void *extra);
@@ -348,6 +350,19 @@ extern void DefineCustomIntVariable(const char *name,
 									GucIntAssignHook assign_hook,
 									GucShowHook show_hook) pg_attribute_nonnull(1, 4);
 
+extern void DefineCustomInt64Variable(const char *name,
+									  const char *short_desc,
+									  const char *long_desc,
+									  int64 *valueAddr,
+									  int64 bootValue,
+									  int64 minValue,
+									  int64 maxValue,
+									  GucContext context,
+									  int flags,
+									  GucInt64CheckHook check_hook,
+									  GucInt64AssignHook assign_hook,
+									  GucShowHook show_hook) pg_attribute_nonnull(1, 4);
+
 extern void DefineCustomRealVariable(const char *name,
 									 const char *short_desc,
 									 const char *long_desc,
@@ -409,6 +424,8 @@ extern void ParseLongOption(const char *string, char **name, char **value);
 extern const char *get_config_unit_name(int flags);
 extern bool parse_int(const char *value, int *result, int flags,
 					  const char **hintmsg);
+extern bool parse_int64(const char *value, int64 *result, int flags,
+						const char **hintmsg);
 extern bool parse_real(const char *value, double *result, int flags,
 					   const char **hintmsg);
 extern int	set_config_option(const char *name, const char *value,
diff --git a/src/include/utils/guc_tables.h b/src/include/utils/guc_tables.h
index 0c0277c423..c4dfe0afab 100644
--- a/src/include/utils/guc_tables.h
+++ b/src/include/utils/guc_tables.h
@@ -24,6 +24,7 @@ enum config_type
 {
 	PGC_BOOL,
 	PGC_INT,
+	PGC_INT64,
 	PGC_REAL,
 	PGC_STRING,
 	PGC_ENUM,
@@ -33,6 +34,7 @@ union config_var_val
 {
 	bool		boolval;
 	int			intval;
+	int64		int64val;
 	double		realval;
 	char	   *stringval;
 	int			enumval;
@@ -225,6 +227,22 @@ struct config_int
 	void	   *reset_extra;
 };
 
+struct config_int64
+{
+	struct config_generic gen;
+	/* constant fields, must be set correctly in initial value: */
+	int64	   *variable;
+	int64		boot_val;
+	int64		min;
+	int64		max;
+	GucInt64CheckHook check_hook;
+	GucInt64AssignHook assign_hook;
+	GucShowHook show_hook;
+	/* variable fields, initialized at runtime: */
+	int64		reset_val;
+	void	   *reset_extra;
+};
+
 struct config_real
 {
 	struct config_generic gen;
@@ -289,6 +307,7 @@ extern PGDLLIMPORT const char *const GucSource_Names[];
 /* data arrays defining all the built-in GUC variables */
 extern PGDLLIMPORT struct config_bool ConfigureNamesBool[];
 extern PGDLLIMPORT struct config_int ConfigureNamesInt[];
+extern PGDLLIMPORT struct config_int64 ConfigureNamesInt64[];
 extern PGDLLIMPORT struct config_real ConfigureNamesReal[];
 extern PGDLLIMPORT struct config_string ConfigureNamesString[];
 extern PGDLLIMPORT struct config_enum ConfigureNamesEnum[];
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index 8700204953..f89064e274 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -308,9 +308,9 @@ typedef struct ForeignKeyCacheInfo
 typedef struct AutoVacOpts
 {
 	bool		enabled;
-	int			vacuum_threshold;
-	int			vacuum_ins_threshold;
-	int			analyze_threshold;
+	int64		vacuum_threshold;
+	int64		vacuum_ins_threshold;
+	int64		analyze_threshold;
 	int			vacuum_cost_limit;
 	int			freeze_min_age;
 	int			freeze_max_age;
diff --git a/src/test/modules/delay_execution/delay_execution.c b/src/test/modules/delay_execution/delay_execution.c
index 155c8a8d55..62c61d50f8 100644
--- a/src/test/modules/delay_execution/delay_execution.c
+++ b/src/test/modules/delay_execution/delay_execution.c
@@ -31,7 +31,7 @@
 PG_MODULE_MAGIC;
 
 /* GUC: advisory lock ID to use.  Zero disables the feature. */
-static int	post_planning_lock_id = 0;
+static int64 post_planning_lock_id = 0;
 
 /* Save previous planner hook user to be a good citizen */
 static planner_hook_type prev_planner_hook = NULL;
@@ -56,9 +56,9 @@ delay_execution_planner(Query *parse, const char *query_string,
 	if (post_planning_lock_id != 0)
 	{
 		DirectFunctionCall1(pg_advisory_lock_int8,
-							Int64GetDatum((int64) post_planning_lock_id));
+							Int64GetDatum(post_planning_lock_id));
 		DirectFunctionCall1(pg_advisory_unlock_int8,
-							Int64GetDatum((int64) post_planning_lock_id));
+							Int64GetDatum(post_planning_lock_id));
 
 		/*
 		 * Ensure that we notice any pending invalidations, since the advisory
@@ -75,17 +75,17 @@ void
 _PG_init(void)
 {
 	/* Set up the GUC to control which lock is used */
-	DefineCustomIntVariable("delay_execution.post_planning_lock_id",
-							"Sets the advisory lock ID to be locked/unlocked after planning.",
-							"Zero disables the delay.",
-							&post_planning_lock_id,
-							0,
-							0, INT_MAX,
-							PGC_USERSET,
-							0,
-							NULL,
-							NULL,
-							NULL);
+	DefineCustomInt64Variable("delay_execution.post_planning_lock_id",
+							  "Sets the advisory lock ID to be locked/unlocked after planning.",
+							  "Zero disables the delay.",
+							  &post_planning_lock_id,
+							  0,
+							  0, PG_INT64_MAX,
+							  PGC_USERSET,
+							  0,
+							  NULL,
+							  NULL,
+							  NULL);
 
 	MarkGUCPrefixReserved("delay_execution");
 
diff --git a/src/test/modules/delay_execution/expected/partition-addition.out b/src/test/modules/delay_execution/expected/partition-addition.out
index 7d6572b2db..57750db160 100644
--- a/src/test/modules/delay_execution/expected/partition-addition.out
+++ b/src/test/modules/delay_execution/expected/partition-addition.out
@@ -1,19 +1,19 @@
 Parsed test spec with 2 sessions
 
 starting permutation: s2lock s1exec s2addp s2unlock
-step s2lock: SELECT pg_advisory_lock(12345);
+step s2lock: SELECT pg_advisory_lock(0x1122334455667788);
 pg_advisory_lock
 ----------------
                 
 (1 row)
 
 step s1exec: LOAD 'delay_execution';
-		  SET delay_execution.post_planning_lock_id = 12345;
+		  SET delay_execution.post_planning_lock_id = 0x1122334455667788;
 		  SELECT * FROM foo WHERE a <> 1 AND a <> (SELECT 3); <waiting ...>
 step s2addp: CREATE TABLE foo2 (LIKE foo);
 		  ALTER TABLE foo ATTACH PARTITION foo2 FOR VALUES IN (2);
 		  INSERT INTO foo VALUES (2, 'ADD2');
-step s2unlock: SELECT pg_advisory_unlock(12345);
+step s2unlock: SELECT pg_advisory_unlock(0x1122334455667788);
 pg_advisory_unlock
 ------------------
 t                 
diff --git a/src/test/modules/delay_execution/expected/partition-removal-1.out b/src/test/modules/delay_execution/expected/partition-removal-1.out
index b81b9995e9..a2e453fdaa 100644
--- a/src/test/modules/delay_execution/expected/partition-removal-1.out
+++ b/src/test/modules/delay_execution/expected/partition-removal-1.out
@@ -1,7 +1,7 @@
 Parsed test spec with 3 sessions
 
 starting permutation: s3lock s1b s1exec s2remp s3check s3unlock s3check s1c
-step s3lock: SELECT pg_advisory_lock(12543);
+step s3lock: SELECT pg_advisory_lock(0x7766554433221100);
 pg_advisory_lock
 ----------------
                 
@@ -17,7 +17,7 @@ a|b
 3|DEF
 (2 rows)
 
-step s3unlock: SELECT pg_advisory_unlock(12543);
+step s3unlock: SELECT pg_advisory_unlock(0x7766554433221100);
 pg_advisory_unlock
 ------------------
 t                 
@@ -40,7 +40,7 @@ step s1c: COMMIT;
 step s2remp: <... completed>
 
 starting permutation: s3lock s1brr s1exec s2remp s3check s3unlock s3check s1c
-step s3lock: SELECT pg_advisory_lock(12543);
+step s3lock: SELECT pg_advisory_lock(0x7766554433221100);
 pg_advisory_lock
 ----------------
                 
@@ -56,7 +56,7 @@ a|b
 3|DEF
 (2 rows)
 
-step s3unlock: SELECT pg_advisory_unlock(12543);
+step s3unlock: SELECT pg_advisory_unlock(0x7766554433221100);
 pg_advisory_unlock
 ------------------
 t                 
@@ -79,7 +79,7 @@ step s1c: COMMIT;
 step s2remp: <... completed>
 
 starting permutation: s3lock s1b s1exec2 s2remp s3unlock s1c
-step s3lock: SELECT pg_advisory_lock(12543);
+step s3lock: SELECT pg_advisory_lock(0x7766554433221100);
 pg_advisory_lock
 ----------------
                 
@@ -88,7 +88,7 @@ pg_advisory_lock
 step s1b: BEGIN;
 step s1exec2: SELECT * FROM partrem WHERE a <> (SELECT 2) AND a <> 1; <waiting ...>
 step s2remp: ALTER TABLE partrem DETACH PARTITION partrem2 CONCURRENTLY; <waiting ...>
-step s3unlock: SELECT pg_advisory_unlock(12543);
+step s3unlock: SELECT pg_advisory_unlock(0x7766554433221100);
 pg_advisory_unlock
 ------------------
 t                 
@@ -104,7 +104,7 @@ step s1c: COMMIT;
 step s2remp: <... completed>
 
 starting permutation: s3lock s1brr s1exec2 s2remp s3unlock s1c
-step s3lock: SELECT pg_advisory_lock(12543);
+step s3lock: SELECT pg_advisory_lock(0x7766554433221100);
 pg_advisory_lock
 ----------------
                 
@@ -113,7 +113,7 @@ pg_advisory_lock
 step s1brr: BEGIN ISOLATION LEVEL REPEATABLE READ;
 step s1exec2: SELECT * FROM partrem WHERE a <> (SELECT 2) AND a <> 1; <waiting ...>
 step s2remp: ALTER TABLE partrem DETACH PARTITION partrem2 CONCURRENTLY; <waiting ...>
-step s3unlock: SELECT pg_advisory_unlock(12543);
+step s3unlock: SELECT pg_advisory_unlock(0x7766554433221100);
 pg_advisory_unlock
 ------------------
 t                 
@@ -129,7 +129,7 @@ step s1c: COMMIT;
 step s2remp: <... completed>
 
 starting permutation: s3lock s1brr s1prepare s2remp s1execprep s3unlock s1check s1c s1check s1dealloc
-step s3lock: SELECT pg_advisory_lock(12543);
+step s3lock: SELECT pg_advisory_lock(0x7766554433221100);
 pg_advisory_lock
 ----------------
                 
@@ -139,7 +139,7 @@ step s1brr: BEGIN ISOLATION LEVEL REPEATABLE READ;
 step s1prepare: PREPARE ins AS INSERT INTO partrem VALUES ($1, 'GHI');
 step s2remp: ALTER TABLE partrem DETACH PARTITION partrem2 CONCURRENTLY; <waiting ...>
 step s1execprep: EXECUTE ins(2); <waiting ...>
-step s3unlock: SELECT pg_advisory_unlock(12543);
+step s3unlock: SELECT pg_advisory_unlock(0x7766554433221100);
 pg_advisory_unlock
 ------------------
 t                 
@@ -165,14 +165,14 @@ starting permutation: s1brr s1prepare s2remp s3lock s1execprep s3unlock s1check
 step s1brr: BEGIN ISOLATION LEVEL REPEATABLE READ;
 step s1prepare: PREPARE ins AS INSERT INTO partrem VALUES ($1, 'GHI');
 step s2remp: ALTER TABLE partrem DETACH PARTITION partrem2 CONCURRENTLY; <waiting ...>
-step s3lock: SELECT pg_advisory_lock(12543);
+step s3lock: SELECT pg_advisory_lock(0x7766554433221100);
 pg_advisory_lock
 ----------------
                 
 (1 row)
 
 step s1execprep: EXECUTE ins(2); <waiting ...>
-step s3unlock: SELECT pg_advisory_unlock(12543);
+step s3unlock: SELECT pg_advisory_unlock(0x7766554433221100);
 pg_advisory_unlock
 ------------------
 t                 
@@ -201,7 +201,7 @@ a|b
 -+-
 (0 rows)
 
-step s3lock: SELECT pg_advisory_lock(12543);
+step s3lock: SELECT pg_advisory_lock(0x7766554433221100);
 pg_advisory_lock
 ----------------
                 
@@ -210,7 +210,7 @@ pg_advisory_lock
 step s2remp: ALTER TABLE partrem DETACH PARTITION partrem2 CONCURRENTLY; <waiting ...>
 step s1prepare: PREPARE ins AS INSERT INTO partrem VALUES ($1, 'GHI');
 step s1execprep: EXECUTE ins(2); <waiting ...>
-step s3unlock: SELECT pg_advisory_unlock(12543);
+step s3unlock: SELECT pg_advisory_unlock(0x7766554433221100);
 pg_advisory_unlock
 ------------------
 t                 
diff --git a/src/test/modules/delay_execution/specs/partition-addition.spec b/src/test/modules/delay_execution/specs/partition-addition.spec
index 99010dfad5..4a68e88cc7 100644
--- a/src/test/modules/delay_execution/specs/partition-addition.spec
+++ b/src/test/modules/delay_execution/specs/partition-addition.spec
@@ -25,12 +25,12 @@ teardown
 
 session "s1"
 step "s1exec"	{ LOAD 'delay_execution';
-		  SET delay_execution.post_planning_lock_id = 12345;
+		  SET delay_execution.post_planning_lock_id = 0x1122334455667788;
 		  SELECT * FROM foo WHERE a <> 1 AND a <> (SELECT 3); }
 
 session "s2"
-step "s2lock"	{ SELECT pg_advisory_lock(12345); }
-step "s2unlock"	{ SELECT pg_advisory_unlock(12345); }
+step "s2lock"	{ SELECT pg_advisory_lock(0x1122334455667788); }
+step "s2unlock"	{ SELECT pg_advisory_unlock(0x1122334455667788); }
 step "s2addp"	{ CREATE TABLE foo2 (LIKE foo);
 		  ALTER TABLE foo ATTACH PARTITION foo2 FOR VALUES IN (2);
 		  INSERT INTO foo VALUES (2, 'ADD2'); }
diff --git a/src/test/modules/delay_execution/specs/partition-removal-1.spec b/src/test/modules/delay_execution/specs/partition-removal-1.spec
index 5ee2750129..25b40b89a4 100644
--- a/src/test/modules/delay_execution/specs/partition-removal-1.spec
+++ b/src/test/modules/delay_execution/specs/partition-removal-1.spec
@@ -18,7 +18,7 @@ teardown
 
 session "s1"
 setup		{ LOAD 'delay_execution';
-		  SET delay_execution.post_planning_lock_id = 12543; }
+		  SET delay_execution.post_planning_lock_id = 0x7766554433221100; }
 step "s1b"	{ BEGIN; }
 step "s1brr"	{ BEGIN ISOLATION LEVEL REPEATABLE READ; }
 step "s1exec"	{ SELECT * FROM partrem WHERE a <> 1 AND a <> (SELECT 3); }
@@ -33,8 +33,8 @@ session "s2"
 step "s2remp"	{ ALTER TABLE partrem DETACH PARTITION partrem2 CONCURRENTLY; }
 
 session "s3"
-step "s3lock"	{ SELECT pg_advisory_lock(12543); }
-step "s3unlock"	{ SELECT pg_advisory_unlock(12543); }
+step "s3lock"	{ SELECT pg_advisory_lock(0x7766554433221100); }
+step "s3unlock"	{ SELECT pg_advisory_unlock(0x7766554433221100); }
 step "s3check"	{ SELECT * FROM partrem; }
 
 # The SELECT will be planned with all three partitions shown above,
-- 
2.46.0

