Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
perf(query-compiler): skip nested-only update nodes
Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
  • Loading branch information
tensordreams committed Jun 24, 2026
commit 23d89d56c15d5aa10a1d99e165f86483578ff9ff
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use super::*;
use crate::inputs::{UpdateManyRecordsSelectorsInput, UpdateRecordSelectorsInput};
use crate::inputs::{ReturnInput, UpdateManyRecordsSelectorsInput, UpdateRecordSelectorsInput};
use crate::query_graph_builder::write::write_args_parser::WriteArgsParser;
use crate::query_graph_builder::write::update::UpdateManyRecordNodeOptionals;
use crate::{DataExpectation, RowSink};
use crate::{
ParsedInputValue,
query_graph::{NodeRef, QueryGraph, QueryGraphDependency},
query_graph::{Flow, NodeRef, QueryGraph, QueryGraphDependency},
};
use query_structure::{Filter, Model, RelationFieldRef};
use schema::constants::args;
Expand Down Expand Up @@ -89,8 +90,37 @@ pub fn nested_update(
let find_child_records_node =
utils::insert_find_children_by_parent_node(graph, parent, parent_relation_field, filter.clone())?;

let update_node = update::update_record_node(graph, query_schema, filter, child_model.clone(), data_map, None)?;
let child_model_identifier = parent_relation_field.related_model().shard_aware_primary_identifier();
let update_args = WriteArgsParser::from(child_model, data_map)?;

if update_args.args.is_empty() && !update_args.nested.is_empty() {
let return_node = graph.create_node(Flow::Return(Vec::new()));

graph.create_edge(
&find_child_records_node,
&return_node,
QueryGraphDependency::ProjectedDataDependency(
child_model_identifier,
RowSink::All(&ReturnInput),
Some(DataExpectation::non_empty_rows(
MissingRelatedRecord::builder()
.model(child_model)
.relation(&parent_relation_field.relation())
.operation(DataOperation::NestedUpdate)
.build(),
)),
),
)?;

for (relation_field, data_map) in update_args.nested {
connect_nested_query(graph, query_schema, return_node, relation_field, data_map)?;
}

continue;
}

let update_node =
update::update_record_node_from_args(graph, query_schema, filter, child_model.clone(), update_args, None)?;

graph.create_edge(
&find_child_records_node,
Expand Down
15 changes: 15 additions & 0 deletions query-compiler/core/src/query_graph_builder/write/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,21 @@ where
T: Clone + Into<Filter>,
{
let update_args = WriteArgsParser::from(&model, data_map)?;

update_record_node_from_args(graph, query_schema, filter, model, update_args, field)
}

pub(crate) fn update_record_node_from_args<T>(
graph: &mut QueryGraph,
query_schema: &QuerySchema,
filter: T,
model: Model,
update_args: WriteArgsParser<'_>,
field: Option<&ParsedField<'_>>,
) -> QueryGraphBuilderResult<NodeRef>
where
T: Clone + Into<Filter>,
{
let mut args = update_args.args;

args.update_datetimes(&model);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,10 @@ transaction
WHERE (1=1 AND "public"."User"."id" IN [$1,*])
OFFSET $2»
params [var(0$userId as Int), const(BigInt(0))])
in let 1 = unique (validate (get 1)
in let 1 = validate (get 1)
[ rowCountNeq 0
] orRaise "MISSING_RELATED_RECORD");
1$id = mapField id (get 1)
in let 2 = unique (query «SELECT "public"."User"."id" FROM
"public"."User" WHERE (1=1 AND
"public"."User"."id" IN [$1,*]) LIMIT $2
OFFSET $3»
params [var(1$id as Int), const(BigInt(1)),
const(BigInt(0))])
] orRaise "MISSING_RELATED_RECORD"
in let 2 = get 1
in let 2$id = mapField id (get 2)
in let 3 = unique (query «SELECT
"public"."NotificationSettings"."userId"
Expand Down