Repository navigation
fix: Preserve Dask historical requests without eligible features - #7000
Conversation
Signed-off-by: NUAAwqy <[email protected]>
| # Null candidates sort first, so deduplication still prefers a valid match. | ||
| return df_to_join.assign( | ||
| **{ | ||
| column: df_to_join[column].mask(~valid) |
There was a problem hiding this comment.
The fix works (13/14 new tests fail on master, all pass here), but .mask() turns Int64 features into float64 even when nothing ends up null (I got trips [7, 8] → [7.0, 8.0]). Could you keep the TTL filter and add back only the requests that lost all their candidates, as null rows?
Use pandas' nullable missing value when retaining entity rows whose feature candidate is outside the TTL window. This keeps integer feature columns from being widened to float64 while preserving the existing candidate filtering behavior. Add a regression test for integer feature values. Prepared with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]>
af2f161 to
0c8ba98
Compare
| column: df_to_join[column].mask(~valid) | ||
| # Use pandas' nullable missing value so integer feature columns do not | ||
| # get silently widened to float64 when an ineligible candidate is nulled. | ||
| column: df_to_join[column].mask(~valid, other=pd.NA) |
There was a problem hiding this comment.
Thanks for the update! I think other=pd.NA doesn’t change anything here: a plain int64 column still becomes float64 (I tested on pandas 2.3.3). The new test uses nullable Int64, so it passes even without this change. Could you switch it to plain int64?
Cast integer feature columns to pandas nullable integer dtypes before masking expired candidates, so ordinary int64 inputs do not widen to float64 when the left-join request row is preserved. Add a regression covering the plain int64 source case. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]>
Cast integer feature columns to pandas nullable integer dtypes before masking expired candidates, so ordinary int64 inputs do not widen to float64 when the left-join request row is preserved. Add a regression covering the plain int64 source case. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]>
Cast integer feature columns to pandas nullable integer dtypes before masking expired candidates, so ordinary int64 inputs do not widen to float64 when the left-join request row is preserved. Add a regression covering the plain int64 source case. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]>
Keep valid feature candidates unchanged and add a null-feature row only when every candidate for a request is outside the TTL window. This preserves ordinary integer dtypes when a valid candidate exists while retaining left-join behavior for expired requests. Prepared with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]>
a25d1d4 to
7de0ebf
Compare
Keep eligible rows unchanged and re-add null rows only for requests with no eligible candidates, preserving integer feature dtypes. Signed-off-by: NUAAwqy <[email protected]>
Return the filtered Dask frame unchanged when every request has an eligible candidate, and cover this path with a direct plain-int64 regression test. Signed-off-by: NUAAwqy <[email protected]>
patelchaitany
left a comment
There was a problem hiding this comment.
Thanks, the dtype handling looks good now! Two issues with multi-file sources (more than one Dask partition), which the current tests don't cover since they use a single file. Could you add a test with a multi-file source?
|
|
||
| # If every request has an eligible candidate, return the filtered frame | ||
| # unchanged so plain integer feature columns keep their original dtype. | ||
| if missing_requests.head(1).empty: |
There was a problem hiding this comment.
Dask's head() only checks the first partition by default, so with a multi-file source a lost request in a later partition is missed and its row is dropped again (I reproduced this with 6 files). missing_requests.head(1, npartitions=-1).empty fixed it for me.
| how="left", | ||
| ) | ||
| ttl_missing = marked["__ttl_missing"].fillna(False) | ||
| marked = marked[valid | ttl_missing] |
There was a problem hiding this comment.
With a multi-file source this raises IndexError: indices are out-of-bounds: valid comes from df_to_join, but the merge reorders rows in marked. Carrying it through the merge fixed it for me:
marked = df_to_join.assign(__ttl_valid=valid).merge(...)
marked = marked[marked["__ttl_valid"] | ttl_missing].drop(columns=["__ttl_valid"])Keep only requests that lose every eligible TTL candidate in the null-row path, so matched plain integer feature columns retain their dtype. Add regression coverage for both missing and all-matched requests. Signed-off-by: NUAAwqy <[email protected]>
Preserve entity requests whose feature candidates all fall outside the TTL window without relying on the first Dask partition to detect missing rows. Carry the TTL validity mask through the merge so row reordering cannot apply stale indices, and cover multi-partition sources with a regression test. The focused Dask TTL suite passes (17 tests), along with Ruff, formatting, and diff checks. Prepared with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]>
Cast integer feature columns to pandas nullable integer dtypes before masking expired candidates, so ordinary int64 inputs do not widen to float64 when the left-join request row is preserved. Add a regression covering the plain int64 source case. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]>
Cast integer feature columns to pandas nullable integer dtypes before masking expired candidates, so ordinary int64 inputs do not widen to float64 when the left-join request row is preserved. Add a regression covering the plain int64 source case. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]>
Keep missing requests from later Dask partitions when TTL filtering re-adds the left-join row, and preserve ordinary integer feature dtypes when masking expired candidates. Extend regression coverage for multi-file inputs and plain int64 source columns. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]>
Keep missing requests from later Dask partitions when TTL filtering re-adds the left-join row, and preserve ordinary integer feature dtypes when masking expired candidates. Extend regression coverage for multi-file inputs and plain int64 source columns. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]>
Keep missing requests from later Dask partitions when TTL filtering re-adds the left-join row, and preserve ordinary integer feature dtypes when masking expired candidates. Extend regression coverage for multi-file inputs and plain int64 source columns. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]>
Keep missing requests from later Dask partitions when TTL filtering re-adds the left-join row, and preserve ordinary integer feature dtypes when masking expired candidates. Extend regression coverage for multi-file inputs and plain int64 source columns. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]>
Keep missing requests from later Dask partitions and preserve plain integer feature dtypes when TTL filtering. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]>
Preserve unmatched entity requests without widening integer feature columns. Add regressions for plain integer values, later Dask partitions, and merge row reordering. Signed-off-by: NUAAwqy <[email protected]>
Keep missing requests from later Dask partitions when TTL filtering re-adds the left-join row, and preserve ordinary integer feature dtypes when masking expired candidates. Extend regression coverage for multi-file inputs and plain int64 source columns. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]>
Keep missing requests from later Dask partitions when TTL filtering re-adds the left-join row, and preserve ordinary integer feature dtypes when masking expired candidates. Extend regression coverage for multi-file inputs and plain int64 source columns. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]>
Keep missing requests from later Dask partitions when TTL filtering re-adds the left-join row, and preserve ordinary integer feature dtypes when masking expired candidates. Extend regression coverage for multi-file inputs and plain int64 source columns. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]>
Keep missing requests from later Dask partitions when TTL filtering re-adds the left-join row, and preserve ordinary integer feature dtypes when masking expired candidates. Extend regression coverage for multi-file inputs and plain int64 source columns. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]>
Keep missing requests from later Dask partitions when TTL filtering re-adds the left-join row, and preserve ordinary integer feature dtypes when masking expired candidates. Extend regression coverage for multi-file inputs and plain int64 source columns. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]>
patelchaitany
left a comment
There was a problem hiding this comment.
Thanks for the updates! LGTM, I verified with 1 and 6 parquet files and the dtypes look right now. Small non-blocking note: an entity dataframe with a list column now fails with unhashable type: list in drop_duplicates. Using only join keys + entity timestamp as request_columns (like _drop_duplicates) would avoid it.
Use only join keys and the entity timestamp to identify requests when restoring rows that have no eligible feature candidates. Preserve list-valued entity columns without requiring them to be hashable. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]>
Use only join keys and the entity timestamp to identify requests when restoring rows that have no eligible feature candidates. Preserve list-valued entity columns without requiring them to be hashable. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]>
Prepared and tested with Codex assistance. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]>
Use only join keys and the entity timestamp to identify requests when restoring rows that have no eligible feature candidates. Preserve list-valued entity columns without requiring them to be hashable. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]>
Use only join keys and the entity timestamp to identify requests when restoring rows that have no eligible feature candidates. Preserve list-valued entity columns without requiring them to be hashable. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]>
Use only join keys and the entity timestamp to identify requests when restoring rows that have no eligible feature candidates. Preserve list-valued entity columns without requiring them to be hashable. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]>
Use only join keys and the entity timestamp to identify requests when restoring rows that have no eligible feature candidates. Preserve list-valued entity columns without requiring them to be hashable. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]>
Keep the existing TTL filtering and restore only requests with no eligible candidate. Use all Dask partitions when checking missing requests and carry validity through the merge. Signed-off-by: NUAAwqy <[email protected]>
a448943 to
b4dc32c
Compare
|
@patelchaitany the non-blocking note is addressed in the follow-up commits: |
Keep plain integer feature columns unchanged when all requests have eligible matches, and restore null rows only for requests that lose every candidate across Dask partitions. Signed-off-by: NUAAwqy <[email protected]>
# [0.68.0](v0.67.0...v0.68.0) (2026-11-10) ### Bug Fixes * add watch verb on clusterroles and clusterrolebindings for feast-operator ([#7062](#7062)) ([b6bdda4](b6bdda4)) * Apply on demand feature views in SparkRetrievalJob.to_spark_df() ([#6993](#6993)) ([f416309](f416309)) * Break event timestamp ties by created timestamp in Milvus write batches ([#7084](#7084)) ([bbaca76](bbaca76)) * Break event timestamp ties by created timestamp in the Dask offline store ([#6952](#6952)) ([eb93b08](eb93b08)) * Build the Go feature server image in two stages ([1e5e90c](1e5e90c)), closes [#7060](#7060) * Fall back to the serialized body when UDF source misses globals ([#6816](#6816)) ([f61079f](f61079f)) * Install patched libbrotli1 to address DSA-6582-1 ([#7096](#7096)) ([d458393](d458393)) * Keep description, tags and nested types of ODFV schema fields ([8ef6e75](8ef6e75)) * Keep entity columns out of StreamFeatureView proto features ([#7033](#7033)) ([d520584](d520584)) * Keep the metrics server running when a Gunicorn worker exits ([#7012](#7012)) ([68c5d54](68c5d54)), closes [#7011](#7011) * Key registry proto caches on the proto, not its id() ([#7085](#7085)) ([147adad](147adad)) * Log ODFV materialization skips instead of printing them ([#7117](#7117)) ([8fdcee7](8fdcee7)) * Pin build dependencies of source builds to the CI lock ([#7104](#7104)) ([dec2f24](dec2f24)) * Populate spec.project in registry REST feature view responses (#… ([#7037](#7037)) ([e304a84](e304a84)) * Preserve colliding source timestamps in Dask retrieval ([#7071](#7071)) ([1396c88](1396c88)) * Preserve Dask historical requests without eligible features ([#7000](#7000)) ([fff09f7](fff09f7)) * Read None elements of UUID and Decimal lists as None ([#7039](#7039)) ([03f30fe](03f30fe)) * Retire the support of Python3.10 ([#7101](#7101)) ([a56766e](a56766e)), closes [#7104](#7104) [#7089](#7089) [#7106](#7106) [#7105](#7105) * Serialize UUID and TimeUuid entity keys ([#7032](#7032)) ([0c845a1](0c845a1)) * Stop the Ray engine from hiding materialization errors ([#7026](#7026)) ([7903e2e](7903e2e)), closes [#7024](#7024) * **ui:** stop treating the monitoring baseline as the latest window ([#7056](#7056)) ([0f01802](0f01802)), closes [#7054](#7054) * Use date-only bounds for partition filters built from string timestamps ([#7116](#7116)) ([b1f2168](b1f2168)) * Validate entity column types in feast dbt import ([#7067](#7067)) ([abca80c](abca80c)), closes [#5876](#5876) * Warm up the whole DynamoDB connection pool ([#6985](#6985)) ([8ce548c](8ce548c)) ### Features * Add --gc-freeze option to feast serve ([#7089](#7089)) ([aad0c15](aad0c15)) * Add native complex types and scalar index tags to the Milvus online store ([#7120](#7120)) ([f7068d6](f7068d6)) * Add num_partitions and partition_key_isolation to the Milvus online store ([#7083](#7083)) ([68de84e](68de84e)), closes [#6940](#6940) * Add Pinecone online store integration ([#6585](#6585)) ([7a84f2a](7a84f2a)) * Add PolarisSource and PolarisProvider for Apache Polaris ([#7006](#7006)) ([386759c](386759c)) * Add row deletion to the Milvus online store ([#7082](#7082)) ([d3e2041](d3e2041)) * Add upstream FeatureView lineage support for PushSource ([#6853](#6853)) ([c9b9d72](c9b9d72)) * Optional nameless pre-computed vectors with a schema fingerprint ([#7077](#7077)) ([9420fac](9420fac)) ### Performance Improvements * Scan Lance sources lazily in the DuckDB offline store ([1299e4e](1299e4e))
…st-dev#7000) * fix: Preserve Dask historical requests without eligible features Signed-off-by: NUAAwqy <[email protected]> * fix: preserve integer dtypes when masking expired Dask features Use pandas' nullable missing value when retaining entity rows whose feature candidate is outside the TTL window. This keeps integer feature columns from being widened to float64 while preserving the existing candidate filtering behavior. Add a regression test for integer feature values. Prepared with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> * fix: preserve integer dtypes when masking expired features Cast integer feature columns to pandas nullable integer dtypes before masking expired candidates, so ordinary int64 inputs do not widen to float64 when the left-join request row is preserved. Add a regression covering the plain int64 source case. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]> * fix: preserve integer dtypes when masking expired features Cast integer feature columns to pandas nullable integer dtypes before masking expired candidates, so ordinary int64 inputs do not widen to float64 when the left-join request row is preserved. Add a regression covering the plain int64 source case. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]> * fix: preserve integer dtypes when masking expired features Cast integer feature columns to pandas nullable integer dtypes before masking expired candidates, so ordinary int64 inputs do not widen to float64 when the left-join request row is preserved. Add a regression covering the plain int64 source case. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]> * fix: preserve Dask TTL request dtypes Keep valid feature candidates unchanged and add a null-feature row only when every candidate for a request is outside the TTL window. This preserves ordinary integer dtypes when a valid candidate exists while retaining left-join behavior for expired requests. Prepared with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> * fix: preserve feature dtypes when restoring TTL rows Keep eligible rows unchanged and re-add null rows only for requests with no eligible candidates, preserving integer feature dtypes. Signed-off-by: NUAAwqy <[email protected]> * fix: retain plain integer dtype when no TTL rows are missing Return the filtered Dask frame unchanged when every request has an eligible candidate, and cover this path with a direct plain-int64 regression test. Signed-off-by: NUAAwqy <[email protected]> * fix: preserve request rows without widening matched integer features Keep only requests that lose every eligible TTL candidate in the null-row path, so matched plain integer feature columns retain their dtype. Add regression coverage for both missing and all-matched requests. Signed-off-by: NUAAwqy <[email protected]> * fix: Handle Dask TTL filtering across partitions Preserve entity requests whose feature candidates all fall outside the TTL window without relying on the first Dask partition to detect missing rows. Carry the TTL validity mask through the merge so row reordering cannot apply stale indices, and cover multi-partition sources with a regression test. The focused Dask TTL suite passes (17 tests), along with Ruff, formatting, and diff checks. Prepared with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> * fix: preserve integer dtypes when masking expired features Cast integer feature columns to pandas nullable integer dtypes before masking expired candidates, so ordinary int64 inputs do not widen to float64 when the left-join request row is preserved. Add a regression covering the plain int64 source case. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]> * fix: preserve integer dtypes when masking expired features Cast integer feature columns to pandas nullable integer dtypes before masking expired candidates, so ordinary int64 inputs do not widen to float64 when the left-join request row is preserved. Add a regression covering the plain int64 source case. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]> * fix: preserve integer dtypes and multi-file TTL requests Keep missing requests from later Dask partitions when TTL filtering re-adds the left-join row, and preserve ordinary integer feature dtypes when masking expired candidates. Extend regression coverage for multi-file inputs and plain int64 source columns. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]> * fix: preserve integer dtypes and multi-file TTL requests Keep missing requests from later Dask partitions when TTL filtering re-adds the left-join row, and preserve ordinary integer feature dtypes when masking expired candidates. Extend regression coverage for multi-file inputs and plain int64 source columns. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]> * fix: preserve integer dtypes and multi-file TTL requests Keep missing requests from later Dask partitions when TTL filtering re-adds the left-join row, and preserve ordinary integer feature dtypes when masking expired candidates. Extend regression coverage for multi-file inputs and plain int64 source columns. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]> * fix: preserve integer dtypes and multi-file TTL requests Keep missing requests from later Dask partitions when TTL filtering re-adds the left-join row, and preserve ordinary integer feature dtypes when masking expired candidates. Extend regression coverage for multi-file inputs and plain int64 source columns. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]> * fix: preserve Dask TTL rows across partitions Keep missing requests from later Dask partitions and preserve plain integer feature dtypes when TTL filtering. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]> * Fix Dask TTL filtering across partitions Preserve unmatched entity requests without widening integer feature columns. Add regressions for plain integer values, later Dask partitions, and merge row reordering. Signed-off-by: NUAAwqy <[email protected]> * fix: preserve integer dtypes and multi-file TTL requests Keep missing requests from later Dask partitions when TTL filtering re-adds the left-join row, and preserve ordinary integer feature dtypes when masking expired candidates. Extend regression coverage for multi-file inputs and plain int64 source columns. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]> * fix: preserve integer dtypes and multi-file TTL requests Keep missing requests from later Dask partitions when TTL filtering re-adds the left-join row, and preserve ordinary integer feature dtypes when masking expired candidates. Extend regression coverage for multi-file inputs and plain int64 source columns. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]> * fix: preserve integer dtypes and multi-file TTL requests Keep missing requests from later Dask partitions when TTL filtering re-adds the left-join row, and preserve ordinary integer feature dtypes when masking expired candidates. Extend regression coverage for multi-file inputs and plain int64 source columns. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]> * fix: preserve integer dtypes and multi-file TTL requests Keep missing requests from later Dask partitions when TTL filtering re-adds the left-join row, and preserve ordinary integer feature dtypes when masking expired candidates. Extend regression coverage for multi-file inputs and plain int64 source columns. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]> * fix: preserve integer dtypes and multi-file TTL requests Keep missing requests from later Dask partitions when TTL filtering re-adds the left-join row, and preserve ordinary integer feature dtypes when masking expired candidates. Extend regression coverage for multi-file inputs and plain int64 source columns. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]> * fix: avoid hashing preserved entity columns in TTL filtering Use only join keys and the entity timestamp to identify requests when restoring rows that have no eligible feature candidates. Preserve list-valued entity columns without requiring them to be hashable. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]> * fix: avoid hashing preserved entity columns in TTL filtering Use only join keys and the entity timestamp to identify requests when restoring rows that have no eligible feature candidates. Preserve list-valued entity columns without requiring them to be hashable. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]> * fix: preserve Dask TTL request identity across partitions Prepared and tested with Codex assistance. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]> * fix: avoid hashing preserved columns in TTL request matching Use only join keys and the entity timestamp to identify requests when restoring rows that have no eligible feature candidates. Preserve list-valued entity columns without requiring them to be hashable. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> * fix: avoid hashing preserved entity columns in TTL filtering Use only join keys and the entity timestamp to identify requests when restoring rows that have no eligible feature candidates. Preserve list-valued entity columns without requiring them to be hashable. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]> * fix: avoid hashing preserved entity columns in TTL filtering Use only join keys and the entity timestamp to identify requests when restoring rows that have no eligible feature candidates. Preserve list-valued entity columns without requiring them to be hashable. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]> * fix: avoid hashing preserved entity columns in TTL filtering Use only join keys and the entity timestamp to identify requests when restoring rows that have no eligible feature candidates. Preserve list-valued entity columns without requiring them to be hashable. Prepared and tested with Codex assistance; no human review is claimed. Signed-off-by: NUAAwqy <[email protected]> Co-Authored-By: Codex <[email protected]> * fix: preserve Dask request rows across partitions Keep the existing TTL filtering and restore only requests with no eligible candidate. Use all Dask partitions when checking missing requests and carry validity through the merge. Signed-off-by: NUAAwqy <[email protected]> * fix: preserve Dask TTL request dtypes Keep plain integer feature columns unchanged when all requests have eligible matches, and restore null rows only for requests that lose every candidate across Dask partitions. Signed-off-by: NUAAwqy <[email protected]> --------- Signed-off-by: NUAAwqy <[email protected]> Signed-off-by: NUAAwqy <[email protected]> Co-authored-by: Codex <[email protected]> Co-authored-by: NUAAwqy <[email protected]> Co-authored-by: Shuchu Han <[email protected]> Signed-off-by: Shuchu Han <[email protected]>
# [0.68.0](feast-dev/feast@v0.67.0...v0.68.0) (2026-11-10) ### Bug Fixes * add watch verb on clusterroles and clusterrolebindings for feast-operator ([feast-dev#7062](feast-dev#7062)) ([b6bdda4](feast-dev@b6bdda4)) * Apply on demand feature views in SparkRetrievalJob.to_spark_df() ([feast-dev#6993](feast-dev#6993)) ([f416309](feast-dev@f416309)) * Break event timestamp ties by created timestamp in Milvus write batches ([feast-dev#7084](feast-dev#7084)) ([bbaca76](feast-dev@bbaca76)) * Break event timestamp ties by created timestamp in the Dask offline store ([feast-dev#6952](feast-dev#6952)) ([eb93b08](feast-dev@eb93b08)) * Build the Go feature server image in two stages ([1e5e90c](feast-dev@1e5e90c)), closes [feast-dev#7060](feast-dev#7060) * Fall back to the serialized body when UDF source misses globals ([feast-dev#6816](feast-dev#6816)) ([f61079f](feast-dev@f61079f)) * Install patched libbrotli1 to address DSA-6582-1 ([feast-dev#7096](feast-dev#7096)) ([d458393](feast-dev@d458393)) * Keep description, tags and nested types of ODFV schema fields ([8ef6e75](feast-dev@8ef6e75)) * Keep entity columns out of StreamFeatureView proto features ([feast-dev#7033](feast-dev#7033)) ([d520584](feast-dev@d520584)) * Keep the metrics server running when a Gunicorn worker exits ([feast-dev#7012](feast-dev#7012)) ([68c5d54](feast-dev@68c5d54)), closes [feast-dev#7011](feast-dev#7011) * Key registry proto caches on the proto, not its id() ([feast-dev#7085](feast-dev#7085)) ([147adad](feast-dev@147adad)) * Log ODFV materialization skips instead of printing them ([feast-dev#7117](feast-dev#7117)) ([8fdcee7](feast-dev@8fdcee7)) * Pin build dependencies of source builds to the CI lock ([feast-dev#7104](feast-dev#7104)) ([dec2f24](feast-dev@dec2f24)) * Populate spec.project in registry REST feature view responses (#… ([feast-dev#7037](feast-dev#7037)) ([e304a84](feast-dev@e304a84)) * Preserve colliding source timestamps in Dask retrieval ([feast-dev#7071](feast-dev#7071)) ([1396c88](feast-dev@1396c88)) * Preserve Dask historical requests without eligible features ([feast-dev#7000](feast-dev#7000)) ([fff09f7](feast-dev@fff09f7)) * Read None elements of UUID and Decimal lists as None ([feast-dev#7039](feast-dev#7039)) ([03f30fe](feast-dev@03f30fe)) * Retire the support of Python3.10 ([feast-dev#7101](feast-dev#7101)) ([a56766e](feast-dev@a56766e)), closes [feast-dev#7104](feast-dev#7104) [feast-dev#7089](feast-dev#7089) [feast-dev#7106](feast-dev#7106) [feast-dev#7105](feast-dev#7105) * Serialize UUID and TimeUuid entity keys ([feast-dev#7032](feast-dev#7032)) ([0c845a1](feast-dev@0c845a1)) * Stop the Ray engine from hiding materialization errors ([feast-dev#7026](feast-dev#7026)) ([7903e2e](feast-dev@7903e2e)), closes [feast-dev#7024](feast-dev#7024) * **ui:** stop treating the monitoring baseline as the latest window ([feast-dev#7056](feast-dev#7056)) ([0f01802](feast-dev@0f01802)), closes [feast-dev#7054](feast-dev#7054) * Use date-only bounds for partition filters built from string timestamps ([feast-dev#7116](feast-dev#7116)) ([b1f2168](feast-dev@b1f2168)) * Validate entity column types in feast dbt import ([feast-dev#7067](feast-dev#7067)) ([abca80c](feast-dev@abca80c)), closes [feast-dev#5876](feast-dev#5876) * Warm up the whole DynamoDB connection pool ([feast-dev#6985](feast-dev#6985)) ([8ce548c](feast-dev@8ce548c)) ### Features * Add --gc-freeze option to feast serve ([feast-dev#7089](feast-dev#7089)) ([aad0c15](feast-dev@aad0c15)) * Add native complex types and scalar index tags to the Milvus online store ([feast-dev#7120](feast-dev#7120)) ([f7068d6](feast-dev@f7068d6)) * Add num_partitions and partition_key_isolation to the Milvus online store ([feast-dev#7083](feast-dev#7083)) ([68de84e](feast-dev@68de84e)), closes [feast-dev#6940](feast-dev#6940) * Add Pinecone online store integration ([feast-dev#6585](feast-dev#6585)) ([7a84f2a](feast-dev@7a84f2a)) * Add PolarisSource and PolarisProvider for Apache Polaris ([feast-dev#7006](feast-dev#7006)) ([386759c](feast-dev@386759c)) * Add row deletion to the Milvus online store ([feast-dev#7082](feast-dev#7082)) ([d3e2041](feast-dev@d3e2041)) * Add upstream FeatureView lineage support for PushSource ([feast-dev#6853](feast-dev#6853)) ([c9b9d72](feast-dev@c9b9d72)) * Optional nameless pre-computed vectors with a schema fingerprint ([feast-dev#7077](feast-dev#7077)) ([9420fac](feast-dev@9420fac)) ### Performance Improvements * Scan Lance sources lazily in the DuckDB offline store ([1299e4e](feast-dev@1299e4e)) Signed-off-by: Shuchu Han <[email protected]>
What this PR does / why we need it:
Dask/File historical retrieval currently drops an entity request when matching source records exist but all are expired or future-dated. For example, a five-row entity dataframe with expired, future, valid, boundary, and missing-source cases returns only three rows with a one-day TTL. Caller-supplied labels disappear too, and a later feature view can erase valid features joined earlier.
Preserve the entity side of the left join by nulling the current feature view's ineligible columns before deduplication. Keep valid candidates preferred over null candidates and retain previously joined features. Non-entity snapshot retrieval keeps its existing filtering behavior.
Add 14 regressions using actual Parquet files, a local registry, and the public FeatureStore API. They cover nonzero/zero/unset TTL, the inclusive boundary, mixed valid and invalid candidates, both feature-name modes, both created-timestamp-filter settings, label preservation, multiple feature views, input immutability, and non-entity snapshots. Update the Dask store documentation.
Which issue(s) this PR fixes:
Fixes #6999
This addresses out-of-window source candidates, independently of duplicate input requests in #6787.
Checks
git commit -s).Testing Strategy
Validation on Python 3.11:
Misc
Implementation and test execution were assisted by Codex.
Follow-up validation for the requested plain-integer regression:
the original test used pandas nullable Int64 and therefore did not exercise the reported widening. The updated test starts with ordinary int64 source data; the implementation converts integer feature columns to the matching nullable integer dtype before masking. The focused TTL test file passes (15 passed), and Ruff check, Ruff format, and diff checks pass. Prepared and tested with Codex assistance; no human review is claimed.
Follow-up validation for the requested plain-integer and multi-file regressions:
the original test used pandas nullable Int64 and therefore did not exercise the reported widening. The updated test starts with ordinary int64 source data; the implementation converts integer feature columns to the matching nullable integer dtype before masking. The focused TTL test file passes (17 passed), and Ruff check, Ruff format, and diff checks pass. Prepared and tested with Codex assistance; no human review is claimed.
Follow-up validation for the reported list-valued entity column regression:
the previous implementation included every preserved entity column in the request-key deduplication, so a list-valued label raised
TypeError: unhashable type: 'list'. The update keys missing-request restoration only by join keys and entity timestamp, with a focused regression covering list-valued preserved data. The Dask TTL test file passes (19 passed), the related Dask checks pass (43 passed, 5 skipped for optional backends), Ruff, mypy, and diff checks pass. Prepared with Codex assistance; no human review is claimed.Follow-up validation for the reported list-valued entity column regression:
The prior request-key deduplication included every preserved entity column, so list-valued labels could raise
TypeError: unhashable type: 'list'. The follow-up keys missing-request restoration only by join keys and entity timestamp, and adds focused coverage. Validation: focused TTL tests 19 passed; related Dask tests 43 passed, 5 skipped for optional backends; Ruff check/format andgit diff --checkpassed. Prepared and tested with Codex assistance; no human review is claimed.