Skip to content

bigtable: add ValueBitmaskFilter for data client#17567

Open
mutianf wants to merge 9 commits into
googleapis:mainfrom
mutianf:pr-17252
Open

bigtable: add ValueBitmaskFilter for data client#17567
mutianf wants to merge 9 commits into
googleapis:mainfrom
mutianf:pr-17252

Conversation

@mutianf

@mutianf mutianf commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly:

  • Make sure to open an issue as a bug/issue before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea
  • Ensure the tests and linter pass
  • Code coverage does not decrease (if any source code was changed)
  • Appropriate docs were updated (if necessary)

Fixes #<issue_number_goes_here> 🦕

@mutianf mutianf requested a review from a team as a code owner June 24, 2026 18:26

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the ValueBitmaskFilter class to support value bitmask row filters, along with corresponding unit tests. The review feedback correctly identifies that in the Bigtable V2 API, value_bitmask_filter is a direct bytes field rather than a nested message. Consequently, the _to_dict implementation and both unit tests (test_to_dict and test_to_pb) need to be updated to map the mask directly to value_bitmask_filter to avoid runtime errors and match the API schema.

Comment on lines +510 to +512
def _to_dict(self) -> dict[str, Any]:
"""Converts the row filter to a dict representation."""
return {"value_bitmask_filter": {"mask": self.mask}}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

In the Bigtable V2 API, value_bitmask_filter is a bytes field, not a message with a mask field. Therefore, _to_dict should return {"value_bitmask_filter": self.mask} directly rather than nesting it under a "mask" key.

Suggested change
def _to_dict(self) -> dict[str, Any]:
"""Converts the row filter to a dict representation."""
return {"value_bitmask_filter": {"mask": self.mask}}
def _to_dict(self) -> dict[str, bytes]:
"""Converts the row filter to a dict representation."""
return {"value_bitmask_filter": self.mask}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is right. The proto is a ValueBitMask message with a mask field.

Comment on lines +1997 to +2001
def test_to_dict(self):
mask = b"\xaa" * 8
row_filter = self._target_class()(mask)
expected = {"value_bitmask_filter": {"mask": mask}}
assert row_filter._to_dict() == expected

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Update the expected dictionary format to match the corrected _to_dict implementation where value_bitmask_filter maps directly to the bytes mask.

Suggested change
def test_to_dict(self):
mask = b"\xaa" * 8
row_filter = self._target_class()(mask)
expected = {"value_bitmask_filter": {"mask": mask}}
assert row_filter._to_dict() == expected
def test_to_dict(self):
mask = b"\xaa" * 8
row_filter = self._target_class()(mask)
expected = {"value_bitmask_filter": mask}
assert row_filter._to_dict() == expected

Comment on lines +2003 to +2007
def test_to_pb(self):
mask = b"\xaa" * 8
row_filter = self._target_class()(mask)
pb = row_filter._to_pb()
assert pb.value_bitmask_filter.mask == mask

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Since value_bitmask_filter is a bytes field in the protobuf definition, accessing .mask on it will raise an AttributeError. Assert directly against pb.value_bitmask_filter.

Suggested change
def test_to_pb(self):
mask = b"\xaa" * 8
row_filter = self._target_class()(mask)
pb = row_filter._to_pb()
assert pb.value_bitmask_filter.mask == mask
def test_to_pb(self):
mask = b"\xaa" * 8
row_filter = self._target_class()(mask)
pb = row_filter._to_pb()
assert pb.value_bitmask_filter == mask

@mutianf

mutianf commented Jun 24, 2026

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the ValueBitmaskFilter class to support filtering Bigtable cells using a bitmask condition, along with corresponding unit and system tests. The reviewer suggested improving the comparison logic in ValueBitmaskFilter by removing the redundant __ne__ method and using the class name directly in isinstance checks. Additionally, the reviewer recommended specifying row_keys in the system tests to avoid inefficient full table scans and prevent potential test flakiness.

Comment thread packages/google-cloud-bigtable/google/cloud/bigtable/data/row_filters.py Outdated
Comment thread packages/google-cloud-bigtable/tests/system/data/test_system_async.py Outdated
mutianf and others added 2 commits June 24, 2026 16:36
…filters.py

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
…sync.py

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants