diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c
new file mode 100644
index ec10762..98e25d6
*** a/src/backend/access/common/reloptions.c
--- b/src/backend/access/common/reloptions.c
*************** static relopt_int intRelOpts[] =
*** 334,339 ****
--- 334,347 ----
  	{{NULL}}
  };
  
+ 
+ static relopt_int64 int64RelOpts[] =
+ {
+ 	/* list terminator */
+ 	{{NULL}}
+ };
+ 
+ 
  static relopt_real realRelOpts[] =
  {
  	{
*************** initialize_reloptions(void)
*** 460,465 ****
--- 468,479 ----
  								   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,
*************** initialize_reloptions(void)
*** 496,501 ****
--- 510,523 ----
  		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;
*************** allocate_reloption(bits32 kinds, int typ
*** 598,603 ****
--- 620,628 ----
  		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;
*************** add_int_reloption(bits32 kinds, char *na
*** 661,666 ****
--- 686,710 ----
  }
  
  /*
+  * add_int64_reloption
+  *		Add a new 64-bit integer reloption
+  */
+ void
+ add_int64_reloption(bits32 kinds, char *name, char *desc, int64 default_val,
+ 					int64 min_val, int64 max_val)
+ {
+ 	relopt_int64 *newoption;
+ 
+ 	newoption = (relopt_int64 *) allocate_reloption(kinds, RELOPT_TYPE_INT64,
+ 													name, desc);
+ 	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
   */
*************** parse_one_reloption(relopt_value *option
*** 1161,1166 ****
--- 1205,1231 ----
  									   optint->min, optint->max)));
  			}
  			break;
+ 		case RELOPT_TYPE_INT64:
+ 			{
+ 				relopt_int64 *optint = (relopt_int64 *) option->gen;
+ 
+ 				parsed = parse_int64(value, &option->values.int64_val, 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 \"" INT64_FORMAT
+ 					 		   "\" and \"" INT64_FORMAT "\".",
+ 							   optint->min, optint->max)));
+ 			}
+ 			break;
  		case RELOPT_TYPE_REAL:
  			{
  				relopt_real *optreal = (relopt_real *) option->gen;
*************** fillRelOptions(void *rdopts, Size basesi
*** 1269,1274 ****
--- 1334,1344 ----
  							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 :
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
new file mode 100644
index bc9f09a..1226f67
*** a/src/backend/utils/misc/guc.c
--- b/src/backend/utils/misc/guc.c
*************** static bool call_bool_check_hook(struct 
*** 140,145 ****
--- 140,147 ----
  					 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,
*************** const char *const config_type_names[] =
*** 675,680 ****
--- 677,683 ----
  {
  	 /* PGC_BOOL */ "bool",
  	 /* PGC_INT */ "integer",
+ 	 /* PGC_INT64 */ "int64",
  	 /* PGC_REAL */ "real",
  	 /* PGC_STRING */ "string",
  	 /* PGC_ENUM */ "enum"
*************** static struct config_real ConfigureNames
*** 3054,3059 ****
--- 3057,3071 ----
  };
  
  
+ static struct config_int64 ConfigureNamesInt64[] =
+ {
+ 	/* End-of-list marker */
+ 	{
+ 		{NULL, 0, 0, NULL, NULL}, NULL, 0.0, 0.0, 0.0, NULL, NULL, NULL
+ 	}
+ };
+ 
+ 
  static struct config_string ConfigureNamesString[] =
  {
  	{
*************** extra_field_used(struct config_generic *
*** 4089,4094 ****
--- 4101,4110 ----
  			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;
*************** set_stack_value(struct config_generic *g
*** 4150,4155 ****
--- 4166,4175 ----
  			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;
*************** discard_stack_value(struct config_generi
*** 4178,4183 ****
--- 4198,4204 ----
  	{
  		case PGC_BOOL:
  		case PGC_INT:
+ 		case PGC_INT64:
  		case PGC_REAL:
  		case PGC_ENUM:
  			/* no need to do anything */
*************** build_guc_variables(void)
*** 4232,4237 ****
--- 4253,4266 ----
  		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];
*************** build_guc_variables(void)
*** 4272,4277 ****
--- 4301,4309 ----
  	for (i = 0; ConfigureNamesInt[i].gen.name; i++)
  		guc_vars[num_vars++] = &ConfigureNamesInt[i].gen;
  
+ 	for (i = 0; ConfigureNamesInt64[i].gen.name; i++)
+ 		guc_vars[num_vars++] = &ConfigureNamesInt64[i].gen;
+ 
  	for (i = 0; ConfigureNamesReal[i].gen.name; i++)
  		guc_vars[num_vars++] = &ConfigureNamesReal[i].gen;
  
*************** InitializeOneGUCOption(struct config_gen
*** 4626,4631 ****
--- 4658,4681 ----
  				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 " INT64_FORMAT,
+ 						 conf->gen.name, 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;
*************** ResetAllOptions(void)
*** 4921,4926 ****
--- 4971,4988 ----
  									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);
+ 					*conf->variable = conf->reset_val;
+ 					set_extra_field(&conf->gen, &conf->gen.extra,
+ 									conf->reset_extra);
+ 					break;
+ 				}
  			case PGC_REAL:
  				{
  					struct config_real *conf = (struct config_real *) gconf;
*************** AtEOXact_GUC(bool isCommit, int nestLeve
*** 5267,5272 ****
--- 5329,5352 ----
  							}
  							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)
+ 							{
+ 								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_REAL:
  						{
  							struct config_real *conf = (struct config_real *) gconf;
*************** parse_int(const char *value, int *result
*** 5587,5592 ****
--- 5667,5720 ----
  
  
  /*
+  * 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, 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;
+ #ifdef _MSC_VER					/* MSVC only */
+ 	val = _strtoi64(value, &endptr, 10);
+ #elif defined(HAVE_STRTOLL) && SIZEOF_LONG < 8
+ 	val = strtoll(value, &endptr, 10);
+ #else
+ 	val = strtol(value, &endptr, 10);
+ #endif
+ 
+ 	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;
+ 	}
+ 
+ 	if (result)
+ 		*result = val;
+ 	return true;
+ }
+ 
+ 
+ 
+ /*
   * Try to parse value as a floating point number in the usual format.
   * If the string parses okay, return true, else false.
   * If okay and result is not NULL, return the value in *result.
*************** parse_and_validate_value(struct config_g
*** 5789,5794 ****
--- 5917,5953 ----
  					return false;
  			}
  			break;
+ 		case PGC_INT64:
+ 			{
+ 				struct config_int64 *conf = (struct config_int64 *) record;
+ 				const char *hintmsg;
+ 
+ 				if (!parse_int64(value, &newval->int64val, &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(INT64_FORMAT " is outside the valid range for parameter \"%s\" ("
+ 									INT64_FORMAT " .. " INT64_FORMAT ")",
+ 									newval->int64val, name,
+ 									conf->min, 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;
*************** set_config_option(const char *name, cons
*** 6342,6347 ****
--- 6501,6596 ----
  #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))
+ 					free(newextra);
+ 				break;
+ 
+ #undef newval
+ 			}
+ 
  		case PGC_REAL:
  			{
  				struct config_real *conf = (struct config_real *) record;
*************** GetConfigOption(const char *name, bool m
*** 6738,6743 ****
--- 6987,6997 ----
  					 *((struct config_int *) record)->variable);
  			return buffer;
  
+ 		case PGC_INT64:
+ 			snprintf(buffer, sizeof(buffer), INT64_FORMAT,
+ 					 *((struct config_int64 *) record)->variable);
+ 			return buffer;
+ 
  		case PGC_REAL:
  			snprintf(buffer, sizeof(buffer), "%g",
  					 *((struct config_real *) record)->variable);
*************** GetConfigOptionResetString(const char *n
*** 6788,6793 ****
--- 7042,7052 ----
  					 ((struct config_int *) record)->reset_val);
  			return buffer;
  
+ 		case PGC_INT64:
+ 			snprintf(buffer, sizeof(buffer), INT64_FORMAT,
+ 					 ((struct config_int64 *) record)->reset_val);
+ 			return buffer;
+ 
  		case PGC_REAL:
  			snprintf(buffer, sizeof(buffer), "%g",
  					 ((struct config_real *) record)->reset_val);
*************** DefineCustomIntVariable(const char *name
*** 7794,7799 ****
--- 8053,8088 ----
  }
  
  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,
  						 const char *long_desc,
*************** GetConfigOptionByNum(int varnum, const c
*** 8220,8225 ****
--- 8509,8539 ----
  			}
  			break;
  
+ 		case PGC_INT64:
+ 			{
+ 				struct config_int64 *lconf = (struct config_int64 *) conf;
+ 
+ 				/* min_val */
+ 				snprintf(buffer, sizeof(buffer), INT64_FORMAT, lconf->min);
+ 				values[9] = pstrdup(buffer);
+ 
+ 				/* max_val */
+ 				snprintf(buffer, sizeof(buffer), INT64_FORMAT, lconf->max);
+ 				values[10] = pstrdup(buffer);
+ 
+ 				/* enumvals */
+ 				values[11] = NULL;
+ 
+ 				/* boot_val */
+ 				snprintf(buffer, sizeof(buffer), INT64_FORMAT, lconf->boot_val);
+ 				values[12] = pstrdup(buffer);
+ 
+ 				/* reset_val */
+ 				snprintf(buffer, sizeof(buffer), INT64_FORMAT, lconf->reset_val);
+ 				values[13] = pstrdup(buffer);
+ 			}
+ 			break;
+ 
  		case PGC_REAL:
  			{
  				struct config_real *lconf = (struct config_real *) conf;
*************** _ShowOption(struct config_generic *recor
*** 8693,8698 ****
--- 9007,9027 ----
  			}
  			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), INT64_FORMAT,
+ 							 *conf->variable);
+ 					val = buffer;
+ 				}
+ 			}
+ 			break;
+ 
  		case PGC_REAL:
  			{
  				struct config_real *conf = (struct config_real *) record;
*************** write_one_nondefault_variable(FILE *fp, 
*** 8785,8790 ****
--- 9114,9127 ----
  			}
  			break;
  
+ 		case PGC_INT64:
+ 			{
+ 				struct config_int64 *conf = (struct config_int64 *) gconf;
+ 
+ 				fprintf(fp, INT64_FORMAT, *conf->variable);
+ 			}
+ 			break;
+ 
  		case PGC_REAL:
  			{
  				struct config_real *conf = (struct config_real *) gconf;
*************** estimate_variable_size(struct config_gen
*** 9042,9047 ****
--- 9379,9402 ----
  			}
  			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.
+ 				 */
+ 				if (Abs(*conf->variable) < 1000)
+ 					valsize = 3 + 1;
+ 				else
+ 					valsize = 20 + 1;
+ 			}
+ 			break;
+ 
+ 
  		case PGC_REAL:
  			{
  				/*
*************** serialize_variable(char **destptr, Size 
*** 9203,9208 ****
--- 9558,9571 ----
  			}
  			break;
  
+ 		case PGC_INT64:
+ 			{
+ 				struct config_int64 *conf = (struct config_int64 *) gconf;
+ 
+ 				do_serialize(destptr, maxbytes, INT64_FORMAT, *conf->variable);
+ 			}
+ 			break;
+ 
  		case PGC_REAL:
  			{
  				struct config_real *conf = (struct config_real *) gconf;
*************** call_int_check_hook(struct config_int *c
*** 9866,9871 ****
--- 10229,10268 ----
  }
  
  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\": " INT64_FORMAT,
+ 						conf->gen.name, *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/include/access/reloptions.h b/src/include/access/reloptions.h
new file mode 100644
index 5cdaa3b..286b39c
*** a/src/include/access/reloptions.h
--- b/src/include/access/reloptions.h
*************** typedef enum relopt_type
*** 30,35 ****
--- 30,36 ----
  {
  	RELOPT_TYPE_BOOL,
  	RELOPT_TYPE_INT,
+ 	RELOPT_TYPE_INT64,
  	RELOPT_TYPE_REAL,
  	RELOPT_TYPE_STRING
  } relopt_type;
*************** typedef struct relopt_value
*** 79,84 ****
--- 80,86 ----
  	{
  		bool		bool_val;
  		int			int_val;
+ 		int64		int64_val;
  		double		real_val;
  		char	   *string_val; /* allocated separately */
  	}			values;
*************** typedef struct relopt_int
*** 99,104 ****
--- 101,114 ----
  	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;
*************** extern void add_bool_reloption(bits32 ki
*** 250,255 ****
--- 260,267 ----
  				   bool default_val);
  extern void add_int_reloption(bits32 kinds, char *name, char *desc,
  				  int default_val, int min_val, int max_val);
+ extern void add_int64_reloption(bits32 kinds, char *name, char *desc,
+ 				  int64 default_val, int64 min_val, int64 max_val);
  extern void add_real_reloption(bits32 kinds, char *name, char *desc,
  				   double default_val, double min_val, double max_val);
  extern void add_string_reloption(bits32 kinds, char *name, char *desc,
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
new file mode 100644
index 467125a..13956d2
*** a/src/include/utils/guc.h
--- b/src/include/utils/guc.h
*************** struct config_enum_entry
*** 173,184 ****
--- 173,186 ----
   */
  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);
*************** extern void DefineCustomIntVariable(
*** 304,309 ****
--- 306,325 ----
  						GucIntAssignHook assign_hook,
  						GucShowHook show_hook);
  
+ 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);
+ 
  extern void DefineCustomRealVariable(
  						 const char *name,
  						 const char *short_desc,
*************** extern void BeginReportingGUCOptions(voi
*** 359,364 ****
--- 375,381 ----
  extern void ParseLongOption(const char *string, char **name, char **value);
  extern bool parse_int(const char *value, int *result, int flags,
  		  const char **hintmsg);
+ extern bool parse_int64(const char *value, int64 *result, const char **hintmsg);
  extern bool parse_real(const char *value, double *result);
  extern int set_config_option(const char *name, const char *value,
  				  GucContext context, GucSource source,
diff --git a/src/include/utils/guc_tables.h b/src/include/utils/guc_tables.h
new file mode 100644
index 042f7a0..469f83a
*** a/src/include/utils/guc_tables.h
--- b/src/include/utils/guc_tables.h
*************** enum config_type
*** 23,28 ****
--- 23,29 ----
  {
  	PGC_BOOL,
  	PGC_INT,
+ 	PGC_INT64,
  	PGC_REAL,
  	PGC_STRING,
  	PGC_ENUM
*************** union config_var_val
*** 32,37 ****
--- 33,39 ----
  {
  	bool		boolval;
  	int			intval;
+ 	int64		int64val;
  	double		realval;
  	char	   *stringval;
  	int			enumval;
*************** struct config_int
*** 204,209 ****
--- 206,227 ----
  	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;
