1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//! Native FFI query plan provider using the QueryPlanInterop C++ library.
//!
//! This module provides a safe Rust wrapper around `Cosmos.QueryPlanInterop.dll`
//! (Windows) / `libqueryplaninterop.so` (Linux), which generates partitioned
//! query execution plans for Cosmos DB SQL queries.
//!
//! Gated behind the `__internal_native_query_plan` feature flag. When disabled,
//! the driver uses the Gateway for all query plans. The module itself always
//! compiles so that tests can run independently of the feature flag.
//!
//! # Library loading
//!
//! The native library is loaded lazily on first query plan request.
//! If the DLL/.so is not found, the result is cached and the driver
//! falls back to the Gateway for all subsequent calls.
//!
//! Search order:
//! 1. `AZURE_COSMOS_QUERYPLANINTEROP_DIR` environment variable (absolute path)
//! 2. OS default (`PATH` on Windows, `LD_LIBRARY_PATH` on Linux)
//!
//! | Platform | Library name |
//! |----------|-------------|
//! | Windows | `Cosmos.QueryPlanInterop.dll` |
//! | Linux | `libqueryplaninterop.so` |
//! | macOS | `libqueryplaninterop.dylib` |
//!
//! # Call chain
//!
//! ```text
//! cosmos_driver::plan_operation()
//! -> NativeQueryPlanProvider::get_query_plan()
//! -> OnceLock: cached QueryPlanProvider (created once, reused)
//! -> QueryPlanProvider::new(config)
//! -> query_plan_native_lib() [OnceLock: loaded once per process]
//! -> platform::load_library(LIB_NAME) -> LoadLibraryA / dlopen
//! -> GetProcAddress / dlsym for each export
//! -> calls CreateServiceProvider(config)
//! -> provider.get_partition_key_ranges(query, pk_paths, options)
//! -> calls GetPartitionKeyRangesFromQuery4(...)
//! -> deserialize JSON -> QueryPlan
//! -> if Err: fall through to gateway_query_plan()
//! ```
//!
//! # Reusing the driver's `QueryPlan` model
//!
//! The native DLL outputs the same JSON format as the Cosmos DB Gateway's
//! query plan endpoint. The provider deserializes the DLL's output directly
//! into `crate::driver::dataflow::query_plan::QueryPlan`, avoiding type
//! duplication.
//!
//! The following deserialization differences between Gateway JSON and native
//! DLL JSON are handled in `query_plan.rs`:
//!
//! | Field | Gateway format | Native DLL format | Resolution |
//! |---|---|---|---|
//! | `hasSelectValue`, `hasNonStreamingOrderBy`, `requiresGlobalStatistics`, `isMinInclusive`, `isMaxInclusive` | `true`/`false` | `0`/`1` integer | `bool_from_int_or_bool` custom deserializer |
//! | `rewrittenQuery` | `"SELECT ..."` | `null` when absent | Changed from `String` to `Option<String>` |
//! | `groupByAliasToAggregateType` values | `"Average"` | `""`, `null`, or `"Average"` | Changed from `HashMap<String, String>` to `HashMap<String, serde_json::Value>` |
//! | `queryRanges[].min/max` | hex EPK strings (`"05C1..."`) | structured JSON values (arrays/objects) | `string_or_json` custom deserializer (converts non-strings to JSON text at deserialization time) |
//! | `partitionedQueryExecutionInfoVersion` | always present | omitted by native DLL | Added `#[serde(default)]` on `QueryPlan` struct |
//! | `aggregates` (non-VALUE queries) | populated | empty (info in `groupByAliasToAggregateType` instead) | Tests use `has_aggregates()` helper that checks both fields |
//!
//! # Running tests
//!
//! ```bash
//! # Unit tests (no native DLL needed)
//! cargo test -p azure_data_cosmos_driver --lib query_plan_native
//!
//! # Integration tests (requires native DLL)
//! AZURE_COSMOS_QUERYPLANINTEROP_DIR=/path/to/lib \
//! RUSTFLAGS='--cfg test_category="native_query_plan"' \
//! cargo test -p azure_data_cosmos_driver --lib query_plan_native \
//! --features __internal_native_query_plan
//! ```
//!
//! # Regenerating bindgen bindings
//!
//! Requires `bindgen-cli` and `libclang`:
//!
//! ```bash
//! cargo install bindgen-cli
//! cd sdk/cosmos/azure_data_cosmos_driver/src/query_plan_native
//! LIBCLANG_PATH=/path/to/libclang bindgen bindgen_wrapper.h \
//! --use-core --no-layout-tests \
//! --allowlist-type "QueryPlanInterop.*" \
//! --allowlist-function "CreateServiceProvider|UpdateServiceProvider|GetPartitionKeyRangesFromQuery4" \
//! --output generated/native_bindings.rs \
//! -- -x c++ -D_WIN32
//! ```
// ABI contract items (HRESULT constants, enum variants, free_library) are
// defined for completeness but not all are consumed by the driver yet.
pub
// NOTE: Generated bindings assume Windows (WCHAR = u16). On Linux/macOS
// WCHAR is u32. These bindings are only used for struct layout validation,
// not for runtime FFI calls. See native.rs for the platform-correct WChar type.
pub
pub
pub
// Re-export the driver's query plan model types for use by integration tests.
pub use crate;
/// High-level entry point for native query plan generation.
///
/// Encapsulates all lazy-initialization logic: the inner
/// [`QueryPlanProvider`](provider::QueryPlanProvider) is created on first use
/// and cached for the process lifetime. If the native library is unavailable,
/// `None` is cached so subsequent calls fail fast without retrying.
///
/// The query engine configuration is accepted per-call and the provider is
/// updated when it changes (e.g. after an account metadata refresh).
///
/// The driver holds an instance of this type and calls
/// [`get_query_plan`](NativeQueryPlanProvider::get_query_plan) -- no `OnceLock`
/// or `Option` handling leaks into the driver code.
pub