}
else if (operation == CMD_UPDATE)
{
- Bitmapset *tmpset = bms_copy(rte->modifiedCols);
- AttrNumber col;
+ int col;
- while ((col = bms_first_member(tmpset)) >= 0)
+ col = -1;
+ while ((col = bms_next_member(rte->modifiedCols, col)) >= 0)
{
- col += FirstLowInvalidHeapAttributeNumber;
- if (col <= InvalidAttrNumber) /* shouldn't happen */
+ /* bit numbers are offset by FirstLowInvalidHeapAttributeNumber */
+ AttrNumber attno = col + FirstLowInvalidHeapAttributeNumber;
+
+ if (attno <= InvalidAttrNumber) /* shouldn't happen */
elog(ERROR, "system-column update is not supported");
- targetAttrs = lappend_int(targetAttrs, col);
+ targetAttrs = lappend_int(targetAttrs, attno);
}
}
static Bitmapset *
fixup_inherited_columns(Oid parentId, Oid childId, Bitmapset *columns)
{
- AttrNumber attno;
- Bitmapset *tmpset;
Bitmapset *result = NULL;
- char *attname;
int index;
/*
if (parentId == childId)
return columns;
- tmpset = bms_copy(columns);
- while ((index = bms_first_member(tmpset)) > 0)
+ index = -1;
+ while ((index = bms_next_member(columns, index)) >= 0)
{
- attno = index + FirstLowInvalidHeapAttributeNumber;
+ /* bit numbers are offset by FirstLowInvalidHeapAttributeNumber */
+ AttrNumber attno = index + FirstLowInvalidHeapAttributeNumber;
+ char *attname;
/*
* whole-row-reference shall be fixed-up later
elog(ERROR, "cache lookup failed for attribute %s of relation %u",
attname, childId);
- index = attno - FirstLowInvalidHeapAttributeNumber;
- result = bms_add_member(result, index);
+ result = bms_add_member(result,
+ attno - FirstLowInvalidHeapAttributeNumber);
pfree(attname);
}
- bms_free(tmpset);
return result;
}
AclMode remainingPerms;
Oid relOid;
Oid userid;
- Bitmapset *tmpset;
int col;
/*
return false;
}
- tmpset = bms_copy(rte->selectedCols);
- while ((col = bms_first_member(tmpset)) >= 0)
+ col = -1;
+ while ((col = bms_next_member(rte->selectedCols, col)) >= 0)
{
- /* remove the column number offset */
- col += FirstLowInvalidHeapAttributeNumber;
- if (col == InvalidAttrNumber)
+ /* bit #s are offset by FirstLowInvalidHeapAttributeNumber */
+ AttrNumber attno = col + FirstLowInvalidHeapAttributeNumber;
+
+ if (attno == InvalidAttrNumber)
{
/* Whole-row reference, must have priv on all cols */
if (pg_attribute_aclcheck_all(relOid, userid, ACL_SELECT,
}
else
{
- if (pg_attribute_aclcheck(relOid, col, userid,
+ if (pg_attribute_aclcheck(relOid, attno, userid,
ACL_SELECT) != ACLCHECK_OK)
return false;
}
}
- bms_free(tmpset);
}
/*
return false;
}
- tmpset = bms_copy(rte->modifiedCols);
- while ((col = bms_first_member(tmpset)) >= 0)
+ col = -1;
+ while ((col = bms_next_member(rte->modifiedCols, col)) >= 0)
{
- /* remove the column number offset */
- col += FirstLowInvalidHeapAttributeNumber;
- if (col == InvalidAttrNumber)
+ /* bit #s are offset by FirstLowInvalidHeapAttributeNumber */
+ AttrNumber attno = col + FirstLowInvalidHeapAttributeNumber;
+
+ if (attno == InvalidAttrNumber)
{
/* whole-row reference can't happen here */
elog(ERROR, "whole-row update is not implemented");
}
else
{
- if (pg_attribute_aclcheck(relOid, col, userid,
+ if (pg_attribute_aclcheck(relOid, attno, userid,
remainingPerms) != ACLCHECK_OK)
return false;
}
}
- bms_free(tmpset);
}
}
return true;
return result;
}
-/*----------
+/*
* bms_first_member - find and remove first member of a set
*
* Returns -1 if set is empty. NB: set is destructively modified!
* 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)
+ * while ((x = bms_first_member(inputset)) >= 0)
* process member x;
- * bms_free(tmpset);
- *----------
+ *
+ * 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)
return -1;
}
+/*
+ * bms_next_member - find next member of a set
+ *
+ * Returns smallest member greater than "prevbit", or -2 if there is none.
+ * "prevbit" must NOT be less than -1, or the behavior is unpredictable.
+ *
+ * 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;
+ *
+ * Notice that when there are no more members, we return -2, not -1 as you
+ * might expect. The rationale for that is to allow distinguishing the
+ * loop-not-started state (x == -1) from the loop-completed state (x == -2).
+ * It makes no difference in simple loop usage, but complex iteration logic
+ * might need such an ability.
+ */
+int
+bms_next_member(const Bitmapset *a, int prevbit)
+{
+ int nwords;
+ int wordnum;
+ bitmapword mask;
+
+ if (a == NULL)
+ return -2;
+ 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;
+
+ 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 -2;
+}
+
/*
* bms_hash_value - compute a hash key for a Bitmapset
*
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)
+ x = -1;
+ while ((x = bms_next_member(bms, x)) >= 0)
appendStringInfo(str, " %d", x);
- bms_free(tmpset);
appendStringInfoChar(str, ')');
}
static void
print_relids(Relids relids)
{
- Relids tmprelids;
int x;
bool first = true;
- tmprelids = bms_copy(relids);
- while ((x = bms_first_member(tmprelids)) >= 0)
+ x = -1;
+ while ((x = bms_next_member(relids, x)) >= 0)
{
if (!first)
printf(" ");
printf("%d", x);
first = false;
}
- bms_free(tmprelids);
}
static void
{
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)
+ relid = -1;
+ while ((relid = bms_next_member(outer_relids, relid)) >= 0)
{
RelOptInfo *outer_rel;
if (result == 1.0 || result > outer_rel->rows)
result = outer_rel->rows;
}
- bms_free(outer_relids);
}
return result;
}
RestrictInfo *restrictinfo,
Relids join_relids)
{
- Relids tmprelids;
int cur_relid;
- tmprelids = bms_copy(join_relids);
- while ((cur_relid = bms_first_member(tmprelids)) >= 0)
+ 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);
}
- bms_free(tmprelids);
}
/*
RestrictInfo *restrictinfo,
Relids join_relids)
{
- Relids tmprelids;
int cur_relid;
- tmprelids = bms_copy(join_relids);
- while ((cur_relid = bms_first_member(tmprelids)) >= 0)
+ cur_relid = -1;
+ while ((cur_relid = bms_next_member(join_relids, cur_relid)) >= 0)
{
RelOptInfo *rel = find_base_rel(root, cur_relid);
Assert(list_member_ptr(rel->joininfo, restrictinfo));
rel->joininfo = list_delete_ptr(rel->joininfo, restrictinfo);
}
- bms_free(tmprelids);
}
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)
+ rtindex = -1;
+ while ((rtindex = bms_next_member(relids, rtindex)) >= 0)
{
RangeTblEntry *rte = rt_fetch(rtindex, root->parse->rtable);
else
result = bms_add_member(result, rtindex);
}
- bms_free(tmprelids);
return result;
}
adjust_view_column_set(Bitmapset *cols, List *targetlist)
{
Bitmapset *result = NULL;
- Bitmapset *tmpcols;
- AttrNumber col;
+ int col;
- tmpcols = bms_copy(cols);
- while ((col = bms_first_member(tmpcols)) >= 0)
+ col = -1;
+ while ((col = bms_next_member(cols, col)) >= 0)
{
/* bit numbers are offset by FirstLowInvalidHeapAttributeNumber */
AttrNumber attno = col + FirstLowInvalidHeapAttributeNumber;
attno);
}
}
- bms_free(tmpcols);
return result;
}
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)
+ rtindex = -1;
+ while ((rtindex = bms_next_member(relids, rtindex)) >= 0)
result = bms_add_member(result, rtindex + offset);
- bms_free(tmprelids);
return result;
}
/* 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);
*/
if (!bms_is_empty(expr->paramnos))
{
- Bitmapset *tmpset;
int dno;
paramLI = (ParamListInfo)
paramLI->numParams = estate->ndatums;
/* Instantiate values for "safe" parameters of the expression */
- tmpset = bms_copy(expr->paramnos);
- while ((dno = bms_first_member(tmpset)) >= 0)
+ dno = -1;
+ while ((dno = bms_next_member(expr->paramnos, dno)) >= 0)
{
PLpgSQL_datum *datum = estate->datums[dno];
prm->ptype = var->datatype->typoid;
}
}
- bms_free(tmpset);
/*
* Set up link to active expr where the hook functions can find it.
int paramno;
int dno;
StringInfoData paramstr;
- Bitmapset *tmpset;
if (!expr->paramnos)
return NULL;
initStringInfo(¶mstr);
- tmpset = bms_copy(expr->paramnos);
paramno = 0;
- while ((dno = bms_first_member(tmpset)) >= 0)
+ dno = -1;
+ while ((dno = bms_next_member(expr->paramnos, dno)) >= 0)
{
Datum paramdatum;
Oid paramtypeid;
paramno++;
}
- bms_free(tmpset);
return paramstr.data;
}