Skip to content

Commit 194e30e

Browse files
authored
Add '#[deny(clippy::missing_trait_methods)]' to wrapper/delegation trait impls (spiceai#10795)
* Add '#[deny(clippy::missing_trait_methods)]' to wrapper/delegation trait impls * implement missing * fix: implement missing delegation methods caught by missing_trait_methods lint * fix: rustfmt get_logical_plan signature in indexed.rs * fix: implement missing TableProvider delegation methods in PartitionTableProvider * fix: correct ScanResult return type and IndexedMemTable::scan_with_args delegation - runtime-table-partition/src/provider.rs:490: use datafusion::error::Result instead of bare Result<T> (no type alias in scope; std::result::Result requires two generic args, causing E0107 compile error on all CI jobs) - data_components/src/arrow/indexed.rs: unpack ScanArgs and call self.scan() instead of forwarding to self.inner.scan_with_args(), preserving the index fast-path logic that IndexedMemTable::scan implements * fix: replace redundant closure with method reference (clippy pedantic) * fix: replace redundant closure with method reference in scan_with_args * fix: add missing trait method forwarding impls for #[deny(clippy::missing_trait_methods)] Adds explicit implementations for all provided/default trait methods across wrapper and stub types so the deny attribute compiles cleanly: TableProvider wrappers (delegate to inner): - AcceleratedTable: get_table_definition, get_logical_plan, get_column_default, scan_with_args, statistics, truncate - UpsertDedupTableProvider: same set - EmbeddingTable: scan_with_args, truncate - LocationPruningListingTable: get_logical_plan, get_column_default, scan_with_args, statistics, insert_into, delete_from TableProvider with no inner (None / NotImplemented stubs): - SwappableTableProvider: get_table_definition/get_logical_plan/get_column_default return None (can't borrow from current() temporary Arc); scan_with_args and truncate delegate via current() - DatasetTableProvider: all missing methods return Internal errors or None - RerankUDTFProvider: metadata returns None; DML returns NotImplemented - ReciprocalRankFusion: same pattern CatalogProvider wrapper: - RefreshingCatalogProvider: register_schema, deregister_schema forwarded to inner DataConnector wrappers: - DeferredConnector: all missing methods added; stream methods return false/None (connector is a pre-initialization placeholder); setup/metrics methods delegate to self.inner - EmbeddingConnector: resolve_refresh_mode, initialization_for_dataset - FullTextConnector: initialization_for_dataset Embed wrapper: - TaskEmbed: cache, get_cached_embed, put_cached_embed delegated to self.inner * fix: remove #[deny(clippy::missing_trait_methods)] from AcceleratedTable, DeferredConnector, DatasetTableProvider * linting * fix: implement missing TableProvider trait methods for LocationPruningListingTable and EmbeddingTable - Add and to LocationPruningListingTable, delegating to inner - Add and to EmbeddingTable, delegating to base_table - Add missing imports: std::borrow::Cow and datafusion::logical_expr::LogicalPlan * fix AcceleratedTable * comments * clippy * remove nasa --------- Co-authored-by: Jeadie <[email protected]>
1 parent 287f004 commit 194e30e

25 files changed

Lines changed: 790 additions & 2 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/cayenne/src/provider/vortex_format.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ impl DeletionFilteringVortexFormat {
200200
}
201201
}
202202

203+
#[deny(clippy::missing_trait_methods)]
203204
#[async_trait]
204205
impl FileFormat for DeletionFilteringVortexFormat {
205206
fn as_any(&self) -> &dyn Any {

crates/data_components/src/arrow/indexed.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,7 @@ impl PrimaryKeyValue {
571571
}
572572
}
573573

574+
#[deny(clippy::missing_trait_methods)]
574575
#[async_trait]
575576
impl TableProvider for IndexedMemTable {
576577
fn as_any(&self) -> &dyn Any {
@@ -806,6 +807,47 @@ impl TableProvider for IndexedMemTable {
806807
) -> Result<Arc<dyn ExecutionPlan>> {
807808
self.inner.delete_from(state, filters).await
808809
}
810+
811+
fn get_table_definition(&self) -> Option<&str> {
812+
self.inner.get_table_definition()
813+
}
814+
815+
fn get_logical_plan(
816+
&self,
817+
) -> Option<std::borrow::Cow<'_, datafusion::logical_expr::LogicalPlan>> {
818+
self.inner.get_logical_plan()
819+
}
820+
821+
async fn scan_with_args<'a>(
822+
&self,
823+
state: &dyn Session,
824+
args: datafusion::catalog::ScanArgs<'a>,
825+
) -> Result<datafusion::catalog::ScanResult> {
826+
let filters = args.filters().unwrap_or(&[]);
827+
let projection = args.projection().map(<[usize]>::to_vec);
828+
let limit = args.limit();
829+
let plan = self
830+
.scan(state, projection.as_ref(), filters, limit)
831+
.await?;
832+
Ok(datafusion::catalog::ScanResult::new(plan))
833+
}
834+
835+
fn statistics(&self) -> Option<datafusion::common::Statistics> {
836+
self.inner.statistics()
837+
}
838+
839+
async fn update(
840+
&self,
841+
state: &dyn Session,
842+
assignments: Vec<(String, Expr)>,
843+
filters: Vec<Expr>,
844+
) -> Result<Arc<dyn ExecutionPlan>> {
845+
self.inner.update(state, assignments, filters).await
846+
}
847+
848+
async fn truncate(&self, state: &dyn Session) -> Result<Arc<dyn ExecutionPlan>> {
849+
self.inner.truncate(state).await
850+
}
809851
}
810852

811853
#[async_trait]

crates/data_components/src/ducklake/writer.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ impl DuckDbFederatedTableWriter {
110110
}
111111
}
112112

113+
#[deny(clippy::missing_trait_methods)]
113114
#[async_trait]
114115
impl TableProvider for DuckDbFederatedTableWriter {
115116
fn as_any(&self) -> &dyn Any {
@@ -196,6 +197,27 @@ impl TableProvider for DuckDbFederatedTableWriter {
196197

197198
Ok(Arc::new(DataSinkExec::new(input, Arc::new(sink), None)) as _)
198199
}
200+
201+
async fn delete_from(
202+
&self,
203+
state: &dyn Session,
204+
filters: Vec<Expr>,
205+
) -> DFResult<Arc<dyn ExecutionPlan>> {
206+
self.read_provider.delete_from(state, filters).await
207+
}
208+
209+
async fn update(
210+
&self,
211+
state: &dyn Session,
212+
assignments: Vec<(String, Expr)>,
213+
filters: Vec<Expr>,
214+
) -> DFResult<Arc<dyn ExecutionPlan>> {
215+
self.read_provider.update(state, assignments, filters).await
216+
}
217+
218+
async fn truncate(&self, state: &dyn Session) -> DFResult<Arc<dyn ExecutionPlan>> {
219+
self.read_provider.truncate(state).await
220+
}
199221
}
200222

201223
struct DuckDbFederatedDataSink {

crates/data_components/src/s3_single_file_cached.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ impl RefreshSkipTableProvider for S3SingleFileCached {
199199
}
200200
}
201201

202+
#[deny(clippy::missing_trait_methods)]
202203
#[async_trait]
203204
impl TableProvider for S3SingleFileCached {
204205
fn as_any(&self) -> &dyn Any {
@@ -258,6 +259,35 @@ impl TableProvider for S3SingleFileCached {
258259
// The metadata check happens during refresh, not during scan
259260
self.inner.scan(state, projection, filters, limit).await
260261
}
262+
263+
async fn scan_with_args<'a>(
264+
&self,
265+
state: &dyn Session,
266+
args: datafusion::catalog::ScanArgs<'a>,
267+
) -> DataFusionResult<datafusion::catalog::ScanResult> {
268+
self.inner.scan_with_args(state, args).await
269+
}
270+
271+
async fn delete_from(
272+
&self,
273+
state: &dyn Session,
274+
filters: Vec<Expr>,
275+
) -> DataFusionResult<Arc<dyn ExecutionPlan>> {
276+
self.inner.delete_from(state, filters).await
277+
}
278+
279+
async fn update(
280+
&self,
281+
state: &dyn Session,
282+
assignments: Vec<(String, Expr)>,
283+
filters: Vec<Expr>,
284+
) -> DataFusionResult<Arc<dyn ExecutionPlan>> {
285+
self.inner.update(state, assignments, filters).await
286+
}
287+
288+
async fn truncate(&self, state: &dyn Session) -> DataFusionResult<Arc<dyn ExecutionPlan>> {
289+
self.inner.truncate(state).await
290+
}
261291
}
262292

263293
#[cfg(test)]

crates/object_store_occ/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ description = "Type-safe object storage with optimistic concurrency control"
77

88
[dependencies]
99
async-trait.workspace = true
10+
bytes.workspace = true
1011
futures.workspace = true
1112
object_store.workspace = true
1213
parking_lot.workspace = true

crates/object_store_occ/src/local_conditional_put.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,11 @@ limitations under the License.
3434
use std::fmt::{self, Display, Formatter};
3535
use std::fs::{File, OpenOptions};
3636
use std::io;
37+
use std::ops::Range;
3738
use std::path::PathBuf;
3839

3940
use async_trait::async_trait;
41+
use bytes::Bytes;
4042
use futures::stream::BoxStream;
4143
use object_store::local::LocalFileSystem;
4244
use object_store::path::Path;
@@ -141,6 +143,7 @@ impl Display for LocalConditionalPut {
141143
}
142144
}
143145

146+
#[deny(clippy::missing_trait_methods)]
144147
#[async_trait]
145148
impl ObjectStore for LocalConditionalPut {
146149
async fn put_opts(
@@ -237,6 +240,53 @@ impl ObjectStore for LocalConditionalPut {
237240
async fn rename_if_not_exists(&self, from: &Path, to: &Path) -> Result<(), ObjectStoreError> {
238241
self.inner.rename_if_not_exists(from, to).await
239242
}
243+
244+
async fn put(
245+
&self,
246+
location: &Path,
247+
payload: PutPayload,
248+
) -> Result<PutResult, ObjectStoreError> {
249+
self.put_opts(location, payload, PutOptions::default())
250+
.await
251+
}
252+
253+
async fn put_multipart(
254+
&self,
255+
location: &Path,
256+
) -> Result<Box<dyn MultipartUpload>, ObjectStoreError> {
257+
self.inner.put_multipart(location).await
258+
}
259+
260+
async fn get(&self, location: &Path) -> Result<GetResult, ObjectStoreError> {
261+
self.inner.get(location).await
262+
}
263+
264+
async fn get_range(
265+
&self,
266+
location: &Path,
267+
range: Range<u64>,
268+
) -> Result<Bytes, ObjectStoreError> {
269+
self.inner.get_range(location, range).await
270+
}
271+
272+
async fn get_ranges(
273+
&self,
274+
location: &Path,
275+
ranges: &[Range<u64>],
276+
) -> Result<Vec<Bytes>, ObjectStoreError> {
277+
self.inner.get_ranges(location, ranges).await
278+
}
279+
280+
fn delete_stream<'a>(
281+
&'a self,
282+
locations: BoxStream<'a, Result<Path, ObjectStoreError>>,
283+
) -> BoxStream<'a, Result<Path, ObjectStoreError>> {
284+
self.inner.delete_stream(locations)
285+
}
286+
287+
async fn rename(&self, from: &Path, to: &Path) -> Result<(), ObjectStoreError> {
288+
self.inner.rename(from, to).await
289+
}
240290
}
241291

242292
#[cfg(test)]

crates/runtime-datafusion-index/src/provider.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use std::{any::Any, borrow::Cow, sync::Arc};
1919
use async_trait::async_trait;
2020
use datafusion::{
2121
arrow::datatypes::SchemaRef,
22-
catalog::{Session, TableProvider},
22+
catalog::{ScanArgs, ScanResult, Session, TableProvider},
2323
common::{Constraints, Statistics},
2424
datasource::TableType,
2525
error::Result as DataFusionResult,
@@ -95,6 +95,7 @@ impl IndexedTableProvider {
9595
}
9696
}
9797

98+
#[deny(clippy::missing_trait_methods)]
9899
#[async_trait]
99100
impl TableProvider for IndexedTableProvider {
100101
fn as_any(&self) -> &dyn Any {
@@ -175,4 +176,16 @@ impl TableProvider for IndexedTableProvider {
175176
) -> DataFusionResult<Arc<dyn ExecutionPlan>> {
176177
self.underlying.update(state, assignments, filters).await
177178
}
179+
180+
async fn scan_with_args<'a>(
181+
&self,
182+
state: &dyn Session,
183+
args: ScanArgs<'a>,
184+
) -> DataFusionResult<ScanResult> {
185+
self.underlying.scan_with_args(state, args).await
186+
}
187+
188+
async fn truncate(&self, state: &dyn Session) -> DataFusionResult<Arc<dyn ExecutionPlan>> {
189+
self.underlying.truncate(state).await
190+
}
178191
}

crates/runtime-object-store/src/registry/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,7 @@ impl SpiceObjectStoreRegistry {
708708
}
709709
}
710710

711+
#[deny(clippy::missing_trait_methods)]
711712
impl ObjectStoreRegistry for SpiceObjectStoreRegistry {
712713
fn register_store(
713714
&self,
@@ -724,6 +725,10 @@ impl ObjectStoreRegistry for SpiceObjectStoreRegistry {
724725
Ok(store)
725726
})
726727
}
728+
729+
fn deregister_store(&self, url: &Url) -> datafusion::error::Result<Arc<dyn ObjectStore>> {
730+
self.inner.deregister_store(url)
731+
}
727732
}
728733

729734
// This method uses unwrap_or_default, however it should never fail on the initialization. See

crates/runtime-table-partition/src/provider.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ impl PartitionTableProvider {
288288
}
289289
}
290290

291+
#[deny(clippy::missing_trait_methods)]
291292
#[async_trait]
292293
impl TableProvider for PartitionTableProvider {
293294
fn as_any(&self) -> &dyn Any {
@@ -468,6 +469,47 @@ impl TableProvider for PartitionTableProvider {
468469
Ok(plan)
469470
}
470471

472+
fn get_table_definition(&self) -> Option<&str> {
473+
None
474+
}
475+
476+
fn get_logical_plan(
477+
&self,
478+
) -> Option<std::borrow::Cow<'_, datafusion::logical_expr::LogicalPlan>> {
479+
None
480+
}
481+
482+
fn get_column_default(&self, _column: &str) -> Option<&Expr> {
483+
None
484+
}
485+
486+
async fn scan_with_args<'a>(
487+
&self,
488+
state: &dyn Session,
489+
args: datafusion::catalog::ScanArgs<'a>,
490+
) -> datafusion::error::Result<datafusion::catalog::ScanResult> {
491+
let filters = args.filters().unwrap_or(&[]);
492+
let projection = args.projection().map(<[usize]>::to_vec);
493+
let limit = args.limit();
494+
let plan = self
495+
.scan(state, projection.as_ref(), filters, limit)
496+
.await?;
497+
Ok(datafusion::catalog::ScanResult::new(plan))
498+
}
499+
500+
fn statistics(&self) -> Option<datafusion::common::Statistics> {
501+
None
502+
}
503+
504+
async fn truncate(
505+
&self,
506+
_state: &dyn Session,
507+
) -> datafusion::error::Result<Arc<dyn ExecutionPlan>> {
508+
Err(DataFusionError::NotImplemented(
509+
"PartitionTableProvider does not support truncate".to_string(),
510+
))
511+
}
512+
471513
async fn insert_into(
472514
&self,
473515
_state: &dyn Session,

0 commit comments

Comments
 (0)