Skip to content

Commit

Permalink
Fixed
Browse files Browse the repository at this point in the history
- inmemory distinct will actually be used
Added
- capability for distinct inmem when orderby
  • Loading branch information
Druue committed Nov 29, 2023
1 parent 40a9917 commit 611cc4e
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ mod distinct {
}

#[connector_test]
async fn with_skip(runner: Runner) -> TestResult<()> {
async fn with_skip_basic(runner: Runner) -> TestResult<()> {
test_user(&runner, r#"{ id: 1, first_name: "Joe", last_name: "Doe", email: "1" }"#).await?;
test_user(
&runner,
Expand All @@ -104,7 +104,7 @@ mod distinct {
),
// r#"{"data":{"findManyUser":[{"id":2,"first_name":"Hans","last_name":"Wurst"}]}}"#
// ! SELECT DISTINCT ON expressions must match initial ORDER BY expressions
@r###""###
@r###"{"data":{"findManyUser":[{"id":2,"first_name":"Hans","last_name":"Wurst"},{"id":3,"first_name":"Joe","last_name":"Doe"}]}}"###
);

Ok(())
Expand Down Expand Up @@ -158,14 +158,14 @@ mod distinct {
),
// r#"{"data":{"findManyUser":[{"id":3,"first_name":"Joe","last_name":"Doe"},{"id":2,"first_name":"Hans","last_name":"Wurst"}]}}"#
// ! SELECT DISTINCT ON expressions must match initial ORDER BY expressions
@r###""###
@r###"{"data":{"findManyUser":[{"id":3,"first_name":"Joe","last_name":"Doe"},{"id":2,"first_name":"Hans","last_name":"Wurst"}]}}"###
);

Ok(())
}

/// Mut return only distinct records for top record, and only for those the distinct relation records.
// #[connector_test]
#[connector_test]
async fn nested_distinct(runner: Runner) -> TestResult<()> {
nested_dataset(&runner).await?;

Expand All @@ -187,7 +187,7 @@ mod distinct {
),
// {"data":{"findManyUser":[{"id":1,"posts":[{"title":"3"},{"title":"1"},{"title":"2"}]},{"id":3,"posts":[]},{"id":4,"posts":[{"title":"1"}]},{"id":5,"posts":[{"title":"2"},{"title":"3"}]}]}}
// ! SELECT DISTINCT ON expressions must match initial ORDER BY expressions
@r###""###
@r###"{"data":{"findManyUser":[{"id":1,"posts":[{"title":"3"},{"title":"1"},{"title":"2"}]},{"id":4,"posts":[{"title":"1"}]},{"id":3,"posts":[]},{"id":5,"posts":[{"title":"2"},{"title":"3"}]}]}}"###
);

Ok(())
Expand Down Expand Up @@ -218,7 +218,7 @@ mod distinct {
),
// {"data":{"findManyUser":[{"id":5,"posts":[{"title":"2"},{"title":"3"}]},{"id":4,"posts":[{"title":"1"}]},{"id":3,"posts":[]},{"id":2,"posts":[{"title":"2"},{"title":"1"}]}]}}
// ! SELECT DISTINCT ON expressions must match initial ORDER BY expressions
@r###""###
@r###"{"data":{"findManyUser":[{"id":5,"posts":[{"title":"2"},{"title":"3"}]},{"id":4,"posts":[{"title":"1"}]},{"id":3,"posts":[]},{"id":2,"posts":[{"title":"2"},{"title":"1"}]}]}}"###
);

Ok(())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,8 @@ impl InMemoryRecordProcessorBuilder {
self
}

pub fn distinct(mut self, distinct: FieldSelection) -> Self {
self.args.distinct = Some(distinct);
pub fn distinct(mut self, distinct: Option<FieldSelection>) -> Self {
self.args.distinct = distinct.clone();
self
}

Expand Down
39 changes: 18 additions & 21 deletions query-engine/core/src/interpreter/query_interpreters/nested_read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,16 @@ pub(crate) async fn m2m(
query.args.ignore_take,
);

let processor = match query.args.distinct {
Some(ref fs) => {
if query.args.requires_inmemory_distinct() {
inm_builder.distinct(fs.clone())
} else {
inm_builder
}
}
None => inm_builder,
}
.build();
let inm_builder = if query.args.requires_inmemory_distinct() {
let inm_builder = inm_builder.distinct(query.args.distinct.clone());
query.args.distinct = None;

inm_builder
} else {
inm_builder
};

let processor = inm_builder.build();

let parent_field = &query.parent_field;
let child_link_id = parent_field.related_field().linking_fields();
Expand Down Expand Up @@ -153,7 +152,7 @@ pub async fn one2m(
parent_field: &RelationFieldRef,
parent_selections: Option<Vec<SelectionResult>>,
parent_result: Option<&ManyRecords>,
query_args: QueryArguments,
mut query_args: QueryArguments,
selected_fields: &FieldSelection,
aggr_selections: Vec<RelAggregationSelection>,
trace_id: Option<String>,
Expand Down Expand Up @@ -220,15 +219,13 @@ pub async fn one2m(
query_args.ignore_take,
);

let inm_builder = match query_args.distinct {
Some(ref fs) => {
if req_inmem_distinct {
inm_builder.distinct(fs.clone())
} else {
inm_builder
}
}
None => inm_builder,
let inm_builder = if req_inmem_distinct {
let inm_builder = inm_builder.distinct(query_args.distinct);
query_args.distinct = None;

inm_builder
} else {
inm_builder
};

Some(inm_builder.build())
Expand Down
20 changes: 10 additions & 10 deletions query-engine/core/src/interpreter/query_interpreters/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ fn read_one(
/// -> Unstable cursors can't reliably be fetched by the underlying datasource, so we need to process part of it in-memory.
fn read_many(
tx: &mut dyn ConnectionLike,
query: ManyRecordsQuery,
mut query: ManyRecordsQuery,
trace_id: Option<String>,
) -> BoxFuture<'_, InterpretationResult<QueryResult>> {
let req_inmem_distinct = query.args.requires_inmemory_distinct();
Expand All @@ -98,15 +98,15 @@ fn read_many(
query.args.ignore_take,
);

let inm_builder = match query.args.distinct {
Some(ref fs) => {
if req_inmem_distinct {
inm_builder.distinct(fs.clone())
} else {
inm_builder
}
}
None => inm_builder,
dbg!(req_inmem_distinct);
let inm_builder = if req_inmem_distinct {
let inm_builder = inm_builder.distinct(query.args.distinct);
query.args.distinct = None;
dbg!(&query.args.distinct);

inm_builder
} else {
inm_builder
};

Some(inm_builder.build())
Expand Down
24 changes: 17 additions & 7 deletions query-engine/query-structure/src/query_arguments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,27 @@ impl QueryArguments {
/// retrieved by the connector or if it requires the query engine to fetch a raw set
/// of records and perform certain operations itself, in-memory.
pub fn requires_inmemory_processing(&self) -> bool {
self.contains_unstable_cursor() || self.contains_null_cursor()
self.contains_unstable_cursor() || self.contains_null_cursor() || self.requires_inmemory_distinct()
}

pub fn requires_inmemory_distinct(&self) -> bool {
self.has_distinct() && (!self.has_distinct_capability() || self.has_orderby())
}

fn has_distinct_capability(&self) -> bool {
self.model()
.dm
.schema
.connector
.has_capability(ConnectorCapability::Distinct)
}

fn has_distinct(&self) -> bool {
self.distinct.is_some()
&& !self
.model()
.dm
.schema
.connector
.has_capability(ConnectorCapability::Distinct)
}

fn has_orderby(&self) -> bool {
!self.order_by.is_empty()
}

/// An unstable cursor is a cursor that is used in conjunction with an unstable (non-unique) combination of orderBys.
Expand Down

0 comments on commit 611cc4e

Please sign in to comment.