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
2 changes: 1 addition & 1 deletion impl/parser.ml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ let read_edn input =
| _ -> false
in
let is_delimiter = function
| '[' | ']' | '(' | ')' | '{' | '}' | '"' | '\'' -> true
| '[' | ']' | '(' | ')' | '{' | '}' | '"' -> true
| c -> is_whitespace c
in
let rec skip index =
Expand Down
27 changes: 26 additions & 1 deletion impl/query_where.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1678,7 +1678,7 @@ end) = struct
| QValue (Keyword attr | String attr | Symbol attr) -> QAttr attr
| term -> term

let bound_relation_clause binding = function
let rec bound_relation_clause binding = function
| Pattern (e_term, a_term, v_term) ->
Pattern
( bound_pattern_term binding e_term
Expand Down Expand Up @@ -1723,6 +1723,31 @@ end) = struct
| ComparisonPredicate (predicate, left_term, right_term) ->
ComparisonPredicate
(predicate, bound_pattern_term binding left_term, bound_pattern_term binding right_term)
| ComparisonPredicateN (predicate, terms) ->
ComparisonPredicateN (predicate, List.map (bound_pattern_term binding) terms)
| EqualityPredicate (predicate, terms) ->
EqualityPredicate (predicate, List.map (bound_pattern_term binding) terms)
| ArithmeticValue (op, terms, output_var) ->
ArithmeticValue (op, List.map (bound_pattern_term binding) terms, output_var)
| NameValue (term, output_var) ->
NameValue (bound_pattern_term binding term, output_var)
| NamespaceValue (term, output_var) ->
NamespaceValue (bound_pattern_term binding term, output_var)
| KeywordFromName (term, output_var) ->
KeywordFromName (bound_pattern_term binding term, output_var)
| KeywordFromNamespaceName (namespace_term, name_term, output_var) ->
KeywordFromNamespaceName
(bound_pattern_term binding namespace_term, bound_pattern_term binding name_term, output_var)
| SourceClause (source_name, clause) ->
SourceClause (source_name, bound_relation_clause binding clause)
| Not clauses ->
Not (List.map (bound_relation_clause binding) clauses)
| SourceNot (source_name, clauses) ->
SourceNot (source_name, List.map (bound_relation_clause binding) clauses)
| NotJoin (vars, clauses) ->
NotJoin (vars, List.map (bound_relation_clause binding) clauses)
| SourceNotJoin (source_name, vars, clauses) ->
SourceNotJoin (source_name, vars, List.map (bound_relation_clause binding) clauses)
| clause -> clause

let relation_prefix_clause = function
Expand Down
64 changes: 43 additions & 21 deletions impl/transact.ml
Original file line number Diff line number Diff line change
Expand Up @@ -726,12 +726,39 @@ let apply_tx context tx_ops db =
if entity.db_id = None && has_only_forward_nested_attrs entity then
apply_nested_first_entity_map (datoms, max_eid, tempids, entity_tempids, tx_data) entity
else
let e, attrs, datoms, max_eid, tempids, tx_data =
(* Upsert probes resolve non-strictly against the pre-entity datoms:
unresolvable refs keep their raw form and simply never match. Strict
resolution happens per attr at add time, matching upstream's
sequential [:db/add] resolution order. *)
let probe_attrs =
let probe_attrs, _, _ =
List.fold_left
(fun (probe_attrs, max_eid, tempids) (attr, tx_value) ->
match
(try
Some
(resolve_tx_value_for_attr
context.resolve_context
db
attr
datoms
tx
max_eid
tempids
tx_value)
with Invalid_argument _ -> None)
with
| Some (tx_value, max_eid, tempids) ->
(attr, tx_value) :: probe_attrs, max_eid, tempids
| None -> (attr, tx_value) :: probe_attrs, max_eid, tempids)
([], max_eid, tempids)
entity.attrs
in
List.rev probe_attrs
in
let e, datoms, max_eid, tempids, tx_data =
match entity.db_id with
| Some (Temp_id tempid) ->
let probe_attrs, _, _ =
resolve_entity_attrs context.resolve_context db datoms tx max_eid tempids entity.attrs
in
(match context.entity_unique_identity db datoms probe_attrs with
| Some target_e ->
let datoms, tempids, tx_data =
Expand All @@ -741,37 +768,29 @@ let apply_tx context tx_ops db =
| Some _ -> datoms, tempids, tx_data
| None -> datoms, remember_tempid tempids tempid target_e, tx_data
in
let attrs, max_eid, tempids =
resolve_entity_attrs context.resolve_context db datoms tx max_eid tempids entity.attrs
in
target_e, attrs, datoms, context.resolve_context.max_eid_with_entity_id max_eid target_e, tempids, tx_data
target_e, datoms, context.resolve_context.max_eid_with_entity_id max_eid target_e, tempids, tx_data
| None ->
let e, max_eid, tempids =
resolve_entity_ref context.resolve_context db datoms tx max_eid tempids (Temp_id tempid)
in
let attrs, max_eid, tempids =
resolve_entity_attrs context.resolve_context db datoms tx max_eid tempids entity.attrs
in
e, attrs, datoms, max_eid, tempids, tx_data)
e, datoms, max_eid, tempids, tx_data)
| Some entity_ref ->
let e, max_eid, tempids = resolve_entity_ref context.resolve_context db datoms tx max_eid tempids entity_ref in
let attrs, max_eid, tempids = resolve_entity_attrs context.resolve_context db datoms tx max_eid tempids entity.attrs in
context.validate_explicit_upsert_target db datoms e attrs;
e, attrs, datoms, max_eid, tempids, tx_data
context.validate_explicit_upsert_target db datoms e probe_attrs;
e, datoms, max_eid, tempids, tx_data
| None ->
let e = context.resolve_context.allocate_entity_id max_eid in
let attrs, max_eid, tempids = resolve_entity_attrs context.resolve_context db datoms tx e tempids entity.attrs in
(match context.entity_unique_identity db datoms attrs with
| Some e -> e, attrs, datoms, context.resolve_context.max_eid_with_entity_id max_eid e, tempids, tx_data
| None -> e, attrs, datoms, max_eid, tempids, tx_data)
(match context.entity_unique_identity db datoms probe_attrs with
| Some e -> e, datoms, context.resolve_context.max_eid_with_entity_id max_eid e, tempids, tx_data
| None -> e, datoms, context.resolve_context.max_eid_with_entity_id max_eid e, tempids, tx_data)
in
let entity_tempids =
match entity.db_id with
| Some entity_ref -> mark_entity_tempid entity_tempids entity_ref
| None -> entity_tempids
in
let tuple_identity_lookup_writes =
attrs
probe_attrs
|> List.filter_map (function
| attr, One_value value when context.is_tuple_attr db attr && context.is_unique_identity db attr ->
(match context.resolve_context.entid datoms attr value with
Expand Down Expand Up @@ -851,6 +870,9 @@ let apply_tx context tx_ops db =
end
in
let apply_attr (datoms, max_eid, tempids, entity_tempids, tx_data, tuple_sources, direct_tuple_writes) (attr, tx_value) =
let tx_value, max_eid, tempids =
resolve_tx_value_for_attr context.resolve_context db attr datoms tx max_eid tempids tx_value
in
match tx_value with
| One_value (List values | Vector values) when attr_expands_collection context.resolve_context db attr ->
List.fold_left
Expand Down Expand Up @@ -878,7 +900,7 @@ let apply_tx context tx_ops db =
nested_entities
in
let datoms, max_eid, tempids, entity_tempids, tx_data, tuple_sources, direct_tuple_writes =
List.fold_left apply_attr (datoms, max_eid, tempids, entity_tempids, tx_data, [], []) attrs
List.fold_left apply_attr (datoms, max_eid, tempids, entity_tempids, tx_data, [], []) entity.attrs
in
let tuple_sources = List.sort_uniq compare tuple_sources in
let datoms, tx_data =
Expand Down
5 changes: 5 additions & 0 deletions test/dune
Original file line number Diff line number Diff line change
Expand Up @@ -244,3 +244,8 @@
%{dep:cross_runtime_parity_test.sh}
%{dep:cross_runtime_ocaml.exe}
%{dep:../script/cross_runtime_upstream.js})))

(test
(name test_query_engine_fixes)
(modules test_query_engine_fixes)
(libraries datascript-ocaml-native))
Loading
Loading