Skip to content

fix: Read None elements of UUID and Decimal lists as None - #7039

Open
spicysharkco wants to merge 1 commit into
feast-dev:masterfrom
spicysharkco:fix/none-in-uuid-decimal-lists
Open

spicysharkco wants to merge 1 commit into
feast-dev:masterfrom
spicysharkco:fix/none-in-uuid-decimal-lists

Conversation

@spicysharkco

Copy link
Copy Markdown

What this PR does / why we need it:

A None inside a UUID_LIST, TIME_UUID_LIST or DECIMAL_LIST is written to the proto as "" (_LIST_NONE_DEFAULTS in type_map.py, because a repeated string field cannot hold None). feast_value_type_to_python_type then calls UUID("") or Decimal("") on it. So the write works and the read fails:

fv = FeatureView(..., schema=[Field(name="u", dtype=Array(Uuid)), Field(name="dec", dtype=Array(Decimal))], ...)
store.apply([entity, fv])
df = pd.DataFrame({"id": [1], "event_timestamp": [...], "u": [[str(u), None]], "dec": [["1.5", None]]})
store.write_to_online_store("fv", df)
store.get_online_features(features=["fv:u", "fv:dec"], entity_rows=[{"id": 1}]).to_dict()
# raises ValueError: badly formed hexadecimal UUID string
# or decimal.InvalidOperation: [<class 'decimal.ConversionSyntax'>],
# depending on which column is converted first

With this change the same call returns {'u': [[UUID('...'), None]], 'dec': [[Decimal('1.5'), None]]}. The reader now maps "" to None for the three list types, the way the unix_timestamp_list_val branch maps its NULL_TIMESTAMP_INT_VALUE sentinel to None. The scalar and set branches are not touched.

Cause: the list readers and the "" default.

Which issue(s) this PR fixes:

No issue, found while checking list conversions in type_map.py.

Checks

  • I've made sure the tests are passing.
  • My commits are signed off (git commit -s)
  • My PR title follows conventional commits format

Testing Strategy

  • Unit tests
  • Integration tests

Added test_uuid_list_with_none_roundtrip, test_time_uuid_list_with_none_roundtrip and test_decimal_list_with_none_roundtrip to sdk/python/tests/unit/test_type_map.py. All three fail on master with the errors above and pass with the fix: pytest sdk/python/tests/unit/test_type_map.py -k with_none_roundtrip gives 3 passed. The rest of the file passes apart from TestSparkNativeTypeValidation (needs pyspark). ruff check and ruff format --check are clean on both files.

A None element in a UUID_LIST, TIME_UUID_LIST or DECIMAL_LIST is written
as "" (see _LIST_NONE_DEFAULTS), but feast_value_type_to_python_type
passed every element to UUID() or Decimal(). The write succeeded and
reading the row back raised ValueError or InvalidOperation. Read "" back
as None, as the unix timestamp list reader already does for its null
sentinel.

Signed-off-by: spicysharkco <321699413+spicysharkco@users.noreply.github.com>
@spicysharkco
spicysharkco requested a review from a team as a code owner October 19, 2026 02:13

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants