100 Commits
Author SHA1 Message Date
5def5ced4a enhance: enforce function-field binding principle for function DDL (#51360)
## What

Enforce a function–field binding principle for function DDL (add / drop
/ alter function on an existing collection), so a function and its
output field stay coupled and already-stored vectors can never be
silently invalidated by DDL.

BM25 and MinHash follow the strict binding: add/drop only via the
unified `add_function_field` / `drop_function_field`, output field
always coupled. **TextEmbedding is a temporary carve-out** — its legacy
`AddCollectionFunction` / `DropCollectionFunction` paths are retained,
so attach-over-existing-field and detach are still possible for it,
because `add_function_field` embedding backfill is not yet implemented.
It will be folded into the unified path in a follow-up. So the "always
coupled" invariant currently holds for BM25/MinHash, not TextEmbedding.

## Changes

- **AlterCollectionSchema invariant**: reject standalone add-function (a
function must be added together with its new output field), reject
detaching a function without dropping its output field, and reject
function cascade (a new function's input being another function's
output).
- **Legacy RPCs**: `AddCollectionFunction` / `DropCollectionFunction`
are rejected for BM25/MinHash (must use `add_function_field` /
`drop_function_field`) and retained only for TextEmbedding (see
carve-out). `AlterCollectionFunction` is kept and gains the whitelist
below. In the alter and legacy-add paths, function field IDs are always
re-derived from field names (never trusted from the request), so a
request cannot inject an unrelated field ID that a later
`drop_function_field` would delete.
- **alter_function whitelist**: only connection/runtime params may
change (TextEmbedding: `url`, `credential`, `timeout_ms`,
`max_client_batch_size`, `region`, `location`, `projectid`, `user`);
BM25/MinHash have no alterable params. Function identity (type, name,
input/output fields) and output-shaping params (`dim`, `model_name`,
`endpoint` — the TEI model identity, `normalize`, `truncate*`, prompts,
...) are immutable. Params are normalized (keys lowercased, duplicate
keys rejected) so a crafted duplicate key cannot bypass the diff.
- **drop_function_field**: allow any output-producing function (dropping
needs no backfill), removing the previous BM25/MinHash-only restriction.

## Not in scope / follow-up

- Extending `add_function_field` to TextEmbedding (post-creation add
would require backfilling every existing row through the external
embedding model) — deferred; folding the TextEmbedding legacy paths into
the unified binding follows this.
- MinHash input-field analyzer immutability lives on a different DDL
path (`AlterCollectionField`); tracked as a separate follow-up.

## Breaking changes

- `DropCollectionFunction` on a **MinHash** function (detach — remove
the function but keep its output field) is no longer supported; use
`drop_function_field` instead (drops the function together with its
output field). If a released version supported MinHash detach, migrate
any such call to `drop_function_field`.

issue: #51348

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-18 05:04:39 +08:00
0671607431 fix: CAS the schema-bump in-place manifest commit to stop dropping a concurrent index (#51376) (#51377)
issue: #51376

## What this fixes

The in-place partial-materialization path of
`bump_schema_version_compaction` commits onto a live segment's manifest,
and DataCoord adopted the result on a version-newer check only — it
never verified the result was built on the segment's *current* manifest.
A bump built on a plan-pinned base could therefore be adopted after a
concurrent stats/index task advanced the manifest pointer, silently
dropping that index (correct version number, wrong content lineage). The
loss is permanent and non-self-healing, because the segment meta stats
placeholder stops the stats inspector from re-triggering.

## Fix — application-layer adoption CAS (mirrors the stats path)

- The schema-bump result carries the plan-pinned base manifest
(`CompactionSegment.base_manifest`, like `StatsResult.base_manifest`);
the DataNode fills it with the manifest it materialized on.
- DataCoord adopts the in-place result only if `result.base_manifest ==
segment.ManifestPath` (the current pointer); a missing or stale base is
rejected (`ErrIllegalCompactionPlan`) so the task re-triggers and
rebuilds on the current manifest instead of overwriting the concurrent
commit. This mirrors the stats path's `errStatsResultStale`.
- The storage commit stays on `OverwriteResolver` (unchanged). Because
the CAS is at the adoption layer (against the meta pointer, not
storage-latest), a result lost after a DataNode crash self-heals on
retry: the pointer stays put, so the retry re-pins the same base and is
adopted — no wedge.
- The bump policy is restricted to internal collections (matching every
sibling compaction policy), so a rejected attempt's orphan is reclaimed
by internal dropped-segment GC and bump never churns on external
collections.

## Verification
Both interleavings converge with no data loss: stats-first → bump's base
no longer matches the advanced pointer → reject + retrigger on the
current manifest; bump-first → stats' existing base-check rejects and
retries. Added meta-level adoption tests (matching/stale base) and
updated the in-place adoption tests to carry the base.

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-17 15:52:40 +08:00
4dbaba0042 fix: skip dropped-field column groups when loading StorageV3 segments (#51275) (#51277)
issue: #51275

### Problem

Under StorageV3 growing-source flush, a manifest legally keeps column
groups whose fields were later dropped: drop does not rewrite flushed
data, and compaction removes the leftover lazily. Loaders however
projected such groups against the **current** schema and treated the
mismatch as an error:

- **Growing recovery** (`SegmentGrowingImpl::LoadColumnsGroups`)
submitted every manifest group with a full-schema projection; a group
whose fields were all dropped has an empty projection, which
milvus-storage rejects by contract (`ChunkReaderImpl::open`: "No needed
columns found in column group"). The channel-recovery level retried the
deterministic failure every second — observed locally: **4140 identical
failures over ~3 minutes**, the channel unavailable (`no available shard
leaders`) the whole time, until a compaction rewrite happened to remove
the group.
- **Sealed load** (`ChunkedSegmentSealedImpl::LoadColumnGroups`)
resolved every manifest column to a field id without a membership check
and tripped the schema-lookup assert on any group still carrying a
dropped column — mixed groups included.

### Fix

Treat a dropped-field column as a legal leftover at the loaders:

- Growing: skip a column group before submitting its load task when none
of its columns exist in the segment schema (logged).
- Sealed: filter resolved field ids absent from the schema snapshot
while building `cg_field_ids` (logged); a group filtered to empty
produces no load task. Mixed groups keep loading their live columns via
projection, unchanged.

### Verification

- Local A/B with a schema-evolution chaos workload (concurrent add/drop
ordinary + BM25 function field, DML/query/search, `useLoonFFI` +
growing-source flush enabled, StreamingNode SIGKILL/restart injections):
before the fix, recovery wedged in the retry loop (4140 errors / ~3 min
/ final query 503); after the fix the same scenario logs 2 group skips,
the channel recovers in seconds, and the full serial consistency
validation passes.
- New UT `LoadGrowingSegmentSkipsDroppedFieldColumnGroup`: flushes a
manifest with a field-exclusive column group (writer pattern
`"0|1|100,101"`), reloads the segment under a schema without that field,
and asserts the load succeeds with the group skipped (plus a guard
assertion that the manifest really contains the exclusive group).
- The sealed-path filter is exercised by code inspection and mirrors the
growing-side semantics; on current master the external-table load path
derives its projection from schema-owned column names and is not exposed
to this class.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 22:18:36 +08:00
a3a5ac8d44 fix: skip non-materialized function output field on growing segment flush (#51117) (#51266)
issue: #51117

Supersedes #51207 per team decision to ship the skipped-field tolerance
for 3.0.0; the era-consistent replay consume path (#51146) remains a
follow-up.

### Problem

A growing segment created while a field was absent from the schema never
materializes that column: the InsertRecord ctor only allocates fields
present at creation, Reopen fills later-added ordinary fields but skips
function outputs by design, and a field dropped before segment creation
is skipped at consume. Flushing such a segment with a schema snapshot
that still carries the field hit `Assert "data_.find(field_id) !=
data_.end()"` in the growing-source flush path and crash-looped the
StreamingNode (exit 134 / CrashLoopBackOff in the schema-evolution L3
runs).

### Design

Principle: the flush writes exactly `flushSchema ∩ materialized`. A
non-materialized column is legally absent — a field dropped from the
segment's own schema, or a function output recomputed by bump-schema
compaction backfill. Real schema/data inconsistency is segcore's own
concern and is verified inside the flush.

- **Go (layout source of truth)**: trim the column groups to the source
segment's materialized field ids (plus system fields) right after layout
derivation — `Fields` and the parallel `Columns` array in lockstep — so
the writer pattern, binlog meta and metacache current split all describe
the same layout. An empty materialized report is refused. On a
committed-flush ack retry the layout is trimmed to the committed binlogs
(`ChildFields` union), the persisted truth.
- **C++ (segment-internal judgement)**: a column missing from the insert
record (`HasFieldData` semantics: allocated-but-empty counts as missing)
is skipped when the field is gone from the segment's own schema
(dropped) or is a function output; a regular field still present in the
segment schema is materialized by ctor/Reopen by construction, so that
case hard-errors instead of asserting.
- Skipped columns are backfilled by bump-schema compaction via
`RecordMaterializer`.

### Review responses (@liliu-z)

- stale `Columns` / phantom column in writer pattern →
`filterColumnGroupFields` trims `Fields`+`Columns` in lockstep at all
three trim sites
- committed ack-retry currentSplit divergence → layout trimmed to
committed binlogs' `ChildFields` union
- allocated-but-empty function-output column wedging the flush →
materialized report and the flush skip both gate on `HasFieldData`
semantics (empty = not materialized)
- silent skip of a missing regular field → three-way judgement: dropped
from segment schema → skip; function output → skip;
present-in-segment-schema regular field → hard error (`has no field data
in growing segment ... but is present in the segment schema`)
- retryability routing of the missing-field error: the legally-absent
cases no longer produce an error at all; the remaining hard error
indicates real data loss and is construction-unreachable via public APIs
(the consume path asserts regular fields carry data)

### Verification

- Go UT (`growing_source_test.go`): trim semantics — dropped ordinary
field trimmed, `Columns` kept in lockstep, empty materialized report
refused, committed-retry trim by `ChildFields`
- C++ UT (`test_storage.cpp`): flush skips a non-materialized function
output; skips a dropped field carried by a staler flush schema; skips an
allocated-but-empty function-output column
- Local schema-evolution chaos runs (concurrent add/drop field + BM25
function field + DML/query/search with `useLoonFFI` + growing-source
flush enabled, incl. StreamingNode force-kill/restart injections): no
panic, no crash loop, final serial consistency validation passes. The
exact original assert requires an era-mismatch replay not reproduced
locally; that path is covered by the unit tests above.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 23:38:36 +08:00
1993feaeea fix: build text index for newly added enable_match field on growing segment reopen (#50484) (#51201)
## Summary

After schema evolution adds an `enable_match` field (e.g.
`drop_collection_field` + `add_collection_field` of a same-name text
field), `text_match` could fail with `text index not found for field
<id>` on a growing segment even though `describe_index` reported
`Finished`.

## Root cause

A growing segment builds its per-segment text indexes exactly once, in
the constructor (`CreateTextIndexes`), against the construction-time
schema — `text_indexes_` has a single writer, reachable only from that
path. When a query carrying the new schema drives `LazyCheckSchema ->
Reopen(SchemaPtr)`, Reopen only backfilled empty column data
(`fill_empty_field`) and never built the text index for the newly added
field — unlike the sealed path, where both load and schema-only reopen
go through `ComputeDiff -> text_indexes_to_create -> CreateTextIndex`.
So an old growing segment upgraded by Reopen had no
`text_indexes_[new_field]`, and `text_match` hit `GetTextIndex()` and
threw `TextIndexNotFound`. The window closes once the segment is
flushed/sealed, loaded (sealed load rebuilds the index) and released
from the delegator, which is why the failure is intermittent and
self-healing but hard, non-retryable while it lasts.

## Fix

In `SegmentGrowingImpl::Reopen(SchemaPtr)`, for newly added
`IsStringDataType && enable_match` fields, **before publishing
`schema_`** (LazyCheckSchema readers don't take `sch_mutex_`, so a
concurrent query observing the new schema skips Reopen and queries
immediately — the index must already exist by then):

1. Build the text index via the new `BuildTextIndexForMeta(const
FieldMeta&)` (the field is not yet in the published `schema_`, so the
meta is passed in; mirrors sealed's `CreateTextIndexWithSchema`). The
index is **staged as a local object** — it is not visible in
`text_indexes_` yet.
2. **Index the pre-existing rows with the same default-value-or-nulls
fill the column received** (constructed directly — the content is
knowable without reading the column back, since the exclusive
`sch_mutex_` blocks concurrent inserts). This keeps the index consistent
with the column, matching sealed's create-from-raw behavior
(`BulkRawStringAt -> AddTextSealed`): when the added field carries a
`default_value`, old rows must match text queries against the default
text and report not-null. Backfilling every row (nulls included) also
keeps text-index doc offsets dense and aligned with `insert_record_`
rows, which query-side bitmap sizing relies on.
3. Force `Commit()+Reload()` on each staged index; after **every** new
field succeeds, publish all staged indexes into `text_indexes_` together
(an O(1) map insert per field under one `mutex_` acquisition).

Publish-after-success makes the failure path sound across fields as well
as within one: a present `text_indexes_` entry is always a fully
backfilled, committed index; a throw anywhere during any field's
build/backfill/commit publishes nothing and leaves `schema_`
un-advanced, so the next query rebuilds everything from scratch (no
per-field partial publication that a retry's presence guard would skip
over). It also shrinks the `mutex_` hold during Reopen from the O(N)
backfill to the final map insert, so concurrent `GetTextIndex` readers
(text_match on existing fields) are not stalled by the backfill.

Function-output fields (e.g. BM25 sparse output) remain skipped: they
are non-string and never carry a text index. The related-but-distinct
`field index meta not found` symptom for BM25 function-output fields
(follow-up of #50783: `index_meta_` is not updated on growing reopen) is
a separate fix and not covered here.

## Test

`test_schema_reopen.cpp`:
- `ReopenBuildsTextIndexForNewEnableMatchField`: growing segment on
schema v1, old rows inserted, Reopen to v2 adding a nullable
`enable_match` VARCHAR (no default) — `GetTextIndex` throws before
Reopen; after Reopen it returns the index, `MatchQuery` finds nothing
and `IsNotNull` reports all rows null, consistent with the column.
- `ReopenTextIndexIndexesDefaultValueForOldRows`: same flow with a
`default_value` on the added field — after Reopen
`MatchQuery("default")` matches all N pre-existing rows and `IsNotNull`
reports them non-null, matching sealed semantics.
- `ReopenBuildsTextIndexesForMultipleNewFields`: one Reopen adds two
enable_match fields (one nullable-null, one with default) — both indexes
come out complete through the batched staged publish.

All tests query immediately after Reopen with no explicit
`Commit()/Reload()`, asserting the forced-visibility behavior.

## Known limitation (pre-existing, follow-up)

`EnsureArrayOffsetsForStructField` still runs after `schema_` is
published, so a throw there can leave a schema-advanced segment without
array offsets — pre-existing behavior, unchanged by this PR; reworking
Reopen's publication order for non-text state is left as a follow-up.
(The text-index half of this concern is resolved: the index is now built
before publication and a build failure leaves the reopen retryable.)

issue: #50484

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 18:20:35 +08:00
f244642ba9 enhance: support query order-by in RESTful v2 API and Go SDK (#51170) (#51173)
issue: #51170

Expose the existing server-side query ORDER BY capability (query param
key `order_by_fields`, already consumed by proxy `task_query.go`)
through the two remaining client surfaces:

- **Go SDK**: `queryOption.WithOrderByFields(fields ...string)` — each
spec is `"field"`, `"field:asc"` or `"field:desc"`, joined into the
`order_by_fields` query param.
- **RESTful v2**: `QueryReqV2` gains `orderByFields` (`[]string`, same
spec format), forwarded by the query handler as the `order_by_fields`
query param.

Validation (sortable type, explicit-limit requirement, iterator
exclusion) stays server-side in the proxy, consistent with how
limit/offset/group-by are handled at these layers. Interface shape
mirrors pymilvus (`order_by=["price:desc"]`).

Tests: Go SDK option unit test, RESTful v2 handler unit test (asserts
the KV pair is forwarded, and absent when not requested), and a
go_client e2e case (desc / asc-default / no-limit rejection).

Follow-up (out of scope here): search-side `order_by` first-class parity
for RESTful v2 / Go SDK (currently reachable via raw search params
only).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 18:28:35 +08:00
aea5d701bd enhance: bind index meta to add function field DDL (#51105)
issue: #51104
companion SDK PR (merge first): milvus-io/pymilvus#3670

## Summary

`add_function_field` previously accepted a vector output field without
any index meta; bump-schema-version compaction then stalled forever (no
segment index task can be created for a field with no index defined, and
`GetQueryVChanPositions` never hands off unindexed compacted-to segments
— the fail-closed chain is silent). This PR makes the index meta a
mandatory, atomically-bound part of the DDL:

- **Mandatory at every layer**: SDK requires `index_params`; proxy and
rootcoord reject vector function-output fields without an explicit
`index_type` strictly before the broadcast (no silent AUTOINDEX).
- **create_index-aligned materialization**: proxy normalizes the params
with the same logic as `create_index` (name rules via
`validateIndexName`, checker existence, `CheckTrain` incl. dimension
filling, function-type defaults such as `bm25_k1/bm25_b/bm25_avgdl`) and
writes them back into the request; rootcoord prepare allocates index
id/name, rejects name conflicts and unknown index types, and serializes
a complete `indexpb.FieldIndex` into the new
`AlterCollectionMessageUpdates.bound_field_indexes` WAL field.
- **Atomic apply**: the alter-collection ack callback commits the schema
and then applies the bound index by dispatching a synthetic
`CreateIndexMessage` to datacoord's existing `createIndexV2AckCallback`
(same pattern as `cascadeDropFieldIndexesInline`). The callback is
replayed until success across crashes and is fully idempotent (all ids
come from the message body), so `DDL success ⇒ index meta exists` holds
with no partial terminal state.
- **Reuse promotion**: `ValidateIndexParams`/`CheckDuplidateKey` moved
from datacoord to `internal/util/indexparamcheck`; shared
`ExpandIndexParams` / `FillFunctionOutputIndexParams` /
`PrepareFunctionOutputIndexParams` helpers now back both the
create_index path and this DDL.
- **Dead fan-out removed**: the ordinary `CreateIndex` broadcast is
reverted to control-channel-only; the vchannel fan-out had no consumer
and wrote one dead WAL entry per vchannel per index creation.
- **No milvus-proto change**: the request already carried
`FieldInfo.index_name`/`extra_params` (previously unused); this feature
activates them.
- e2e suites updated to the new semantics:
`test_add_function_field_feature.py` rewritten (explicit `index_params`
everywhere, post-DDL `create_index` blocks removed since the bound index
conflicts with a second distinct index per existing semantics, new
negative cases for the mandatory checks); the external-table negative
case updated as well.

## Verification

- New/updated unit tests: rootcoord DDL callbacks
(mandatory/AUTOINDEX/unknown-index-type rejections, bound-index
materialization + ack-callback application via a recording fake), proxy
task validation (invalid index name, normalization write-back), shared
helper tests.
- End-to-end on a live cluster (StorageV3 + bump compaction enabled):
request without params rejected; index meta visible with
create_index-aligned params immediately after the DDL returns; bump
compaction rewrote 2000-row sealed segments and the bound index built on
the results (the exact chain that previously stalled); BM25 search over
pre-DDL rows succeeds once the compacted segments are loaded.

## Limitations (follow-ups)

- Live propagation of the new index meta to already-loaded QueryNode
delegators is intentionally out of scope; a loaded collection observes
the bound index through the segment load path (e.g. reload /
compacted-segment load). Tracked as a separate follow-up PR.
- The python e2e suites require the companion pymilvus change:
milvus-io/pymilvus#3670 is merged and
`tests/python_client/requirements.txt` is bumped to
`pymilvus==3.1.0rc61` in this PR (all 22 rewritten cases + the
external-table case verified locally against the released rc61).
- During a rolling-upgrade window an old coordinator replaying the new
message ignores `bound_field_indexes` (proto3 unknown field), i.e.
pre-existing behavior; avoid the new argument in mixed-version clusters.
- `AddCollectionFunction` on an existing field and plain
add-vector-field keep their current behavior (the WAL carrier is generic
for future extension).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 17:38:41 +08:00
b16c821b36 enhance: carry TEXT LOB refs through schema-bump full-rewrite compaction (#51125)
### What & why

`bump_schema_version`'s full-rewrite path (`runFullSchemaRewrite`,
reached only for a **drop-field** schema bump) builds a from-scratch
output manifest via `NewBinlogRecordWriter` and did **not** carry the
source segment's TEXT LOB references — leaving dangling refs for an
out-of-line (`>=64KB`) TEXT column. This was the `TODO(#50021)`.

### What this does

Wire **REUSE_ALL** LOB handling into `runFullSchemaRewrite`, mirroring
sort compaction. Both are `1->1` with a single output manifest, so
REUSE_ALL is always correct: a schema bump never changes the existing
TEXT LOB data — only its references are carried.

- `internal/compaction/lob_compaction.go`: `GetForcedStrategy` forces
REUSE_ALL for `BumpSchemaVersionCompaction`.
- `internal/datanode/compactor/bump_schema_version_compactor.go`:
collect the source LOB files into a `LOBCompactionContext`, pass
`storage.WithTextRefsAsBinary()`, update per-LOB-file `valid_rows`
(`SetSegmentRowStats`), and merge the LOB references into the output
manifest (`applyLOBCompaction`) **before** building the text-match index
— `createTextIndex` reads the TEXT column through this manifest, so the
carried LOB files must already be referenced (matches sort/mix
ordering). Removed the `TODO(#50021)`.
- Unit tests: forced strategy, init/apply LOB wiring, the
applyLOBCompaction-before-createTextIndex ordering
(`TestFullRewriteMergesLOBRefsBeforeBuildingTextIndex`), and a real
add-nullable-TEXT + drop-field full-rewrite regression driving the
actual packed writer
(`TestFullRewriteFillsMissingNullableTextAsBinary`).

### Also: guard add_function_field behind StorageV3 (#51167)

Adding a function to an existing collection must backfill the new output
field into **pre-existing** sealed segments; that backfill runs through
`bump_schema_version` compaction, which only works on a StorageV3
segment. A pre-existing V2 segment is only backfilled after the
storage-version upgrade compaction rewrites it to V3, and that upgrade
runs only when **both** `common.storage.useLoonFFI` and
`dataCoord.compaction.storageVersion.enabled` are on. The proxy now
rejects add-function unless both are enabled
(`validateAddFunctionRequiresStorageV3`, wired into
`addCollectionFunctionTask` and `alterCollectionSchemaTask`).
`create_collection` with a function is unaffected. Full reasoning in
#51167.

### Notes

- Reuses the LOB machinery from **#50784**.
- The `GenerateEmptyArrayFromSchema` binary-TEXT production fix landed
independently on master via **#51124**; this PR keeps the regression
test guarding the bump path.

issue: #50021, #51167

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 17:20:34 +08:00
1f7fe3b7d9 fix: skip insert payload fields absent from schema on querynode consumption (#51117) (#51137)
## What

Filter out insert payload columns whose field is absent from the current
collection schema when converting an insert message on the QueryNode
consumption path (`TransferInsertMsgToInsertRecord`), instead of
forwarding them into segcore where `SegmentGrowingImpl::Insert`
hard-asserts on unknown fields and panics the whole StreamingNode.

## Why (root cause, verified from Loki logs of the failing run)

1. A growing segment was created under schema v104 and received one
insert whose payload — written at WAL-append time under v104 — contains
field 158 (a field generation that was later dropped; by v112 it no
longer exists in the schema).
2. The StreamingNode died once for an unrelated reason. On every
subsequent restart, `WatchDmChannels` seeds the collection with the
**latest** schema (v112, without field 158 — coord meta is updated right
after the DDL's WAL append ack, so it always runs ahead of any replaying
consumer), and WAL replay starts from the channel checkpoint, which
predates the segment's data.
3. The replayed v104 insert still carries field 158; the growing segment
rebuilt with v112 has no such column and can never gain it. Replayed
schema events (v1→v103) are correctly skipped by the schema-version gate
(#50577), so the mismatch is structural, not a race.
4. `SegmentGrowingImpl::Insert` tolerates only the inverse staleness
(segment schema newer than payload → fill empty columns). An unknown
payload field hits `AssertInfo(insert_record_.is_data_exist(field_id),
...)` → SegcoreError → `delegator.ProcessInsert` panics → the checkpoint
never advances past the message → deterministic CrashLoopBackOff.

Dropped-field data is unqueryable by definition, so skipping those
columns is semantically lossless. On the live path the WAL-append
schema-version gate plus segment fencing on schema change guarantee the
payload is a subset of the current schema, making this filter a no-op
outside replay.

A WARN log records the skipped field IDs for observability.

## Notes

- Related latent issues intentionally out of scope (to be filed
separately): compaction can leave a flushed segment out of the watch
request's flushed/dropped exclusion lists (duplicate-data risk on
replay); `Reopen`/`FillAbsentFields` never create function-output
columns on pre-existing growing segments.

issue: #51117

---------

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 17:16:33 +08:00
9b5a9a866a fix: check indexMeta before executing search on segments (#50783) (#50802)
## Summary

A sealed segment that predates a function-output field added by
`add_function_field`
lazy-loads that field's raw column (so `HasFieldData` becomes true) but
has **no index
meta** for it on this segment. A BM25 brute-force search then reached
`GetFieldIndexMeta(field_id)`, which dereferenced an `end()` iterator —
the guarding
`assert` is stripped in release builds — and the QueryNode died with
`SIGSEGV
SI_ADDR=(nil)` while copying the garbage index-params map.

## Fix

- `FieldAccessible` now requires `HasIndex || (HasFieldData &&
HasFieldIndexMeta)`.
`HasIndex` is checked **first** so the field becomes serviceable again
the moment its
index loads — recovery does not depend on `col_index_meta_` ever being
refreshed
  (it is set once at construction and never updated on a stale segment).
- New `virtual HasFieldIndexMeta` (default `true`;
`ChunkedSegmentSealedImpl` /
`SegmentGrowingImpl` override via `col_index_meta_` / `index_meta_ ->
HasField`).
- Defense-in-depth: `CollectionIndexMeta::GetFieldIndexMeta` `assert` ->
`AssertInfo`,
so a missing field throws a `SegcoreError` even under NDEBUG instead of
UB.

With the gate in place the existing empty-result branch in
`segment_c.cpp` AsyncSearch
serves a graceful partial result (the not-yet-indexed old segment
contributes nothing)
instead of crashing.

issue: #50783

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 16:34:29 +08:00
a7fae63d78 fix: apply search order by offset after scalar sort (#50143)
issue: https://github.com/milvus-io/milvus/issues/49879

## Summary
- Keep `limit + offset` candidates during reduce for common search with
`order_by_fields`.
- Apply final offset/limit after scalar order_by sorting in the search
pipeline.
- Add targeted proxy unit tests for row-aligned reorder, group
pagination, string IDs, and vector slicing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-26 10:36:26 +08:00
a57cdbc5a1 fix: validate REST v2 collection TTL properties (#49843) (#50731)
issue: #49843

## What
- Reject invalid TTL values passed through REST v2 create-collection
`properties`.
- Normalize REST `ttl.seconds` to `collection.ttl.seconds` so existing
Proxy TTL validation handles both accepted TTL spellings consistently.
- Reject duplicate TTL sources when `properties` and legacy
`params.ttlSeconds` are both provided.

## Verification
- `gofmt`
- `git diff --check`
- `go -C /home/hanchun/Documents/project/milvus-master-temp/milvus test
./internal/distributed/proxy/httpserver -run
'Test(CreateCollection|DML)$' -count=1` failed before running tests
because local pkg-config cannot find `rocksdb.pc` and `milvus_core.pc`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-06-26 10:24:27 +08:00
b5aec64ab5 fix: support dropping and re-adding BM25 function field (#50735)
issue: #50729

### What
Dropping a BM25 function field and re-adding it with the same function
name and output field left the new sparse index stuck `InProgress`. The
flow was blocked on two layers, fixed here:

- **DataCoord**: accept expanded pre-allocated segment ID ranges when
completing the schema-bump replacement compaction (previously only a
single-ID range was allowed, causing `BumpSchemaVersionCompaction failed
... compaction plan illegal`). Still require the replacement segment to
use the range begin, matching DataNode full-rewrite behavior.
- **QueryNode**: allow a BM25 function field to be dropped and re-added
with a new output field ID (reject only incompatible in-place changes to
a shared output field), and prune dropped BM25 stats from
current/growing/sealed state and local disk so reclaimed disk size stays
accurate.

### Tests
- Cover expanded-range completion in the schema-bump metadata regression
test.
- Cover drop/re-add validation and dropped-stats pruning
(current/growing/sealed + on-disk) in the delegator and idf_oracle
tests.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 21:20:26 +08:00
59401b0fa4 enhance: support minhash schema bump backfill (#50330)
## What this PR does

This PR supports end-to-end add-MinHash-function schema evolution by:
- allowing RootCoord alter-schema to accept MinHash functions with
strict arity validation;
- adding a concrete MinHash record materializer in DataNode compactor;
- extending bump schema version compaction to materialize missing
MinHash BinaryVector outputs while keeping BM25 stats BM25-only.

## Tests

- source ./scripts/setenv.sh && go test -v -count=1 -gcflags="all=-N -l"
-tags dynamic,test ./internal/datanode/compactor -run
'TestBumpSchemaVersionCompactionTaskSuite/TestBumpSchemaVersionCompactionMaterializesMinHashOutput'
- source ./scripts/setenv.sh && go test -v -count=1 -gcflags="all=-N -l"
-tags dynamic,test ./internal/datanode/compactor -run
'Test(BumpSchemaVersionCompactionTaskSuite|RecordMaterializer|BM25FunctionMaterializer|MinHashFunctionMaterializer)'
- source ./scripts/setenv.sh && go test -v -count=1 -gcflags="all=-N -l"
-tags dynamic,test ./internal/rootcoord -run
TestDDLCallbacksBroadcastAlterCollectionSchema

issue: #48808

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 22:40:20 +08:00
f7047d89df enhance: route reopened bm25 stats in delegator (#48808) (#50181)
issue: #48808

## Summary
- sync delegator function/analyzer runtime state on schema update
- allow additive BM25 function fields in the IDF oracle without dropping
existing stats
- route Reopen BM25 stats through the delegator oracle with field-level
idempotency

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-06 07:46:17 +08:00
3c54deb42b fix: reject unsupported search aggregation inputs (#50151)
issue: #49841
issue: #49842

## Summary
- Reject search iterator when search_aggregation is enabled instead of
returning an empty page.
- Reject JSON and dynamic fields across search_aggregation context
building for group_by, metric sources, and top_hits sort fields.
- Add regression coverage for unsupported iterator and JSON/dynamic
aggregation inputs.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-03 14:06:19 +08:00
720338c1dc fix: support null ordering for search order by (#50163)
issue: #49869

## Summary
- Align search ORDER BY null placement with query/PostgreSQL defaults:
ASC NULLS LAST and DESC NULLS FIRST.
- Support explicit `nulls_first` / `nulls_last` options in search
`order_by_fields`.
- Cover scalar, JSON path, and dynamic-field null ordering behavior in
proxy tests.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-02 12:24:16 +08:00
99cf5e8d48 fix: preserve search aggregation group-by metadata (#50176)
issue: #49840

## Summary
- Preserve plural group-by field IDs when shallow-copying search
requests for query nodes.
- Add regression coverage for SearchRequest shallow-copy metadata
propagation.
- Re-enable the growing-segment search aggregation E2E case.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-01 19:40:15 +08:00
dbaeb50cb1 enhance: support search aggregation search size (#49892)
## Summary
- Add per-level `search_size` handling for search aggregation context
building.
- Preserve `size` as the response bucket limit while using `search_size`
for downstream candidate bucket budget derivation.
- Bump the root module milvus-proto dependency to the version that
contains `SearchAggregationSpec.search_size`.

## Test Plan
- [x] `git diff --check trunk/master...HEAD`
- [x] `go test -tags dynamic,test -gcflags=\"all=-N -l\" -count=1
./internal/proxy/search_agg/...`

related: #48971

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-29 18:18:14 +08:00
9cc6d526b3 test: xfail unstable nullable metric aggregation e2e (#50174)
issue: #49046

## What this PR does

Marks `test_search_aggregation_nullable_metric_field` as non-strict
xfail because the case is unstable when `top_hits` does not include NULL
nullable metric rows.

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 14:00:14 +08:00
7841f8a9b0 enhance: use bump_schema_version to involve backfill and drop field compaction(#48808) (#49759)
related: https://github.com/milvus-io/milvus/issues/48808

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2026-05-29 13:26:15 +08:00
6b18f5a4d7 test: add search aggregation e2e coverage(#49046) (#49795)
Add MilvusClient E2E coverage for basic search aggregation buckets,
metrics, ordering, top_hits, nested aggregation, and filters.
related: #49046

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 15:30:27 +08:00
4be055541d enhance: remove schema version consistency gate (#49733)
## Summary
- Remove proxy-side schema version consistency gate for schema-change
DDLs.
- Allow mix and clustering compaction to process mixed schema-version
segments.

issue: #49475

## Test plan
- [x] git diff --check
- [ ] go test -tags dynamic,test -gcflags=\"all=-N -l\" -count=1
./internal/proxy -run
'TestProxy_AddCollectionField_DoesNotBlockOnSchemaVersion|TestProxy_AlterCollectionSchema'
- [ ] go test -tags dynamic,test -gcflags=\"all=-N -l\" -count=1
./internal/datacoord -run
'TestCompactionTriggerKeepsMixedSchemaVersionSegments|TestClusteringCompactionPolicySuite/TestTriggerOneCollectionAllowsMixedSchemaVersionGroup|TestMetaBasicSuite/TestCompleteCompactionMutation/(mixed
schema version mix compaction uses task schema version|mixed schema
version clustering compaction uses task schema version)'

Note: Go test commands were blocked locally because pkg-config could not
find milvus_core / milvus-storage.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 12:18:27 +08:00
25e6cd3992 fix: wrong inner length for ColumnVector(#49340) (#49576)
related: #49340

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2026-05-12 10:28:10 +08:00
72f83e01f1 enhance: shard_interceptor check schema version for insert msg(#49455) (#49456)
related: #49455

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2026-04-30 15:57:51 +08:00
0fa822fc0a enhance: support search aggregation go-layer (#49071)
## Summary
- add `search_agg` package in proxy for context build, recursive
aggregation compute, and bucket ordering
- wire `group_by` aggregation through `task_search` and built-in
pipeline (`searchWithAggPipe` + aggregate operator serialization)
- upgrade querynode reduce key extraction for agg multi-field grouping,
and update related proxy/querynode tests
- keep local proto iteration path and local core build job defaults
aligned for this development workflow

## Test plan
- [x] bash
/home/zilliz/hc-claude-projects/hc-milvus-projects/search-aggregation/scripts/verify_baseline.sh
- [x] direct association tests passed
- [x] indirect association tests passed

issue: #49046

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-04-30 15:51:50 +08:00
3aadc7a226 fix: sync ColumnVector append length with FieldData state(#49071) (#49391)
related: #49071

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 02:25:51 +08:00
fa0343b580 feat: add function field backfill - Part 4: streaming part (#48809)(#48808) (#48865)
## Summary
- Add schema version check on insert path in streaming node shard
interceptor, rejecting inserts with mismatched schema version
- Add
`AlterCollection`/`AppendNewCollectionSchema`/`CheckIfCollectionSchemaVersionMatch`
methods to shard manager for schema lifecycle management
- Propagate schema version through segment allocation chain:
`shard_manager_segment` → `partition_manager` → `segment_alloc_worker` →
`CreateSegment` message header
- Add `SchemaVersionMismatch` streaming error type (classified as
unrecoverable to force proxy metadata refresh)
- Track collection schema in `CollectionInfo` with
`CollectionSchemaOfVChannel` for version gating

related: https://github.com/milvus-io/milvus/issues/48808
design doc:
https://github.com/milvus-io/milvus-design-docs/blob/main/design_docs/20260129-add-function-field-design.md

## Test plan
- [x] partition_manager_test.go updated for new `schemaVersion`
parameter
- [x] wal_test.go updated with CollectionSchema in CreateCollection
messages
- [ ] CI: code-check, ut-go, integration-test

🤖 Generated with [Claude Code](https://claude.ai/code)

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-23 23:29:46 +08:00
4e51991e55 feat: support multi-field composite group_by for vector search (segcore layer) (#48971)
## Summary

Refactor search-side GROUP BY from single-field to multi-field composite
key in the **segcore (C++) layer**, aligning with Elasticsearch's
`multi_terms` aggregation semantics.

**Scope: segcore layer only.** Go-layer changes (proxy search reduce,
delegator multi-field wiring, SDK API) will be tracked and submitted in
a separate PR.

## Core Changes

- **CompositeGroupKey** (Types.h): New composite key type
(vector<GroupByValueType>) with CompositeGroupKeyHash using
bits::hashMix, consistent with query-agg HashTable.h
- **MultiFieldDataGetter** (SearchGroupByOperator.{h,cpp}): Type-erased
multi-field data reader via std::function<GroupByValueType(int64_t)>,
replacing ~300 lines of per-type template dispatch
- **GroupByMap<CompositeGroupKey>** specialization for composite key
grouping with hash collision handling
- **SearchInfo.group_by_field_ids_** (QueryInfo.h): Replaced
optional<FieldId> group_by_field_id_ with vector<FieldId>
group_by_field_ids_; added has_group_by() / has_multi_field_group_by()
helpers
- **Proto**: New `repeated int64 group_by_field_ids = 17` in QueryInfo,
with backward compat for old group_by_field_id
- **Reduce pipeline**: GroupReduce, Reduce::SortEqualScoresOneNQ, and
AssembleCompositeGroupByValues all updated for composite keys
- **JSON group_by**: Restored proper json_type dispatch
(bool/int8/16/32/64/varchar) in MultiFieldDataGetter
- **Dead code cleanup**: Removed old AssembleGroupByValues() (~290
lines), removed write-only SearchResultPair.group_by_value_ field

## What This Enables (for follow-up Go-layer PR)

This commit provides the segcore foundation for the **Proxy-Only
architecture**:
1. Proxy amplifies group_count and group_size, flattens all nested
levels into a flat multi_terms composite key
2. Segcore / Delegator / QN execute standard flat group_by with
amplified parameters — zero awareness of nesting or metrics
3. Proxy reconstructs the nested hierarchy, computes metrics from
returned docs, and trims to user-requested group_size

The Go-layer PR will wire up: proto group_by_field_values (plural)
reading, proxy search reduce with composite keys, metric field injection
into output_fields, and nested reconstruction logic.

The full feature surface (per-group metrics R4, intra-bucket sort R5,
**bucket-level ordering / per-level-orderby R7**) is described in the
design doc below.

## Test plan

- [x] 5 existing single-field GroupBY.* tests adapted to composite key
path — all pass
- [x] 3 existing GroupBYJSON.* tests adapted — all pass
- [x] ElementFilter group_by interaction tests adapted — all pass
- [x] New GroupBY.CompositeKeySealedIndex — dual-field (int32+int64)
sealed+HNSW, strict_group_size=true, ground truth verification via
seg_offset -> raw_data lookup, exact group count and per-group size
assertions
- [x] New GroupBY.CompositeKeyGrowing — dual-field (int8+int32) growing
segment, exact 6 groups x group_size=3, every group fully filled
- [x] New GroupBY.CompositeKeyReduce — dual-field cross-segment C-API
reduce via ReduceSearchResultsAndFillData, PK dedup + composite
group_size validation
- [x] New GroupBY.SingleFieldViaCompositeProtoPath — single field via
new group_by_field_ids proto, backward compat with exact 7 groups x
group_size=3 = 20 results
- [x] **All 68 guarded tests passing**, clang-format clean

issue: #49046
design doc:
https://github.com/milvus-io/milvus-design-docs/blob/main/design_docs/20260413-search_embedded_agg.md

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-22 20:53:45 +08:00
cc809208e9 feat: add function field backfill - Part 3 (#48809) (#48831)
DataCoord/DataNode compaction execution layer for function field
backfill.

- DataCoord: BackfillCompactionPolicy (trigger when schema version
inconsistent), BackfillCompactionTask (coord-side state machine), schema
version consistency gating in GetCollectionStatistics, clustering
compaction guard
- DataNode: BackfillCompactionTask (executor-side), backfillCompactor
for physical data transformation of function output fields
- storagev2: AsNewColumnGroups() API for packed writer transactions

related: https://github.com/milvus-io/milvus/issues/48808
design doc:
https://github.com/milvus-io/milvus-design-docs/blob/main/design_docs/20260129-add-function-field-design.md

---------

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 20:03:43 +08:00
d05a1c6c9c fix: correct nullable vector field merge to prevent panic on empty lidData (#48700) (#48819)
Two bugs in the Go-layer query reduce pipeline caused panics and wrong
ValidData output for nullable vector fields:

Bug 1: buildCompactIndices inferred nullable from ValidData presence.
When segcore returns empty ValidData + empty Contents (e.g. index not
ready via fill_with_empty), the compact mapping was not built, causing
getVecDataIdx to return rowIdx directly and Contents[rowIdx] to panic.

Bug 2: buildMergedFieldData set validData[i]=true when ValidData was
absent for a nullable field, incorrectly marking null rows as valid.

Fix: use schema (map[fieldID]bool) as the source of truth for
nullability. Empty ValidData for a nullable field now means "all rows
are null" rather than "non-nullable". All QN-side and proxy-side
operators (ReduceByPKTS, DeduplicatePK, ReduceByPK, ConcatAndCheckPK)
receive the nullable map built from schema at construction time.

Also add bounds checks to buildMergedScalarField for all scalar types to
guard against nullable fields with empty Data arrays.

related: #48700

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 15:25:43 +08:00
e0873a65d4 enhance: remove SuffixSnapshot mechanism from RootCoord metadata storage (#47960)
## Summary

Remove the entire SuffixSnapshot time-travel layer from RootCoord
metadata storage, replacing it with plain KV operations.

Replace SnapShotKV with TxnKV in Catalog (~30 call sites)
Delete suffix_snapshot.go (~750 lines) and tests (~917 lines)
Remove SnapShotKV interface from pkg/kv/kv.go
Remove snapshot GC config params (ttl, reserveTime)
Keep IsTombstone/ComposeSnapshotKey constants for migration tool
compatibility
Why: Investigation confirmed snapshot keys are write-only artifacts that
nobody reads:

No client/proxy sends non-zero timestamp for time-travel metadata
queries
Tombstone sweeper calls RemoveCollection(ts=0), bypassing snapshot
tombstone writes entirely
Snapshot keys accumulate as orphans — the old GC couldn't fully clean
them because ts=0 deletion path never wrote tombstone markers
Net reduction: -2180 lines

related: #48697

## Test plan
- [x] Unit tests for GC batch logic (expiry, cursor progress,
latest-per-group protection, tombstone cleanup)
- [x] Unit tests for Save/Load with time-travel verification
- [x] `go vet` passes on all changed packages
- [ ] CI passes

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 14:33:39 +08:00
8746f52efb feat: add function field backfill - Part 2 (#48808) (#48810)
Proxy/RootCoord/Schema layer for AlterCollectionSchema API.

- Proxy: AlterCollectionSchema handler (alterCollectionSchemaTask,
validateAddFieldRequest), schema version consistency gate
(checkSchemaVersionConsistency), external collection guard
- RootCoord: broadcastAlterCollectionSchema DDL callback with schema
version increment
- metastore/model: DoPhysicalBackfill field in Collection,
MinSchemaVersion field in Index
- pkg/common: SchemaVersionConsistentSegmentsKey/TotalSegmentsKey

related: #48808
design doc:
https://github.com/milvus-io/milvus-design-docs/blob/main/design_docs/20260129-add-function-field-design.md

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 18:41:39 +08:00
d0a2078901 enhance: improve HuaweiCloud credential provider robustness and observability (#48046)
## Summary

- **Go layer**: Replace `sync.Once` with recoverable `sync.Mutex` init;
add process-level singleton; set `duration_seconds=7200` (was defaulting
to 15min); add `refreshMu` to deduplicate concurrent STS calls and
prevent data race on `IsExpired()`; validate credential completeness
(AK/SK/Token); add comprehensive logging with masked AK
- **C++ layer**: Default-initialize `STSCallResult.success{false}` (was
UB); validate AK/SK/Token completeness before updating cached
credentials in `Reload()`; mask access key in DEBUG log

related: #48045

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 10:21:34 +08:00
88e91f6caf enhance: add trace for search pipeline(#47731) (#47736)
related: #47731

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 11:07:34 +08:00
ef987a35f3 enhance: add GetCollectionName() to RESTful request types for metrics (#48465)
## Summary
- Add `GetCollectionName()` method to 12 RESTful API request types that
were missing it
- Ensures `ProxyFunctionCall` metrics report the correct collection name
label for all RESTful endpoints
- Affected types: `RenameCollectionReq`, `QueryReqV2`,
`CollectionIDReq`, `CollectionFilterReq`, `CollectionDataReq`,
`SearchReqV2`, `HybridSearchReq`, `PartitionsReq`, `GrantV2Req`,
`IndexParamReq`, `CollectionReq`, `RunAnalyzerReq`

issue: #48461

## Test plan
- [ ] Verify existing unit tests pass
- [ ] Confirm RESTful API metrics now include collection name for
search/query/hybrid_search endpoints

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 14:41:32 +08:00
3e68a9c0c9 feat: add Go-layer ORDER BY pipeline for query (#41675) (#48298)
Add Go-layer query ORDER BY support:
- Pipeline-based query reduction at QN/Delegator/Proxy levels
- DeduplicatePK operator (hash-set dedup with timestamp) for ORDER BY
- OrderByLimitOperator with heap-based partial sort O(N log K)
- Remap/Slice operators for proxy-level offset/limit and field
reordering
- ORDER BY field parsing, validation, and plan translation
- E2E tests for ORDER BY with various field types, nullable,
cross-segment

design doc:
https://github.com/milvus-io/milvus-design-docs/blob/main/design_docs/20260203-query-orderby.md
issue: https://github.com/milvus-io/milvus/issues/41675

---------

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 02:17:31 +08:00
cc9c60eeaf fix: HashTable dynamic rehash and group count limit for GROUP BY aggregation (#48174)
## Summary
- HashTable now dynamically rehashes (doubles capacity) when load factor
exceeds 7/8, fixing crash when GROUP BY cardinality > ~1792
- Added configurable `queryNode.segcore.maxGroupByGroups` (default 100K)
to cap total groups and prevent OOM on both C++ (per-segment HashTable)
and Go (cross-segment agg reducer) layers
- Added 4 C++ unit tests covering rehash basic/correctness, max groups
limit, and multiple rehash rounds

issue: #47569

## Test plan
- [ ] C++ unit tests: `--gtest_filter="*HashTableRehash*:*MaxGroups*"`
- [ ] E2E: GROUP BY aggregation with >2K unique values should succeed
- [ ] E2E: Set `queryNode.segcore.maxGroupByGroups` to small value,
verify clear error message

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 18:21:29 +08:00
182b35c347 feat: add segcore ORDER BY support for query (#48125)
## Summary
- Add `QueryOrderByNode` operator with `SortBuffer` for heap-based
partial sort in segcore
- Add `FillOrderByResult` path in `SegmentInterface` that bypasses
`find_first` for ORDER BY queries
- Parse `order_by_fields` from query plan proto into segcore plan nodes
- Proto changes: add `OrderByField` message and `order_by_fields` field
in `QueryPlanNode`

issue: #41675

## Test plan
- [x] C++ unit test `test_sort_buffer.cpp` covers SortBuffer with
various data types, null handling, multi-key sort
- [ ] Full E2E coverage in the follow-up Go-layer PR

design doc:
https://github.com/milvus-io/milvus-design-docs/blob/main/design_docs/20260203-query-orderby.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 11:39:26 +08:00
65f0df9f17 fix: empty result set crashes Milvus on GROUP BY aggregation query (#48050)
## Summary

Fixes #47316

- **GroupingSet::outputRowCount()**: Add null check for `lookup_` to
prevent SIGSEGV when filter matches zero rows and no input data arrives
- **ExecPlanNodeVisitor::setupRetrieveResult()**: When query result is
nullptr, build empty field_data arrays with correct schema (0 rows, N
columns) so downstream receives proper column structure instead of
missing columns
- Enable previously skipped E2E test `test_empty_result_aggregation`

## Test plan

- [x] E2E test `test_empty_result_aggregation` passes (GROUP BY +
aggregation with filter matching 0 rows returns empty result `[]`)
- [ ] Existing aggregation E2E tests still pass
- [ ] CI green

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 22:31:24 +08:00
bc9b741d3c enhance: optimize count aggregation performance for nullable fields (#48055)
## Summary
- Optimize `addSingleGroupRawInput` (global aggregation): replace O(N)
row-by-row `ValidAt()` loop with O(1) `nullCount()`-based computation
- Optimize `addRawInput` (GROUP BY): add `nullCount()==0` fast path to
skip validity checks entirely; for columns with actual nulls, use direct
bitmap access instead of virtual `ValidAt()` calls

issue: #47566

## Test plan
- [ ] Existing aggregation E2E tests pass
- [ ] C++ unit tests for query aggregation pass
- [ ] Benchmark nullable vs non-nullable count aggregation performance

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2026-03-09 12:01:22 +08:00
addcb3410c enhance: enhance internal logic for huaweicloud credential provider (#47676) (#47682)
## Summary

Enhance HuaweiCloud credential provider to fix infinite retry loop and
improve robustness.

- Add exception safety (try-catch) around STS calls that can throw
- Add `success` flag and result validation before overwriting
credentials
- Add null response and HTTP status code checks in STS client
- Add tiered cooldown mechanism (5s urgent / 30s normal) to prevent STS
endpoint flooding
- Fix inconsistent reader/writer lock predicate in `RefreshIfExpired()`
- Improve log levels and messages

issue: https://github.com/milvus-io/milvus/issues/47676

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 11:05:20 +08:00
552cba98a0 fix: count(*) returns wrong result when queried with count(nullable_f… (#47881)
related: #47509
related: #47539

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 14:25:20 +08:00
9031783ea6 enhance: involve text index when estimating memory cost for loading (#47899)
related: #47539

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 19:15:21 +08:00
fd38f40ff7 fix: assemble validity map for query aggregation result(#47350) (#47445)
related: #47350

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2026-02-12 16:58:42 +08:00
af11c336fd enhance: remove stream reduce logic(#47516) (#47544)
related: #47516

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2026-02-09 18:25:52 +08:00
25a155efcb feat: part1 for add field backfill(#44444) (#46808)
related: #44444
design doc:
https://github.com/milvus-io/milvus-design-docs/blob/main/design_docs/20260129-add-function-field-design.md

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2026-02-05 19:19:52 +08:00
0958b0f907 feat: support milvus orderby (#41675) (#47222)
related: #41675
design doc:
https://github.com/milvus-io/milvus-design-docs/blob/main/design_docs/20260129-orderby.md

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2026-02-03 15:30:25 +08:00
a8a1acc08b fix: wrong groups returned when pagination(#47246) (#47247)
related: #47246

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2026-01-29 09:51:33 +08:00
8ef6c2f092 feat: support restful search_by_pk(#47259) (#47260)
related: #47259

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2026-01-23 17:33:31 +08:00
ce55d128d5 enhance: simply code for subscripting json data(#46826) (#47002)
related: #46826

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2026-01-14 20:05:27 +08:00
224c03b969 fix: groupby dynamic field failed to return correct results(#46605) (#46985)
related: #46605

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2026-01-12 19:41:26 +08:00
4065c86040 fix: is_null_expr crash on indexed-json field(#46614) (#46923)
related: #46614

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2026-01-08 21:23:26 +08:00
b7ee93fc52 feat: support query aggregtion(#36380) (#44394)
related: #36380

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
- Core invariant: aggregation is centralized and schema-aware — all
aggregate functions are created via the exec Aggregate registry
(milvus::exec::Aggregate) and validated by ValidateAggFieldType, use a
single in-memory accumulator layout (Accumulator/RowContainer) and
grouping primitives (GroupingSet, HashTable, VectorHasher), ensuring
consistent typing, null semantics and offsets across planner → exec →
reducer conversion paths (toAggregateInfo, Aggregate::create,
GroupingSet, AggResult converters).

- Removed / simplified logic: removed ad‑hoc count/group-by and reducer
code (CountNode/PhyCountNode, GroupByNode/PhyGroupByNode, cntReducer and
its tests) and consolidated into a unified AggregationNode →
PhyAggregationNode + GroupingSet + HashTable execution path and
centralized reducers (MilvusAggReducer, InternalAggReducer,
SegcoreAggReducer). AVG now implemented compositionally (SUM + COUNT)
rather than a bespoke operator, eliminating duplicate implementations.

- Why this does NOT cause data loss or regressions: existing data-access
and serialization paths are preserved and explicitly validated —
bulk_subscript / bulk_script_field_data and FieldData creation are used
for output materialization; converters (InternalResult2AggResult ↔
AggResult2internalResult, SegcoreResults2AggResult ↔
AggResult2segcoreResult) enforce shape/type/row-count validation; proxy
and plan-level checks (MatchAggregationExpression,
translateOutputFields, ValidateAggFieldType, translateGroupByFieldIds)
reject unsupported inputs (ARRAY/JSON, unsupported datatypes) early.
Empty-result generation and explicit error returns guard against silent
corruption.

- New capability and scope: end-to-end GROUP BY and aggregation support
added across the stack — proto (plan.proto, RetrieveRequest fields
group_by_field_ids/aggregates), planner nodes (AggregationNode,
ProjectNode, SearchGroupByNode), exec operators (PhyAggregationNode,
PhyProjectNode) and aggregation core (Aggregate implementations:
Sum/Count/Min/Max, SimpleNumericAggregate, RowContainer, GroupingSet,
HashTable) plus proxy/querynode reducers and tests — enabling grouped
and global aggregation (sum, count, min, max, avg via sum+count) with
schema-aware validation and reduction.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2026-01-06 16:29:25 +08:00
da732ec04d enhance: change credential provider to singleton(#46649) (#46653)
related: #46649

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
- Core invariant: STS IAM credential providers for Aliyun, Tencent
Cloud, and Huawei Cloud are global, stateless resources that must be
instantiated once and reused across all ChunkManager instances
(singleton), rather than created per-manager.
- Logic removed/simplified: Removed per-instance Aws::MakeShared
instantiation of STSAssumeRoleWebIdentityCredentialsProvider inside
Aliyun/Tencent/Huawei ChunkManager constructors and replaced them with
public static Get...CredentialsProvider() methods that return a
thread-safe, lazily-initialized shared_ptr singleton (static local
variable). This eliminates duplicate provider construction and
header/signal dependency usages tied to per-constructor instantiation.
- Why this does NOT introduce data loss or behavior regression:
Credential acquisition and usage paths are unchanged — callers still
call provider->GetAWSCredentials() and use the returned AWSCredentials
to construct Aws::S3::S3Client. The singleton returns the same provider
object but the provider is stateless with respect to per-manager data
(it only reads environment/platform credentials and produces
AWSCredentials). C++11+ static local initialization provides atomic,
thread-safe construction, so first-access semantics and validation
checks (AssertInfo on access key/secret/token) remain intact.
- PR type (Enhancement/Refactor): Improves credential management by
centralizing provider lifecycle, removing redundant allocations and
header dependencies, and enforcing a single shared provider per cloud
vendor where IAM is used.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-12-29 20:35:21 +08:00
f087b7432e fix: increase expiry time for huawei cloud(#46296) (#46298)
related: #46296

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
- Core invariant: expiration comparisons use
Aws::Utils::DateTime::Now().count() which returns milliseconds; any
expiration grace period must be expressed in milliseconds and compared
via (GetExpiration() - Now()).count() in ExpiresSoon() (Huawei and
Tencent providers).
- Root cause and fix: the grace period constant was authored as 7200
(seconds) but used against millisecond counts, causing premature
refreshes. The PR changes
STS_CREDENTIAL_PROVIDER_EXPIRATION_GRACE_PERIOD to 180 * 1000 (180000
ms) in HuaweiCloudCredentialsProvider.cpp and
TencentCloudCredentialsProvider.cpp to align units and stop unnecessary
refreshes.
- Removed/replaced redundant/incorrect behavior: the PR does not add new
control flow but corrects unit mismatch and simplifies logging/STS
request handling — HuaweiCloudSTSClient now explicitly requests a
7200-second token by adding "token": {"duration_seconds": 7200} to the
JSON body and uses JsonValue(...).View() for parsing; Huawei logging
level raised from TRACE to DEBUG and now logs expiration_count_diff_ms
for clarity. These changes remove ambiguity about requested token
lifetime and improve diagnostic output.
- No data loss or regression: credential contents and assignment are
unchanged — Reload()/RefreshIfExpired()/ExpiresSoon() still populate
m_credentials from STS responses and return them via
GetAWSCredentials(); only the grace-period unit and the Huawei STS
request body/parsing/logging were adjusted. Code paths affected are
ExpiresSoon()/RefreshIfExpired()/Reload() in both providers and
HuaweiCloudSTSCredentialsClient::callHuaweiCloudSTS; since credentials
are still read from the same response fields (access, secret,
securitytoken, expires_at) and assigned to result.creds, there is no
data loss or altered persistence/authorization semantics beyond aligning
requested token duration and correct refresh timing.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-12-29 14:05:20 +08:00
f0265dde18 fix: catch exception from LoadWithStrategy(#46380) (#46381)
related: #46380

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-12-17 11:37:17 +08:00
d9f8e38d6a fix: query failed for int value on edge(#46075) (#46126)
related: #46075

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-12-10 15:59:12 +08:00
f34eb3ae90 enhance: remove useless code(#30376) (#45685)
related: #30376

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-11-27 10:43:07 +08:00
406fa7b694 fix: failed to get raw data for hybrid index(#45318) (#45411)
related: #45318

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-11-13 10:17:37 +08:00
69f3aab229 feat: milvus support huawei cloud iam verification(#45298) (#45457)
related: #45298

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-11-11 14:41:41 +08:00
87b466fd83 fix: Group value is nil(#45418) (#45422)
related: #45418

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-11-08 10:29:33 +08:00
2ea8d85c2f feat: restful support run analyzer(#44803) (#44805)
related: #44803

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-10-14 14:41:59 +08:00
1b7562a766 feat: support mannual compact l0(#44439) (#44440)
related: #44439

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-09-23 12:44:07 +08:00
26a024625d feat: support search by on json field and dynamic field(#43124) (#43203)
related: #43124

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-09-09 21:51:56 +08:00
da156981c6 feat: milvus support posix-compatible mode(milvus-io#43942) (#43944)
related: #43942

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-08-27 16:29:50 +08:00
412a0eb1c3 fix: httpserver crash for division to zero(#43639) (#43799)
related: #43639

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-08-14 14:59:43 +08:00
d826d6ac91 fix: try to get span raw data for variable length data type(#43544) (#43705)
related: #43544

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-08-04 11:15:38 +08:00
d72c0357ff fix: empty hybridsearch result due to one-sub-search empty(#43537) (#43647)
related: #43537

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-07-31 19:47:37 +08:00
4ee9f63f72 fix: return id by default(#43595) (#43601)
related: #43595

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-07-29 12:07:36 +08:00
5a1092304c fix: refine judgement for batch views(#38736) (#43481)
related: #38736

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-07-22 14:20:53 +08:00
07745439b5 fix: empty search groupby result causing crash(#43137) (#43214)
related: #43137

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-07-10 12:04:48 +08:00
001619aef9 feat: supporing load priority for loading (#42413)
related: #40781

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-06-17 15:22:38 +08:00
e9b5d9e8bc enhance: refine compaction trigger to reduce read/write amplifaction(#41336) (#41728)
related: #41336

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-06-04 11:24:38 +08:00
Chun HanandGitHub ed0df38605 enhance: resize high priority wqthreadpool dynamically(#40838) (#41549) (#41929)
related: #40838
pr: https://github.com/milvus-io/milvus/pull/41549

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
2025-05-30 10:18:36 +08:00
d1cfa58a0a feature: support compact expiry data(#41336) (#42056)
related: #41336

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-05-25 16:46:31 +08:00
12cde913b5 fix: fail to get string views due to chunk bound empty loop(#41300) (#41452)
related: #41300

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-04-27 10:40:38 +08:00
016920b023 fix: solve incompitable problem for none-encoding index(#40838) (#41369)
related: #40838

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-04-20 22:56:44 +08:00
59b14d38f5 enhance: Optimize index format for improved load performance(#40838) (#40839)
related: https://github.com/milvus-io/milvus/issues/40838

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-04-15 03:10:30 +08:00
afa519b4c7 fix: array is null failed(#40686) (#41027)
related: #40686

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-04-02 18:20:22 +08:00
eee68e9139 fix: mmap properties failed to apply when creating collection(#40511) (#40512)
related: #40511

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-03-25 10:08:19 +08:00
16aa123185 fix: restful drop db properties failure(#39953) (#40257)
related: #39953

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-03-03 15:39:59 +08:00
259f9106ad enhance: refine variable-length-type memory usage(#38736) (#39578)
related: #38736

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-02-27 21:13:58 +08:00
190ac11cd1 fix: cancel sub contexts casade when http request timeout(#40030) (#40059)
related: #40030

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-02-26 11:33:57 +08:00
d6699b5f50 enhance: support return configable properties when describing index(#39951) (#40042)
related: #39951

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-02-21 19:07:53 +08:00
1dc31619f8 enhance: support create collection with description(#40022) (#40023)
related: #40022

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-02-20 22:31:53 +08:00
ed31a5a4bf enhance: fix inconsistenty of alias and db for query iterator(#39045) (#39216)
related: #39045

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-01-15 09:48:59 +08:00
3739446a33 enhance: refine array view to optimize memory usage(#38736) (#38808)
related: #38736

700m data, array_length=10
non-mmap_offsets_uint64: 2.0G
mmap_offsets_uint64: 1.1G
mmap_offsets_uint32: 880MB

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2025-01-07 13:26:55 +08:00
decdfdae10 fix: growing-groupby-crush(#38533) (#38538)
related: #38533

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2024-12-17 21:05:12 +08:00
c1f9158996 fix: search-group-by failed to get data from multi-chunked-segment(##… (#38383)
related: #38343

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2024-12-13 16:54:43 +08:00
f2a2fd6808 enhance: shallow copy search request for large nq cases(#37732) (#37749)
related: #37732

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2024-11-18 13:06:32 +08:00
2d29dcd30c enhance:refine group_strict_size parameter(#37482) (#37483)
related: #37482

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2024-11-12 09:56:28 +08:00
e2f2fd55a5 enhance: avoid limiting ddl operations repeatedly(#37006) (#37010)
related: #37006

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2024-10-22 20:11:27 +08:00
eccc326e8b enhance: report err when group_size is wrong(#36146) (#36908)
related: #36146

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2024-10-17 16:05:29 +08:00
903450f5c6 enhance: add ts support for iterator(#22718) (#36572)
related: #22718

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2024-10-16 18:51:23 +08:00
a25dc98794 enhance: support group_size and hybridsearch+groupby on httpv2 side(#36386) (#36461)
related: #36386

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2024-09-30 11:09:16 +08:00
a54bffd6cd fix: refine test case for search_group_by(#36401) (#36511)
related: #36401

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2024-09-30 10:13:17 +08:00
d55d9d6e1d fix: change pymilvus version for hybridsearch-groupby(#36407) (#36451)
related: #36407

---------

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2024-09-24 14:29:13 +08:00
df7ae08851 fix: iterator cursor progress too fast(#36179) (#36180)
related: #36179

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2024-09-24 11:45:13 +08:00
eb23e23cd2 enhance: refine parameter relationship for hybridsearch_group_by(#35096) (#36289)
related: #35096

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
2024-09-20 14:55:11 +08:00