Commit 7627ddc
[OPIK-8023] Bind dataset-item JSON sort keys as query parameters (#7935)
* [OPIK-8023] Bind dataset-item JSON sort keys as query parameters
Dataset-item sorting by output.*/input.*/metadata.* built the JSONExtractRaw
key by interpolating the key text directly into the SQL expression, whereas
data.* keys are passed as bound query parameters. Make the JSON sort keys
consistent with data.* by binding the key as a ClickHouse parameter
(JSONExtractRaw(col, :param)). This also handles keys containing special
characters correctly.
- FilterQueryBuilder: template uses a bound placeholder; bind key via field.bindKey()
- SortingFactoryDatasets: JSON fields go through the standard dynamic bindKeyParam path
- SortingQueryBuilder: bind all dynamic keys; remove now-unused overloads
- DatasetItemDAO: use single-arg hasDynamicKeys/bindDynamicKeys
- Add integration test covering JSON sort keys containing special characters
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* [OPIK-8023] Address review feedback on dataset-item sort key binding
- SortingField: bindKeyParam feeds a SQL parameter placeholder name, so generate it
server-side only -- it is no longer read from request input (READ_ONLY) and is always
a safe identifier. This keeps the placeholder name safe for data.* and
experiment_scores.* too, which build namespace[:sorting_param_<bindKeyParam>].
- Strengthen the dataset-item sort test: seed distinct values under the requested JSON
key and assert the full ordered result for both ASC and DESC, comparing whole objects.
- Add SortingFactoryTest coverage asserting bindKeyParam is server-generated, not taken
from input.
- Fix stale comments in FilterQueryBuilder and SortableFields to match the
bound-parameter approach.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* [OPIK-8023] Add version-DAO JSON sort coverage and document nested-key behavior
- DatasetVersionResourceTest: add a regression test that sorts versioned experiment items
by a JSON output key (with special characters) through the push-top-limit path, which was
previously uncovered (only total_estimated_cost and usage.total_tokens were tested).
- FilterQueryBuilder: note that the JSON sort key is the segment after the first dot, i.e. a
single top-level key ("output.a.b" looks up "a.b"); nested traversal is not performed. This
matches the previous behavior.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* [OPIK-8023] Mark bindKeyParam @JsonIgnore (internal, off the JSON API surface)
bindKeyParam is an internal value used only to build the SQL parameter placeholder name.
Use @JsonIgnore instead of READ_ONLY so it is neither serialized nor deserialized; it is
always (re)generated server-side as a safe identifier in the canonical constructor.
Confirmed the frontend and Python/TS SDKs only send field/direction, so this is transparent.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* [OPIK-8023] Rely on SortingField constructor for bindKeyParam; annotate @nullable
- SortingFactoryDatasets: remove processFields/ensureBindKeyParam. The canonical constructor
now guarantees a safe bindKeyParam for dynamic fields, so the factory-side normalization was
duplicate work (and left two implementations to maintain). This also aligns the datasets
factory with the other sorting factories, which never overrode processFields.
- SortingField: annotate bindKeyParam @nullable and document the contract (null for static
fields, a server-generated safe identifier for dynamic fields).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* [OPIK-8023] Parameterize version-DAO JSON sort test over namespace and direction
Replace the single output.* test with a @MethodSource-parameterized test covering
output.*, input.* and metadata.* (with special-character keys) for both ASC and DESC,
asserting the full expected item order via whole-object comparison. This exercises the
separate input/metadata push-top-limit CTE bindings, and uses SortingField.builder()
instead of the positional constructor.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>1 parent fa282b0 commit 7627ddc
9 files changed
Lines changed: 289 additions & 80 deletions
File tree
- apps/opik-backend/src
- main/java/com/comet/opik
- api/sorting
- domain
- filter
- sorting
- test/java/com/comet/opik/api
- resources/v1/priv
- sorting
Lines changed: 3 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
51 | 51 | | |
52 | 52 | | |
53 | 53 | | |
54 | | - | |
55 | | - | |
56 | | - | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
57 | 57 | | |
58 | 58 | | |
59 | 59 | | |
| |||
Lines changed: 2 additions & 42 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
5 | 4 | | |
6 | 5 | | |
7 | 6 | | |
8 | | - | |
9 | 7 | | |
10 | 8 | | |
11 | 9 | | |
| |||
26 | 24 | | |
27 | 25 | | |
28 | 26 | | |
29 | | - | |
30 | | - | |
31 | | - | |
32 | 27 | | |
33 | 28 | | |
34 | 29 | | |
| |||
88 | 83 | | |
89 | 84 | | |
90 | 85 | | |
91 | | - | |
92 | | - | |
93 | | - | |
94 | | - | |
95 | | - | |
96 | | - | |
97 | | - | |
98 | | - | |
99 | | - | |
100 | | - | |
101 | | - | |
102 | | - | |
103 | | - | |
104 | | - | |
105 | | - | |
106 | | - | |
107 | | - | |
108 | | - | |
109 | | - | |
110 | | - | |
111 | | - | |
112 | | - | |
113 | | - | |
114 | | - | |
115 | | - | |
116 | | - | |
117 | | - | |
118 | | - | |
119 | | - | |
120 | | - | |
121 | | - | |
122 | | - | |
123 | | - | |
124 | | - | |
125 | | - | |
126 | | - | |
127 | | - | |
| 86 | + | |
| 87 | + | |
128 | 88 | | |
Lines changed: 15 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
| 3 | + | |
3 | 4 | | |
4 | 5 | | |
5 | 6 | | |
| 7 | + | |
6 | 8 | | |
7 | 9 | | |
8 | 10 | | |
9 | 11 | | |
| 12 | + | |
10 | 13 | | |
11 | 14 | | |
12 | 15 | | |
13 | 16 | | |
14 | 17 | | |
15 | 18 | | |
16 | 19 | | |
17 | | - | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
18 | 25 | | |
19 | | - | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
20 | 31 | | |
21 | | - | |
22 | | - | |
| 32 | + | |
| 33 | + | |
23 | 34 | | |
24 | 35 | | |
25 | 36 | | |
| |||
Lines changed: 2 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1392 | 1392 | | |
1393 | 1393 | | |
1394 | 1394 | | |
1395 | | - | |
1396 | | - | |
| 1395 | + | |
1397 | 1396 | | |
1398 | 1397 | | |
1399 | 1398 | | |
| |||
1411 | 1410 | | |
1412 | 1411 | | |
1413 | 1412 | | |
1414 | | - | |
| 1413 | + | |
1415 | 1414 | | |
1416 | 1415 | | |
1417 | 1416 | | |
| |||
Lines changed: 17 additions & 11 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
53 | 53 | | |
54 | 54 | | |
55 | 55 | | |
56 | | - | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
57 | 60 | | |
58 | 61 | | |
59 | 62 | | |
| |||
1395 | 1398 | | |
1396 | 1399 | | |
1397 | 1400 | | |
1398 | | - | |
1399 | | - | |
| 1401 | + | |
| 1402 | + | |
1400 | 1403 | | |
1401 | 1404 | | |
1402 | 1405 | | |
| |||
1409 | 1412 | | |
1410 | 1413 | | |
1411 | 1414 | | |
1412 | | - | |
1413 | | - | |
| 1415 | + | |
| 1416 | + | |
| 1417 | + | |
| 1418 | + | |
| 1419 | + | |
| 1420 | + | |
| 1421 | + | |
| 1422 | + | |
1414 | 1423 | | |
1415 | | - | |
1416 | 1424 | | |
1417 | | - | |
| 1425 | + | |
1418 | 1426 | | |
1419 | | - | |
1420 | 1427 | | |
1421 | | - | |
| 1428 | + | |
1422 | 1429 | | |
1423 | | - | |
1424 | 1430 | | |
1425 | | - | |
| 1431 | + | |
1426 | 1432 | | |
1427 | 1433 | | |
1428 | 1434 | | |
| |||
Lines changed: 5 additions & 15 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
70 | 70 | | |
71 | 71 | | |
72 | 72 | | |
73 | | - | |
74 | | - | |
75 | | - | |
76 | | - | |
77 | | - | |
78 | | - | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
79 | 76 | | |
80 | 77 | | |
81 | | - | |
82 | | - | |
83 | | - | |
84 | | - | |
85 | | - | |
86 | | - | |
| 78 | + | |
87 | 79 | | |
88 | 80 | | |
89 | | - | |
90 | | - | |
| 81 | + | |
91 | 82 | | |
92 | 83 | | |
93 | 84 | | |
94 | | - | |
95 | 85 | | |
96 | 86 | | |
97 | 87 | | |
| |||
Lines changed: 83 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3510 | 3510 | | |
3511 | 3511 | | |
3512 | 3512 | | |
| 3513 | + | |
| 3514 | + | |
| 3515 | + | |
| 3516 | + | |
| 3517 | + | |
| 3518 | + | |
| 3519 | + | |
| 3520 | + | |
| 3521 | + | |
| 3522 | + | |
| 3523 | + | |
| 3524 | + | |
| 3525 | + | |
| 3526 | + | |
| 3527 | + | |
| 3528 | + | |
| 3529 | + | |
| 3530 | + | |
| 3531 | + | |
| 3532 | + | |
| 3533 | + | |
| 3534 | + | |
| 3535 | + | |
| 3536 | + | |
| 3537 | + | |
| 3538 | + | |
| 3539 | + | |
| 3540 | + | |
| 3541 | + | |
| 3542 | + | |
| 3543 | + | |
| 3544 | + | |
| 3545 | + | |
| 3546 | + | |
| 3547 | + | |
| 3548 | + | |
| 3549 | + | |
| 3550 | + | |
| 3551 | + | |
| 3552 | + | |
| 3553 | + | |
| 3554 | + | |
| 3555 | + | |
| 3556 | + | |
| 3557 | + | |
| 3558 | + | |
| 3559 | + | |
| 3560 | + | |
| 3561 | + | |
| 3562 | + | |
| 3563 | + | |
| 3564 | + | |
| 3565 | + | |
| 3566 | + | |
| 3567 | + | |
| 3568 | + | |
| 3569 | + | |
| 3570 | + | |
| 3571 | + | |
| 3572 | + | |
| 3573 | + | |
| 3574 | + | |
| 3575 | + | |
| 3576 | + | |
| 3577 | + | |
| 3578 | + | |
| 3579 | + | |
| 3580 | + | |
| 3581 | + | |
| 3582 | + | |
| 3583 | + | |
| 3584 | + | |
| 3585 | + | |
| 3586 | + | |
| 3587 | + | |
| 3588 | + | |
| 3589 | + | |
| 3590 | + | |
| 3591 | + | |
| 3592 | + | |
| 3593 | + | |
| 3594 | + | |
| 3595 | + | |
3513 | 3596 | | |
3514 | 3597 | | |
3515 | 3598 | | |
| |||
0 commit comments