diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c
index 76bda73..7dcedd1 100644
*** a/contrib/postgres_fdw/postgres_fdw.c
--- b/contrib/postgres_fdw/postgres_fdw.c
*************** postgresPlanForeignModify(PlannerInfo *r
*** 1198,1212 ****
  	}
  	else if (operation == CMD_UPDATE)
  	{
- 		Bitmapset  *tmpset = bms_copy(rte->modifiedCols);
  		AttrNumber	col;
  
! 		while ((col = bms_first_member(tmpset)) >= 0)
  		{
  			col += FirstLowInvalidHeapAttributeNumber;
  			if (col <= InvalidAttrNumber)		/* shouldn't happen */
  				elog(ERROR, "system-column update is not supported");
  			targetAttrs = lappend_int(targetAttrs, col);
  		}
  	}
  
--- 1198,1213 ----
  	}
  	else if (operation == CMD_UPDATE)
  	{
  		AttrNumber	col;
  
! 		col = -1;
! 		while ((col = bms_next_member(rte->modifiedCols, col)) >= 0)
  		{
  			col += FirstLowInvalidHeapAttributeNumber;
  			if (col <= InvalidAttrNumber)		/* shouldn't happen */
  				elog(ERROR, "system-column update is not supported");
  			targetAttrs = lappend_int(targetAttrs, col);
+ 			col -= FirstLowInvalidHeapAttributeNumber;
  		}
  	}
  
diff --git a/contrib/sepgsql/dml.c b/contrib/sepgsql/dml.c
index bb82c0d..44c067d 100644
*** a/contrib/sepgsql/dml.c
--- b/contrib/sepgsql/dml.c
*************** static Bitmapset *
*** 94,100 ****
  fixup_inherited_columns(Oid parentId, Oid childId, Bitmapset *columns)
  {
  	AttrNumber	attno;
- 	Bitmapset  *tmpset;
  	Bitmapset  *result = NULL;
  	char	   *attname;
  	int			index;
--- 94,99 ----
*************** fixup_inherited_columns(Oid parentId, Oi
*** 105,112 ****
  	if (parentId == childId)
  		return columns;
  
! 	tmpset = bms_copy(columns);
! 	while ((index = bms_first_member(tmpset)) > 0)
  	{
  		attno = index + FirstLowInvalidHeapAttributeNumber;
  
--- 104,111 ----
  	if (parentId == childId)
  		return columns;
  
! 	index = -1;
! 	while ((index = bms_next_member(columns, index)) > 0)
  	{
  		attno = index + FirstLowInvalidHeapAttributeNumber;
  
*************** fixup_inherited_columns(Oid parentId, Oi
*** 128,139 ****
  			elog(ERROR, "cache lookup failed for attribute %s of relation %u",
  				 attname, childId);
  
! 		index = attno - FirstLowInvalidHeapAttributeNumber;
! 		result = bms_add_member(result, index);
  
  		pfree(attname);
  	}
- 	bms_free(tmpset);
  
  	return result;
  }
--- 127,137 ----
  			elog(ERROR, "cache lookup failed for attribute %s of relation %u",
  				 attname, childId);
  
! 		result = bms_add_member(result,
! 								attno - FirstLowInvalidHeapAttributeNumber);
  
  		pfree(attname);
  	}
  
  	return result;
  }
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index c499486..436b0fa 100644
*** a/src/backend/executor/execMain.c
--- b/src/backend/executor/execMain.c
*************** ExecCheckRTEPerms(RangeTblEntry *rte)
*** 547,553 ****
  	AclMode		remainingPerms;
  	Oid			relOid;
  	Oid			userid;
- 	Bitmapset  *tmpset;
  	int			col;
  
  	/*
--- 547,552 ----
*************** ExecCheckRTEPerms(RangeTblEntry *rte)
*** 614,621 ****
  					return false;
  			}
  
! 			tmpset = bms_copy(rte->selectedCols);
! 			while ((col = bms_first_member(tmpset)) >= 0)
  			{
  				/* remove the column number offset */
  				col += FirstLowInvalidHeapAttributeNumber;
--- 613,620 ----
  					return false;
  			}
  
! 			col = -1;
! 			while ((col = bms_next_member(rte->selectedCols, col)) >= 0)
  			{
  				/* remove the column number offset */
  				col += FirstLowInvalidHeapAttributeNumber;
*************** ExecCheckRTEPerms(RangeTblEntry *rte)
*** 632,639 ****
  											  ACL_SELECT) != ACLCHECK_OK)
  						return false;
  				}
  			}
- 			bms_free(tmpset);
  		}
  
  		/*
--- 631,638 ----
  											  ACL_SELECT) != ACLCHECK_OK)
  						return false;
  				}
+ 				col -= FirstLowInvalidHeapAttributeNumber;
  			}
  		}
  
  		/*
*************** ExecCheckRTEPerms(RangeTblEntry *rte)
*** 656,663 ****
  					return false;
  			}
  
! 			tmpset = bms_copy(rte->modifiedCols);
! 			while ((col = bms_first_member(tmpset)) >= 0)
  			{
  				/* remove the column number offset */
  				col += FirstLowInvalidHeapAttributeNumber;
--- 655,662 ----
  					return false;
  			}
  
! 			col = -1;
! 			while ((col = bms_next_member(rte->modifiedCols, col)) >= 0)
  			{
  				/* remove the column number offset */
  				col += FirstLowInvalidHeapAttributeNumber;
*************** ExecCheckRTEPerms(RangeTblEntry *rte)
*** 672,679 ****
  											  remainingPerms) != ACLCHECK_OK)
  						return false;
  				}
  			}
- 			bms_free(tmpset);
  		}
  	}
  	return true;
--- 671,678 ----
  											  remainingPerms) != ACLCHECK_OK)
  						return false;
  				}
+ 				col -= FirstLowInvalidHeapAttributeNumber;
  			}
  		}
  	}
  	return true;
diff --git a/src/backend/nodes/bitmapset.c b/src/backend/nodes/bitmapset.c
index c927b78..23eb1eb 100644
*** a/src/backend/nodes/bitmapset.c
--- b/src/backend/nodes/bitmapset.c
*************** bms_join(Bitmapset *a, Bitmapset *b)
*** 793,799 ****
  	return result;
  }
  
! /*----------
   * bms_first_member - find and remove first member of a set
   *
   * Returns -1 if set is empty.  NB: set is destructively modified!
--- 793,799 ----
  	return result;
  }
  
! /*
   * bms_first_member - find and remove first member of a set
   *
   * Returns -1 if set is empty.  NB: set is destructively modified!
*************** bms_join(Bitmapset *a, Bitmapset *b)
*** 801,811 ****
   * This is intended as support for iterating through the members of a set.
   * The typical pattern is
   *
!  *			tmpset = bms_copy(inputset);
!  *			while ((x = bms_first_member(tmpset)) >= 0)
   *				process member x;
!  *			bms_free(tmpset);
!  *----------
   */
  int
  bms_first_member(Bitmapset *a)
--- 801,811 ----
   * This is intended as support for iterating through the members of a set.
   * The typical pattern is
   *
!  *			while ((x = bms_first_member(inputset)) >= 0)
   *				process member x;
!  *
!  * CAUTION: this destroys the content of "inputset".  If the set must
!  * not be modified, use bms_next_member instead.
   */
  int
  bms_first_member(Bitmapset *a)
*************** bms_first_member(Bitmapset *a)
*** 841,846 ****
--- 841,899 ----
  }
  
  /*
+  * bms_next_member - find next member of a set
+  *
+  * Returns smallest member greater than "prevbit", or -1 if there is none.
+  *
+  * This is intended as support for iterating through the members of a set.
+  * The typical pattern is
+  *
+  *			x = -1;
+  *			while ((x = bms_next_member(inputset, x)) >= 0)
+  *				process member x;
+  */
+ int
+ bms_next_member(const Bitmapset *a, int prevbit)
+ {
+ 	int			nwords;
+ 	int			wordnum;
+ 	bitmapword	mask;
+ 
+ 	if (a == NULL)
+ 		return -1;
+ 	nwords = a->nwords;
+ 	prevbit++;
+ 	mask = (~(bitmapword) 0) << BITNUM(prevbit);
+ 	for (wordnum = WORDNUM(prevbit); wordnum < nwords; wordnum++)
+ 	{
+ 		bitmapword	w = a->words[wordnum];
+ 
+ 		/* ignore bits before prevbit */
+ 		w &= mask;
+ 
+ 		if (w != 0)
+ 		{
+ 			int			result;
+ 
+ 			w = RIGHTMOST_ONE(w);
+ 
+ 			result = wordnum * BITS_PER_BITMAPWORD;
+ 			while ((w & 255) == 0)
+ 			{
+ 				w >>= 8;
+ 				result += 8;
+ 			}
+ 			result += rightmost_one_pos[w & 255];
+ 			return result;
+ 		}
+ 
+ 		/* in subsequent words, consider all bits */
+ 		mask = (~(bitmapword) 0);
+ 	}
+ 	return -1;
+ }
+ 
+ /*
   * bms_hash_value - compute a hash key for a Bitmapset
   *
   * Note: we must ensure that any two bitmapsets that are bms_equal() will
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index ca9bd4f..edbd09f 100644
*** a/src/backend/nodes/outfuncs.c
--- b/src/backend/nodes/outfuncs.c
*************** _outList(StringInfo str, const List *nod
*** 184,198 ****
  static void
  _outBitmapset(StringInfo str, const Bitmapset *bms)
  {
- 	Bitmapset  *tmpset;
  	int			x;
  
  	appendStringInfoChar(str, '(');
  	appendStringInfoChar(str, 'b');
! 	tmpset = bms_copy(bms);
! 	while ((x = bms_first_member(tmpset)) >= 0)
  		appendStringInfo(str, " %d", x);
- 	bms_free(tmpset);
  	appendStringInfoChar(str, ')');
  }
  
--- 184,196 ----
  static void
  _outBitmapset(StringInfo str, const Bitmapset *bms)
  {
  	int			x;
  
  	appendStringInfoChar(str, '(');
  	appendStringInfoChar(str, 'b');
! 	x = -1;
! 	while ((x = bms_next_member(bms, x)) >= 0)
  		appendStringInfo(str, " %d", x);
  	appendStringInfoChar(str, ')');
  }
  
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index 25f3067..449fdc3 100644
*** a/src/backend/optimizer/path/allpaths.c
--- b/src/backend/optimizer/path/allpaths.c
*************** remove_unused_subquery_outputs(Query *su
*** 2272,2290 ****
  static void
  print_relids(Relids relids)
  {
- 	Relids		tmprelids;
  	int			x;
  	bool		first = true;
  
! 	tmprelids = bms_copy(relids);
! 	while ((x = bms_first_member(tmprelids)) >= 0)
  	{
  		if (!first)
  			printf(" ");
  		printf("%d", x);
  		first = false;
  	}
- 	bms_free(tmprelids);
  }
  
  static void
--- 2272,2288 ----
  static void
  print_relids(Relids relids)
  {
  	int			x;
  	bool		first = true;
  
! 	x = -1;
! 	while ((x = bms_next_member(relids, x)) >= 0)
  	{
  		if (!first)
  			printf(" ");
  		printf("%d", x);
  		first = false;
  	}
  }
  
  static void
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 1ee3b93..7aab644 100644
*** a/src/backend/optimizer/path/indxpath.c
--- b/src/backend/optimizer/path/indxpath.c
*************** get_loop_count(PlannerInfo *root, Relids
*** 1875,1883 ****
  	{
  		int			relid;
  
! 		/* Need a working copy since bms_first_member is destructive */
! 		outer_relids = bms_copy(outer_relids);
! 		while ((relid = bms_first_member(outer_relids)) >= 0)
  		{
  			RelOptInfo *outer_rel;
  
--- 1875,1882 ----
  	{
  		int			relid;
  
! 		relid = -1;
! 		while ((relid = bms_next_member(outer_relids, relid)) >= 0)
  		{
  			RelOptInfo *outer_rel;
  
*************** get_loop_count(PlannerInfo *root, Relids
*** 1900,1906 ****
  			if (result == 1.0 || result > outer_rel->rows)
  				result = outer_rel->rows;
  		}
- 		bms_free(outer_relids);
  	}
  	return result;
  }
--- 1899,1904 ----
diff --git a/src/backend/optimizer/util/joininfo.c b/src/backend/optimizer/util/joininfo.c
index 0418946..40af38d 100644
*** a/src/backend/optimizer/util/joininfo.c
--- b/src/backend/optimizer/util/joininfo.c
*************** add_join_clause_to_rels(PlannerInfo *roo
*** 96,112 ****
  						RestrictInfo *restrictinfo,
  						Relids join_relids)
  {
- 	Relids		tmprelids;
  	int			cur_relid;
  
! 	tmprelids = bms_copy(join_relids);
! 	while ((cur_relid = bms_first_member(tmprelids)) >= 0)
  	{
  		RelOptInfo *rel = find_base_rel(root, cur_relid);
  
  		rel->joininfo = lappend(rel->joininfo, restrictinfo);
  	}
- 	bms_free(tmprelids);
  }
  
  /*
--- 96,110 ----
  						RestrictInfo *restrictinfo,
  						Relids join_relids)
  {
  	int			cur_relid;
  
! 	cur_relid = -1;
! 	while ((cur_relid = bms_next_member(join_relids, cur_relid)) >= 0)
  	{
  		RelOptInfo *rel = find_base_rel(root, cur_relid);
  
  		rel->joininfo = lappend(rel->joininfo, restrictinfo);
  	}
  }
  
  /*
*************** remove_join_clause_from_rels(PlannerInfo
*** 125,135 ****
  							 RestrictInfo *restrictinfo,
  							 Relids join_relids)
  {
- 	Relids		tmprelids;
  	int			cur_relid;
  
! 	tmprelids = bms_copy(join_relids);
! 	while ((cur_relid = bms_first_member(tmprelids)) >= 0)
  	{
  		RelOptInfo *rel = find_base_rel(root, cur_relid);
  
--- 123,132 ----
  							 RestrictInfo *restrictinfo,
  							 Relids join_relids)
  {
  	int			cur_relid;
  
! 	cur_relid = -1;
! 	while ((cur_relid = bms_next_member(join_relids, cur_relid)) >= 0)
  	{
  		RelOptInfo *rel = find_base_rel(root, cur_relid);
  
*************** remove_join_clause_from_rels(PlannerInfo
*** 140,144 ****
  		Assert(list_member_ptr(rel->joininfo, restrictinfo));
  		rel->joininfo = list_delete_ptr(rel->joininfo, restrictinfo);
  	}
- 	bms_free(tmprelids);
  }
--- 137,140 ----
diff --git a/src/backend/optimizer/util/var.c b/src/backend/optimizer/util/var.c
index d4f46b8..a64a8d7 100644
*** a/src/backend/optimizer/util/var.c
--- b/src/backend/optimizer/util/var.c
*************** static Relids
*** 773,783 ****
  alias_relid_set(PlannerInfo *root, Relids relids)
  {
  	Relids		result = NULL;
- 	Relids		tmprelids;
  	int			rtindex;
  
! 	tmprelids = bms_copy(relids);
! 	while ((rtindex = bms_first_member(tmprelids)) >= 0)
  	{
  		RangeTblEntry *rte = rt_fetch(rtindex, root->parse->rtable);
  
--- 773,782 ----
  alias_relid_set(PlannerInfo *root, Relids relids)
  {
  	Relids		result = NULL;
  	int			rtindex;
  
! 	rtindex = -1;
! 	while ((rtindex = bms_next_member(relids, rtindex)) >= 0)
  	{
  		RangeTblEntry *rte = rt_fetch(rtindex, root->parse->rtable);
  
*************** alias_relid_set(PlannerInfo *root, Relid
*** 786,791 ****
  		else
  			result = bms_add_member(result, rtindex);
  	}
- 	bms_free(tmprelids);
  	return result;
  }
--- 785,789 ----
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index ad983c7..c7afea1 100644
*** a/src/backend/rewrite/rewriteHandler.c
--- b/src/backend/rewrite/rewriteHandler.c
*************** static Bitmapset *
*** 2456,2466 ****
  adjust_view_column_set(Bitmapset *cols, List *targetlist)
  {
  	Bitmapset  *result = NULL;
- 	Bitmapset  *tmpcols;
  	AttrNumber	col;
  
! 	tmpcols = bms_copy(cols);
! 	while ((col = bms_first_member(tmpcols)) >= 0)
  	{
  		/* bit numbers are offset by FirstLowInvalidHeapAttributeNumber */
  		AttrNumber	attno = col + FirstLowInvalidHeapAttributeNumber;
--- 2456,2465 ----
  adjust_view_column_set(Bitmapset *cols, List *targetlist)
  {
  	Bitmapset  *result = NULL;
  	AttrNumber	col;
  
! 	col = -1;
! 	while ((col = bms_next_member(cols, col)) >= 0)
  	{
  		/* bit numbers are offset by FirstLowInvalidHeapAttributeNumber */
  		AttrNumber	attno = col + FirstLowInvalidHeapAttributeNumber;
*************** adjust_view_column_set(Bitmapset *cols, 
*** 2510,2516 ****
  					 attno);
  		}
  	}
- 	bms_free(tmpcols);
  
  	return result;
  }
--- 2509,2514 ----
diff --git a/src/backend/rewrite/rewriteManip.c b/src/backend/rewrite/rewriteManip.c
index fb20314..c9e4b68 100644
*** a/src/backend/rewrite/rewriteManip.c
--- b/src/backend/rewrite/rewriteManip.c
*************** static Relids
*** 454,466 ****
  offset_relid_set(Relids relids, int offset)
  {
  	Relids		result = NULL;
- 	Relids		tmprelids;
  	int			rtindex;
  
! 	tmprelids = bms_copy(relids);
! 	while ((rtindex = bms_first_member(tmprelids)) >= 0)
  		result = bms_add_member(result, rtindex + offset);
- 	bms_free(tmprelids);
  	return result;
  }
  
--- 454,464 ----
  offset_relid_set(Relids relids, int offset)
  {
  	Relids		result = NULL;
  	int			rtindex;
  
! 	rtindex = -1;
! 	while ((rtindex = bms_next_member(relids, rtindex)) >= 0)
  		result = bms_add_member(result, rtindex + offset);
  	return result;
  }
  
diff --git a/src/include/nodes/bitmapset.h b/src/include/nodes/bitmapset.h
index f770608..a78ff48 100644
*** a/src/include/nodes/bitmapset.h
--- b/src/include/nodes/bitmapset.h
*************** extern Bitmapset *bms_join(Bitmapset *a,
*** 89,94 ****
--- 89,95 ----
  
  /* support for iterating through the integer elements of a set: */
  extern int	bms_first_member(Bitmapset *a);
+ extern int	bms_next_member(const Bitmapset *a, int prevbit);
  
  /* support for hashtables using Bitmapsets as keys: */
  extern uint32 bms_hash_value(const Bitmapset *a);
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index 11cb47b..d1feef7 100644
*** a/src/pl/plpgsql/src/pl_exec.c
--- b/src/pl/plpgsql/src/pl_exec.c
*************** setup_param_list(PLpgSQL_execstate *esta
*** 5263,5269 ****
  	 */
  	if (!bms_is_empty(expr->paramnos))
  	{
- 		Bitmapset  *tmpset;
  		int			dno;
  
  		paramLI = (ParamListInfo)
--- 5263,5268 ----
*************** setup_param_list(PLpgSQL_execstate *esta
*** 5276,5283 ****
  		paramLI->numParams = estate->ndatums;
  
  		/* Instantiate values for "safe" parameters of the expression */
! 		tmpset = bms_copy(expr->paramnos);
! 		while ((dno = bms_first_member(tmpset)) >= 0)
  		{
  			PLpgSQL_datum *datum = estate->datums[dno];
  
--- 5275,5282 ----
  		paramLI->numParams = estate->ndatums;
  
  		/* Instantiate values for "safe" parameters of the expression */
! 		dno = -1;
! 		while ((dno = bms_next_member(expr->paramnos, dno)) >= 0)
  		{
  			PLpgSQL_datum *datum = estate->datums[dno];
  
*************** setup_param_list(PLpgSQL_execstate *esta
*** 5292,5298 ****
  				prm->ptype = var->datatype->typoid;
  			}
  		}
- 		bms_free(tmpset);
  
  		/*
  		 * Set up link to active expr where the hook functions can find it.
--- 5291,5296 ----
*************** format_expr_params(PLpgSQL_execstate *es
*** 6528,6542 ****
  	int			paramno;
  	int			dno;
  	StringInfoData paramstr;
- 	Bitmapset  *tmpset;
  
  	if (!expr->paramnos)
  		return NULL;
  
  	initStringInfo(&paramstr);
- 	tmpset = bms_copy(expr->paramnos);
  	paramno = 0;
! 	while ((dno = bms_first_member(tmpset)) >= 0)
  	{
  		Datum		paramdatum;
  		Oid			paramtypeid;
--- 6526,6539 ----
  	int			paramno;
  	int			dno;
  	StringInfoData paramstr;
  
  	if (!expr->paramnos)
  		return NULL;
  
  	initStringInfo(&paramstr);
  	paramno = 0;
! 	dno = -1;
! 	while ((dno = bms_next_member(expr->paramnos, dno)) >= 0)
  	{
  		Datum		paramdatum;
  		Oid			paramtypeid;
*************** format_expr_params(PLpgSQL_execstate *es
*** 6572,6578 ****
  
  		paramno++;
  	}
- 	bms_free(tmpset);
  
  	return paramstr.data;
  }
--- 6569,6574 ----
