janhoy opened a new pull request, #4943:
URL: https://github.com/apache/solr/pull/4943

   https://issues.apache.org/jira/browse/SOLR-18479
   
   # Description
   
   Fields, dynamic fields and field types each have `PUT`/`DELETE` routes in 
the v2 Schema API. Copy-fields were the one resource reachable only through 
`/schema/bulk` — the routes existed but were commented out, with a TODO noting 
that copy-field rules have no name to address them by.
   
   # Philosophy
   
   **Address rules by their source field.** A copy-field rule has no name, but 
it does have a source, and `/copyfields/{sourceField}` is a well-defined 
resource: *the set of rules copying from that field*. Every verb acts on that 
set.
   
   **The verb says what happens to the set.** `PUT` replaces it, `POST` adds to 
it, `DELETE` removes from it. That distinction matters because the underlying 
`add-copy-field` is purely additive and does **not** check for duplicates — 
re-adding an existing rule makes the source get copied twice at index time. So 
`PUT` clears before adding and `POST` skips destinations already present, which 
makes both safe to repeat. A client that times out never has to know whether 
its request landed.
   
   **Diff under the schema update lock.** Working out which rules to drop or 
skip happens inside `SchemaManager`, in two internal-only ops 
(`upsert-copy-field`, `append-copy-field`) alongside the existing 
`upsert-field`. `doOperations` refreshes the schema under the lock and replays 
ops on retry, so a diff computed in the resource layer would go stale exactly 
when it matters.
   
   # Endpoints
   
   All under `/api/collections/{collection}/schema` (or `/cores/{core}`). Write 
operations require `schema-edit`, the read requires `schema-read`.
   
   ### `GET /copyfields/{sourceField}`
   Lists the rules copying from `sourceField`, covering glob rules as well as 
explicit ones.
   - **200** — `{"copyFields":[{"source":…,"dest":…,"maxChars":…}]}`; an empty 
list if the source has no rules.
   
   > Preferred over `GET /copyfields?source.fl=…`, which remains the only way 
to filter by destination or by several sources at once.
   
   Note the response is a list of individual rules, not the set-shaped body the 
write verbs take. That is deliberate: the shape is identical to the existing 
`/copyfields`, and `maxChars` is per rule, so `{"source":…,"destinations":[…]}` 
could not represent a source whose rules have differing limits.
   
   ### `PUT /copyfields/{sourceField}`
   Sets the complete destination list for the source, removing any rule left 
out. Idempotent.
   - **body** — `{"destinations":["a","b"],"maxChars":100}`. `destinations` is 
required; a bare string is accepted for a single destination, and `dest` is 
accepted as an alias because v1 commands deserialize through the same model. 
`maxChars` optional. An empty list clears the source.
   - **200** — applied.
   - **400** — `destinations` missing, a body `source` contradicting the path, 
or the schema rejects a rule.
   
   ### `POST /copyfields/{sourceField}`
   Adds destinations, leaving the source's existing rules in place. 
Destinations already present are skipped, so repeating is harmless. Idempotent.
   - **body / responses** — as `PUT`.
   
   ### `DELETE /copyfields/{sourceField}`
   Removes every rule copying from the source.
   - **200** — applied.
   - **404** — the source has no copy-field rules.
   
   ### `DELETE /copyfields/{sourceField}/{destinationFields}`
   Removes the named rules. `destinationFields` is one destination or a 
comma-separated list.
   - **200** — applied.
   - **400** — the segment names no destinations, or a named rule does not 
exist.
   
   # Tests
   
   `V2CopyFieldApiTest` covers all six routes: replace, append, idempotency of 
both, per-destination and bulk delete, the transactional rollback of a rejected 
replace, non-interference with other sources, and the error cases. Error-case 
unit coverage in `V2UpdateSchemaErrorCaseTests`. Ref guide updated. `./gradlew 
check` passes.
   
   PR authored using Claude AI
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to