-
[OPIK-4518] [BE] Restore stable dataset item IDs in versioned API (#5370)
发布于
2026-03-24 11:56:11 +00:00 - [OPIK-4518] [BE] Restore stable dataset item IDs in versioned API
After dataset versioning was introduced, the old API endpoints started
returning version-specific row IDs (changing per version) as theid
field instead of the stabledataset_item_id. This broke user flows
where items would get new IDs with each new version snapshot.Fix: expose
dataset_item_id AS idin all versioned item queries so
theidfield is stable across versions. Update streaming pagination
cursor to usedataset_item_idinstead of rowid. Remove the
row-ID-to-dataset-item-ID mapping logic in the service since incoming
idvalues are now already stabledataset_item_ids.- fix(backend): clean up review issues in stable dataset item IDs
- Remove unused workspaceId param from getDatasetItemWorkspace DAO
(query is intentionally unscoped for cross-workspace validation) - Fix allMatch validation gap in ExperimentItemService: verify all
requested item IDs were found before checking workspace ownership - Remove identity map indirection from editItemsViaSelectInsert now
that IDs are stable dataset_item_ids
- fix(backend): renumber migration files to avoid conflicts with main
000062 → 000065, 000063 → 000066 (skip indexes and projection for
dataset_item_id). Updated changeset IDs inside files to match.-
fix(backend): clarify DatasetItemEdit.id is the stable dataset_item_id
-
Fix warnings on updated code
-
feat(backend): resolve experiment dataset_item_id in trace queries
Resolve old physical row IDs to stable dataset_item_ids in the
experiments_agg CTE using a targeted LEFT JOIN to
dataset_item_versions. No dedup needed since id and dataset_item_id
are immutable columns.Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
- chore(backend): remove manual data migration for experiment items
The dual-join approach handles both old (physical row ID) and new
(stable dataset_item_id) experiment items at query time, making
the manual migration unnecessary.Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
- feat(backend): dual-join all experiment-item queries for backward compat
All queries joining experiment_items.dataset_item_id with
dataset_item_versions now match on both physical row id AND stable
dataset_item_id, so old experiment items (storing row IDs) and new
ones (storing stable IDs) both resolve correctly without requiring
a data migration.Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
- fix(backend): renumber migrations 000065/000066 → 000070/000071
Avoid collision with main's 000065-000069 added since last rebase.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
- fix(backend): renumber migrations 000070/000071 → 000073/000074
Main now has 000070-000072, so bump to next available.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
- fix(backend): use if() instead of COALESCE for FixedString LEFT JOIN
ClickHouse FixedString(36) columns return null bytes (not SQL NULL)
on LEFT JOIN miss, so COALESCE never falls through. Use if(div.id != '')
to check whether the join actually matched.Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
- chore(backend): remove ClickHouse projection migration
Defer the dataset_item_id projection to a follow-up. The skip indexes
(000073) provide sufficient coverage for now. The projection can be
added later if large-version performance requires it.Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
- perf(backend): use arrayJoin to avoid duplicate CTE evaluation
Consolidate OR-expanded filter conditions that referenced the same CTE
twice into single arrayJoin([col1, col2]) calls. Each CTE is now
evaluated exactly once per usage site.Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
- fix(backend): rename skip indexes to follow naming convention
Use idx_{table}_{column} pattern: idx_dataset_item_versions_dataset_item_id_bf
and idx_dataset_item_versions_dataset_item_id_minmax.Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
- fix(backend): restore optimized SELECT_EXPERIMENT_ITEMS_OUTPUT_COLUMNS
Revert to main's simpler query that resolves trace_ids directly from
experiment_items without joining dataset_item_versions. The dual-join
treatment is unnecessary here — output column discovery only needs
trace_ids, not dataset item mapping.Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
- fix(backend): add two-level dedup to aggregated CTEs, fix naming/javadoc
- Add LIMIT 1 BY dataset_item_id to dataset_items_agg_resolved,
dataset_items_aggr_resolved, and ExperimentAggregatesDAO's
dataset_item_versions_resolved CTEs. Without this, the OR-condition
joins could match one experiment item to multiple dataset item rows
from different versions, inflating groupArray results. - Remove orphaned Javadoc from deleted validateMappingsBelongToSameDataset
- Rename deletedRowIds to deletedIds (now holds stable IDs, not row IDs)
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
- fix(backend): fix stats query item_agg filter for dual-ID compat
The dataset_item_filters in item_agg selected only physical id,
missing new experiment items that store stable dataset_item_id.
Use arrayJoin([id, dataset_item_id]) and add two-level dedup.Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
- fix(backend): renumber migration 000073 → 000074
Main added 000073_add_minmax_index_trace_threads_last_updated_at.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
- fix(backend): unify CTE column aliases to dataset_item_id AS id, id AS row_id
All aggregated CTEs (dataset_items_agg_resolved, dataset_items_aggr_resolved,
dataset_item_versions_resolved) now use the same convention as
dataset_items_resolved: dataset_item_id AS id (stable), id AS row_id (physical).
Updated all join conditions, arrayJoin filters, and GROUP BY references.Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
- test(backend): add multi-dataset rejection tests for delete and batch update
Verify that delete and batch update requests with item IDs spanning
multiple datasets (without explicit datasetId) return 400.Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Co-authored-by: Claude Opus 4.6 noreply@anthropic.com
下载附件