Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions sdk/cosmos/.cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"accountname",
"activityid",
"ALPN",
"antisymmetry",
"apacsoutheast",
"Appleby's",
"argtypes",
Expand Down Expand Up @@ -61,6 +62,7 @@
"consumingly",
"Conv",
"cooldown",
"copysign",
"cosmosclient",
"cosmosdriver",
"correlator",
Expand Down Expand Up @@ -118,6 +120,7 @@
"fixdate",
"flamegraph",
"fmix",
"formattableorderbyquery",
"fract",
"francecentral",
"francesouth",
Expand Down Expand Up @@ -308,6 +311,7 @@
"uncollapsed",
"uncontended",
"undrained",
"unemitted",
"unfaulted",
"ungoverned",
"unparseable",
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 @@ -13,6 +13,7 @@
- Added change feed pull support via `ContainerClient::query_change_feed()`, which takes a required `ChangeFeedStartFrom` start position (`Beginning`, `Now`, `PointInTime`) and returns a `ChangeFeedPageIterator<T>` that streams `FeedPage<T>` results. New `feed` types `ChangeFeedPageIterator`, `FeedScope`, and `ContinuationToken`, plus `options` types `ChangeFeedOptions` and `ChangeFeedMode` (currently `LatestVersion`); supports single-partition, per-partition-key, and full-container (cross-partition fan-out) reads with continuation-token resumption that persists the original start position so never-polled partitions don't replay history on resume. ([#4621](https://github.com/Azure/azure-sdk-for-rust/pull/4621))
- Change feed items are now surfaced as an envelope. `ContainerClient::query_change_feed::<YourDoc>()` yields `ChangeFeedItem<YourDoc>`, binding the envelope into the return type so the post-change document is read via `ChangeFeedItem::current()` and cannot be silently deserialized away. The envelope also exposes the pre-change document (`previous()`) and per-change `metadata()` (populated by full-fidelity reads; absent for `LatestVersion`). A full-fidelity delete returns an empty `current` object, which maps to `None` so callers with strict document types still deserialize the delete; the deleted item's identity is available via `ChangeFeedMetadata::id()` and `ChangeFeedMetadata::partition_key()`. `ChangeFeedOperationType` includes an `Unknown` catch-all so a future operation type cannot fail a page and stall the feed. A backend that does not envelope change feed items (such as the Cosmos emulator) returns the bare document, which is mapped onto `current()` so no data is lost. Added the `models` types `ChangeFeedItem<T>`, `ChangeFeedMetadata`, `ChangeFeedOperationType`, and `LogicalSequenceNumber`. ([#4723](https://github.com/Azure/azure-sdk-for-rust/pull/4723))
- Added `TlsBackend` (re-exported) and a `tls_backend` option on `ConnectionPoolOptions` (`ConnectionPoolOptionsBuilder::with_tls_backend`), defaulting to `TlsBackend::Rustls`, available under the `rustls` feature, to pin the TLS backend used by the transport. This is additive and changes no behavior for the default (rustls) build; it only has an effect in builds that compile in multiple reqwest TLS backends, where reqwest would otherwise default to native-tls and the driver now pins rustls instead. ([#4649](https://github.com/Azure/azure-sdk-for-rust/pull/4649))
- Added resumable cross-partition streaming `ORDER BY` query support. ([#4800](https://github.com/Azure/azure-sdk-for-rust/pull/4800))

### Breaking Changes

Expand Down
62 changes: 16 additions & 46 deletions sdk/cosmos/azure_data_cosmos/tests/emulator_tests/cosmos_query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use azure_data_cosmos::feed::ContinuationToken;
use azure_data_cosmos::{
clients::DatabaseClient,
feed::FeedScope,
models::CosmosStatus,
options::{MaxItemCountHint, QueryOptions},
Query,
};
Expand Down Expand Up @@ -263,56 +262,27 @@ pub async fn cross_partition_query_with_projection_and_filter() -> Result<(), Bo
test_category = "emulator_vnext",
ignore = "skipped on vnext emulator: behavioral divergence"
)]
pub async fn cross_partition_query_with_order_by_fails() -> Result<(), Box<dyn Error>> {
pub async fn cross_partition_query_with_order_by() -> Result<(), Box<dyn Error>> {
TestClient::run_with_unique_db(
async |_, db_client| {
let items = test_data::generate_mock_items(10, 10);
let container_client =
test_data::create_container_with_items(db_client, items.clone(), None).await?;
let mut expected = items.clone();
expected.sort_by_key(|item| item.merge_order);
let expected_ids = expected.into_iter().map(|item| item.id).collect();

let Err(err) = container_client
.query_items::<String>(
"select value c.id from c order by c.mergeOrder",
FeedScope::full_container(),
None,
)
.await
else {
panic!("Expected query to fail due to cross-partition ORDER BY");
};
assert_eq!(
err.status(),
CosmosStatus::CROSS_PARTITION_QUERY_NOT_SERVABLE,
"Expected 400 / 1004 (CrossPartitionQueryNotServable) for cross-partition ORDER BY"
);
execute_query_test(
db_client,
items,
"select value c.id from c order by c.mergeOrder",
FeedScope::full_container(),
expected_ids,
QueryTestOptions {
max_item_count: Some(7),
use_continuation_token_resume: true,
},
)
.await?;

let body = err
.response()
.and_then(|r| match r.body() {
azure_data_cosmos_driver::models::ResponseBody::Bytes(b) => Some(b.as_ref()),
_ => None,
})
.expect("service error should carry a response body");
#[derive(serde::Deserialize)]
struct ErrorDetail {
code: String,
message: String,
}
let error_detail: ErrorDetail =
serde_json::from_slice(body).expect("response body must be JSON");
assert_eq!(error_detail.code, "BadRequest");

// Take only the first two lines of the message for comparison, since the full message may contain additional details that could change over time
let clean_message = error_detail
.message
.lines()
.take(2)
.collect::<Vec<_>>()
.join("\n");
assert_eq!(
clean_message,
"Query contains 1 or more unsupported features. Upgrade your SDK to a version that does support the requested features:\nQuery contained OrderBy, which the calling client does not support."
);
Ok(())
},
Some(TestOptions::for_emulator()),
Expand Down
4 changes: 4 additions & 0 deletions sdk/cosmos/azure_data_cosmos/tests/in_memory_emulator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@
// the entire translation unit (and its dev-only deps such as `uuid`) out of
// the build when the feature is off.

// Test futures compose many operations and near clippy's `large_futures`
// threshold on tokio's large test stacks; allowed here (mirrors `tests/split.rs`).
#![allow(clippy::large_futures)]

mod in_memory_emulator_tests;
Loading
Loading