Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
11 changes: 10 additions & 1 deletion query-compiler/query-compiler/src/binding.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use std::borrow::Cow;

use query_core::NodeRef;
use query_structure::{ScalarField, SelectedField};
use query_structure::{RelationField, ScalarField, SelectedField};

const JOIN_PARENT: &str = "@parent";
const DEFAULTS: &str = "@defaults";
const GENERATED: &str = "@generated";
const SELECTOR: &str = "@selector";
const NESTED: &str = "@nested";

const FIELD_SEPARATOR: &str = "$";

Expand Down Expand Up @@ -37,3 +38,11 @@ pub fn generated(row_idx: usize, field_name: &str) -> Cow<'static, str> {
pub fn selector(field: &SelectedField) -> Cow<'static, str> {
format!("{SELECTOR}{FIELD_SEPARATOR}{}", field.prisma_name()).into()
}

pub fn nested_relation_field(field: &RelationField) -> Cow<'static, str> {
nested_relation_field_by_name(field.name())
}

pub fn nested_relation_field_by_name(field_name: &str) -> Cow<'static, str> {
format!("{NESTED}{FIELD_SEPARATOR}{}", field_name).into()
}
111 changes: 77 additions & 34 deletions query-compiler/query-compiler/src/data_mapper.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use crate::result_node::{ObjectKind, ResultNode, ResultNodeBuilder};
use crate::{
binding,
result_node::{ResultNode, ResultNodeBuilder},
};
use indexmap::IndexSet;
use itertools::Itertools;
use query_core::{
CreateManyRecordsFields, DeleteRecordFields, Node, Query, QueryGraph, ReadQuery, UpdateManyRecordsFields,
UpdateRecord, WriteQuery, schema::constants::aggregations,
};
use query_structure::{AggregationSelection, FieldSelection, SelectedField};
use std::collections::HashMap;
use std::{borrow::Cow, collections::HashMap};

pub fn map_result_structure(graph: &QueryGraph, builder: &mut ResultNodeBuilder) -> Option<ResultNode> {
graph
Expand Down Expand Up @@ -34,44 +37,57 @@ pub fn map_result_structure(graph: &QueryGraph, builder: &mut ResultNodeBuilder)

fn map_query(query: &Query, builder: &mut ResultNodeBuilder) -> Option<ResultNode> {
match query {
Query::Read(read_query) => map_read_query(read_query, builder),
Query::Read(read_query) => map_read_query(read_query, builder, None),
Query::Write(write_query) => map_write_query(write_query, builder),
}
}

fn map_read_query(query: &ReadQuery, builder: &mut ResultNodeBuilder) -> Option<ResultNode> {
fn map_read_query(
query: &ReadQuery,
builder: &mut ResultNodeBuilder,
object_name: Option<Cow<'static, str>>,
) -> Option<ResultNode> {
match query {
ReadQuery::RecordQuery(q) => get_result_node(
&q.selected_fields,
&q.selection_order,
&q.nested,
q.relation_load_strategy.is_join(),
builder,
object_name,
),
ReadQuery::ManyRecordsQuery(q) => get_result_node(
&q.selected_fields,
&q.selection_order,
&q.nested,
q.relation_load_strategy.is_join(),
builder,
object_name,
),
ReadQuery::RelatedRecordsQuery(q) => get_result_node(
&q.selected_fields,
&q.selection_order,
&q.nested,
false,
builder,
object_name,
),
ReadQuery::RelatedRecordsQuery(q) => {
get_result_node(&q.selected_fields, &q.selection_order, &q.nested, false, builder)
}
ReadQuery::AggregateRecordsQuery(q) => {
get_result_node_for_aggregation(&q.selectors, &q.selection_order, builder)
get_result_node_for_aggregation(&q.selectors, &q.selection_order, builder, object_name)
}
}
}

fn map_write_query(query: &WriteQuery, builder: &mut ResultNodeBuilder) -> Option<ResultNode> {
match query {
WriteQuery::CreateRecord(q) => get_result_node(&q.selected_fields, &q.selection_order, &[], false, builder),
WriteQuery::CreateRecord(q) => {
get_result_node(&q.selected_fields, &q.selection_order, &[], false, builder, None)
}
WriteQuery::CreateManyRecords(q) => get_result_node_for_create_many(q.selected_fields.as_ref(), builder),
WriteQuery::UpdateRecord(u) => {
match u {
UpdateRecord::WithSelection(w) => {
get_result_node(&w.selected_fields, &w.selection_order, &[], false, builder)
get_result_node(&w.selected_fields, &w.selection_order, &[], false, builder, None)
}
UpdateRecord::WithoutSelection(_) => None, // No result data
}
Expand All @@ -83,7 +99,7 @@ fn map_write_query(query: &WriteQuery, builder: &mut ResultNodeBuilder) -> Optio
WriteQuery::DisconnectRecords(_) => None, // No result data
WriteQuery::ExecuteRaw(_) => None, // No data mapping
WriteQuery::QueryRaw(_) => None, // No data mapping
WriteQuery::Upsert(q) => get_result_node(&q.selected_fields, &q.selection_order, &[], false, builder),
WriteQuery::Upsert(q) => get_result_node(&q.selected_fields, &q.selection_order, &[], false, builder, None),
}
}

Expand All @@ -94,6 +110,7 @@ fn get_result_node(
// relationJoins queries use prisma names rather than db names
uses_relation_joins: bool,
builder: &mut ResultNodeBuilder,
original_name: Option<Cow<'static, str>>,
) -> Option<ResultNode> {
let field_map = field_selection
.selections()
Expand All @@ -107,24 +124,38 @@ fn get_result_node(
.map(|q| (q.get_alias_or_name(), q))
.collect::<HashMap<_, _>>();

let mut node = ResultNodeBuilder::new_object();
let mut node = ResultNodeBuilder::new_object(original_name);

for prisma_name in selection_order {
match field_map.get(prisma_name.as_str()) {
Some(sf @ SelectedField::Scalar(f)) => {
let name = if uses_relation_joins {
sf.prisma_name().into_owned()
sf.prisma_name()
} else {
sf.db_name().into_owned()
sf.db_name()
};
node.add_field(prisma_name, builder.new_value(name, f.type_info()));
node.add_field(
prisma_name.to_owned(),
builder.new_value(name.into_owned(), f.type_info()),
);
}
Some(SelectedField::Composite(_)) => todo!("MongoDB specific"),
Some(SelectedField::Relation(f)) => {
let nested_selection = FieldSelection::new(f.selections.to_vec());
let nested_node =
get_result_node(&nested_selection, &f.result_fields, &[], uses_relation_joins, builder);
let nested_node = get_result_node(
&nested_selection,
&f.result_fields,
&[],
uses_relation_joins,
builder,
Some(if uses_relation_joins {
f.field.name().to_owned().into()
} else {
binding::nested_relation_field(&f.field)
}),
);
if let Some(nested_node) = nested_node {
node.add_field(f.field.name(), nested_node);
node.add_field(f.field.name().to_owned(), nested_node);
}
}
Some(SelectedField::Virtual(f)) => {
Expand All @@ -140,22 +171,23 @@ fn get_result_node(
vs.db_alias()
};

node.entry_or_insert(
group_name,
if uses_relation_joins {
ObjectKind::Nested
} else {
ObjectKind::Flattened
},
)
.add_field(field_name, builder.new_value(db_name, vs.r#type().into()));
node.entry_or_insert(group_name, uses_relation_joins.then_some(group_name))
.add_field(field_name.to_owned(), builder.new_value(db_name, vs.r#type().into()));
}
}
None => {
if let Some(q) = nested_map.get(prisma_name.as_str()) {
let nested_node = map_read_query(q, builder);
let nested_node = map_read_query(
q,
builder,
Some(if uses_relation_joins {
prisma_name.to_owned().into()
} else {
binding::nested_relation_field_by_name(prisma_name)
}),
);
if let Some(nested_node) = nested_node {
node.add_field(q.get_alias_or_name(), nested_node);
node.add_field(q.get_alias_or_name().to_owned(), nested_node);
}
}
}
Expand All @@ -169,6 +201,7 @@ fn get_result_node_for_aggregation(
selectors: &[AggregationSelection],
selection_order: &[(String, Option<Vec<String>>)],
builder: &mut ResultNodeBuilder,
object_name: Option<Cow<'static, str>>,
) -> Option<ResultNode> {
let mut ordered_set = IndexSet::new();

Expand All @@ -182,7 +215,7 @@ fn get_result_node_for_aggregation(
}
}

let mut node = ResultNodeBuilder::new_object();
let mut node = ResultNodeBuilder::new_object(object_name);

for (underscore_name, name, db_name, typ) in selectors
.iter()
Expand All @@ -199,11 +232,12 @@ fn get_result_node_for_aggregation(
})
.sorted_by_key(|(underscore_name, name, _, _)| ordered_set.get_index_of(&(*underscore_name, *name)))
{
let value = builder.new_value(db_name.into(), typ.into());
let value = builder.new_value(db_name.to_owned(), typ.into());
if let Some(undescore_name) = underscore_name {
node.entry_or_insert_nested(undescore_name).add_field(name, value);
node.entry_or_insert_nested(undescore_name)
.add_field(name.to_owned(), value);
} else {
node.add_field(name, value);
node.add_field(name.to_owned(), value);
}
}

Expand Down Expand Up @@ -231,14 +265,22 @@ fn get_result_node_for_create_many(
&selected_fields?.nested,
false,
builder,
None,
)
}

fn get_result_node_for_delete(
selected_fields: Option<&DeleteRecordFields>,
builder: &mut ResultNodeBuilder,
) -> Option<ResultNode> {
get_result_node(&selected_fields?.fields, &selected_fields?.order, &[], false, builder)
get_result_node(
&selected_fields?.fields,
&selected_fields?.order,
&[],
false,
builder,
None,
)
}

fn get_result_node_for_update_many(
Expand All @@ -251,5 +293,6 @@ fn get_result_node_for_update_many(
&selected_fields?.nested,
false,
builder,
None,
)
}
11 changes: 9 additions & 2 deletions query-compiler/query-compiler/src/expression/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,15 @@ where
ResultNode::AffectedRows => self.keyword("affectedRows"),
ResultNode::Object(object) => self.object(object.fields().iter().map(|(name, field)| {
let mut key = self.field_name(name);
if object.is_flattened() {
key = key.append(self.space().append(self.keyword("(flattened)")));
if let ResultNode::Object(nested_object) = field {
let source = match nested_object.serialized_name() {
Some(original_key) => self
.keyword("from")
.append(self.space())
.append(self.field_name(original_key)),
None => self.keyword("inlined"),
};
key = key.append(self.space().append(source.parens()))
}
(key, self.data_map_node(field))
})),
Expand Down
Loading
Loading