Skip to content
10 changes: 10 additions & 0 deletions sdk/cosmos/.cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@
"Daad",
"dcount",
"dedicatedgateway",
"dedup",
"dedupe",
"dedups",
"deprioritized",
"dkunda",
"deprioritizes",
Expand Down Expand Up @@ -156,6 +159,7 @@
"Gson",
"Gtle",
"hedgeable",
"hexdigit",
"HRESULT",
"hresult",
"hostnames",
Expand All @@ -167,6 +171,8 @@
"injective",
"inlines",
"inmemory",
"inspectable",
"intprop",
"ints",
"intptr",
"INVALIDARG",
Expand All @@ -187,6 +193,7 @@
"LIBCLANG",
"libfuzzer",
"libqueryplaninterop",
"queryplan",
"QUERYPLANINTEROP",
"linearizability",
"livesite",
Expand Down Expand Up @@ -279,6 +286,8 @@
"readfeed",
"recompiles",
"redecoded",
"reemit",
"reemitted",
"reencode",
"reencoded",
"refetch",
Expand All @@ -290,6 +299,7 @@
"Replicaset",
"reqs",
"restype",
"resumability",
"Retriable",
"retryable",
"replayable",
Expand Down
1 change: 1 addition & 0 deletions sdk/cosmos/azure_data_cosmos/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
- Added `DatabaseClient::name()` and `DatabaseClient::rid()` to inspect how a database client was addressed. ([#4687](https://github.com/Azure/azure-sdk-for-rust/pull/4687))
- RID-addressed databases skip the extra database read when resolving throughput offers, reusing the addressed RID directly. ([#4687](https://github.com/Azure/azure-sdk-for-rust/pull/4687))
- Reading and querying items by RID now works end-to-end, including a parent-database cross-check that rejects a container RID belonging to a different database. ([#4687](https://github.com/Azure/azure-sdk-for-rust/pull/4687))
- Added cross-partition `DISTINCT` query support. `SELECT DISTINCT` now deduplicates structurally equal values across every physical partition and page, rather than failing as an unsupported query feature. A `DISTINCT` query whose `ORDER BY` prefixes its projection (for example `SELECT DISTINCT VALUE c.city FROM c ORDER BY c.city`) is resumable from a continuation token; one without such an `ORDER BY` is not, and requesting a token for it returns an error explaining how to rewrite the query. ([#5026](https://github.com/Azure/azure-sdk-for-rust/pull/5026))
Comment thread
tvaron3 marked this conversation as resolved.
Outdated
- Added an SDK-generated `x-ms-client-id` header that remains stable for each `CosmosClient`. ([#4844](https://github.com/Azure/azure-sdk-for-rust/pull/4844))
- Added opt-in Cosmos binary JSON encoding for item operations (`create`/`read`/`replace`/`upsert`). Enable it via `CosmosClientBuilder::with_binary_encoding_options` (or the `AZURE_COSMOS_BINARY_ENCODING_ENABLED` environment-variable fallback). Off by default; when disabled, requests and responses are byte-for-byte unchanged. ([#4671](https://github.com/Azure/azure-sdk-for-rust/pull/4671))
- Added `FeedOptions::max_fan_out` (and `FeedOptions::with_max_fan_out`) to cap how many physical partitions a cross-partition query or change feed may fan out to. Applies to `ContainerClient::query_items` and `ContainerClient::query_change_feed`. The cap is enforced only at initial query setup; a partition that splits mid-execution and pushes the fan-out higher does not abort the operation. ([#4855](https://github.com/Azure/azure-sdk-for-rust/pull/4855))
Expand Down
39 changes: 29 additions & 10 deletions sdk/cosmos/azure_data_cosmos/tests/emulator_tests/cosmos_hpk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -802,16 +802,17 @@ pub async fn hpk_query_single_partition_order_by_servable() -> Result<(), Box<dy
.await
}

/// B9: cross-partition advanced query operators (`DISTINCT`, aggregates,
/// `GROUP BY`) over a hierarchical container are not servable.
/// B9: cross-partition advanced query operators over a hierarchical container.
///
/// The Rust SDK only advertises the `OffsetAndLimit,Top` cross-partition query
/// features (see #4750), so any full-container query needing a client-side
/// pipeline the SDK does not yet implement is rejected. HPK fan-out itself
/// works since #4729 (see B6); these cases fail solely because the SDK lacks
/// the corresponding cross-partition operator pipeline. Each case is expected
/// to error with 400 BadRequest / 1004 CrossPartitionQueryNotServable.
/// `OFFSET/LIMIT/TOP` are covered separately by the servable case below.
/// The SDK advertises only the features it has a client-side pipeline for (see
/// `query::SUPPORTED_QUERY_FEATURES`), and the service rejects any query needing
/// one it did not advertise with 400 BadRequest / 1004
/// CrossPartitionQueryNotServable. HPK fan-out itself already works (see B6),
/// so these cases turn on operator support alone.
///
/// `DISTINCT` and `OFFSET`/`LIMIT`/`TOP` are servable now that their stages
/// landed; aggregates and `GROUP BY` are still pipeline-less and remain
/// rejected.
#[tokio::test]
#[cfg_attr(
not(any(test_category = "emulator", test_category = "emulator_vnext")),
Expand All @@ -826,8 +827,26 @@ pub async fn hpk_query_cross_partition_advanced_not_servable() -> Result<(), Box
async |run_context, db_client| {
let container = seed_three_level(run_context, db_client).await?;

// Servable: DISTINCT has a client-side stage, and it must
// deduplicate correctly across the container's physical partitions.
let mut countries = collect_query::<serde_json::Value>(
&container,
"SELECT DISTINCT VALUE c.country FROM c",
FeedScope::full_container(),
)
.await?
.into_iter()
.map(|v| v.as_str().unwrap_or_default().to_owned())
.collect::<Vec<_>>();
countries.sort();
assert_eq!(
countries,
vec!["CANADA".to_string(), "USA".to_string()],
"cross-partition DISTINCT over an HPK container must return each country once"
);

// Still rejected: no client-side pipeline for these yet.
let advanced = [
"SELECT DISTINCT c.country FROM c",
"SELECT VALUE COUNT(1) FROM c",
"SELECT c.state, COUNT(1) AS n FROM c GROUP BY c.state",
];
Expand Down
Loading
Loading