Skip to main content

ReadBatch

Struct ReadBatch 

Source
pub struct ReadBatch { /* private fields */ }
Expand description

A batch of read-only queries for sequential execution in one transaction

This allows multiple related read queries to be executed atomically, with results stored in named variables that can be referenced by subsequent queries and returned as a structured result.

Important: ReadBatch only accepts read-only traversals (no mutations). Attempting to add a traversal containing mutation steps will fail at compile time.

Implementations§

Source§

impl ReadBatch

Source

pub fn var_as<S: TraversalState>( self, name: &str, traversal: Traversal<S, ReadOnly>, ) -> Self

Add a read-only query that stores result in a named variable

The traversal is executed and its result is stored in a variable that can be referenced by subsequent queries using NodeRef::var().

Note: Only accepts read-only traversals. Mutation traversals will fail at compile time.

Examples found in repository?
examples/generate_parity_fixtures.rs (line 258)
159fn runtime_fixtures() -> Vec<Fixture> {
160    vec![
161        runtime(
162            "001-write-seed-core",
163            write_request(
164                write_batch()
165                    .var_as(
166                        "alice",
167                        g().add_n(
168                            "ParityUser",
169                            user_props(
170                                "user-alice",
171                                "Alice",
172                                31,
173                                90.5,
174                                "active",
175                                "London",
176                                "Alice writes graph database tests",
177                                vec![1.0, 0.0, 0.0],
178                            ),
179                        ),
180                    )
181                    .var_as(
182                        "bob",
183                        g().add_n(
184                            "ParityUser",
185                            user_props(
186                                "user-bob",
187                                "Bob",
188                                27,
189                                72.25,
190                                "active",
191                                "Paris",
192                                "Bob likes traversal testing",
193                                vec![0.9, 0.1, 0.0],
194                            ),
195                        ),
196                    )
197                    .var_as(
198                        "carol",
199                        g().add_n(
200                            "ParityUser",
201                            user_props(
202                                "user-carol",
203                                "Carol",
204                                42,
205                                64.0,
206                                "inactive",
207                                "Berlin",
208                                "Carol archives old records",
209                                vec![0.0, 1.0, 0.0],
210                            ),
211                        ),
212                    )
213                    .var_as(
214                        "alice_follows_bob",
215                        g().n(NodeRef::var("alice")).add_e(
216                            "FOLLOWS",
217                            NodeRef::var("bob"),
218                            vec![
219                                ("weight", PropertyInput::from(1.0f64)),
220                                ("since", PropertyInput::from("2024-01-01")),
221                                ("note", PropertyInput::from("Alice follows Bob")),
222                                (
223                                    "embedding",
224                                    PropertyInput::from(PropertyValue::from(vec![1.0f32, 0.0])),
225                                ),
226                            ],
227                        ),
228                    )
229                    .var_as(
230                        "bob_follows_carol",
231                        g().n(NodeRef::var("bob")).add_e(
232                            "FOLLOWS",
233                            NodeRef::var("carol"),
234                            vec![
235                                ("weight", PropertyInput::from(0.5f64)),
236                                ("since", PropertyInput::from("2024-02-01")),
237                                ("note", PropertyInput::from("Bob follows Carol")),
238                                (
239                                    "embedding",
240                                    PropertyInput::from(PropertyValue::from(vec![0.0f32, 1.0])),
241                                ),
242                            ],
243                        ),
244                    )
245                    .returning([
246                        "alice",
247                        "bob",
248                        "carol",
249                        "alice_follows_bob",
250                        "bob_follows_carol",
251                    ]),
252            ),
253        ),
254        runtime(
255            "002-read-count-all-users",
256            read_request(
257                read_batch()
258                    .var_as("user_count", g().n_with_label("ParityUser").count())
259                    .returning(["user_count"]),
260            ),
261        ),
262        runtime(
263            "003-read-source-predicate-and-count",
264            read_request(
265                read_batch()
266                    .var_as(
267                        "active_adults",
268                        g().n_with_label_where(
269                            "ParityUser",
270                            SourcePredicate::and(vec![
271                                SourcePredicate::eq("status", "active"),
272                                SourcePredicate::gte("age", 30i64),
273                            ]),
274                        )
275                        .count(),
276                    )
277                    .returning(["active_adults"]),
278            ),
279        ),
280        runtime(
281            "004-read-value-map-projection",
282            read_request(
283                read_batch()
284                    .var_as(
285                        "alice",
286                        g().n_with_label("ParityUser")
287                            .where_(Predicate::eq("externalId", "user-alice"))
288                            .project(vec![
289                                Projection::property("externalId", "id"),
290                                Projection::property("name", "name"),
291                                Projection::expr(
292                                    "score_plus_one",
293                                    Expr::prop("score").add(Expr::val(1.0f64)),
294                                ),
295                                Projection::expr(
296                                    "status_label",
297                                    Expr::case(
298                                        vec![(
299                                            Predicate::eq("status", "active"),
300                                            Expr::val("enabled"),
301                                        )],
302                                        Some(Expr::val("disabled")),
303                                    ),
304                                ),
305                            ]),
306                    )
307                    .returning(["alice"]),
308            ),
309        ),
310        runtime(
311            "005-read-order-range-values",
312            read_request(
313                read_batch()
314                    .var_as(
315                        "ordered",
316                        g().n_with_label("ParityUser")
317                            .order_by_multiple(vec![("status", Order::Asc), ("age", Order::Desc)])
318                            .range(0usize, 2usize)
319                            .value_map(Some(vec!["externalId", "age", "status"])),
320                    )
321                    .returning(["ordered"]),
322            ),
323        ),
324        runtime(
325            "006-read-edge-count",
326            read_request(
327                read_batch()
328                    .var_as(
329                        "edge_count",
330                        g().n_with_label("ParityUser")
331                            .where_(Predicate::eq("externalId", "user-alice"))
332                            .out_e(Some("FOLLOWS"))
333                            .count(),
334                    )
335                    .returning(["edge_count"]),
336            ),
337        ),
338        runtime(
339            "007-read-edge-properties",
340            read_request(
341                read_batch()
342                    .var_as(
343                        "edges",
344                        g().e_with_label("FOLLOWS")
345                            .edge_has("weight", PropertyInput::from(1.0f64))
346                            .edge_properties(),
347                    )
348                    .returning(["edges"]),
349            ),
350        ),
351        runtime(
352            "008-read-edge-endpoints",
353            read_request(
354                read_batch()
355                    .var_as(
356                        "from_nodes",
357                        g().e_with_label("FOLLOWS")
358                            .edge_has_label("FOLLOWS")
359                            .in_n()
360                            .value_map(Some(vec!["externalId", "name"])),
361                    )
362                    .var_as(
363                        "to_nodes",
364                        g().e_with_label("FOLLOWS")
365                            .out_n()
366                            .value_map(Some(vec!["externalId", "name"])),
367                    )
368                    .returning(["from_nodes", "to_nodes"]),
369            ),
370        ),
371        runtime(
372            "009-read-conditional-var-not-empty",
373            read_request(
374                read_batch()
375                    .var_as(
376                        "alice",
377                        g().n_with_label("ParityUser")
378                            .where_(Predicate::eq("externalId", "user-alice")),
379                    )
380                    .var_as_if(
381                        "friends",
382                        BatchCondition::VarNotEmpty("alice".to_string()),
383                        g().n(NodeRef::var("alice"))
384                            .out(Some("FOLLOWS"))
385                            .value_map(Some(vec!["externalId", "name"])),
386                    )
387                    .returning(["alice", "friends"]),
388            ),
389        ),
390        runtime(
391            "010-read-conditional-var-empty",
392            read_request(
393                read_batch()
394                    .var_as(
395                        "missing",
396                        g().n_with_label("ParityUser")
397                            .where_(Predicate::eq("externalId", "missing-user")),
398                    )
399                    .var_as_if(
400                        "fallback",
401                        BatchCondition::VarEmpty("missing".to_string()),
402                        g().n_with_label("ParityUser")
403                            .limit(1usize)
404                            .value_map(Some(vec!["externalId"])),
405                    )
406                    .returning(["missing", "fallback"]),
407            ),
408        ),
409        runtime(
410            "011-read-conditional-var-min-size-prev",
411            read_request(
412                read_batch()
413                    .var_as("users", g().n_with_label("ParityUser").limit(3usize))
414                    .var_as_if(
415                        "min_two",
416                        BatchCondition::VarMinSize("users".to_string(), 2),
417                        g().n(NodeRef::var("users")).count(),
418                    )
419                    .var_as_if(
420                        "prev_ok",
421                        BatchCondition::PrevNotEmpty,
422                        g().n(NodeRef::var("users")).exists(),
423                    )
424                    .returning(["min_two", "prev_ok"]),
425            ),
426        ),
427        runtime(
428            "012-read-foreach-param",
429            with_params(
430                read_request(
431                    read_batch()
432                        .for_each_param(
433                            "lookups",
434                            read_batch().var_as(
435                                "matched",
436                                g().n_with_label("ParityUser")
437                                    .where_(Predicate::eq_param("externalId", "externalId"))
438                                    .value_map(Some(vec!["externalId", "name"])),
439                            ),
440                        )
441                        .returning(["matched"]),
442                ),
443                vec![(
444                    "lookups",
445                    array(vec![
446                        object(vec![("externalId", string("user-alice"))]),
447                        object(vec![("externalId", string("user-carol"))]),
448                    ]),
449                )],
450                vec![(
451                    "lookups",
452                    QueryParamType::Array(Box::new(QueryParamType::Object)),
453                )],
454            ),
455        ),
456        runtime(
457            "013-write-foreach-param-create",
458            with_params(
459                write_request(
460                    write_batch()
461                        .for_each_param(
462                            "rows",
463                            write_batch().var_as(
464                                "created",
465                                g().add_n(
466                                    "ParityEvent",
467                                    vec![
468                                        ("eventId", PropertyInput::param("eventId")),
469                                        ("kind", PropertyInput::param("kind")),
470                                        ("score", PropertyInput::param("score")),
471                                    ],
472                                ),
473                            ),
474                        )
475                        .returning(["created"]),
476                ),
477                vec![(
478                    "rows",
479                    array(vec![
480                        object(vec![
481                            ("eventId", string("event-1")),
482                            ("kind", string("click")),
483                            ("score", i64_value(10)),
484                        ]),
485                        object(vec![
486                            ("eventId", string("event-2")),
487                            ("kind", string("view")),
488                            ("score", i64_value(5)),
489                        ]),
490                    ]),
491                )],
492                vec![(
493                    "rows",
494                    QueryParamType::Array(Box::new(QueryParamType::Object)),
495                )],
496            ),
497        ),
498        runtime(
499            "014-read-after-foreach-param",
500            read_request(
501                read_batch()
502                    .var_as("event_count", g().n_with_label("ParityEvent").count())
503                    .returning(["event_count"]),
504            ),
505        ),
506        runtime(
507            "015-write-set-remove-properties",
508            write_request(
509                write_batch()
510                    .var_as(
511                        "updated",
512                        g().n_with_label("ParityUser")
513                            .where_(Predicate::eq("externalId", "user-bob"))
514                            .set_property("status", PropertyInput::from("inactive"))
515                            .set_property(
516                                "updatedAt",
517                                PropertyInput::from(DateTime::from_millis(1_777_000_000_000)),
518                            )
519                            .remove_property("city")
520                            .count(),
521                    )
522                    .returning(["updated"]),
523            ),
524        ),
525        runtime(
526            "016-read-updated-properties",
527            read_request(
528                read_batch()
529                    .var_as(
530                        "bob",
531                        g().n_with_label("ParityUser")
532                            .where_(Predicate::eq("externalId", "user-bob"))
533                            .value_map(Some(vec!["externalId", "status", "updatedAt", "city"])),
534                    )
535                    .returning(["bob"]),
536            ),
537        ),
538        runtime(
539            "017-read-repeat-union",
540            read_request(
541                read_batch()
542                    .var_as(
543                        "walked",
544                        g().n_with_label("ParityUser")
545                            .where_(Predicate::eq("externalId", "user-alice"))
546                            .repeat(
547                                RepeatConfig::new(sub().out(Some("FOLLOWS")))
548                                    .times(2)
549                                    .emit_all()
550                                    .max_depth(4),
551                            )
552                            .union(vec![sub().out(Some("FOLLOWS")), sub().in_(Some("FOLLOWS"))])
553                            .dedup()
554                            .value_map(Some(vec!["externalId", "name"])),
555                    )
556                    .returning(["walked"]),
557            ),
558        ),
559        runtime(
560            "018-read-choose-coalesce-optional",
561            read_request(
562                read_batch()
563                    .var_as(
564                        "branched",
565                        g().n_with_label("ParityUser")
566                            .where_(Predicate::eq("externalId", "user-alice"))
567                            .choose(
568                                Predicate::eq("status", "active"),
569                                sub().out(Some("FOLLOWS")),
570                                Some(sub().in_(Some("FOLLOWS"))),
571                            )
572                            .coalesce(vec![sub().out(Some("FOLLOWS")), sub().in_(Some("FOLLOWS"))])
573                            .optional(sub().out(Some("FOLLOWS")))
574                            .dedup()
575                            .value_map(Some(vec!["externalId", "name"])),
576                    )
577                    .returning(["branched"]),
578            ),
579        ),
580        runtime(
581            "019-read-aggregations",
582            read_request(
583                read_batch()
584                    .var_as(
585                        "by_status",
586                        g().n_with_label("ParityUser").group_count("status"),
587                    )
588                    .var_as(
589                        "mean_score",
590                        g().n_with_label("ParityUser")
591                            .aggregate_by(AggregateFunction::Mean, "score"),
592                    )
593                    .var_as(
594                        "max_age",
595                        g().n_with_label("ParityUser")
596                            .aggregate_by(AggregateFunction::Max, "age"),
597                    )
598                    .returning(["by_status", "mean_score", "max_age"]),
599            ),
600        ),
601        runtime(
602            "020-write-index-create",
603            write_request(
604                write_batch()
605                    .var_as(
606                        "node_eq",
607                        g().create_index_if_not_exists(IndexSpec::node_equality(
608                            "ParityUser",
609                            "externalId",
610                        )),
611                    )
612                    .var_as(
613                        "node_range",
614                        g().create_index_if_not_exists(IndexSpec::node_range("ParityUser", "age")),
615                    )
616                    .var_as(
617                        "edge_eq",
618                        g().create_index_if_not_exists(IndexSpec::edge_equality(
619                            "FOLLOWS", "since",
620                        )),
621                    )
622                    .var_as(
623                        "edge_range",
624                        g().create_index_if_not_exists(IndexSpec::edge_range("FOLLOWS", "weight")),
625                    )
626                    .returning(["node_eq", "node_range", "edge_eq", "edge_range"]),
627            ),
628        ),
629        runtime(
630            "021-read-parameter-types",
631            with_params(
632                read_request(
633                    read_batch()
634                        .var_as(
635                            "matches",
636                            g().n_with_label("ParityUser")
637                                .where_(Predicate::is_in_param("status", "statuses"))
638                                .where_(Predicate::gte_param("createdAt", "created_after"))
639                                .limit(Expr::param("limit"))
640                                .value_map(Some(vec!["externalId", "status"])),
641                        )
642                        .returning(["matches"]),
643                ),
644                vec![
645                    (
646                        "statuses",
647                        array(vec![string("active"), string("inactive")]),
648                    ),
649                    ("created_after", string("2026-01-01T00:00:00.000Z")),
650                    ("limit", i64_value(5)),
651                ],
652                vec![
653                    (
654                        "statuses",
655                        QueryParamType::Array(Box::new(QueryParamType::String)),
656                    ),
657                    ("created_after", QueryParamType::DateTime),
658                    ("limit", QueryParamType::I64),
659                ],
660            ),
661        ),
662        runtime(
663            "022-write-property-value-variants",
664            write_request(
665                write_batch()
666                    .var_as(
667                        "variant_node",
668                        g().add_n(
669                            "ParityVariant",
670                            vec![
671                                ("nullValue", PropertyInput::from(PropertyValue::Null)),
672                                ("boolValue", PropertyInput::from(true)),
673                                (
674                                    "i64Value",
675                                    PropertyInput::from(9_223_372_036_854_775_000i64),
676                                ),
677                                (
678                                    "dateTimeValue",
679                                    PropertyInput::from(DateTime::from_millis(-1)),
680                                ),
681                                ("f64Value", PropertyInput::from(3.25f64)),
682                                ("f32Value", PropertyInput::from(1.5f32)),
683                                ("stringValue", PropertyInput::from("variant")),
684                                (
685                                    "bytesValue",
686                                    PropertyInput::from(PropertyValue::from(vec![1u8, 2u8, 3u8])),
687                                ),
688                                (
689                                    "i64Array",
690                                    PropertyInput::from(PropertyValue::from(vec![
691                                        1i64, 2i64, 3i64,
692                                    ])),
693                                ),
694                                (
695                                    "f64Array",
696                                    PropertyInput::from(PropertyValue::from(vec![1.0f64, 2.0f64])),
697                                ),
698                                (
699                                    "f32Array",
700                                    PropertyInput::from(PropertyValue::from(vec![1.0f32, 2.0f32])),
701                                ),
702                                (
703                                    "stringArray",
704                                    PropertyInput::from(PropertyValue::from(vec![
705                                        "a".to_string(),
706                                        "b".to_string(),
707                                    ])),
708                                ),
709                            ],
710                        ),
711                    )
712                    .returning(["variant_node"]),
713            ),
714        ),
715        runtime(
716            "023-read-property-value-variants",
717            read_request(
718                read_batch()
719                    .var_as(
720                        "variant",
721                        g().n_with_label("ParityVariant")
722                            .value_map(None::<Vec<&str>>),
723                    )
724                    .returning(["variant"]),
725            ),
726        ),
727        runtime(
728            "024-write-text-vector-indexes",
729            write_request(
730                write_batch()
731                    .var_as(
732                        "node_text",
733                        g().create_text_index_nodes("ParityUser", "bio", None::<&str>),
734                    )
735                    .var_as(
736                        "node_vector",
737                        g().create_vector_index_nodes("ParityUser", "embedding", None::<&str>),
738                    )
739                    .var_as(
740                        "edge_text",
741                        g().create_text_index_edges("FOLLOWS", "note", None::<&str>),
742                    )
743                    .var_as(
744                        "edge_vector",
745                        g().create_vector_index_edges("FOLLOWS", "embedding", None::<&str>),
746                    )
747                    .returning(["node_text", "node_vector", "edge_text", "edge_vector"]),
748            ),
749        ),
750        runtime(
751            "025-read-text-search-nodes",
752            read_request(
753                read_batch()
754                    .var_as(
755                        "text_hits",
756                        g().text_search_nodes("ParityUser", "bio", "graph", 5, None)
757                            .value_map(Some(vec!["externalId", "bio", "$distance"])),
758                    )
759                    .returning(["text_hits"]),
760            ),
761        ),
762        runtime(
763            "026-read-vector-search-nodes",
764            read_request(
765                read_batch()
766                    .var_as(
767                        "vector_hits",
768                        g().vector_search_nodes(
769                            "ParityUser",
770                            "embedding",
771                            vec![1.0, 0.0, 0.0],
772                            3,
773                            None,
774                        )
775                        .project(vec![
776                            Projection::property("externalId", "externalId"),
777                            Projection::property("$distance", "distance"),
778                        ]),
779                    )
780                    .returning(["vector_hits"]),
781            ),
782        ),
783        runtime(
784            "027-read-text-search-edges",
785            read_request(
786                read_batch()
787                    .var_as(
788                        "edge_text_hits",
789                        g().text_search_edges("FOLLOWS", "note", "follows", 5, None)
790                            .edge_properties(),
791                    )
792                    .returning(["edge_text_hits"]),
793            ),
794        ),
795        runtime(
796            "028-read-vector-search-edges",
797            read_request(
798                read_batch()
799                    .var_as(
800                        "edge_vector_hits",
801                        g().vector_search_edges("FOLLOWS", "embedding", vec![1.0, 0.0], 5, None)
802                            .edge_properties(),
803                    )
804                    .returning(["edge_vector_hits"]),
805            ),
806        ),
807        runtime(
808            "029-write-drop-temp-node",
809            write_request(
810                write_batch()
811                    .var_as(
812                        "temp",
813                        g().add_n("ParityTemp", vec![("name", PropertyInput::from("temp"))]),
814                    )
815                    .var_as("dropped", g().n(NodeRef::var("temp")).drop().count())
816                    .returning(["dropped"]),
817            ),
818        ),
819        runtime(
820            "030-read-final-counts",
821            read_request(
822                read_batch()
823                    .var_as("users", g().n_with_label("ParityUser").count())
824                    .var_as("events", g().n_with_label("ParityEvent").count())
825                    .var_as("variants", g().n_with_label("ParityVariant").count())
826                    .returning(["users", "events", "variants"]),
827            ),
828        ),
829        runtime(
830            "031-read-source-predicate-eq-param",
831            with_params(
832                read_request(
833                    read_batch()
834                        .var_as(
835                            "user",
836                            g().n_where(SourcePredicate::and(vec![
837                                SourcePredicate::eq("$label", "ParityUser"),
838                                SourcePredicate::eq("name", Expr::param("name")),
839                            ]))
840                            .value_map(Some(vec!["externalId", "name"])),
841                        )
842                        .returning(["user"]),
843                ),
844                vec![("name", string("Alice"))],
845                vec![("name", QueryParamType::String)],
846            ),
847        ),
848        runtime(
849            "032-read-source-predicate-between-param",
850            with_params(
851                read_request(
852                    read_batch()
853                        .var_as(
854                            "adults",
855                            g().n_where(SourcePredicate::and(vec![
856                                SourcePredicate::eq("$label", "ParityUser"),
857                                SourcePredicate::between("age", Expr::param("min_age"), 65i64),
858                            ]))
859                            .value_map(Some(vec!["externalId", "age"])),
860                        )
861                        .returning(["adults"]),
862                ),
863                vec![("min_age", i64_value(30))],
864                vec![("min_age", QueryParamType::I64)],
865            ),
866        ),
867    ]
868}
869
870fn node_permutation_fixtures() -> Vec<Fixture> {
871    let sources = ["label", "where", "all"];
872    let filters = ["none", "has", "logic", "expr"];
873    let bounds = ["none", "limit", "skip", "range"];
874    let terminals = ["count", "exists", "value_map", "project"];
875
876    let mut fixtures = Vec::new();
877    let mut index = 100;
878    for source in sources {
879        for filter in filters {
880            for bound in bounds {
881                for terminal in terminals {
882                    let name =
883                        format!("{index:03}-combo-node-{source}-{filter}-{bound}-{terminal}");
884                    index += 1;
885                    fixtures.push(runtime(
886                        name,
887                        read_request(node_combo_batch(source, filter, bound, terminal)),
888                    ));
889                }
890            }
891        }
892    }
893    fixtures
894}
895
896fn node_combo_batch(source: &str, filter: &str, bound: &str, terminal: &str) -> ReadBatch {
897    let traversal = apply_node_bound(apply_node_filter(node_source(source), filter), bound)
898        .order_by("externalId", Order::Asc);
899    let traversal = match terminal {
900        "count" => traversal.count(),
901        "exists" => traversal.exists(),
902        "value_map" => traversal.value_map(Some(vec!["externalId", "name", "age", "status"])),
903        "project" => traversal.project(vec![
904            Projection::property("externalId", "externalId"),
905            Projection::property("status", "status"),
906            Projection::expr("age_plus_two", Expr::prop("age").add(Expr::val(2i64))),
907        ]),
908        other => panic!("unknown terminal {other}"),
909    };
910    read_batch()
911        .var_as("result", traversal)
912        .returning(["result"])
913}
914
915fn node_source(source: &str) -> Traversal<OnNodes, ReadOnly> {
916    match source {
917        "label" => g().n_with_label("ParityUser"),
918        "where" => g().n_where(SourcePredicate::eq("$label", "ParityUser")),
919        "all" => g().n(NodeRef::all()).has_label("ParityUser"),
920        other => panic!("unknown source {other}"),
921    }
922}
923
924fn apply_node_filter(
925    traversal: Traversal<OnNodes, ReadOnly>,
926    filter: &str,
927) -> Traversal<OnNodes, ReadOnly> {
928    match filter {
929        "none" => traversal,
930        "has" => traversal.has("status", "active"),
931        "logic" => traversal.where_(Predicate::and(vec![
932            Predicate::has_key("externalId"),
933            Predicate::or(vec![
934                Predicate::starts_with("name", "A"),
935                Predicate::ends_with("name", "b"),
936            ]),
937            Predicate::not(Predicate::is_null("age")),
938        ])),
939        "expr" => traversal.where_(Predicate::compare(
940            Expr::prop("score").add(Expr::val(1.0f64)),
941            CompareOp::Gt,
942            Expr::val(65.0f64),
943        )),
944        other => panic!("unknown filter {other}"),
945    }
946}
947
948fn apply_node_bound(
949    traversal: Traversal<OnNodes, ReadOnly>,
950    bound: &str,
951) -> Traversal<OnNodes, ReadOnly> {
952    match bound {
953        "none" => traversal,
954        "limit" => traversal.limit(2usize),
955        "skip" => traversal.skip(1usize),
956        "range" => traversal.range(0usize, 2usize),
957        other => panic!("unknown bound {other}"),
958    }
959}
960
961fn json_only_fixtures() -> Vec<Fixture> {
962    vec![
963        json_only(
964            "900-exhaustive-raw-read-steps",
965            with_params(
966                read_request(
967                    read_batch()
968                        .var_as(
969                            "raw_nodes",
970                            Traversal::<OnNodes, ReadOnly>::from_steps(vec![
971                                Step::N(NodeRef::Param("node_ids".to_string())),
972                                Step::Has("name".to_string(), PropertyValue::from("Alice")),
973                                Step::Where(Predicate::contains_param("bio", "needle")),
974                                Step::LimitBy(Expr::param("limit")),
975                                Step::SkipBy(Expr::param("skip")),
976                                Step::RangeBy(
977                                    StreamBound::literal(0),
978                                    StreamBound::expr(Expr::param("end")),
979                                ),
980                                Step::As("a".to_string()),
981                                Step::Store("stored".to_string()),
982                                Step::Select("stored".to_string()),
983                                Step::Dedup,
984                                Step::Within("stored".to_string()),
985                                Step::Without("missing".to_string()),
986                                Step::Fold,
987                                Step::Unfold,
988                                Step::Path,
989                                Step::SimplePath,
990                                Step::WithSack(PropertyValue::from(0i64)),
991                                Step::SackSet("score".to_string()),
992                                Step::SackAdd("score".to_string()),
993                                Step::SackGet,
994                                Step::Project(vec![
995                                    Projection::property("externalId", "externalId"),
996                                    Projection::expr("neg_age", Expr::prop("age").neg()),
997                                ]),
998                            ]),
999                        )
1000                        .var_as(
1001                            "raw_edges",
1002                            Traversal::<helix_db::OnEdges, ReadOnly>::from_steps(vec![
1003                                Step::E(EdgeRef::Param("edge_ids".to_string())),
1004                                Step::EWhere(SourcePredicate::or(vec![
1005                                    SourcePredicate::has_key("since"),
1006                                    SourcePredicate::starts_with("note", "Alice"),
1007                                ])),
1008                                Step::OutN,
1009                                Step::InN,
1010                                Step::OtherN,
1011                                Step::EdgeHas("weight".to_string(), PropertyInput::from(1.0f64)),
1012                                Step::EdgeHasLabel("FOLLOWS".to_string()),
1013                                Step::OrderBy("weight".to_string(), Order::Desc),
1014                                Step::EdgeProperties,
1015                            ]),
1016                        )
1017                        .returning(["raw_nodes", "raw_edges"]),
1018                ),
1019                vec![
1020                    ("node_ids", array(vec![i64_value(1), i64_value(2)])),
1021                    ("edge_ids", array(vec![i64_value(1)])),
1022                    ("needle", string("graph")),
1023                    ("limit", i64_value(10)),
1024                    ("skip", i64_value(0)),
1025                    ("end", i64_value(10)),
1026                ],
1027                vec![
1028                    (
1029                        "node_ids",
1030                        QueryParamType::Array(Box::new(QueryParamType::I64)),
1031                    ),
1032                    (
1033                        "edge_ids",
1034                        QueryParamType::Array(Box::new(QueryParamType::I64)),
1035                    ),
1036                    ("needle", QueryParamType::String),
1037                    ("limit", QueryParamType::I64),
1038                    ("skip", QueryParamType::I64),
1039                    ("end", QueryParamType::I64),
1040                ],
1041            ),
1042        ),
1043        json_only(
1044            "901-exhaustive-raw-write-steps",
1045            write_request(
1046                write_batch()
1047                    .var_as(
1048                        "raw_indexes",
1049                        Traversal::<helix_db::Terminal, WriteEnabled>::from_steps(vec![
1050                            Step::CreateIndex {
1051                                spec: IndexSpec::node_unique_equality("ParityUser", "externalId"),
1052                                if_not_exists: true,
1053                            },
1054                            Step::DropIndex {
1055                                spec: IndexSpec::node_range("ParityUser", "age"),
1056                            },
1057                            Step::CreateVectorIndexNodes {
1058                                label: "ParityUser".to_string(),
1059                                property: "embedding".to_string(),
1060                                tenant_property: Some("tenantId".to_string()),
1061                            },
1062                            Step::CreateVectorIndexEdges {
1063                                label: "FOLLOWS".to_string(),
1064                                property: "embedding".to_string(),
1065                                tenant_property: Some("tenantId".to_string()),
1066                            },
1067                            Step::CreateTextIndexNodes {
1068                                label: "ParityUser".to_string(),
1069                                property: "bio".to_string(),
1070                                tenant_property: Some("tenantId".to_string()),
1071                            },
1072                            Step::CreateTextIndexEdges {
1073                                label: "FOLLOWS".to_string(),
1074                                property: "note".to_string(),
1075                                tenant_property: Some("tenantId".to_string()),
1076                            },
1077                        ]),
1078                    )
1079                    .var_as(
1080                        "raw_mutations",
1081                        Traversal::<OnNodes, WriteEnabled>::from_steps(vec![
1082                            Step::AddN {
1083                                label: "RawNode".to_string(),
1084                                properties: vec![("name".to_string(), PropertyInput::from("raw"))],
1085                            },
1086                            Step::AddE {
1087                                label: "RAW_EDGE".to_string(),
1088                                to: NodeRef::Var("raw_mutations".to_string()),
1089                                properties: vec![("weight".to_string(), PropertyInput::from(1i64))],
1090                            },
1091                            Step::SetProperty(
1092                                "name".to_string(),
1093                                PropertyInput::Expr(Expr::param("name")),
1094                            ),
1095                            Step::RemoveProperty("old".to_string()),
1096                            Step::DropEdge(NodeRef::Ids(vec![999_999])),
1097                            Step::DropEdgeLabeled {
1098                                to: NodeRef::Ids(vec![999_999]),
1099                                label: "RAW_EDGE".to_string(),
1100                            },
1101                            Step::DropEdgeById(EdgeRef::Ids(vec![999_999])),
1102                            Step::Drop,
1103                        ]),
1104                    )
1105                    .returning(["raw_indexes", "raw_mutations"]),
1106            ),
1107        ),
1108        json_only(
1109            "902-dynamic-value-and-param-type-shapes",
1110            with_params(
1111                read_request(
1112                    read_batch()
1113                        .var_as("empty", g().n_with_label("Missing").count())
1114                        .returning(["empty"]),
1115                ),
1116                vec![
1117                    ("null", DynamicQueryValue::Null),
1118                    ("bool", DynamicQueryValue::Bool(true)),
1119                    ("i64", DynamicQueryValue::I64(i64::MAX)),
1120                    ("f64", DynamicQueryValue::F64(1.25)),
1121                    ("f32", DynamicQueryValue::F32(1.5)),
1122                    ("string", string("value")),
1123                    ("array", array(vec![i64_value(1), string("two")])),
1124                    (
1125                        "object",
1126                        object(vec![("nested", DynamicQueryValue::Bool(true))]),
1127                    ),
1128                ],
1129                vec![
1130                    ("null", QueryParamType::Value),
1131                    ("bool", QueryParamType::Bool),
1132                    ("i64", QueryParamType::I64),
1133                    ("f64", QueryParamType::F64),
1134                    ("f32", QueryParamType::F32),
1135                    ("string", QueryParamType::String),
1136                    (
1137                        "array",
1138                        QueryParamType::Array(Box::new(QueryParamType::Value)),
1139                    ),
1140                    ("object", QueryParamType::Object),
1141                ],
1142            ),
1143        ),
1144        json_only(
1145            "903-empty-source-vector-text-runtime-inputs",
1146            with_params(
1147                read_request(
1148                    read_batch()
1149                        .var_as(
1150                            "vector_nodes",
1151                            g().vector_search_nodes_with(
1152                                "ParityUser",
1153                                "embedding",
1154                                PropertyInput::param("query_vector"),
1155                                Expr::param("limit"),
1156                                Some(PropertyInput::param("tenant")),
1157                            ),
1158                        )
1159                        .var_as(
1160                            "text_nodes",
1161                            g().text_search_nodes_with(
1162                                "ParityUser",
1163                                "bio",
1164                                PropertyInput::param("query_text"),
1165                                Expr::param("limit"),
1166                                Some(PropertyInput::param("tenant")),
1167                            ),
1168                        )
1169                        .returning(["vector_nodes", "text_nodes"]),
1170                ),
1171                vec![
1172                    (
1173                        "query_vector",
1174                        array(vec![f64_value(1.0), f64_value(0.0), f64_value(0.0)]),
1175                    ),
1176                    ("query_text", string("graph")),
1177                    ("limit", i64_value(5)),
1178                    ("tenant", string("tenant-a")),
1179                ],
1180                vec![
1181                    (
1182                        "query_vector",
1183                        QueryParamType::Array(Box::new(QueryParamType::F64)),
1184                    ),
1185                    ("query_text", QueryParamType::String),
1186                    ("limit", QueryParamType::I64),
1187                    ("tenant", QueryParamType::String),
1188                ],
1189            ),
1190        ),
1191        json_only(
1192            "904-empty-query-and-node-edge-ref-shapes",
1193            read_request(
1194                read_batch()
1195                    .var_as(
1196                        "all_nodes",
1197                        Traversal::<OnNodes, ReadOnly>::from_steps(vec![
1198                            Step::N(NodeRef::All),
1199                            Step::Count,
1200                        ]),
1201                    )
1202                    .var_as(
1203                        "node_ids",
1204                        Traversal::<OnNodes, ReadOnly>::from_steps(vec![
1205                            Step::N(NodeRef::ids([1, 2])),
1206                            Step::Id,
1207                        ]),
1208                    )
1209                    .var_as(
1210                        "node_var",
1211                        Traversal::<OnNodes, ReadOnly>::from_steps(vec![
1212                            Step::N(NodeRef::Var("all_nodes".to_string())),
1213                            Step::Label,
1214                        ]),
1215                    )
1216                    .var_as(
1217                        "edge_ids",
1218                        Traversal::<helix_db::OnEdges, ReadOnly>::from_steps(vec![
1219                            Step::E(EdgeRef::ids([1, 2])),
1220                            Step::Id,
1221                        ]),
1222                    )
1223                    .var_as(
1224                        "edge_var",
1225                        Traversal::<helix_db::OnEdges, ReadOnly>::from_steps(vec![
1226                            Step::E(EdgeRef::Var("edge_ids".to_string())),
1227                            Step::Label,
1228                        ]),
1229                    )
1230                    .returning(["all_nodes", "node_ids", "node_var", "edge_ids", "edge_var"]),
1231            ),
1232        ),
1233        json_only(
1234            "905-empty-traversal-source-mutators",
1235            write_request(
1236                write_batch()
1237                    .var_as(
1238                        "inject",
1239                        Traversal::<Empty, ReadOnly>::new()
1240                            .inject("some_var")
1241                            .count(),
1242                    )
1243                    .var_as(
1244                        "drop_edge_by_id",
1245                        g().drop_edge_by_id(EdgeRef::id(123_456)).count(),
1246                    )
1247                    .returning(["inject", "drop_edge_by_id"]),
1248            ),
1249        ),
1250        json_only(
1251            "906-nested-dynamic-property-write-shapes",
1252            with_params(
1253                write_request(
1254                    write_batch()
1255                        .var_as(
1256                            "created",
1257                            g().add_n(
1258                                "ParityNested",
1259                                vec![
1260                                    ("name", PropertyInput::from("nested")),
1261                                    (
1262                                        "metadata",
1263                                        PropertyInput::from(nested_metadata_property(
1264                                            "some_id", 20,
1265                                        )),
1266                                    ),
1267                                ],
1268                            ),
1269                        )
1270                        .var_as(
1271                            "updated",
1272                            g().n(NodeRef::var("created"))
1273                                .set_property("metadata", PropertyInput::param("metadata"))
1274                                .value_map(Some(vec!["metadata.externalID"])),
1275                        )
1276                        .var_as(
1277                            "target",
1278                            g().add_n(
1279                                "ParityNestedTarget",
1280                                vec![("name", PropertyInput::from("target"))],
1281                            ),
1282                        )
1283                        .var_as(
1284                            "edge",
1285                            g().n(NodeRef::var("created"))
1286                                .add_e(
1287                                    "NESTED_LINK",
1288                                    NodeRef::var("target"),
1289                                    vec![(
1290                                        "metadata",
1291                                        PropertyInput::from(nested_metadata_property("edge_id", 5)),
1292                                    )],
1293                                )
1294                                .count(),
1295                        )
1296                        .returning(["created", "updated", "edge"]),
1297                ),
1298                vec![("metadata", nested_metadata_param("param_id", 22))],
1299                vec![("metadata", QueryParamType::Object)],
1300            ),
1301        ),
1302        json_only(
1303            "907-nested-dynamic-property-read-shapes",
1304            with_params(
1305                read_request(
1306                    read_batch()
1307                        .var_as(
1308                            "nested_users",
1309                            g().n_where(SourcePredicate::and(vec![
1310                                SourcePredicate::eq("$label", "ParityNested"),
1311                                SourcePredicate::eq(
1312                                    "metadata.externalID",
1313                                    Expr::param("external_id"),
1314                                ),
1315                            ]))
1316                            .where_(Predicate::compare(
1317                                Expr::prop("metadata.score"),
1318                                CompareOp::Gt,
1319                                Expr::val(10i64),
1320                            ))
1321                            .order_by_multiple(vec![
1322                                ("metadata.score", Order::Desc),
1323                                ("name", Order::Asc),
1324                            ])
1325                            .project(vec![
1326                                Projection::property("metadata.externalID", "external_id"),
1327                                Projection::expr("score_copy", Expr::prop("metadata.score")),
1328                            ]),
1329                        )
1330                        .var_as(
1331                            "nested_values",
1332                            g().n_with_label("ParityNested")
1333                                .values(vec!["metadata.externalID"]),
1334                        )
1335                        .var_as(
1336                            "nested_map",
1337                            g().n_with_label("ParityNested")
1338                                .value_map(Some(vec!["metadata.externalID", "metadata.score"])),
1339                        )
1340                        .var_as(
1341                            "nested_edges",
1342                            g().e_where(SourcePredicate::and(vec![
1343                                SourcePredicate::eq("$label", "NESTED_LINK"),
1344                                SourcePredicate::eq("metadata.externalID", "edge_id"),
1345                            ]))
1346                            .edge_has("metadata.externalID", PropertyInput::from("edge_id"))
1347                            .edge_properties(),
1348                        )
1349                        .returning([
1350                            "nested_users",
1351                            "nested_values",
1352                            "nested_map",
1353                            "nested_edges",
1354                        ]),
1355                ),
1356                vec![("external_id", string("param_id"))],
1357                vec![("external_id", QueryParamType::String)],
1358            ),
1359        ),
1360        json_only(
1361            "908-edge-endpoint-projection",
1362            read_request(
1363                read_batch()
1364                    .var_as(
1365                        "endpoints",
1366                        g().e_with_label("FOLLOWS").project(vec![
1367                            Projection::from_endpoint("externalId", "from_id"),
1368                            Projection::to_endpoint("externalId", "to_id"),
1369                            Projection::property("$id", "edge_id"),
1370                        ]),
1371                    )
1372                    .returning(["endpoints"]),
1373            ),
1374        ),
1375        json_only(
1376            "909-row-binding-basic-projection",
1377            read_request(
1378                read_batch()
1379                    .var_as(
1380                        "bindings",
1381                        g().n_with_label("ParityService")
1382                            .bind("service")
1383                            .project_bindings(vec![
1384                                BindingProjection::binding("service", "$id", "service_id"),
1385                                BindingProjection::current("metadata.name", "current_name"),
1386                                BindingProjection::binding(
1387                                    "missing_binding",
1388                                    "externalId",
1389                                    "missing_external_id",
1390                                ),
1391                            ]),
1392                    )
1393                    .returning(["bindings"]),
1394            ),
1395        ),
1396        json_only(
1397            "910-row-binding-branch-distinct-projection",
1398            read_request(
1399                read_batch()
1400                    .var_as(
1401                        "workloads",
1402                        g().n_with_label("ParityService")
1403                            .bind("service")
1404                            .out(Some("ROUTES_TO"))
1405                            .bind("pod")
1406                            .optional(sub().in_(Some("CREATES")).bind("deployment"))
1407                            .union(vec![
1408                                sub().in_(Some("MANAGES")).bind("owner"),
1409                                sub().out(Some("ROUTES_TO")).bind("workload"),
1410                            ])
1411                            .project_distinct_bindings(vec![
1412                                BindingProjection::binding("service", "$id", "service_id"),
1413                                BindingProjection::coalesce(
1414                                    vec![
1415                                        BindingValueRef::binding("deployment", "$id"),
1416                                        BindingValueRef::binding("owner", "$id"),
1417                                        BindingValueRef::binding("workload", "$id"),
1418                                    ],
1419                                    "workload_id",
1420                                ),
1421                            ]),
1422                    )
1423                    .returning(["workloads"]),
1424            ),
1425        ),
1426        json_only(
1427            "911-range-index-direction",
1428            write_request(
1429                write_batch()
1430                    .var_as(
1431                        "node_desc",
1432                        g().create_index_if_not_exists(IndexSpec::node_range_desc(
1433                            "ParityUser",
1434                            "age",
1435                        )),
1436                    )
1437                    .var_as(
1438                        "edge_desc",
1439                        g().create_index_if_not_exists(IndexSpec::edge_range_desc(
1440                            "FOLLOWS", "weight",
1441                        )),
1442                    )
1443                    .var_as(
1444                        "node_asc",
1445                        g().create_index_if_not_exists(IndexSpec::node_range(
1446                            "ParityUser",
1447                            "score",
1448                        )),
1449                    )
1450                    .returning(["node_desc", "edge_desc", "node_asc"]),
1451            ),
1452        ),
1453    ]
1454}
Source

pub fn var_as_if<S: TraversalState>( self, name: &str, condition: BatchCondition, traversal: Traversal<S, ReadOnly>, ) -> Self

Add a conditional read-only query that only executes if the condition is met

Examples found in repository?
examples/generate_parity_fixtures.rs (lines 380-386)
159fn runtime_fixtures() -> Vec<Fixture> {
160    vec![
161        runtime(
162            "001-write-seed-core",
163            write_request(
164                write_batch()
165                    .var_as(
166                        "alice",
167                        g().add_n(
168                            "ParityUser",
169                            user_props(
170                                "user-alice",
171                                "Alice",
172                                31,
173                                90.5,
174                                "active",
175                                "London",
176                                "Alice writes graph database tests",
177                                vec![1.0, 0.0, 0.0],
178                            ),
179                        ),
180                    )
181                    .var_as(
182                        "bob",
183                        g().add_n(
184                            "ParityUser",
185                            user_props(
186                                "user-bob",
187                                "Bob",
188                                27,
189                                72.25,
190                                "active",
191                                "Paris",
192                                "Bob likes traversal testing",
193                                vec![0.9, 0.1, 0.0],
194                            ),
195                        ),
196                    )
197                    .var_as(
198                        "carol",
199                        g().add_n(
200                            "ParityUser",
201                            user_props(
202                                "user-carol",
203                                "Carol",
204                                42,
205                                64.0,
206                                "inactive",
207                                "Berlin",
208                                "Carol archives old records",
209                                vec![0.0, 1.0, 0.0],
210                            ),
211                        ),
212                    )
213                    .var_as(
214                        "alice_follows_bob",
215                        g().n(NodeRef::var("alice")).add_e(
216                            "FOLLOWS",
217                            NodeRef::var("bob"),
218                            vec![
219                                ("weight", PropertyInput::from(1.0f64)),
220                                ("since", PropertyInput::from("2024-01-01")),
221                                ("note", PropertyInput::from("Alice follows Bob")),
222                                (
223                                    "embedding",
224                                    PropertyInput::from(PropertyValue::from(vec![1.0f32, 0.0])),
225                                ),
226                            ],
227                        ),
228                    )
229                    .var_as(
230                        "bob_follows_carol",
231                        g().n(NodeRef::var("bob")).add_e(
232                            "FOLLOWS",
233                            NodeRef::var("carol"),
234                            vec![
235                                ("weight", PropertyInput::from(0.5f64)),
236                                ("since", PropertyInput::from("2024-02-01")),
237                                ("note", PropertyInput::from("Bob follows Carol")),
238                                (
239                                    "embedding",
240                                    PropertyInput::from(PropertyValue::from(vec![0.0f32, 1.0])),
241                                ),
242                            ],
243                        ),
244                    )
245                    .returning([
246                        "alice",
247                        "bob",
248                        "carol",
249                        "alice_follows_bob",
250                        "bob_follows_carol",
251                    ]),
252            ),
253        ),
254        runtime(
255            "002-read-count-all-users",
256            read_request(
257                read_batch()
258                    .var_as("user_count", g().n_with_label("ParityUser").count())
259                    .returning(["user_count"]),
260            ),
261        ),
262        runtime(
263            "003-read-source-predicate-and-count",
264            read_request(
265                read_batch()
266                    .var_as(
267                        "active_adults",
268                        g().n_with_label_where(
269                            "ParityUser",
270                            SourcePredicate::and(vec![
271                                SourcePredicate::eq("status", "active"),
272                                SourcePredicate::gte("age", 30i64),
273                            ]),
274                        )
275                        .count(),
276                    )
277                    .returning(["active_adults"]),
278            ),
279        ),
280        runtime(
281            "004-read-value-map-projection",
282            read_request(
283                read_batch()
284                    .var_as(
285                        "alice",
286                        g().n_with_label("ParityUser")
287                            .where_(Predicate::eq("externalId", "user-alice"))
288                            .project(vec![
289                                Projection::property("externalId", "id"),
290                                Projection::property("name", "name"),
291                                Projection::expr(
292                                    "score_plus_one",
293                                    Expr::prop("score").add(Expr::val(1.0f64)),
294                                ),
295                                Projection::expr(
296                                    "status_label",
297                                    Expr::case(
298                                        vec![(
299                                            Predicate::eq("status", "active"),
300                                            Expr::val("enabled"),
301                                        )],
302                                        Some(Expr::val("disabled")),
303                                    ),
304                                ),
305                            ]),
306                    )
307                    .returning(["alice"]),
308            ),
309        ),
310        runtime(
311            "005-read-order-range-values",
312            read_request(
313                read_batch()
314                    .var_as(
315                        "ordered",
316                        g().n_with_label("ParityUser")
317                            .order_by_multiple(vec![("status", Order::Asc), ("age", Order::Desc)])
318                            .range(0usize, 2usize)
319                            .value_map(Some(vec!["externalId", "age", "status"])),
320                    )
321                    .returning(["ordered"]),
322            ),
323        ),
324        runtime(
325            "006-read-edge-count",
326            read_request(
327                read_batch()
328                    .var_as(
329                        "edge_count",
330                        g().n_with_label("ParityUser")
331                            .where_(Predicate::eq("externalId", "user-alice"))
332                            .out_e(Some("FOLLOWS"))
333                            .count(),
334                    )
335                    .returning(["edge_count"]),
336            ),
337        ),
338        runtime(
339            "007-read-edge-properties",
340            read_request(
341                read_batch()
342                    .var_as(
343                        "edges",
344                        g().e_with_label("FOLLOWS")
345                            .edge_has("weight", PropertyInput::from(1.0f64))
346                            .edge_properties(),
347                    )
348                    .returning(["edges"]),
349            ),
350        ),
351        runtime(
352            "008-read-edge-endpoints",
353            read_request(
354                read_batch()
355                    .var_as(
356                        "from_nodes",
357                        g().e_with_label("FOLLOWS")
358                            .edge_has_label("FOLLOWS")
359                            .in_n()
360                            .value_map(Some(vec!["externalId", "name"])),
361                    )
362                    .var_as(
363                        "to_nodes",
364                        g().e_with_label("FOLLOWS")
365                            .out_n()
366                            .value_map(Some(vec!["externalId", "name"])),
367                    )
368                    .returning(["from_nodes", "to_nodes"]),
369            ),
370        ),
371        runtime(
372            "009-read-conditional-var-not-empty",
373            read_request(
374                read_batch()
375                    .var_as(
376                        "alice",
377                        g().n_with_label("ParityUser")
378                            .where_(Predicate::eq("externalId", "user-alice")),
379                    )
380                    .var_as_if(
381                        "friends",
382                        BatchCondition::VarNotEmpty("alice".to_string()),
383                        g().n(NodeRef::var("alice"))
384                            .out(Some("FOLLOWS"))
385                            .value_map(Some(vec!["externalId", "name"])),
386                    )
387                    .returning(["alice", "friends"]),
388            ),
389        ),
390        runtime(
391            "010-read-conditional-var-empty",
392            read_request(
393                read_batch()
394                    .var_as(
395                        "missing",
396                        g().n_with_label("ParityUser")
397                            .where_(Predicate::eq("externalId", "missing-user")),
398                    )
399                    .var_as_if(
400                        "fallback",
401                        BatchCondition::VarEmpty("missing".to_string()),
402                        g().n_with_label("ParityUser")
403                            .limit(1usize)
404                            .value_map(Some(vec!["externalId"])),
405                    )
406                    .returning(["missing", "fallback"]),
407            ),
408        ),
409        runtime(
410            "011-read-conditional-var-min-size-prev",
411            read_request(
412                read_batch()
413                    .var_as("users", g().n_with_label("ParityUser").limit(3usize))
414                    .var_as_if(
415                        "min_two",
416                        BatchCondition::VarMinSize("users".to_string(), 2),
417                        g().n(NodeRef::var("users")).count(),
418                    )
419                    .var_as_if(
420                        "prev_ok",
421                        BatchCondition::PrevNotEmpty,
422                        g().n(NodeRef::var("users")).exists(),
423                    )
424                    .returning(["min_two", "prev_ok"]),
425            ),
426        ),
427        runtime(
428            "012-read-foreach-param",
429            with_params(
430                read_request(
431                    read_batch()
432                        .for_each_param(
433                            "lookups",
434                            read_batch().var_as(
435                                "matched",
436                                g().n_with_label("ParityUser")
437                                    .where_(Predicate::eq_param("externalId", "externalId"))
438                                    .value_map(Some(vec!["externalId", "name"])),
439                            ),
440                        )
441                        .returning(["matched"]),
442                ),
443                vec![(
444                    "lookups",
445                    array(vec![
446                        object(vec![("externalId", string("user-alice"))]),
447                        object(vec![("externalId", string("user-carol"))]),
448                    ]),
449                )],
450                vec![(
451                    "lookups",
452                    QueryParamType::Array(Box::new(QueryParamType::Object)),
453                )],
454            ),
455        ),
456        runtime(
457            "013-write-foreach-param-create",
458            with_params(
459                write_request(
460                    write_batch()
461                        .for_each_param(
462                            "rows",
463                            write_batch().var_as(
464                                "created",
465                                g().add_n(
466                                    "ParityEvent",
467                                    vec![
468                                        ("eventId", PropertyInput::param("eventId")),
469                                        ("kind", PropertyInput::param("kind")),
470                                        ("score", PropertyInput::param("score")),
471                                    ],
472                                ),
473                            ),
474                        )
475                        .returning(["created"]),
476                ),
477                vec![(
478                    "rows",
479                    array(vec![
480                        object(vec![
481                            ("eventId", string("event-1")),
482                            ("kind", string("click")),
483                            ("score", i64_value(10)),
484                        ]),
485                        object(vec![
486                            ("eventId", string("event-2")),
487                            ("kind", string("view")),
488                            ("score", i64_value(5)),
489                        ]),
490                    ]),
491                )],
492                vec![(
493                    "rows",
494                    QueryParamType::Array(Box::new(QueryParamType::Object)),
495                )],
496            ),
497        ),
498        runtime(
499            "014-read-after-foreach-param",
500            read_request(
501                read_batch()
502                    .var_as("event_count", g().n_with_label("ParityEvent").count())
503                    .returning(["event_count"]),
504            ),
505        ),
506        runtime(
507            "015-write-set-remove-properties",
508            write_request(
509                write_batch()
510                    .var_as(
511                        "updated",
512                        g().n_with_label("ParityUser")
513                            .where_(Predicate::eq("externalId", "user-bob"))
514                            .set_property("status", PropertyInput::from("inactive"))
515                            .set_property(
516                                "updatedAt",
517                                PropertyInput::from(DateTime::from_millis(1_777_000_000_000)),
518                            )
519                            .remove_property("city")
520                            .count(),
521                    )
522                    .returning(["updated"]),
523            ),
524        ),
525        runtime(
526            "016-read-updated-properties",
527            read_request(
528                read_batch()
529                    .var_as(
530                        "bob",
531                        g().n_with_label("ParityUser")
532                            .where_(Predicate::eq("externalId", "user-bob"))
533                            .value_map(Some(vec!["externalId", "status", "updatedAt", "city"])),
534                    )
535                    .returning(["bob"]),
536            ),
537        ),
538        runtime(
539            "017-read-repeat-union",
540            read_request(
541                read_batch()
542                    .var_as(
543                        "walked",
544                        g().n_with_label("ParityUser")
545                            .where_(Predicate::eq("externalId", "user-alice"))
546                            .repeat(
547                                RepeatConfig::new(sub().out(Some("FOLLOWS")))
548                                    .times(2)
549                                    .emit_all()
550                                    .max_depth(4),
551                            )
552                            .union(vec![sub().out(Some("FOLLOWS")), sub().in_(Some("FOLLOWS"))])
553                            .dedup()
554                            .value_map(Some(vec!["externalId", "name"])),
555                    )
556                    .returning(["walked"]),
557            ),
558        ),
559        runtime(
560            "018-read-choose-coalesce-optional",
561            read_request(
562                read_batch()
563                    .var_as(
564                        "branched",
565                        g().n_with_label("ParityUser")
566                            .where_(Predicate::eq("externalId", "user-alice"))
567                            .choose(
568                                Predicate::eq("status", "active"),
569                                sub().out(Some("FOLLOWS")),
570                                Some(sub().in_(Some("FOLLOWS"))),
571                            )
572                            .coalesce(vec![sub().out(Some("FOLLOWS")), sub().in_(Some("FOLLOWS"))])
573                            .optional(sub().out(Some("FOLLOWS")))
574                            .dedup()
575                            .value_map(Some(vec!["externalId", "name"])),
576                    )
577                    .returning(["branched"]),
578            ),
579        ),
580        runtime(
581            "019-read-aggregations",
582            read_request(
583                read_batch()
584                    .var_as(
585                        "by_status",
586                        g().n_with_label("ParityUser").group_count("status"),
587                    )
588                    .var_as(
589                        "mean_score",
590                        g().n_with_label("ParityUser")
591                            .aggregate_by(AggregateFunction::Mean, "score"),
592                    )
593                    .var_as(
594                        "max_age",
595                        g().n_with_label("ParityUser")
596                            .aggregate_by(AggregateFunction::Max, "age"),
597                    )
598                    .returning(["by_status", "mean_score", "max_age"]),
599            ),
600        ),
601        runtime(
602            "020-write-index-create",
603            write_request(
604                write_batch()
605                    .var_as(
606                        "node_eq",
607                        g().create_index_if_not_exists(IndexSpec::node_equality(
608                            "ParityUser",
609                            "externalId",
610                        )),
611                    )
612                    .var_as(
613                        "node_range",
614                        g().create_index_if_not_exists(IndexSpec::node_range("ParityUser", "age")),
615                    )
616                    .var_as(
617                        "edge_eq",
618                        g().create_index_if_not_exists(IndexSpec::edge_equality(
619                            "FOLLOWS", "since",
620                        )),
621                    )
622                    .var_as(
623                        "edge_range",
624                        g().create_index_if_not_exists(IndexSpec::edge_range("FOLLOWS", "weight")),
625                    )
626                    .returning(["node_eq", "node_range", "edge_eq", "edge_range"]),
627            ),
628        ),
629        runtime(
630            "021-read-parameter-types",
631            with_params(
632                read_request(
633                    read_batch()
634                        .var_as(
635                            "matches",
636                            g().n_with_label("ParityUser")
637                                .where_(Predicate::is_in_param("status", "statuses"))
638                                .where_(Predicate::gte_param("createdAt", "created_after"))
639                                .limit(Expr::param("limit"))
640                                .value_map(Some(vec!["externalId", "status"])),
641                        )
642                        .returning(["matches"]),
643                ),
644                vec![
645                    (
646                        "statuses",
647                        array(vec![string("active"), string("inactive")]),
648                    ),
649                    ("created_after", string("2026-01-01T00:00:00.000Z")),
650                    ("limit", i64_value(5)),
651                ],
652                vec![
653                    (
654                        "statuses",
655                        QueryParamType::Array(Box::new(QueryParamType::String)),
656                    ),
657                    ("created_after", QueryParamType::DateTime),
658                    ("limit", QueryParamType::I64),
659                ],
660            ),
661        ),
662        runtime(
663            "022-write-property-value-variants",
664            write_request(
665                write_batch()
666                    .var_as(
667                        "variant_node",
668                        g().add_n(
669                            "ParityVariant",
670                            vec![
671                                ("nullValue", PropertyInput::from(PropertyValue::Null)),
672                                ("boolValue", PropertyInput::from(true)),
673                                (
674                                    "i64Value",
675                                    PropertyInput::from(9_223_372_036_854_775_000i64),
676                                ),
677                                (
678                                    "dateTimeValue",
679                                    PropertyInput::from(DateTime::from_millis(-1)),
680                                ),
681                                ("f64Value", PropertyInput::from(3.25f64)),
682                                ("f32Value", PropertyInput::from(1.5f32)),
683                                ("stringValue", PropertyInput::from("variant")),
684                                (
685                                    "bytesValue",
686                                    PropertyInput::from(PropertyValue::from(vec![1u8, 2u8, 3u8])),
687                                ),
688                                (
689                                    "i64Array",
690                                    PropertyInput::from(PropertyValue::from(vec![
691                                        1i64, 2i64, 3i64,
692                                    ])),
693                                ),
694                                (
695                                    "f64Array",
696                                    PropertyInput::from(PropertyValue::from(vec![1.0f64, 2.0f64])),
697                                ),
698                                (
699                                    "f32Array",
700                                    PropertyInput::from(PropertyValue::from(vec![1.0f32, 2.0f32])),
701                                ),
702                                (
703                                    "stringArray",
704                                    PropertyInput::from(PropertyValue::from(vec![
705                                        "a".to_string(),
706                                        "b".to_string(),
707                                    ])),
708                                ),
709                            ],
710                        ),
711                    )
712                    .returning(["variant_node"]),
713            ),
714        ),
715        runtime(
716            "023-read-property-value-variants",
717            read_request(
718                read_batch()
719                    .var_as(
720                        "variant",
721                        g().n_with_label("ParityVariant")
722                            .value_map(None::<Vec<&str>>),
723                    )
724                    .returning(["variant"]),
725            ),
726        ),
727        runtime(
728            "024-write-text-vector-indexes",
729            write_request(
730                write_batch()
731                    .var_as(
732                        "node_text",
733                        g().create_text_index_nodes("ParityUser", "bio", None::<&str>),
734                    )
735                    .var_as(
736                        "node_vector",
737                        g().create_vector_index_nodes("ParityUser", "embedding", None::<&str>),
738                    )
739                    .var_as(
740                        "edge_text",
741                        g().create_text_index_edges("FOLLOWS", "note", None::<&str>),
742                    )
743                    .var_as(
744                        "edge_vector",
745                        g().create_vector_index_edges("FOLLOWS", "embedding", None::<&str>),
746                    )
747                    .returning(["node_text", "node_vector", "edge_text", "edge_vector"]),
748            ),
749        ),
750        runtime(
751            "025-read-text-search-nodes",
752            read_request(
753                read_batch()
754                    .var_as(
755                        "text_hits",
756                        g().text_search_nodes("ParityUser", "bio", "graph", 5, None)
757                            .value_map(Some(vec!["externalId", "bio", "$distance"])),
758                    )
759                    .returning(["text_hits"]),
760            ),
761        ),
762        runtime(
763            "026-read-vector-search-nodes",
764            read_request(
765                read_batch()
766                    .var_as(
767                        "vector_hits",
768                        g().vector_search_nodes(
769                            "ParityUser",
770                            "embedding",
771                            vec![1.0, 0.0, 0.0],
772                            3,
773                            None,
774                        )
775                        .project(vec![
776                            Projection::property("externalId", "externalId"),
777                            Projection::property("$distance", "distance"),
778                        ]),
779                    )
780                    .returning(["vector_hits"]),
781            ),
782        ),
783        runtime(
784            "027-read-text-search-edges",
785            read_request(
786                read_batch()
787                    .var_as(
788                        "edge_text_hits",
789                        g().text_search_edges("FOLLOWS", "note", "follows", 5, None)
790                            .edge_properties(),
791                    )
792                    .returning(["edge_text_hits"]),
793            ),
794        ),
795        runtime(
796            "028-read-vector-search-edges",
797            read_request(
798                read_batch()
799                    .var_as(
800                        "edge_vector_hits",
801                        g().vector_search_edges("FOLLOWS", "embedding", vec![1.0, 0.0], 5, None)
802                            .edge_properties(),
803                    )
804                    .returning(["edge_vector_hits"]),
805            ),
806        ),
807        runtime(
808            "029-write-drop-temp-node",
809            write_request(
810                write_batch()
811                    .var_as(
812                        "temp",
813                        g().add_n("ParityTemp", vec![("name", PropertyInput::from("temp"))]),
814                    )
815                    .var_as("dropped", g().n(NodeRef::var("temp")).drop().count())
816                    .returning(["dropped"]),
817            ),
818        ),
819        runtime(
820            "030-read-final-counts",
821            read_request(
822                read_batch()
823                    .var_as("users", g().n_with_label("ParityUser").count())
824                    .var_as("events", g().n_with_label("ParityEvent").count())
825                    .var_as("variants", g().n_with_label("ParityVariant").count())
826                    .returning(["users", "events", "variants"]),
827            ),
828        ),
829        runtime(
830            "031-read-source-predicate-eq-param",
831            with_params(
832                read_request(
833                    read_batch()
834                        .var_as(
835                            "user",
836                            g().n_where(SourcePredicate::and(vec![
837                                SourcePredicate::eq("$label", "ParityUser"),
838                                SourcePredicate::eq("name", Expr::param("name")),
839                            ]))
840                            .value_map(Some(vec!["externalId", "name"])),
841                        )
842                        .returning(["user"]),
843                ),
844                vec![("name", string("Alice"))],
845                vec![("name", QueryParamType::String)],
846            ),
847        ),
848        runtime(
849            "032-read-source-predicate-between-param",
850            with_params(
851                read_request(
852                    read_batch()
853                        .var_as(
854                            "adults",
855                            g().n_where(SourcePredicate::and(vec![
856                                SourcePredicate::eq("$label", "ParityUser"),
857                                SourcePredicate::between("age", Expr::param("min_age"), 65i64),
858                            ]))
859                            .value_map(Some(vec!["externalId", "age"])),
860                        )
861                        .returning(["adults"]),
862                ),
863                vec![("min_age", i64_value(30))],
864                vec![("min_age", QueryParamType::I64)],
865            ),
866        ),
867    ]
868}
Source

pub fn for_each_param(self, param: &str, body: ReadBatch) -> Self

Execute the provided body once per object in the named array parameter.

Examples found in repository?
examples/generate_parity_fixtures.rs (lines 432-440)
159fn runtime_fixtures() -> Vec<Fixture> {
160    vec![
161        runtime(
162            "001-write-seed-core",
163            write_request(
164                write_batch()
165                    .var_as(
166                        "alice",
167                        g().add_n(
168                            "ParityUser",
169                            user_props(
170                                "user-alice",
171                                "Alice",
172                                31,
173                                90.5,
174                                "active",
175                                "London",
176                                "Alice writes graph database tests",
177                                vec![1.0, 0.0, 0.0],
178                            ),
179                        ),
180                    )
181                    .var_as(
182                        "bob",
183                        g().add_n(
184                            "ParityUser",
185                            user_props(
186                                "user-bob",
187                                "Bob",
188                                27,
189                                72.25,
190                                "active",
191                                "Paris",
192                                "Bob likes traversal testing",
193                                vec![0.9, 0.1, 0.0],
194                            ),
195                        ),
196                    )
197                    .var_as(
198                        "carol",
199                        g().add_n(
200                            "ParityUser",
201                            user_props(
202                                "user-carol",
203                                "Carol",
204                                42,
205                                64.0,
206                                "inactive",
207                                "Berlin",
208                                "Carol archives old records",
209                                vec![0.0, 1.0, 0.0],
210                            ),
211                        ),
212                    )
213                    .var_as(
214                        "alice_follows_bob",
215                        g().n(NodeRef::var("alice")).add_e(
216                            "FOLLOWS",
217                            NodeRef::var("bob"),
218                            vec![
219                                ("weight", PropertyInput::from(1.0f64)),
220                                ("since", PropertyInput::from("2024-01-01")),
221                                ("note", PropertyInput::from("Alice follows Bob")),
222                                (
223                                    "embedding",
224                                    PropertyInput::from(PropertyValue::from(vec![1.0f32, 0.0])),
225                                ),
226                            ],
227                        ),
228                    )
229                    .var_as(
230                        "bob_follows_carol",
231                        g().n(NodeRef::var("bob")).add_e(
232                            "FOLLOWS",
233                            NodeRef::var("carol"),
234                            vec![
235                                ("weight", PropertyInput::from(0.5f64)),
236                                ("since", PropertyInput::from("2024-02-01")),
237                                ("note", PropertyInput::from("Bob follows Carol")),
238                                (
239                                    "embedding",
240                                    PropertyInput::from(PropertyValue::from(vec![0.0f32, 1.0])),
241                                ),
242                            ],
243                        ),
244                    )
245                    .returning([
246                        "alice",
247                        "bob",
248                        "carol",
249                        "alice_follows_bob",
250                        "bob_follows_carol",
251                    ]),
252            ),
253        ),
254        runtime(
255            "002-read-count-all-users",
256            read_request(
257                read_batch()
258                    .var_as("user_count", g().n_with_label("ParityUser").count())
259                    .returning(["user_count"]),
260            ),
261        ),
262        runtime(
263            "003-read-source-predicate-and-count",
264            read_request(
265                read_batch()
266                    .var_as(
267                        "active_adults",
268                        g().n_with_label_where(
269                            "ParityUser",
270                            SourcePredicate::and(vec![
271                                SourcePredicate::eq("status", "active"),
272                                SourcePredicate::gte("age", 30i64),
273                            ]),
274                        )
275                        .count(),
276                    )
277                    .returning(["active_adults"]),
278            ),
279        ),
280        runtime(
281            "004-read-value-map-projection",
282            read_request(
283                read_batch()
284                    .var_as(
285                        "alice",
286                        g().n_with_label("ParityUser")
287                            .where_(Predicate::eq("externalId", "user-alice"))
288                            .project(vec![
289                                Projection::property("externalId", "id"),
290                                Projection::property("name", "name"),
291                                Projection::expr(
292                                    "score_plus_one",
293                                    Expr::prop("score").add(Expr::val(1.0f64)),
294                                ),
295                                Projection::expr(
296                                    "status_label",
297                                    Expr::case(
298                                        vec![(
299                                            Predicate::eq("status", "active"),
300                                            Expr::val("enabled"),
301                                        )],
302                                        Some(Expr::val("disabled")),
303                                    ),
304                                ),
305                            ]),
306                    )
307                    .returning(["alice"]),
308            ),
309        ),
310        runtime(
311            "005-read-order-range-values",
312            read_request(
313                read_batch()
314                    .var_as(
315                        "ordered",
316                        g().n_with_label("ParityUser")
317                            .order_by_multiple(vec![("status", Order::Asc), ("age", Order::Desc)])
318                            .range(0usize, 2usize)
319                            .value_map(Some(vec!["externalId", "age", "status"])),
320                    )
321                    .returning(["ordered"]),
322            ),
323        ),
324        runtime(
325            "006-read-edge-count",
326            read_request(
327                read_batch()
328                    .var_as(
329                        "edge_count",
330                        g().n_with_label("ParityUser")
331                            .where_(Predicate::eq("externalId", "user-alice"))
332                            .out_e(Some("FOLLOWS"))
333                            .count(),
334                    )
335                    .returning(["edge_count"]),
336            ),
337        ),
338        runtime(
339            "007-read-edge-properties",
340            read_request(
341                read_batch()
342                    .var_as(
343                        "edges",
344                        g().e_with_label("FOLLOWS")
345                            .edge_has("weight", PropertyInput::from(1.0f64))
346                            .edge_properties(),
347                    )
348                    .returning(["edges"]),
349            ),
350        ),
351        runtime(
352            "008-read-edge-endpoints",
353            read_request(
354                read_batch()
355                    .var_as(
356                        "from_nodes",
357                        g().e_with_label("FOLLOWS")
358                            .edge_has_label("FOLLOWS")
359                            .in_n()
360                            .value_map(Some(vec!["externalId", "name"])),
361                    )
362                    .var_as(
363                        "to_nodes",
364                        g().e_with_label("FOLLOWS")
365                            .out_n()
366                            .value_map(Some(vec!["externalId", "name"])),
367                    )
368                    .returning(["from_nodes", "to_nodes"]),
369            ),
370        ),
371        runtime(
372            "009-read-conditional-var-not-empty",
373            read_request(
374                read_batch()
375                    .var_as(
376                        "alice",
377                        g().n_with_label("ParityUser")
378                            .where_(Predicate::eq("externalId", "user-alice")),
379                    )
380                    .var_as_if(
381                        "friends",
382                        BatchCondition::VarNotEmpty("alice".to_string()),
383                        g().n(NodeRef::var("alice"))
384                            .out(Some("FOLLOWS"))
385                            .value_map(Some(vec!["externalId", "name"])),
386                    )
387                    .returning(["alice", "friends"]),
388            ),
389        ),
390        runtime(
391            "010-read-conditional-var-empty",
392            read_request(
393                read_batch()
394                    .var_as(
395                        "missing",
396                        g().n_with_label("ParityUser")
397                            .where_(Predicate::eq("externalId", "missing-user")),
398                    )
399                    .var_as_if(
400                        "fallback",
401                        BatchCondition::VarEmpty("missing".to_string()),
402                        g().n_with_label("ParityUser")
403                            .limit(1usize)
404                            .value_map(Some(vec!["externalId"])),
405                    )
406                    .returning(["missing", "fallback"]),
407            ),
408        ),
409        runtime(
410            "011-read-conditional-var-min-size-prev",
411            read_request(
412                read_batch()
413                    .var_as("users", g().n_with_label("ParityUser").limit(3usize))
414                    .var_as_if(
415                        "min_two",
416                        BatchCondition::VarMinSize("users".to_string(), 2),
417                        g().n(NodeRef::var("users")).count(),
418                    )
419                    .var_as_if(
420                        "prev_ok",
421                        BatchCondition::PrevNotEmpty,
422                        g().n(NodeRef::var("users")).exists(),
423                    )
424                    .returning(["min_two", "prev_ok"]),
425            ),
426        ),
427        runtime(
428            "012-read-foreach-param",
429            with_params(
430                read_request(
431                    read_batch()
432                        .for_each_param(
433                            "lookups",
434                            read_batch().var_as(
435                                "matched",
436                                g().n_with_label("ParityUser")
437                                    .where_(Predicate::eq_param("externalId", "externalId"))
438                                    .value_map(Some(vec!["externalId", "name"])),
439                            ),
440                        )
441                        .returning(["matched"]),
442                ),
443                vec![(
444                    "lookups",
445                    array(vec![
446                        object(vec![("externalId", string("user-alice"))]),
447                        object(vec![("externalId", string("user-carol"))]),
448                    ]),
449                )],
450                vec![(
451                    "lookups",
452                    QueryParamType::Array(Box::new(QueryParamType::Object)),
453                )],
454            ),
455        ),
456        runtime(
457            "013-write-foreach-param-create",
458            with_params(
459                write_request(
460                    write_batch()
461                        .for_each_param(
462                            "rows",
463                            write_batch().var_as(
464                                "created",
465                                g().add_n(
466                                    "ParityEvent",
467                                    vec![
468                                        ("eventId", PropertyInput::param("eventId")),
469                                        ("kind", PropertyInput::param("kind")),
470                                        ("score", PropertyInput::param("score")),
471                                    ],
472                                ),
473                            ),
474                        )
475                        .returning(["created"]),
476                ),
477                vec![(
478                    "rows",
479                    array(vec![
480                        object(vec![
481                            ("eventId", string("event-1")),
482                            ("kind", string("click")),
483                            ("score", i64_value(10)),
484                        ]),
485                        object(vec![
486                            ("eventId", string("event-2")),
487                            ("kind", string("view")),
488                            ("score", i64_value(5)),
489                        ]),
490                    ]),
491                )],
492                vec![(
493                    "rows",
494                    QueryParamType::Array(Box::new(QueryParamType::Object)),
495                )],
496            ),
497        ),
498        runtime(
499            "014-read-after-foreach-param",
500            read_request(
501                read_batch()
502                    .var_as("event_count", g().n_with_label("ParityEvent").count())
503                    .returning(["event_count"]),
504            ),
505        ),
506        runtime(
507            "015-write-set-remove-properties",
508            write_request(
509                write_batch()
510                    .var_as(
511                        "updated",
512                        g().n_with_label("ParityUser")
513                            .where_(Predicate::eq("externalId", "user-bob"))
514                            .set_property("status", PropertyInput::from("inactive"))
515                            .set_property(
516                                "updatedAt",
517                                PropertyInput::from(DateTime::from_millis(1_777_000_000_000)),
518                            )
519                            .remove_property("city")
520                            .count(),
521                    )
522                    .returning(["updated"]),
523            ),
524        ),
525        runtime(
526            "016-read-updated-properties",
527            read_request(
528                read_batch()
529                    .var_as(
530                        "bob",
531                        g().n_with_label("ParityUser")
532                            .where_(Predicate::eq("externalId", "user-bob"))
533                            .value_map(Some(vec!["externalId", "status", "updatedAt", "city"])),
534                    )
535                    .returning(["bob"]),
536            ),
537        ),
538        runtime(
539            "017-read-repeat-union",
540            read_request(
541                read_batch()
542                    .var_as(
543                        "walked",
544                        g().n_with_label("ParityUser")
545                            .where_(Predicate::eq("externalId", "user-alice"))
546                            .repeat(
547                                RepeatConfig::new(sub().out(Some("FOLLOWS")))
548                                    .times(2)
549                                    .emit_all()
550                                    .max_depth(4),
551                            )
552                            .union(vec![sub().out(Some("FOLLOWS")), sub().in_(Some("FOLLOWS"))])
553                            .dedup()
554                            .value_map(Some(vec!["externalId", "name"])),
555                    )
556                    .returning(["walked"]),
557            ),
558        ),
559        runtime(
560            "018-read-choose-coalesce-optional",
561            read_request(
562                read_batch()
563                    .var_as(
564                        "branched",
565                        g().n_with_label("ParityUser")
566                            .where_(Predicate::eq("externalId", "user-alice"))
567                            .choose(
568                                Predicate::eq("status", "active"),
569                                sub().out(Some("FOLLOWS")),
570                                Some(sub().in_(Some("FOLLOWS"))),
571                            )
572                            .coalesce(vec![sub().out(Some("FOLLOWS")), sub().in_(Some("FOLLOWS"))])
573                            .optional(sub().out(Some("FOLLOWS")))
574                            .dedup()
575                            .value_map(Some(vec!["externalId", "name"])),
576                    )
577                    .returning(["branched"]),
578            ),
579        ),
580        runtime(
581            "019-read-aggregations",
582            read_request(
583                read_batch()
584                    .var_as(
585                        "by_status",
586                        g().n_with_label("ParityUser").group_count("status"),
587                    )
588                    .var_as(
589                        "mean_score",
590                        g().n_with_label("ParityUser")
591                            .aggregate_by(AggregateFunction::Mean, "score"),
592                    )
593                    .var_as(
594                        "max_age",
595                        g().n_with_label("ParityUser")
596                            .aggregate_by(AggregateFunction::Max, "age"),
597                    )
598                    .returning(["by_status", "mean_score", "max_age"]),
599            ),
600        ),
601        runtime(
602            "020-write-index-create",
603            write_request(
604                write_batch()
605                    .var_as(
606                        "node_eq",
607                        g().create_index_if_not_exists(IndexSpec::node_equality(
608                            "ParityUser",
609                            "externalId",
610                        )),
611                    )
612                    .var_as(
613                        "node_range",
614                        g().create_index_if_not_exists(IndexSpec::node_range("ParityUser", "age")),
615                    )
616                    .var_as(
617                        "edge_eq",
618                        g().create_index_if_not_exists(IndexSpec::edge_equality(
619                            "FOLLOWS", "since",
620                        )),
621                    )
622                    .var_as(
623                        "edge_range",
624                        g().create_index_if_not_exists(IndexSpec::edge_range("FOLLOWS", "weight")),
625                    )
626                    .returning(["node_eq", "node_range", "edge_eq", "edge_range"]),
627            ),
628        ),
629        runtime(
630            "021-read-parameter-types",
631            with_params(
632                read_request(
633                    read_batch()
634                        .var_as(
635                            "matches",
636                            g().n_with_label("ParityUser")
637                                .where_(Predicate::is_in_param("status", "statuses"))
638                                .where_(Predicate::gte_param("createdAt", "created_after"))
639                                .limit(Expr::param("limit"))
640                                .value_map(Some(vec!["externalId", "status"])),
641                        )
642                        .returning(["matches"]),
643                ),
644                vec![
645                    (
646                        "statuses",
647                        array(vec![string("active"), string("inactive")]),
648                    ),
649                    ("created_after", string("2026-01-01T00:00:00.000Z")),
650                    ("limit", i64_value(5)),
651                ],
652                vec![
653                    (
654                        "statuses",
655                        QueryParamType::Array(Box::new(QueryParamType::String)),
656                    ),
657                    ("created_after", QueryParamType::DateTime),
658                    ("limit", QueryParamType::I64),
659                ],
660            ),
661        ),
662        runtime(
663            "022-write-property-value-variants",
664            write_request(
665                write_batch()
666                    .var_as(
667                        "variant_node",
668                        g().add_n(
669                            "ParityVariant",
670                            vec![
671                                ("nullValue", PropertyInput::from(PropertyValue::Null)),
672                                ("boolValue", PropertyInput::from(true)),
673                                (
674                                    "i64Value",
675                                    PropertyInput::from(9_223_372_036_854_775_000i64),
676                                ),
677                                (
678                                    "dateTimeValue",
679                                    PropertyInput::from(DateTime::from_millis(-1)),
680                                ),
681                                ("f64Value", PropertyInput::from(3.25f64)),
682                                ("f32Value", PropertyInput::from(1.5f32)),
683                                ("stringValue", PropertyInput::from("variant")),
684                                (
685                                    "bytesValue",
686                                    PropertyInput::from(PropertyValue::from(vec![1u8, 2u8, 3u8])),
687                                ),
688                                (
689                                    "i64Array",
690                                    PropertyInput::from(PropertyValue::from(vec![
691                                        1i64, 2i64, 3i64,
692                                    ])),
693                                ),
694                                (
695                                    "f64Array",
696                                    PropertyInput::from(PropertyValue::from(vec![1.0f64, 2.0f64])),
697                                ),
698                                (
699                                    "f32Array",
700                                    PropertyInput::from(PropertyValue::from(vec![1.0f32, 2.0f32])),
701                                ),
702                                (
703                                    "stringArray",
704                                    PropertyInput::from(PropertyValue::from(vec![
705                                        "a".to_string(),
706                                        "b".to_string(),
707                                    ])),
708                                ),
709                            ],
710                        ),
711                    )
712                    .returning(["variant_node"]),
713            ),
714        ),
715        runtime(
716            "023-read-property-value-variants",
717            read_request(
718                read_batch()
719                    .var_as(
720                        "variant",
721                        g().n_with_label("ParityVariant")
722                            .value_map(None::<Vec<&str>>),
723                    )
724                    .returning(["variant"]),
725            ),
726        ),
727        runtime(
728            "024-write-text-vector-indexes",
729            write_request(
730                write_batch()
731                    .var_as(
732                        "node_text",
733                        g().create_text_index_nodes("ParityUser", "bio", None::<&str>),
734                    )
735                    .var_as(
736                        "node_vector",
737                        g().create_vector_index_nodes("ParityUser", "embedding", None::<&str>),
738                    )
739                    .var_as(
740                        "edge_text",
741                        g().create_text_index_edges("FOLLOWS", "note", None::<&str>),
742                    )
743                    .var_as(
744                        "edge_vector",
745                        g().create_vector_index_edges("FOLLOWS", "embedding", None::<&str>),
746                    )
747                    .returning(["node_text", "node_vector", "edge_text", "edge_vector"]),
748            ),
749        ),
750        runtime(
751            "025-read-text-search-nodes",
752            read_request(
753                read_batch()
754                    .var_as(
755                        "text_hits",
756                        g().text_search_nodes("ParityUser", "bio", "graph", 5, None)
757                            .value_map(Some(vec!["externalId", "bio", "$distance"])),
758                    )
759                    .returning(["text_hits"]),
760            ),
761        ),
762        runtime(
763            "026-read-vector-search-nodes",
764            read_request(
765                read_batch()
766                    .var_as(
767                        "vector_hits",
768                        g().vector_search_nodes(
769                            "ParityUser",
770                            "embedding",
771                            vec![1.0, 0.0, 0.0],
772                            3,
773                            None,
774                        )
775                        .project(vec![
776                            Projection::property("externalId", "externalId"),
777                            Projection::property("$distance", "distance"),
778                        ]),
779                    )
780                    .returning(["vector_hits"]),
781            ),
782        ),
783        runtime(
784            "027-read-text-search-edges",
785            read_request(
786                read_batch()
787                    .var_as(
788                        "edge_text_hits",
789                        g().text_search_edges("FOLLOWS", "note", "follows", 5, None)
790                            .edge_properties(),
791                    )
792                    .returning(["edge_text_hits"]),
793            ),
794        ),
795        runtime(
796            "028-read-vector-search-edges",
797            read_request(
798                read_batch()
799                    .var_as(
800                        "edge_vector_hits",
801                        g().vector_search_edges("FOLLOWS", "embedding", vec![1.0, 0.0], 5, None)
802                            .edge_properties(),
803                    )
804                    .returning(["edge_vector_hits"]),
805            ),
806        ),
807        runtime(
808            "029-write-drop-temp-node",
809            write_request(
810                write_batch()
811                    .var_as(
812                        "temp",
813                        g().add_n("ParityTemp", vec![("name", PropertyInput::from("temp"))]),
814                    )
815                    .var_as("dropped", g().n(NodeRef::var("temp")).drop().count())
816                    .returning(["dropped"]),
817            ),
818        ),
819        runtime(
820            "030-read-final-counts",
821            read_request(
822                read_batch()
823                    .var_as("users", g().n_with_label("ParityUser").count())
824                    .var_as("events", g().n_with_label("ParityEvent").count())
825                    .var_as("variants", g().n_with_label("ParityVariant").count())
826                    .returning(["users", "events", "variants"]),
827            ),
828        ),
829        runtime(
830            "031-read-source-predicate-eq-param",
831            with_params(
832                read_request(
833                    read_batch()
834                        .var_as(
835                            "user",
836                            g().n_where(SourcePredicate::and(vec![
837                                SourcePredicate::eq("$label", "ParityUser"),
838                                SourcePredicate::eq("name", Expr::param("name")),
839                            ]))
840                            .value_map(Some(vec!["externalId", "name"])),
841                        )
842                        .returning(["user"]),
843                ),
844                vec![("name", string("Alice"))],
845                vec![("name", QueryParamType::String)],
846            ),
847        ),
848        runtime(
849            "032-read-source-predicate-between-param",
850            with_params(
851                read_request(
852                    read_batch()
853                        .var_as(
854                            "adults",
855                            g().n_where(SourcePredicate::and(vec![
856                                SourcePredicate::eq("$label", "ParityUser"),
857                                SourcePredicate::between("age", Expr::param("min_age"), 65i64),
858                            ]))
859                            .value_map(Some(vec!["externalId", "age"])),
860                        )
861                        .returning(["adults"]),
862                ),
863                vec![("min_age", i64_value(30))],
864                vec![("min_age", QueryParamType::I64)],
865            ),
866        ),
867    ]
868}
Source

pub fn returning<I, S>(self, vars: I) -> Self
where I: IntoIterator<Item = S>, S: Into<String>,

Specify which variables to return (call at end)

If not called, all named variables are returned.

Examples found in repository?
examples/generate_parity_fixtures.rs (line 259)
159fn runtime_fixtures() -> Vec<Fixture> {
160    vec![
161        runtime(
162            "001-write-seed-core",
163            write_request(
164                write_batch()
165                    .var_as(
166                        "alice",
167                        g().add_n(
168                            "ParityUser",
169                            user_props(
170                                "user-alice",
171                                "Alice",
172                                31,
173                                90.5,
174                                "active",
175                                "London",
176                                "Alice writes graph database tests",
177                                vec![1.0, 0.0, 0.0],
178                            ),
179                        ),
180                    )
181                    .var_as(
182                        "bob",
183                        g().add_n(
184                            "ParityUser",
185                            user_props(
186                                "user-bob",
187                                "Bob",
188                                27,
189                                72.25,
190                                "active",
191                                "Paris",
192                                "Bob likes traversal testing",
193                                vec![0.9, 0.1, 0.0],
194                            ),
195                        ),
196                    )
197                    .var_as(
198                        "carol",
199                        g().add_n(
200                            "ParityUser",
201                            user_props(
202                                "user-carol",
203                                "Carol",
204                                42,
205                                64.0,
206                                "inactive",
207                                "Berlin",
208                                "Carol archives old records",
209                                vec![0.0, 1.0, 0.0],
210                            ),
211                        ),
212                    )
213                    .var_as(
214                        "alice_follows_bob",
215                        g().n(NodeRef::var("alice")).add_e(
216                            "FOLLOWS",
217                            NodeRef::var("bob"),
218                            vec![
219                                ("weight", PropertyInput::from(1.0f64)),
220                                ("since", PropertyInput::from("2024-01-01")),
221                                ("note", PropertyInput::from("Alice follows Bob")),
222                                (
223                                    "embedding",
224                                    PropertyInput::from(PropertyValue::from(vec![1.0f32, 0.0])),
225                                ),
226                            ],
227                        ),
228                    )
229                    .var_as(
230                        "bob_follows_carol",
231                        g().n(NodeRef::var("bob")).add_e(
232                            "FOLLOWS",
233                            NodeRef::var("carol"),
234                            vec![
235                                ("weight", PropertyInput::from(0.5f64)),
236                                ("since", PropertyInput::from("2024-02-01")),
237                                ("note", PropertyInput::from("Bob follows Carol")),
238                                (
239                                    "embedding",
240                                    PropertyInput::from(PropertyValue::from(vec![0.0f32, 1.0])),
241                                ),
242                            ],
243                        ),
244                    )
245                    .returning([
246                        "alice",
247                        "bob",
248                        "carol",
249                        "alice_follows_bob",
250                        "bob_follows_carol",
251                    ]),
252            ),
253        ),
254        runtime(
255            "002-read-count-all-users",
256            read_request(
257                read_batch()
258                    .var_as("user_count", g().n_with_label("ParityUser").count())
259                    .returning(["user_count"]),
260            ),
261        ),
262        runtime(
263            "003-read-source-predicate-and-count",
264            read_request(
265                read_batch()
266                    .var_as(
267                        "active_adults",
268                        g().n_with_label_where(
269                            "ParityUser",
270                            SourcePredicate::and(vec![
271                                SourcePredicate::eq("status", "active"),
272                                SourcePredicate::gte("age", 30i64),
273                            ]),
274                        )
275                        .count(),
276                    )
277                    .returning(["active_adults"]),
278            ),
279        ),
280        runtime(
281            "004-read-value-map-projection",
282            read_request(
283                read_batch()
284                    .var_as(
285                        "alice",
286                        g().n_with_label("ParityUser")
287                            .where_(Predicate::eq("externalId", "user-alice"))
288                            .project(vec![
289                                Projection::property("externalId", "id"),
290                                Projection::property("name", "name"),
291                                Projection::expr(
292                                    "score_plus_one",
293                                    Expr::prop("score").add(Expr::val(1.0f64)),
294                                ),
295                                Projection::expr(
296                                    "status_label",
297                                    Expr::case(
298                                        vec![(
299                                            Predicate::eq("status", "active"),
300                                            Expr::val("enabled"),
301                                        )],
302                                        Some(Expr::val("disabled")),
303                                    ),
304                                ),
305                            ]),
306                    )
307                    .returning(["alice"]),
308            ),
309        ),
310        runtime(
311            "005-read-order-range-values",
312            read_request(
313                read_batch()
314                    .var_as(
315                        "ordered",
316                        g().n_with_label("ParityUser")
317                            .order_by_multiple(vec![("status", Order::Asc), ("age", Order::Desc)])
318                            .range(0usize, 2usize)
319                            .value_map(Some(vec!["externalId", "age", "status"])),
320                    )
321                    .returning(["ordered"]),
322            ),
323        ),
324        runtime(
325            "006-read-edge-count",
326            read_request(
327                read_batch()
328                    .var_as(
329                        "edge_count",
330                        g().n_with_label("ParityUser")
331                            .where_(Predicate::eq("externalId", "user-alice"))
332                            .out_e(Some("FOLLOWS"))
333                            .count(),
334                    )
335                    .returning(["edge_count"]),
336            ),
337        ),
338        runtime(
339            "007-read-edge-properties",
340            read_request(
341                read_batch()
342                    .var_as(
343                        "edges",
344                        g().e_with_label("FOLLOWS")
345                            .edge_has("weight", PropertyInput::from(1.0f64))
346                            .edge_properties(),
347                    )
348                    .returning(["edges"]),
349            ),
350        ),
351        runtime(
352            "008-read-edge-endpoints",
353            read_request(
354                read_batch()
355                    .var_as(
356                        "from_nodes",
357                        g().e_with_label("FOLLOWS")
358                            .edge_has_label("FOLLOWS")
359                            .in_n()
360                            .value_map(Some(vec!["externalId", "name"])),
361                    )
362                    .var_as(
363                        "to_nodes",
364                        g().e_with_label("FOLLOWS")
365                            .out_n()
366                            .value_map(Some(vec!["externalId", "name"])),
367                    )
368                    .returning(["from_nodes", "to_nodes"]),
369            ),
370        ),
371        runtime(
372            "009-read-conditional-var-not-empty",
373            read_request(
374                read_batch()
375                    .var_as(
376                        "alice",
377                        g().n_with_label("ParityUser")
378                            .where_(Predicate::eq("externalId", "user-alice")),
379                    )
380                    .var_as_if(
381                        "friends",
382                        BatchCondition::VarNotEmpty("alice".to_string()),
383                        g().n(NodeRef::var("alice"))
384                            .out(Some("FOLLOWS"))
385                            .value_map(Some(vec!["externalId", "name"])),
386                    )
387                    .returning(["alice", "friends"]),
388            ),
389        ),
390        runtime(
391            "010-read-conditional-var-empty",
392            read_request(
393                read_batch()
394                    .var_as(
395                        "missing",
396                        g().n_with_label("ParityUser")
397                            .where_(Predicate::eq("externalId", "missing-user")),
398                    )
399                    .var_as_if(
400                        "fallback",
401                        BatchCondition::VarEmpty("missing".to_string()),
402                        g().n_with_label("ParityUser")
403                            .limit(1usize)
404                            .value_map(Some(vec!["externalId"])),
405                    )
406                    .returning(["missing", "fallback"]),
407            ),
408        ),
409        runtime(
410            "011-read-conditional-var-min-size-prev",
411            read_request(
412                read_batch()
413                    .var_as("users", g().n_with_label("ParityUser").limit(3usize))
414                    .var_as_if(
415                        "min_two",
416                        BatchCondition::VarMinSize("users".to_string(), 2),
417                        g().n(NodeRef::var("users")).count(),
418                    )
419                    .var_as_if(
420                        "prev_ok",
421                        BatchCondition::PrevNotEmpty,
422                        g().n(NodeRef::var("users")).exists(),
423                    )
424                    .returning(["min_two", "prev_ok"]),
425            ),
426        ),
427        runtime(
428            "012-read-foreach-param",
429            with_params(
430                read_request(
431                    read_batch()
432                        .for_each_param(
433                            "lookups",
434                            read_batch().var_as(
435                                "matched",
436                                g().n_with_label("ParityUser")
437                                    .where_(Predicate::eq_param("externalId", "externalId"))
438                                    .value_map(Some(vec!["externalId", "name"])),
439                            ),
440                        )
441                        .returning(["matched"]),
442                ),
443                vec![(
444                    "lookups",
445                    array(vec![
446                        object(vec![("externalId", string("user-alice"))]),
447                        object(vec![("externalId", string("user-carol"))]),
448                    ]),
449                )],
450                vec![(
451                    "lookups",
452                    QueryParamType::Array(Box::new(QueryParamType::Object)),
453                )],
454            ),
455        ),
456        runtime(
457            "013-write-foreach-param-create",
458            with_params(
459                write_request(
460                    write_batch()
461                        .for_each_param(
462                            "rows",
463                            write_batch().var_as(
464                                "created",
465                                g().add_n(
466                                    "ParityEvent",
467                                    vec![
468                                        ("eventId", PropertyInput::param("eventId")),
469                                        ("kind", PropertyInput::param("kind")),
470                                        ("score", PropertyInput::param("score")),
471                                    ],
472                                ),
473                            ),
474                        )
475                        .returning(["created"]),
476                ),
477                vec![(
478                    "rows",
479                    array(vec![
480                        object(vec![
481                            ("eventId", string("event-1")),
482                            ("kind", string("click")),
483                            ("score", i64_value(10)),
484                        ]),
485                        object(vec![
486                            ("eventId", string("event-2")),
487                            ("kind", string("view")),
488                            ("score", i64_value(5)),
489                        ]),
490                    ]),
491                )],
492                vec![(
493                    "rows",
494                    QueryParamType::Array(Box::new(QueryParamType::Object)),
495                )],
496            ),
497        ),
498        runtime(
499            "014-read-after-foreach-param",
500            read_request(
501                read_batch()
502                    .var_as("event_count", g().n_with_label("ParityEvent").count())
503                    .returning(["event_count"]),
504            ),
505        ),
506        runtime(
507            "015-write-set-remove-properties",
508            write_request(
509                write_batch()
510                    .var_as(
511                        "updated",
512                        g().n_with_label("ParityUser")
513                            .where_(Predicate::eq("externalId", "user-bob"))
514                            .set_property("status", PropertyInput::from("inactive"))
515                            .set_property(
516                                "updatedAt",
517                                PropertyInput::from(DateTime::from_millis(1_777_000_000_000)),
518                            )
519                            .remove_property("city")
520                            .count(),
521                    )
522                    .returning(["updated"]),
523            ),
524        ),
525        runtime(
526            "016-read-updated-properties",
527            read_request(
528                read_batch()
529                    .var_as(
530                        "bob",
531                        g().n_with_label("ParityUser")
532                            .where_(Predicate::eq("externalId", "user-bob"))
533                            .value_map(Some(vec!["externalId", "status", "updatedAt", "city"])),
534                    )
535                    .returning(["bob"]),
536            ),
537        ),
538        runtime(
539            "017-read-repeat-union",
540            read_request(
541                read_batch()
542                    .var_as(
543                        "walked",
544                        g().n_with_label("ParityUser")
545                            .where_(Predicate::eq("externalId", "user-alice"))
546                            .repeat(
547                                RepeatConfig::new(sub().out(Some("FOLLOWS")))
548                                    .times(2)
549                                    .emit_all()
550                                    .max_depth(4),
551                            )
552                            .union(vec![sub().out(Some("FOLLOWS")), sub().in_(Some("FOLLOWS"))])
553                            .dedup()
554                            .value_map(Some(vec!["externalId", "name"])),
555                    )
556                    .returning(["walked"]),
557            ),
558        ),
559        runtime(
560            "018-read-choose-coalesce-optional",
561            read_request(
562                read_batch()
563                    .var_as(
564                        "branched",
565                        g().n_with_label("ParityUser")
566                            .where_(Predicate::eq("externalId", "user-alice"))
567                            .choose(
568                                Predicate::eq("status", "active"),
569                                sub().out(Some("FOLLOWS")),
570                                Some(sub().in_(Some("FOLLOWS"))),
571                            )
572                            .coalesce(vec![sub().out(Some("FOLLOWS")), sub().in_(Some("FOLLOWS"))])
573                            .optional(sub().out(Some("FOLLOWS")))
574                            .dedup()
575                            .value_map(Some(vec!["externalId", "name"])),
576                    )
577                    .returning(["branched"]),
578            ),
579        ),
580        runtime(
581            "019-read-aggregations",
582            read_request(
583                read_batch()
584                    .var_as(
585                        "by_status",
586                        g().n_with_label("ParityUser").group_count("status"),
587                    )
588                    .var_as(
589                        "mean_score",
590                        g().n_with_label("ParityUser")
591                            .aggregate_by(AggregateFunction::Mean, "score"),
592                    )
593                    .var_as(
594                        "max_age",
595                        g().n_with_label("ParityUser")
596                            .aggregate_by(AggregateFunction::Max, "age"),
597                    )
598                    .returning(["by_status", "mean_score", "max_age"]),
599            ),
600        ),
601        runtime(
602            "020-write-index-create",
603            write_request(
604                write_batch()
605                    .var_as(
606                        "node_eq",
607                        g().create_index_if_not_exists(IndexSpec::node_equality(
608                            "ParityUser",
609                            "externalId",
610                        )),
611                    )
612                    .var_as(
613                        "node_range",
614                        g().create_index_if_not_exists(IndexSpec::node_range("ParityUser", "age")),
615                    )
616                    .var_as(
617                        "edge_eq",
618                        g().create_index_if_not_exists(IndexSpec::edge_equality(
619                            "FOLLOWS", "since",
620                        )),
621                    )
622                    .var_as(
623                        "edge_range",
624                        g().create_index_if_not_exists(IndexSpec::edge_range("FOLLOWS", "weight")),
625                    )
626                    .returning(["node_eq", "node_range", "edge_eq", "edge_range"]),
627            ),
628        ),
629        runtime(
630            "021-read-parameter-types",
631            with_params(
632                read_request(
633                    read_batch()
634                        .var_as(
635                            "matches",
636                            g().n_with_label("ParityUser")
637                                .where_(Predicate::is_in_param("status", "statuses"))
638                                .where_(Predicate::gte_param("createdAt", "created_after"))
639                                .limit(Expr::param("limit"))
640                                .value_map(Some(vec!["externalId", "status"])),
641                        )
642                        .returning(["matches"]),
643                ),
644                vec![
645                    (
646                        "statuses",
647                        array(vec![string("active"), string("inactive")]),
648                    ),
649                    ("created_after", string("2026-01-01T00:00:00.000Z")),
650                    ("limit", i64_value(5)),
651                ],
652                vec![
653                    (
654                        "statuses",
655                        QueryParamType::Array(Box::new(QueryParamType::String)),
656                    ),
657                    ("created_after", QueryParamType::DateTime),
658                    ("limit", QueryParamType::I64),
659                ],
660            ),
661        ),
662        runtime(
663            "022-write-property-value-variants",
664            write_request(
665                write_batch()
666                    .var_as(
667                        "variant_node",
668                        g().add_n(
669                            "ParityVariant",
670                            vec![
671                                ("nullValue", PropertyInput::from(PropertyValue::Null)),
672                                ("boolValue", PropertyInput::from(true)),
673                                (
674                                    "i64Value",
675                                    PropertyInput::from(9_223_372_036_854_775_000i64),
676                                ),
677                                (
678                                    "dateTimeValue",
679                                    PropertyInput::from(DateTime::from_millis(-1)),
680                                ),
681                                ("f64Value", PropertyInput::from(3.25f64)),
682                                ("f32Value", PropertyInput::from(1.5f32)),
683                                ("stringValue", PropertyInput::from("variant")),
684                                (
685                                    "bytesValue",
686                                    PropertyInput::from(PropertyValue::from(vec![1u8, 2u8, 3u8])),
687                                ),
688                                (
689                                    "i64Array",
690                                    PropertyInput::from(PropertyValue::from(vec![
691                                        1i64, 2i64, 3i64,
692                                    ])),
693                                ),
694                                (
695                                    "f64Array",
696                                    PropertyInput::from(PropertyValue::from(vec![1.0f64, 2.0f64])),
697                                ),
698                                (
699                                    "f32Array",
700                                    PropertyInput::from(PropertyValue::from(vec![1.0f32, 2.0f32])),
701                                ),
702                                (
703                                    "stringArray",
704                                    PropertyInput::from(PropertyValue::from(vec![
705                                        "a".to_string(),
706                                        "b".to_string(),
707                                    ])),
708                                ),
709                            ],
710                        ),
711                    )
712                    .returning(["variant_node"]),
713            ),
714        ),
715        runtime(
716            "023-read-property-value-variants",
717            read_request(
718                read_batch()
719                    .var_as(
720                        "variant",
721                        g().n_with_label("ParityVariant")
722                            .value_map(None::<Vec<&str>>),
723                    )
724                    .returning(["variant"]),
725            ),
726        ),
727        runtime(
728            "024-write-text-vector-indexes",
729            write_request(
730                write_batch()
731                    .var_as(
732                        "node_text",
733                        g().create_text_index_nodes("ParityUser", "bio", None::<&str>),
734                    )
735                    .var_as(
736                        "node_vector",
737                        g().create_vector_index_nodes("ParityUser", "embedding", None::<&str>),
738                    )
739                    .var_as(
740                        "edge_text",
741                        g().create_text_index_edges("FOLLOWS", "note", None::<&str>),
742                    )
743                    .var_as(
744                        "edge_vector",
745                        g().create_vector_index_edges("FOLLOWS", "embedding", None::<&str>),
746                    )
747                    .returning(["node_text", "node_vector", "edge_text", "edge_vector"]),
748            ),
749        ),
750        runtime(
751            "025-read-text-search-nodes",
752            read_request(
753                read_batch()
754                    .var_as(
755                        "text_hits",
756                        g().text_search_nodes("ParityUser", "bio", "graph", 5, None)
757                            .value_map(Some(vec!["externalId", "bio", "$distance"])),
758                    )
759                    .returning(["text_hits"]),
760            ),
761        ),
762        runtime(
763            "026-read-vector-search-nodes",
764            read_request(
765                read_batch()
766                    .var_as(
767                        "vector_hits",
768                        g().vector_search_nodes(
769                            "ParityUser",
770                            "embedding",
771                            vec![1.0, 0.0, 0.0],
772                            3,
773                            None,
774                        )
775                        .project(vec![
776                            Projection::property("externalId", "externalId"),
777                            Projection::property("$distance", "distance"),
778                        ]),
779                    )
780                    .returning(["vector_hits"]),
781            ),
782        ),
783        runtime(
784            "027-read-text-search-edges",
785            read_request(
786                read_batch()
787                    .var_as(
788                        "edge_text_hits",
789                        g().text_search_edges("FOLLOWS", "note", "follows", 5, None)
790                            .edge_properties(),
791                    )
792                    .returning(["edge_text_hits"]),
793            ),
794        ),
795        runtime(
796            "028-read-vector-search-edges",
797            read_request(
798                read_batch()
799                    .var_as(
800                        "edge_vector_hits",
801                        g().vector_search_edges("FOLLOWS", "embedding", vec![1.0, 0.0], 5, None)
802                            .edge_properties(),
803                    )
804                    .returning(["edge_vector_hits"]),
805            ),
806        ),
807        runtime(
808            "029-write-drop-temp-node",
809            write_request(
810                write_batch()
811                    .var_as(
812                        "temp",
813                        g().add_n("ParityTemp", vec![("name", PropertyInput::from("temp"))]),
814                    )
815                    .var_as("dropped", g().n(NodeRef::var("temp")).drop().count())
816                    .returning(["dropped"]),
817            ),
818        ),
819        runtime(
820            "030-read-final-counts",
821            read_request(
822                read_batch()
823                    .var_as("users", g().n_with_label("ParityUser").count())
824                    .var_as("events", g().n_with_label("ParityEvent").count())
825                    .var_as("variants", g().n_with_label("ParityVariant").count())
826                    .returning(["users", "events", "variants"]),
827            ),
828        ),
829        runtime(
830            "031-read-source-predicate-eq-param",
831            with_params(
832                read_request(
833                    read_batch()
834                        .var_as(
835                            "user",
836                            g().n_where(SourcePredicate::and(vec![
837                                SourcePredicate::eq("$label", "ParityUser"),
838                                SourcePredicate::eq("name", Expr::param("name")),
839                            ]))
840                            .value_map(Some(vec!["externalId", "name"])),
841                        )
842                        .returning(["user"]),
843                ),
844                vec![("name", string("Alice"))],
845                vec![("name", QueryParamType::String)],
846            ),
847        ),
848        runtime(
849            "032-read-source-predicate-between-param",
850            with_params(
851                read_request(
852                    read_batch()
853                        .var_as(
854                            "adults",
855                            g().n_where(SourcePredicate::and(vec![
856                                SourcePredicate::eq("$label", "ParityUser"),
857                                SourcePredicate::between("age", Expr::param("min_age"), 65i64),
858                            ]))
859                            .value_map(Some(vec!["externalId", "age"])),
860                        )
861                        .returning(["adults"]),
862                ),
863                vec![("min_age", i64_value(30))],
864                vec![("min_age", QueryParamType::I64)],
865            ),
866        ),
867    ]
868}
869
870fn node_permutation_fixtures() -> Vec<Fixture> {
871    let sources = ["label", "where", "all"];
872    let filters = ["none", "has", "logic", "expr"];
873    let bounds = ["none", "limit", "skip", "range"];
874    let terminals = ["count", "exists", "value_map", "project"];
875
876    let mut fixtures = Vec::new();
877    let mut index = 100;
878    for source in sources {
879        for filter in filters {
880            for bound in bounds {
881                for terminal in terminals {
882                    let name =
883                        format!("{index:03}-combo-node-{source}-{filter}-{bound}-{terminal}");
884                    index += 1;
885                    fixtures.push(runtime(
886                        name,
887                        read_request(node_combo_batch(source, filter, bound, terminal)),
888                    ));
889                }
890            }
891        }
892    }
893    fixtures
894}
895
896fn node_combo_batch(source: &str, filter: &str, bound: &str, terminal: &str) -> ReadBatch {
897    let traversal = apply_node_bound(apply_node_filter(node_source(source), filter), bound)
898        .order_by("externalId", Order::Asc);
899    let traversal = match terminal {
900        "count" => traversal.count(),
901        "exists" => traversal.exists(),
902        "value_map" => traversal.value_map(Some(vec!["externalId", "name", "age", "status"])),
903        "project" => traversal.project(vec![
904            Projection::property("externalId", "externalId"),
905            Projection::property("status", "status"),
906            Projection::expr("age_plus_two", Expr::prop("age").add(Expr::val(2i64))),
907        ]),
908        other => panic!("unknown terminal {other}"),
909    };
910    read_batch()
911        .var_as("result", traversal)
912        .returning(["result"])
913}
914
915fn node_source(source: &str) -> Traversal<OnNodes, ReadOnly> {
916    match source {
917        "label" => g().n_with_label("ParityUser"),
918        "where" => g().n_where(SourcePredicate::eq("$label", "ParityUser")),
919        "all" => g().n(NodeRef::all()).has_label("ParityUser"),
920        other => panic!("unknown source {other}"),
921    }
922}
923
924fn apply_node_filter(
925    traversal: Traversal<OnNodes, ReadOnly>,
926    filter: &str,
927) -> Traversal<OnNodes, ReadOnly> {
928    match filter {
929        "none" => traversal,
930        "has" => traversal.has("status", "active"),
931        "logic" => traversal.where_(Predicate::and(vec![
932            Predicate::has_key("externalId"),
933            Predicate::or(vec![
934                Predicate::starts_with("name", "A"),
935                Predicate::ends_with("name", "b"),
936            ]),
937            Predicate::not(Predicate::is_null("age")),
938        ])),
939        "expr" => traversal.where_(Predicate::compare(
940            Expr::prop("score").add(Expr::val(1.0f64)),
941            CompareOp::Gt,
942            Expr::val(65.0f64),
943        )),
944        other => panic!("unknown filter {other}"),
945    }
946}
947
948fn apply_node_bound(
949    traversal: Traversal<OnNodes, ReadOnly>,
950    bound: &str,
951) -> Traversal<OnNodes, ReadOnly> {
952    match bound {
953        "none" => traversal,
954        "limit" => traversal.limit(2usize),
955        "skip" => traversal.skip(1usize),
956        "range" => traversal.range(0usize, 2usize),
957        other => panic!("unknown bound {other}"),
958    }
959}
960
961fn json_only_fixtures() -> Vec<Fixture> {
962    vec![
963        json_only(
964            "900-exhaustive-raw-read-steps",
965            with_params(
966                read_request(
967                    read_batch()
968                        .var_as(
969                            "raw_nodes",
970                            Traversal::<OnNodes, ReadOnly>::from_steps(vec![
971                                Step::N(NodeRef::Param("node_ids".to_string())),
972                                Step::Has("name".to_string(), PropertyValue::from("Alice")),
973                                Step::Where(Predicate::contains_param("bio", "needle")),
974                                Step::LimitBy(Expr::param("limit")),
975                                Step::SkipBy(Expr::param("skip")),
976                                Step::RangeBy(
977                                    StreamBound::literal(0),
978                                    StreamBound::expr(Expr::param("end")),
979                                ),
980                                Step::As("a".to_string()),
981                                Step::Store("stored".to_string()),
982                                Step::Select("stored".to_string()),
983                                Step::Dedup,
984                                Step::Within("stored".to_string()),
985                                Step::Without("missing".to_string()),
986                                Step::Fold,
987                                Step::Unfold,
988                                Step::Path,
989                                Step::SimplePath,
990                                Step::WithSack(PropertyValue::from(0i64)),
991                                Step::SackSet("score".to_string()),
992                                Step::SackAdd("score".to_string()),
993                                Step::SackGet,
994                                Step::Project(vec![
995                                    Projection::property("externalId", "externalId"),
996                                    Projection::expr("neg_age", Expr::prop("age").neg()),
997                                ]),
998                            ]),
999                        )
1000                        .var_as(
1001                            "raw_edges",
1002                            Traversal::<helix_db::OnEdges, ReadOnly>::from_steps(vec![
1003                                Step::E(EdgeRef::Param("edge_ids".to_string())),
1004                                Step::EWhere(SourcePredicate::or(vec![
1005                                    SourcePredicate::has_key("since"),
1006                                    SourcePredicate::starts_with("note", "Alice"),
1007                                ])),
1008                                Step::OutN,
1009                                Step::InN,
1010                                Step::OtherN,
1011                                Step::EdgeHas("weight".to_string(), PropertyInput::from(1.0f64)),
1012                                Step::EdgeHasLabel("FOLLOWS".to_string()),
1013                                Step::OrderBy("weight".to_string(), Order::Desc),
1014                                Step::EdgeProperties,
1015                            ]),
1016                        )
1017                        .returning(["raw_nodes", "raw_edges"]),
1018                ),
1019                vec![
1020                    ("node_ids", array(vec![i64_value(1), i64_value(2)])),
1021                    ("edge_ids", array(vec![i64_value(1)])),
1022                    ("needle", string("graph")),
1023                    ("limit", i64_value(10)),
1024                    ("skip", i64_value(0)),
1025                    ("end", i64_value(10)),
1026                ],
1027                vec![
1028                    (
1029                        "node_ids",
1030                        QueryParamType::Array(Box::new(QueryParamType::I64)),
1031                    ),
1032                    (
1033                        "edge_ids",
1034                        QueryParamType::Array(Box::new(QueryParamType::I64)),
1035                    ),
1036                    ("needle", QueryParamType::String),
1037                    ("limit", QueryParamType::I64),
1038                    ("skip", QueryParamType::I64),
1039                    ("end", QueryParamType::I64),
1040                ],
1041            ),
1042        ),
1043        json_only(
1044            "901-exhaustive-raw-write-steps",
1045            write_request(
1046                write_batch()
1047                    .var_as(
1048                        "raw_indexes",
1049                        Traversal::<helix_db::Terminal, WriteEnabled>::from_steps(vec![
1050                            Step::CreateIndex {
1051                                spec: IndexSpec::node_unique_equality("ParityUser", "externalId"),
1052                                if_not_exists: true,
1053                            },
1054                            Step::DropIndex {
1055                                spec: IndexSpec::node_range("ParityUser", "age"),
1056                            },
1057                            Step::CreateVectorIndexNodes {
1058                                label: "ParityUser".to_string(),
1059                                property: "embedding".to_string(),
1060                                tenant_property: Some("tenantId".to_string()),
1061                            },
1062                            Step::CreateVectorIndexEdges {
1063                                label: "FOLLOWS".to_string(),
1064                                property: "embedding".to_string(),
1065                                tenant_property: Some("tenantId".to_string()),
1066                            },
1067                            Step::CreateTextIndexNodes {
1068                                label: "ParityUser".to_string(),
1069                                property: "bio".to_string(),
1070                                tenant_property: Some("tenantId".to_string()),
1071                            },
1072                            Step::CreateTextIndexEdges {
1073                                label: "FOLLOWS".to_string(),
1074                                property: "note".to_string(),
1075                                tenant_property: Some("tenantId".to_string()),
1076                            },
1077                        ]),
1078                    )
1079                    .var_as(
1080                        "raw_mutations",
1081                        Traversal::<OnNodes, WriteEnabled>::from_steps(vec![
1082                            Step::AddN {
1083                                label: "RawNode".to_string(),
1084                                properties: vec![("name".to_string(), PropertyInput::from("raw"))],
1085                            },
1086                            Step::AddE {
1087                                label: "RAW_EDGE".to_string(),
1088                                to: NodeRef::Var("raw_mutations".to_string()),
1089                                properties: vec![("weight".to_string(), PropertyInput::from(1i64))],
1090                            },
1091                            Step::SetProperty(
1092                                "name".to_string(),
1093                                PropertyInput::Expr(Expr::param("name")),
1094                            ),
1095                            Step::RemoveProperty("old".to_string()),
1096                            Step::DropEdge(NodeRef::Ids(vec![999_999])),
1097                            Step::DropEdgeLabeled {
1098                                to: NodeRef::Ids(vec![999_999]),
1099                                label: "RAW_EDGE".to_string(),
1100                            },
1101                            Step::DropEdgeById(EdgeRef::Ids(vec![999_999])),
1102                            Step::Drop,
1103                        ]),
1104                    )
1105                    .returning(["raw_indexes", "raw_mutations"]),
1106            ),
1107        ),
1108        json_only(
1109            "902-dynamic-value-and-param-type-shapes",
1110            with_params(
1111                read_request(
1112                    read_batch()
1113                        .var_as("empty", g().n_with_label("Missing").count())
1114                        .returning(["empty"]),
1115                ),
1116                vec![
1117                    ("null", DynamicQueryValue::Null),
1118                    ("bool", DynamicQueryValue::Bool(true)),
1119                    ("i64", DynamicQueryValue::I64(i64::MAX)),
1120                    ("f64", DynamicQueryValue::F64(1.25)),
1121                    ("f32", DynamicQueryValue::F32(1.5)),
1122                    ("string", string("value")),
1123                    ("array", array(vec![i64_value(1), string("two")])),
1124                    (
1125                        "object",
1126                        object(vec![("nested", DynamicQueryValue::Bool(true))]),
1127                    ),
1128                ],
1129                vec![
1130                    ("null", QueryParamType::Value),
1131                    ("bool", QueryParamType::Bool),
1132                    ("i64", QueryParamType::I64),
1133                    ("f64", QueryParamType::F64),
1134                    ("f32", QueryParamType::F32),
1135                    ("string", QueryParamType::String),
1136                    (
1137                        "array",
1138                        QueryParamType::Array(Box::new(QueryParamType::Value)),
1139                    ),
1140                    ("object", QueryParamType::Object),
1141                ],
1142            ),
1143        ),
1144        json_only(
1145            "903-empty-source-vector-text-runtime-inputs",
1146            with_params(
1147                read_request(
1148                    read_batch()
1149                        .var_as(
1150                            "vector_nodes",
1151                            g().vector_search_nodes_with(
1152                                "ParityUser",
1153                                "embedding",
1154                                PropertyInput::param("query_vector"),
1155                                Expr::param("limit"),
1156                                Some(PropertyInput::param("tenant")),
1157                            ),
1158                        )
1159                        .var_as(
1160                            "text_nodes",
1161                            g().text_search_nodes_with(
1162                                "ParityUser",
1163                                "bio",
1164                                PropertyInput::param("query_text"),
1165                                Expr::param("limit"),
1166                                Some(PropertyInput::param("tenant")),
1167                            ),
1168                        )
1169                        .returning(["vector_nodes", "text_nodes"]),
1170                ),
1171                vec![
1172                    (
1173                        "query_vector",
1174                        array(vec![f64_value(1.0), f64_value(0.0), f64_value(0.0)]),
1175                    ),
1176                    ("query_text", string("graph")),
1177                    ("limit", i64_value(5)),
1178                    ("tenant", string("tenant-a")),
1179                ],
1180                vec![
1181                    (
1182                        "query_vector",
1183                        QueryParamType::Array(Box::new(QueryParamType::F64)),
1184                    ),
1185                    ("query_text", QueryParamType::String),
1186                    ("limit", QueryParamType::I64),
1187                    ("tenant", QueryParamType::String),
1188                ],
1189            ),
1190        ),
1191        json_only(
1192            "904-empty-query-and-node-edge-ref-shapes",
1193            read_request(
1194                read_batch()
1195                    .var_as(
1196                        "all_nodes",
1197                        Traversal::<OnNodes, ReadOnly>::from_steps(vec![
1198                            Step::N(NodeRef::All),
1199                            Step::Count,
1200                        ]),
1201                    )
1202                    .var_as(
1203                        "node_ids",
1204                        Traversal::<OnNodes, ReadOnly>::from_steps(vec![
1205                            Step::N(NodeRef::ids([1, 2])),
1206                            Step::Id,
1207                        ]),
1208                    )
1209                    .var_as(
1210                        "node_var",
1211                        Traversal::<OnNodes, ReadOnly>::from_steps(vec![
1212                            Step::N(NodeRef::Var("all_nodes".to_string())),
1213                            Step::Label,
1214                        ]),
1215                    )
1216                    .var_as(
1217                        "edge_ids",
1218                        Traversal::<helix_db::OnEdges, ReadOnly>::from_steps(vec![
1219                            Step::E(EdgeRef::ids([1, 2])),
1220                            Step::Id,
1221                        ]),
1222                    )
1223                    .var_as(
1224                        "edge_var",
1225                        Traversal::<helix_db::OnEdges, ReadOnly>::from_steps(vec![
1226                            Step::E(EdgeRef::Var("edge_ids".to_string())),
1227                            Step::Label,
1228                        ]),
1229                    )
1230                    .returning(["all_nodes", "node_ids", "node_var", "edge_ids", "edge_var"]),
1231            ),
1232        ),
1233        json_only(
1234            "905-empty-traversal-source-mutators",
1235            write_request(
1236                write_batch()
1237                    .var_as(
1238                        "inject",
1239                        Traversal::<Empty, ReadOnly>::new()
1240                            .inject("some_var")
1241                            .count(),
1242                    )
1243                    .var_as(
1244                        "drop_edge_by_id",
1245                        g().drop_edge_by_id(EdgeRef::id(123_456)).count(),
1246                    )
1247                    .returning(["inject", "drop_edge_by_id"]),
1248            ),
1249        ),
1250        json_only(
1251            "906-nested-dynamic-property-write-shapes",
1252            with_params(
1253                write_request(
1254                    write_batch()
1255                        .var_as(
1256                            "created",
1257                            g().add_n(
1258                                "ParityNested",
1259                                vec![
1260                                    ("name", PropertyInput::from("nested")),
1261                                    (
1262                                        "metadata",
1263                                        PropertyInput::from(nested_metadata_property(
1264                                            "some_id", 20,
1265                                        )),
1266                                    ),
1267                                ],
1268                            ),
1269                        )
1270                        .var_as(
1271                            "updated",
1272                            g().n(NodeRef::var("created"))
1273                                .set_property("metadata", PropertyInput::param("metadata"))
1274                                .value_map(Some(vec!["metadata.externalID"])),
1275                        )
1276                        .var_as(
1277                            "target",
1278                            g().add_n(
1279                                "ParityNestedTarget",
1280                                vec![("name", PropertyInput::from("target"))],
1281                            ),
1282                        )
1283                        .var_as(
1284                            "edge",
1285                            g().n(NodeRef::var("created"))
1286                                .add_e(
1287                                    "NESTED_LINK",
1288                                    NodeRef::var("target"),
1289                                    vec![(
1290                                        "metadata",
1291                                        PropertyInput::from(nested_metadata_property("edge_id", 5)),
1292                                    )],
1293                                )
1294                                .count(),
1295                        )
1296                        .returning(["created", "updated", "edge"]),
1297                ),
1298                vec![("metadata", nested_metadata_param("param_id", 22))],
1299                vec![("metadata", QueryParamType::Object)],
1300            ),
1301        ),
1302        json_only(
1303            "907-nested-dynamic-property-read-shapes",
1304            with_params(
1305                read_request(
1306                    read_batch()
1307                        .var_as(
1308                            "nested_users",
1309                            g().n_where(SourcePredicate::and(vec![
1310                                SourcePredicate::eq("$label", "ParityNested"),
1311                                SourcePredicate::eq(
1312                                    "metadata.externalID",
1313                                    Expr::param("external_id"),
1314                                ),
1315                            ]))
1316                            .where_(Predicate::compare(
1317                                Expr::prop("metadata.score"),
1318                                CompareOp::Gt,
1319                                Expr::val(10i64),
1320                            ))
1321                            .order_by_multiple(vec![
1322                                ("metadata.score", Order::Desc),
1323                                ("name", Order::Asc),
1324                            ])
1325                            .project(vec![
1326                                Projection::property("metadata.externalID", "external_id"),
1327                                Projection::expr("score_copy", Expr::prop("metadata.score")),
1328                            ]),
1329                        )
1330                        .var_as(
1331                            "nested_values",
1332                            g().n_with_label("ParityNested")
1333                                .values(vec!["metadata.externalID"]),
1334                        )
1335                        .var_as(
1336                            "nested_map",
1337                            g().n_with_label("ParityNested")
1338                                .value_map(Some(vec!["metadata.externalID", "metadata.score"])),
1339                        )
1340                        .var_as(
1341                            "nested_edges",
1342                            g().e_where(SourcePredicate::and(vec![
1343                                SourcePredicate::eq("$label", "NESTED_LINK"),
1344                                SourcePredicate::eq("metadata.externalID", "edge_id"),
1345                            ]))
1346                            .edge_has("metadata.externalID", PropertyInput::from("edge_id"))
1347                            .edge_properties(),
1348                        )
1349                        .returning([
1350                            "nested_users",
1351                            "nested_values",
1352                            "nested_map",
1353                            "nested_edges",
1354                        ]),
1355                ),
1356                vec![("external_id", string("param_id"))],
1357                vec![("external_id", QueryParamType::String)],
1358            ),
1359        ),
1360        json_only(
1361            "908-edge-endpoint-projection",
1362            read_request(
1363                read_batch()
1364                    .var_as(
1365                        "endpoints",
1366                        g().e_with_label("FOLLOWS").project(vec![
1367                            Projection::from_endpoint("externalId", "from_id"),
1368                            Projection::to_endpoint("externalId", "to_id"),
1369                            Projection::property("$id", "edge_id"),
1370                        ]),
1371                    )
1372                    .returning(["endpoints"]),
1373            ),
1374        ),
1375        json_only(
1376            "909-row-binding-basic-projection",
1377            read_request(
1378                read_batch()
1379                    .var_as(
1380                        "bindings",
1381                        g().n_with_label("ParityService")
1382                            .bind("service")
1383                            .project_bindings(vec![
1384                                BindingProjection::binding("service", "$id", "service_id"),
1385                                BindingProjection::current("metadata.name", "current_name"),
1386                                BindingProjection::binding(
1387                                    "missing_binding",
1388                                    "externalId",
1389                                    "missing_external_id",
1390                                ),
1391                            ]),
1392                    )
1393                    .returning(["bindings"]),
1394            ),
1395        ),
1396        json_only(
1397            "910-row-binding-branch-distinct-projection",
1398            read_request(
1399                read_batch()
1400                    .var_as(
1401                        "workloads",
1402                        g().n_with_label("ParityService")
1403                            .bind("service")
1404                            .out(Some("ROUTES_TO"))
1405                            .bind("pod")
1406                            .optional(sub().in_(Some("CREATES")).bind("deployment"))
1407                            .union(vec![
1408                                sub().in_(Some("MANAGES")).bind("owner"),
1409                                sub().out(Some("ROUTES_TO")).bind("workload"),
1410                            ])
1411                            .project_distinct_bindings(vec![
1412                                BindingProjection::binding("service", "$id", "service_id"),
1413                                BindingProjection::coalesce(
1414                                    vec![
1415                                        BindingValueRef::binding("deployment", "$id"),
1416                                        BindingValueRef::binding("owner", "$id"),
1417                                        BindingValueRef::binding("workload", "$id"),
1418                                    ],
1419                                    "workload_id",
1420                                ),
1421                            ]),
1422                    )
1423                    .returning(["workloads"]),
1424            ),
1425        ),
1426        json_only(
1427            "911-range-index-direction",
1428            write_request(
1429                write_batch()
1430                    .var_as(
1431                        "node_desc",
1432                        g().create_index_if_not_exists(IndexSpec::node_range_desc(
1433                            "ParityUser",
1434                            "age",
1435                        )),
1436                    )
1437                    .var_as(
1438                        "edge_desc",
1439                        g().create_index_if_not_exists(IndexSpec::edge_range_desc(
1440                            "FOLLOWS", "weight",
1441                        )),
1442                    )
1443                    .var_as(
1444                        "node_asc",
1445                        g().create_index_if_not_exists(IndexSpec::node_range(
1446                            "ParityUser",
1447                            "score",
1448                        )),
1449                    )
1450                    .returning(["node_desc", "edge_desc", "node_asc"]),
1451            ),
1452        ),
1453    ]
1454}

Trait Implementations§

Source§

impl Clone for ReadBatch

Source§

fn clone(&self) -> ReadBatch

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ReadBatch

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for ReadBatch

Source§

fn default() -> ReadBatch

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for ReadBatch

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl PartialEq for ReadBatch

Source§

fn eq(&self, other: &ReadBatch) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for ReadBatch

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for ReadBatch

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> MaybeSendSync for T

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more