From ddaeda16bf4a8ff65f2e6abae67cf6513f70d5bb Mon Sep 17 00:00:00 2001 From: qishipengqsp Date: Wed, 27 May 2026 17:48:30 +0800 Subject: [PATCH 1/7] feat(storage): add vertex/edge id allocators Add monotonic AtomicU64 counters on MemoryGraph so callers that don't supply explicit ids (notably the upcoming GQL INSERT executor) can ask storage for fresh ones. Counters start at 1, are observed past any externally provided id inside create_vertex/create_edge, and are positioned past the largest replayed id during WAL replay and checkpoint restore so allocator output never collides with persisted state. Co-Authored-By: Claude Opus 4.7 --- minigu/storage/src/tp/checkpoint.rs | 2 + minigu/storage/src/tp/memory_graph.rs | 70 ++++++++++++++++++++++++++- 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/minigu/storage/src/tp/checkpoint.rs b/minigu/storage/src/tp/checkpoint.rs index e7d38624c..a0e483182 100644 --- a/minigu/storage/src/tp/checkpoint.rs +++ b/minigu/storage/src/tp/checkpoint.rs @@ -220,6 +220,7 @@ impl GraphCheckpoint { drop(current); graph.vertices.insert(*vid, versioned_vertex); + graph.observe_vertex_id(*vid); } // Restore edges @@ -231,6 +232,7 @@ impl GraphCheckpoint { drop(current); graph.edges.insert(*eid, versioned_edge); + graph.observe_edge_id(*eid); } // Restore adjacency list diff --git a/minigu/storage/src/tp/memory_graph.rs b/minigu/storage/src/tp/memory_graph.rs index be0a259b3..4a2a11e13 100644 --- a/minigu/storage/src/tp/memory_graph.rs +++ b/minigu/storage/src/tp/memory_graph.rs @@ -1,6 +1,6 @@ use std::collections::HashSet; use std::path::Path; -use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::atomic::{AtomicU64, AtomicUsize, Ordering}; use std::sync::{Arc, RwLock, Weak}; use arrow::array::BooleanArray; @@ -397,6 +397,15 @@ pub struct MemoryGraph { // ---- WAL entries counter since last checkpoint ---- wal_entries_since_checkpoint: AtomicUsize, + // ---- ID allocators for INSERT statements ---- + // These counters hand out fresh vertex/edge IDs to the executor when a GQL + // `INSERT` statement does not provide explicit IDs. They are bumped via + // `fetch_add(1, ..)` so concurrent inserts get distinct IDs. Recovery + // resets each counter to one past the largest replayed ID so we don't + // collide with persisted state. + next_vertex_id: AtomicU64, + next_edge_id: AtomicU64, + // ---- Vector indices ---- pub(super) vector_indices: DashMap>>>, } @@ -634,6 +643,8 @@ impl MemoryGraph { checkpoint_lock: RwLock::new(()), checkpoint_config, wal_entries_since_checkpoint: AtomicUsize::new(0), + next_vertex_id: AtomicU64::new(1), + next_edge_id: AtomicU64::new(1), vector_indices: DashMap::new(), }); @@ -700,9 +711,11 @@ impl MemoryGraph { if let Some(txn) = txn.as_ref() { match delta { DeltaOp::CreateVertex(vertex) => { + self.observe_vertex_id(vertex.vid()); self.create_vertex(txn, vertex)?; } DeltaOp::CreateEdge(edge) => { + self.observe_edge_id(edge.eid()); self.create_edge(txn, edge)?; } DeltaOp::DelVertex(vid) => { @@ -798,6 +811,56 @@ impl MemoryGraph { &self.txn_manager } + /// Allocates a fresh vertex id for INSERT statements. IDs start at 1 and + /// are monotonically increasing within a graph instance. After recovery + /// the counter is positioned past the largest persisted id. + pub fn alloc_vertex_id(&self) -> VertexId { + self.next_vertex_id.fetch_add(1, Ordering::Relaxed) + } + + /// Allocates a fresh edge id. See [`alloc_vertex_id`] for semantics. + pub fn alloc_edge_id(&self) -> EdgeId { + self.next_edge_id.fetch_add(1, Ordering::Relaxed) + } + + /// Bumps the vertex id counter so that any future [`alloc_vertex_id`] call + /// returns a value strictly greater than `seen`. No-op if the counter is + /// already ahead. + pub fn observe_vertex_id(&self, seen: VertexId) { + let target = seen.saturating_add(1); + loop { + let current = self.next_vertex_id.load(Ordering::Relaxed); + if current >= target { + return; + } + if self + .next_vertex_id + .compare_exchange_weak(current, target, Ordering::Relaxed, Ordering::Relaxed) + .is_ok() + { + return; + } + } + } + + /// Like [`observe_vertex_id`] but for edge ids. + pub fn observe_edge_id(&self, seen: EdgeId) { + let target = seen.saturating_add(1); + loop { + let current = self.next_edge_id.load(Ordering::Relaxed); + if current >= target { + return; + } + if self + .next_edge_id + .compare_exchange_weak(current, target, Ordering::Relaxed, Ordering::Relaxed) + .is_ok() + { + return; + } + } + } + /// Returns a reference to the vertices storage. pub(super) fn vertices(&self) -> &DashMap { &self.vertices @@ -1002,6 +1065,9 @@ impl MemoryGraph { vertex: Vertex, ) -> StorageResult { let vid = vertex.vid(); + // Keep the allocator monotone with any externally supplied id so a + // future `alloc_vertex_id()` call cannot collide with this one. + self.observe_vertex_id(vid); // NOTE: Vertex IDs are not reusable once tombstoned. if let Some(entry) = self.vertices.get(&vid) && entry.chain.current.read().unwrap().data.is_tombstone() @@ -1084,6 +1150,8 @@ impl MemoryGraph { let src_id = edge.src_id(); let dst_id = edge.dst_id(); let label_id = edge.label_id(); + // Keep the allocator monotone with any externally supplied id. + self.observe_edge_id(eid); // Check if the source/destination vertices and the edge exist self.get_vertex(txn, edge.src_id())?; From f69ee9d69c533505555fb997d62f61dcc172be22 Mon Sep 17 00:00:00 2001 From: qishipengqsp Date: Wed, 27 May 2026 18:56:54 +0800 Subject: [PATCH 2/7] feat(parser): add INSERT statement AST and parser Replace the empty LinearDataModifyingStatement stub with a real DataModifyingStatement enum carrying InsertStatement, where each path is a list of alternating node/edge ElementPatterns reusing the existing ElementPattern/Filler/Predicate AST (so labels, properties, and variables share the parser code with MATCH). The parser dispatches on the INSERT keyword and parses `node (edge node)*` chains separated by commas. No quantifiers, alternation, or path prefix are accepted -- INSERT only takes simple shapes in this iteration. Snapshot tests cover single vertex, multiple vertices, vertex+edge, and reverse-direction edge. Co-Authored-By: Claude Opus 4.7 --- minigu/gql/parser/src/ast/data.rs | 24 +++- minigu/gql/parser/src/parser/impls/data.rs | 97 +++++++++++++++-- ...data__tests__insert_multiple_vertices.snap | 75 +++++++++++++ ...pls__data__tests__insert_reverse_edge.snap | 83 ++++++++++++++ ...ls__data__tests__insert_single_vertex.snap | 60 ++++++++++ ...ata__tests__insert_vertex_edge_vertex.snap | 103 ++++++++++++++++++ 6 files changed, 434 insertions(+), 8 deletions(-) create mode 100644 minigu/gql/parser/src/parser/impls/snapshots/gql_parser__parser__impls__data__tests__insert_multiple_vertices.snap create mode 100644 minigu/gql/parser/src/parser/impls/snapshots/gql_parser__parser__impls__data__tests__insert_reverse_edge.snap create mode 100644 minigu/gql/parser/src/parser/impls/snapshots/gql_parser__parser__impls__data__tests__insert_single_vertex.snap create mode 100644 minigu/gql/parser/src/parser/impls/snapshots/gql_parser__parser__impls__data__tests__insert_vertex_edge_vertex.snap diff --git a/minigu/gql/parser/src/ast/data.rs b/minigu/gql/parser/src/ast/data.rs index 9add26760..404987eaf 100644 --- a/minigu/gql/parser/src/ast/data.rs +++ b/minigu/gql/parser/src/ast/data.rs @@ -1,6 +1,28 @@ //! AST definitions for *data-modifying statements*. +use super::{ElementPattern}; use crate::macros::base; +use crate::span::{Spanned, VecSpanned}; +pub type LinearDataModifyingStatement = VecSpanned; + +#[apply(base)] +pub enum DataModifyingStatement { + Insert(InsertStatement), +} + +/// `INSERT (, )*` +#[apply(base)] +pub struct InsertStatement { + pub paths: VecSpanned, +} + +/// A single insert path: alternating node and edge patterns, +/// e.g. `(a:L{...})` or `(a)-[:R{...}]->(b)`. +/// +/// Elements are reused from `ElementPattern` so we share the existing parser and +/// label/property/variable AST. #[apply(base)] -pub struct LinearDataModifyingStatement {} +pub struct InsertPath { + pub elements: VecSpanned, +} diff --git a/minigu/gql/parser/src/parser/impls/data.rs b/minigu/gql/parser/src/parser/impls/data.rs index 23390b001..a955415a4 100644 --- a/minigu/gql/parser/src/parser/impls/data.rs +++ b/minigu/gql/parser/src/parser/impls/data.rs @@ -1,17 +1,64 @@ -use winnow::combinator::{delimited, fail, opt, preceded, separated, seq}; +use winnow::combinator::{dispatch, fail, opt, peek, preceded, repeat, separated}; use winnow::{ModalResult, Parser}; -use super::lexical::{binding_variable, field_name}; -use crate::ast::{Ident, LinearDataModifyingStatement, Procedure, SchemaRef, Yield, YieldItem}; +use super::common::{edge_pattern, node_pattern}; +use crate::ast::{ + DataModifyingStatement, ElementPattern, InsertPath, InsertStatement, + LinearDataModifyingStatement, +}; use crate::lexer::TokenKind; -use crate::parser::token::TokenStream; -use crate::parser::utils::{SpannedParserExt, ToSpanned, def_parser_alias}; -use crate::span::Spanned; +use crate::parser::token::{TokenStream, any}; +use crate::parser::utils::{SpannedParserExt, ToSpanned}; +use crate::span::{Spanned, VecSpanned}; pub fn linear_data_modifying_statement( input: &mut TokenStream, ) -> ModalResult> { - fail(input) + repeat(1.., simple_data_modifying_statement) + .map(|v: Vec<_>| v) + .spanned() + .parse_next(input) +} + +fn simple_data_modifying_statement( + input: &mut TokenStream, +) -> ModalResult> { + dispatch! {peek(any); + TokenKind::Insert => insert_statement.map_inner(DataModifyingStatement::Insert), + _ => fail, + } + .parse_next(input) +} + +fn insert_statement(input: &mut TokenStream) -> ModalResult> { + preceded( + TokenKind::Insert, + separated(1.., insert_path, TokenKind::Comma).map(|v: Vec<_>| v), + ) + .map(|paths| InsertStatement { paths }) + .spanned() + .parse_next(input) +} + +/// A single insert path: a node followed by zero or more `edge node` pairs. +fn insert_path(input: &mut TokenStream) -> ModalResult> { + ( + node_pattern, + repeat(0.., (edge_pattern, node_pattern)).map( + |pairs: Vec<(Spanned, Spanned)>| pairs, + ), + ) + .map(|(first, rest)| { + let mut elements: VecSpanned = Vec::with_capacity(1 + rest.len() * 2); + elements.push(first); + for (e, n) in rest { + elements.push(e); + elements.push(n); + } + InsertPath { elements } + }) + .spanned() + .parse_next(input) } #[cfg(all(test, feature = "serde"))] @@ -20,4 +67,40 @@ mod tests { use super::*; use crate::parser::utils::parse; + + #[test] + fn test_insert_single_vertex() { + let parsed = parse!( + linear_data_modifying_statement, + "INSERT (a:PERSON {name: 'Alice', age: 30})" + ); + assert_yaml_snapshot!(parsed.unwrap()); + } + + #[test] + fn test_insert_multiple_vertices() { + let parsed = parse!( + linear_data_modifying_statement, + "INSERT (a:PERSON {name: 'A'}), (b:COMPANY {name: 'B'})" + ); + assert_yaml_snapshot!(parsed.unwrap()); + } + + #[test] + fn test_insert_vertex_edge_vertex() { + let parsed = parse!( + linear_data_modifying_statement, + "INSERT (a:PERSON {name: 'A'})-[:KNOWS {since: 2020}]->(b:PERSON {name: 'B'})" + ); + assert_yaml_snapshot!(parsed.unwrap()); + } + + #[test] + fn test_insert_reverse_edge() { + let parsed = parse!( + linear_data_modifying_statement, + "INSERT (a:PERSON {name: 'A'})<-[:KNOWS]-(b:PERSON {name: 'B'})" + ); + assert_yaml_snapshot!(parsed.unwrap()); + } } diff --git a/minigu/gql/parser/src/parser/impls/snapshots/gql_parser__parser__impls__data__tests__insert_multiple_vertices.snap b/minigu/gql/parser/src/parser/impls/snapshots/gql_parser__parser__impls__data__tests__insert_multiple_vertices.snap new file mode 100644 index 000000000..831d62c0e --- /dev/null +++ b/minigu/gql/parser/src/parser/impls/snapshots/gql_parser__parser__impls__data__tests__insert_multiple_vertices.snap @@ -0,0 +1,75 @@ +--- +source: minigu/gql/parser/src/parser/impls/data.rs +assertion_line: 86 +expression: parsed.unwrap() +--- +- - - Insert: + paths: + - - elements: + - - Node: + variable: + - a + - start: 8 + end: 9 + label: + - Label: PERSON + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - name + - start: 18 + end: 22 + value: + - Value: + Literal: + String: + kind: Char + literal: A + - start: 24 + end: 27 + - start: 18 + end: 27 + - start: 17 + end: 28 + - start: 7 + end: 29 + - start: 7 + end: 29 + - - elements: + - - Node: + variable: + - b + - start: 32 + end: 33 + label: + - Label: COMPANY + - start: 34 + end: 41 + predicate: + - Property: + - - name: + - name + - start: 43 + end: 47 + value: + - Value: + Literal: + String: + kind: Char + literal: B + - start: 49 + end: 52 + - start: 43 + end: 52 + - start: 42 + end: 53 + - start: 31 + end: 54 + - start: 31 + end: 54 + - start: 0 + end: 54 +- start: 0 + end: 54 diff --git a/minigu/gql/parser/src/parser/impls/snapshots/gql_parser__parser__impls__data__tests__insert_reverse_edge.snap b/minigu/gql/parser/src/parser/impls/snapshots/gql_parser__parser__impls__data__tests__insert_reverse_edge.snap new file mode 100644 index 000000000..1938f70d9 --- /dev/null +++ b/minigu/gql/parser/src/parser/impls/snapshots/gql_parser__parser__impls__data__tests__insert_reverse_edge.snap @@ -0,0 +1,83 @@ +--- +source: minigu/gql/parser/src/parser/impls/data.rs +assertion_line: 104 +expression: parsed.unwrap() +--- +- - - Insert: + paths: + - - elements: + - - Node: + variable: + - a + - start: 8 + end: 9 + label: + - Label: PERSON + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - name + - start: 18 + end: 22 + value: + - Value: + Literal: + String: + kind: Char + literal: A + - start: 24 + end: 27 + - start: 18 + end: 27 + - start: 17 + end: 28 + - start: 7 + end: 29 + - - Edge: + kind: Left + filler: + variable: ~ + label: + - Label: KNOWS + - start: 33 + end: 38 + predicate: ~ + - start: 29 + end: 40 + - - Node: + variable: + - b + - start: 41 + end: 42 + label: + - Label: PERSON + - start: 43 + end: 49 + predicate: + - Property: + - - name: + - name + - start: 51 + end: 55 + value: + - Value: + Literal: + String: + kind: Char + literal: B + - start: 57 + end: 60 + - start: 51 + end: 60 + - start: 50 + end: 61 + - start: 40 + end: 62 + - start: 7 + end: 62 + - start: 0 + end: 62 +- start: 0 + end: 62 diff --git a/minigu/gql/parser/src/parser/impls/snapshots/gql_parser__parser__impls__data__tests__insert_single_vertex.snap b/minigu/gql/parser/src/parser/impls/snapshots/gql_parser__parser__impls__data__tests__insert_single_vertex.snap new file mode 100644 index 000000000..97f147030 --- /dev/null +++ b/minigu/gql/parser/src/parser/impls/snapshots/gql_parser__parser__impls__data__tests__insert_single_vertex.snap @@ -0,0 +1,60 @@ +--- +source: minigu/gql/parser/src/parser/impls/data.rs +assertion_line: 77 +expression: parsed.unwrap() +--- +- - - Insert: + paths: + - - elements: + - - Node: + variable: + - a + - start: 8 + end: 9 + label: + - Label: PERSON + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - name + - start: 18 + end: 22 + value: + - Value: + Literal: + String: + kind: Char + literal: Alice + - start: 24 + end: 31 + - start: 18 + end: 31 + - - name: + - age + - start: 33 + end: 36 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "30" + - start: 38 + end: 40 + - start: 38 + end: 40 + - start: 33 + end: 40 + - start: 17 + end: 41 + - start: 7 + end: 42 + - start: 7 + end: 42 + - start: 0 + end: 42 +- start: 0 + end: 42 diff --git a/minigu/gql/parser/src/parser/impls/snapshots/gql_parser__parser__impls__data__tests__insert_vertex_edge_vertex.snap b/minigu/gql/parser/src/parser/impls/snapshots/gql_parser__parser__impls__data__tests__insert_vertex_edge_vertex.snap new file mode 100644 index 000000000..a6eea00a2 --- /dev/null +++ b/minigu/gql/parser/src/parser/impls/snapshots/gql_parser__parser__impls__data__tests__insert_vertex_edge_vertex.snap @@ -0,0 +1,103 @@ +--- +source: minigu/gql/parser/src/parser/impls/data.rs +assertion_line: 95 +expression: parsed.unwrap() +--- +- - - Insert: + paths: + - - elements: + - - Node: + variable: + - a + - start: 8 + end: 9 + label: + - Label: PERSON + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - name + - start: 18 + end: 22 + value: + - Value: + Literal: + String: + kind: Char + literal: A + - start: 24 + end: 27 + - start: 18 + end: 27 + - start: 17 + end: 28 + - start: 7 + end: 29 + - - Edge: + kind: Right + filler: + variable: ~ + label: + - Label: KNOWS + - start: 32 + end: 37 + predicate: + - Property: + - - name: + - since + - start: 39 + end: 44 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "2020" + - start: 46 + end: 50 + - start: 46 + end: 50 + - start: 39 + end: 50 + - start: 38 + end: 51 + - start: 29 + end: 54 + - - Node: + variable: + - b + - start: 55 + end: 56 + label: + - Label: PERSON + - start: 57 + end: 63 + predicate: + - Property: + - - name: + - name + - start: 65 + end: 69 + value: + - Value: + Literal: + String: + kind: Char + literal: B + - start: 71 + end: 74 + - start: 65 + end: 74 + - start: 64 + end: 75 + - start: 54 + end: 76 + - start: 7 + end: 76 + - start: 0 + end: 76 +- start: 0 + end: 76 From 3f54c6225ac4eba3d95fe820bb28c7b6b1f6fb95 Mon Sep 17 00:00:00 2001 From: qishipengqsp Date: Wed, 27 May 2026 18:58:39 +0800 Subject: [PATCH 3/7] feat(planner): bind and plan INSERT statement Wire INSERT end-to-end through binder, bound AST, logical planner, plan node, and optimizer pass-through. - BoundStatement::Data variant carries a Vec of BoundDataModifyingStatement - BoundInsertStatement holds resolved vertices (label_id + ordered property literals) and edges (label_id + endpoint indices into the vertex list), so the executor never has to touch the parser AST or the catalog provider - Binder resolves labels against current_graph.graph_type(), validates endpoint type compatibility, coerces property literals to declared types, and reports a focused error variant for each failure mode (unknown label/property, missing required property, type mismatch, duplicate variable, undirected edge, etc.) - Plan node PhysicalInsert flows through the optimizer untouched - Standalone INSERT only -- MATCH-context bindings and SET/REMOVE/DELETE are deferred to follow-up work Co-Authored-By: Claude Opus 4.7 --- minigu/gql/planner/src/binder/data.rs | 478 ++++++++++++++++++ minigu/gql/planner/src/binder/error.rs | 63 +++ minigu/gql/planner/src/binder/mod.rs | 1 + .../gql/planner/src/binder/procedure_spec.rs | 4 +- minigu/gql/planner/src/bound/data.rs | 55 ++ minigu/gql/planner/src/bound/mod.rs | 2 + .../gql/planner/src/bound/procedure_spec.rs | 3 +- .../gql/planner/src/logical_planner/data.rs | 20 + minigu/gql/planner/src/logical_planner/mod.rs | 1 + .../src/logical_planner/procedure_spec.rs | 10 + minigu/gql/planner/src/optimizer/mod.rs | 4 + minigu/gql/planner/src/plan/data_modify.rs | 36 ++ minigu/gql/planner/src/plan/mod.rs | 5 + 13 files changed, 680 insertions(+), 2 deletions(-) create mode 100644 minigu/gql/planner/src/binder/data.rs create mode 100644 minigu/gql/planner/src/bound/data.rs create mode 100644 minigu/gql/planner/src/logical_planner/data.rs create mode 100644 minigu/gql/planner/src/plan/data_modify.rs diff --git a/minigu/gql/planner/src/binder/data.rs b/minigu/gql/planner/src/binder/data.rs new file mode 100644 index 000000000..c3d78109f --- /dev/null +++ b/minigu/gql/planner/src/binder/data.rs @@ -0,0 +1,478 @@ +use std::collections::HashMap; + +use gql_parser::ast::{ + DataModifyingStatement, EdgePatternKind, ElementPattern, ElementPatternFiller, + ElementPatternPredicate, FieldOrProperty, Ident, InsertPath, InsertStatement, LabelExpr, + LinearDataModifyingStatement, +}; +use gql_parser::span::Spanned; +use minigu_catalog::label_set::LabelSet; +use minigu_catalog::property::Property; +use minigu_catalog::provider::{EdgeTypeRef, GraphTypeProvider, VertexTypeRef}; +use minigu_common::data_type::LogicalType; +use minigu_common::types::{LabelId, PropertyId}; +use minigu_common::value::ScalarValue; +use smol_str::SmolStr; + +use super::Binder; +use super::error::{BindError, BindResult}; +use crate::bound::{ + BoundDataModifyingStatement, BoundInsertEdge, BoundInsertProperty, BoundInsertStatement, + BoundInsertVertex, +}; + +impl Binder<'_> { + pub fn bind_data_modifying_statement( + &mut self, + statement: &DataModifyingStatement, + ) -> BindResult { + match statement { + DataModifyingStatement::Insert(stmt) => self + .bind_insert_statement(stmt) + .map(BoundDataModifyingStatement::Insert), + } + } + + pub fn bind_linear_data_modifying_statement( + &mut self, + statements: &LinearDataModifyingStatement, + ) -> BindResult> { + statements + .iter() + .map(|s| self.bind_data_modifying_statement(s.value())) + .collect() + } + + fn bind_insert_statement( + &mut self, + stmt: &InsertStatement, + ) -> BindResult { + let graph = self + .current_graph + .as_ref() + .ok_or(BindError::CurrentGraphNotSpecified)? + .clone(); + let graph_type = graph.graph_type(); + + // First pass: walk every path, classify each ElementPattern as either a + // vertex (allocating a slot in `vertices`) or an edge (recorded for the + // second pass). Build the variable -> index map so edges can resolve + // their endpoints. + let mut vertices: Vec = Vec::new(); + let mut var_index: HashMap = HashMap::new(); + // Edge work items: (path_index, element_index, src_var, dst_var) + struct PendingEdge<'a> { + filler: &'a ElementPatternFiller, + kind: EdgePatternKind, + src_var: SmolStr, + dst_var: SmolStr, + } + let mut pending_edges: Vec> = Vec::new(); + + for path in &stmt.paths { + let path = path.value(); + // A path's elements must alternate Node, Edge, Node, Edge, ... + // Insert paths have shape `Node (Edge Node)*` so the first element + // is a node and after that pairs of (edge, node). + let mut iter = path.elements.iter().peekable(); + let first = iter.next().ok_or_else(|| BindError::InsertPathTooComplex(0))?; + let first_var = self.bind_insert_vertex( + first.value(), + graph_type.as_ref(), + &mut vertices, + &mut var_index, + )?; + let mut prev_var = first_var; + while let Some(edge_el) = iter.next() { + let edge_pat = match edge_el.value() { + ElementPattern::Edge { kind, filler } => (kind.clone(), filler), + ElementPattern::Node(_) => { + return Err(BindError::InsertPathTooComplex(path.elements.len())); + } + }; + let next_node = iter + .next() + .ok_or_else(|| BindError::InsertPathTooComplex(path.elements.len()))?; + let next_var = self.bind_insert_vertex( + next_node.value(), + graph_type.as_ref(), + &mut vertices, + &mut var_index, + )?; + + // Resolve direction: which endpoint is the GQL "src"? + let (src_var, dst_var) = match edge_pat.0 { + EdgePatternKind::Right => (prev_var.clone(), next_var.clone()), + EdgePatternKind::Left => (next_var.clone(), prev_var.clone()), + EdgePatternKind::Undirected + | EdgePatternKind::LeftRight + | EdgePatternKind::LeftUndirected + | EdgePatternKind::RightUndirected + | EdgePatternKind::Any => { + return Err(BindError::InsertUndirectedEdgeNotSupported); + } + }; + pending_edges.push(PendingEdge { + filler: edge_pat.1, + kind: edge_pat.0, + src_var, + dst_var, + }); + prev_var = next_var; + } + } + + // Second pass: bind edges now that all vertex variables exist. + let mut edges = Vec::with_capacity(pending_edges.len()); + for pe in pending_edges { + let bound = self.bind_insert_edge( + pe.filler, + graph_type.as_ref(), + &vertices, + &var_index, + &pe.src_var, + &pe.dst_var, + )?; + edges.push(bound); + } + + Ok(BoundInsertStatement { vertices, edges }) + } + + fn bind_insert_vertex( + &self, + pattern: &ElementPattern, + graph_type: &dyn GraphTypeProvider, + vertices: &mut Vec, + var_index: &mut HashMap, + ) -> BindResult { + let filler = match pattern { + ElementPattern::Node(f) => f, + ElementPattern::Edge { .. } => { + return Err(BindError::InsertPathTooComplex(0)); + } + }; + + let variable = filler + .variable + .as_ref() + .map(|v: &Spanned| SmolStr::new(v.value().as_str())) + .ok_or(BindError::InsertAnonymousVertexNotSupported)?; + + // If this variable was already declared as a vertex, this is a + // back-reference rather than a new vertex creation. Reuse it. + if let Some(_existing_index) = var_index.get(&variable) { + // The endpoint is referenced again; the spec says the same variable + // may appear in the same INSERT only once as a definition. For the + // standalone-INSERT scope we treat any *additional* occurrence with + // a non-empty filler as a duplicate; otherwise accept the + // back-reference. + if filler.label.is_some() || filler.predicate.is_some() { + return Err(BindError::InsertDuplicateVariable(variable)); + } + return Ok(variable); + } + + let label_id = bind_single_label(filler.label.as_ref(), graph_type) + .ok_or(BindError::InsertVertexLabelMissing)??; + let label_set: LabelSet = LabelSet::from_iter([label_id]); + let vertex_type = graph_type + .get_vertex_type(&label_set)? + .ok_or_else(|| BindError::InsertVertexTypeNotFound { + label: label_id_to_smol(graph_type, label_id), + })?; + + let label_name = label_id_to_smol(graph_type, label_id); + let properties = bind_property_list( + filler.predicate.as_ref(), + vertex_type.properties(), + &label_name, + )?; + + let index = vertices.len(); + vertices.push(BoundInsertVertex { + variable: variable.clone(), + label_id, + labels: label_set, + properties, + }); + var_index.insert(variable.clone(), index); + Ok(variable) + } + + fn bind_insert_edge( + &self, + filler: &ElementPatternFiller, + graph_type: &dyn GraphTypeProvider, + vertices: &[BoundInsertVertex], + var_index: &HashMap, + src_var: &SmolStr, + dst_var: &SmolStr, + ) -> BindResult { + let label_id = bind_single_label(filler.label.as_ref(), graph_type) + .ok_or(BindError::InsertEdgeLabelMissing)??; + let label_set: LabelSet = LabelSet::from_iter([label_id]); + let edge_type = graph_type.get_edge_type(&label_set)?.ok_or_else(|| { + BindError::InsertEdgeTypeNotFound { + label: label_id_to_smol(graph_type, label_id), + } + })?; + + let src_index = *var_index + .get(src_var) + .ok_or_else(|| BindError::InsertEndpointNotDefined(src_var.clone()))?; + let dst_index = *var_index + .get(dst_var) + .ok_or_else(|| BindError::InsertEndpointNotDefined(dst_var.clone()))?; + + let expected_src_set = edge_type.src().label_set(); + let expected_dst_set = edge_type.dst().label_set(); + let actual_src_set: LabelSet = LabelSet::from_iter([vertices[src_index].label_id]); + let actual_dst_set: LabelSet = LabelSet::from_iter([vertices[dst_index].label_id]); + if expected_src_set != actual_src_set || expected_dst_set != actual_dst_set { + return Err(BindError::InsertEdgeEndpointTypeMismatch { + label: label_id_to_smol(graph_type, label_id), + expected_src: label_set_to_smol(graph_type, &expected_src_set), + expected_dst: label_set_to_smol(graph_type, &expected_dst_set), + actual_src: label_id_to_smol(graph_type, vertices[src_index].label_id), + actual_dst: label_id_to_smol(graph_type, vertices[dst_index].label_id), + }); + } + + let label_name = label_id_to_smol(graph_type, label_id); + let properties = + bind_property_list(filler.predicate.as_ref(), edge_type.properties(), &label_name)?; + + let variable = filler + .variable + .as_ref() + .map(|v| SmolStr::new(v.value().as_str())); + Ok(BoundInsertEdge { + variable, + label_id, + labels: label_set, + properties, + src_index, + dst_index, + }) + } +} + +/// Resolve a single-label expression `:Label` into its id. Returns `None` if no +/// label was provided (caller decides whether that's an error). +fn bind_single_label( + label: Option<&Spanned>, + graph_type: &dyn GraphTypeProvider, +) -> Option> { + let label = label?; + Some(match label.value() { + LabelExpr::Label(name) => graph_type + .get_label_id(name.as_str()) + .map_err(BindError::Catalog) + .and_then(|opt| { + opt.ok_or_else(|| BindError::LabelNotFound(SmolStr::new(name.as_str()))) + }), + _ => Err(BindError::InsertComplexLabelNotSupported), + }) +} + +fn bind_property_list( + predicate: Option<&Spanned>, + declared: Vec<(PropertyId, Property)>, + label: &SmolStr, +) -> BindResult> { + // Map property-name -> (id, declared-property) + let declared_map: HashMap<&str, (PropertyId, &Property)> = declared + .iter() + .map(|(id, p)| (p.name(), (*id, p))) + .collect(); + + let provided: Vec<&Spanned> = match predicate { + None => Vec::new(), + Some(p) => match p.value() { + ElementPatternPredicate::Property(fields) => fields.iter().collect(), + ElementPatternPredicate::Where(_) => { + return Err(BindError::InsertWherePredicateNotAllowed); + } + }, + }; + + // Validate every provided property and coerce literal to the declared type. + let mut by_name: HashMap<&str, BoundInsertProperty> = HashMap::new(); + for field in provided { + let name = field.value().name.value().as_str(); + let (prop_id, declared_prop) = + declared_map + .get(name) + .copied() + .ok_or_else(|| BindError::InsertUnknownProperty { + label: label.clone(), + property: SmolStr::new(name), + })?; + let value = + literal_scalar_from_expr(field.value().value.value()).ok_or_else(|| { + BindError::InsertNonLiteralProperty { + property: SmolStr::new(name), + } + })?; + let value = coerce_scalar_to_type(value, declared_prop.logical_type()).ok_or_else( + || BindError::InsertPropertyTypeMismatch { + label: label.clone(), + property: SmolStr::new(name), + expected: declared_prop.logical_type().clone(), + actual: LogicalType::Null, // best-effort; precise actual omitted to keep msg simple + }, + )?; + by_name.insert( + declared_prop.name(), + BoundInsertProperty { + name: SmolStr::new(declared_prop.name()), + property_id: prop_id, + value, + }, + ); + } + + // Walk declared properties in type order: every non-nullable property must + // be supplied, missing nullable properties become NULL. + let mut out = Vec::with_capacity(declared.len()); + for (prop_id, decl) in &declared { + match by_name.remove(decl.name()) { + Some(bp) => out.push(bp), + None => { + if !decl.nullable() { + return Err(BindError::InsertRequiredPropertyMissing { + label: label.clone(), + property: SmolStr::new(decl.name()), + }); + } + out.push(BoundInsertProperty { + name: SmolStr::new(decl.name()), + property_id: *prop_id, + value: ScalarValue::Null, + }); + } + } + } + Ok(out) +} + +/// Extract a literal scalar value from a parser `Expr`, or `None` if the +/// expression is not a literal. +fn literal_scalar_from_expr(expr: &gql_parser::ast::Expr) -> Option { + use gql_parser::ast::{Expr, Literal, UnaryOp, Value}; + use minigu_common::value::{F32, F64}; + + fn from_literal(literal: &Literal) -> Option { + match literal { + Literal::Boolean(b) => Some(match b { + gql_parser::ast::BooleanLiteral::True => ScalarValue::Boolean(Some(true)), + gql_parser::ast::BooleanLiteral::False => ScalarValue::Boolean(Some(false)), + gql_parser::ast::BooleanLiteral::Unknown => ScalarValue::Boolean(None), + }), + Literal::String(s) => match s.kind { + gql_parser::ast::StringLiteralKind::Char => { + Some(ScalarValue::String(Some(s.literal.to_string()))) + } + _ => None, + }, + Literal::Numeric(n) => match n { + gql_parser::ast::UnsignedNumericLiteral::Integer(i) => { + let s = i.value().integer.as_str(); + if let Ok(v) = s.parse::() { + // Widest fitting int representation; coercion narrows later. + Some(ScalarValue::Int64(Some(v))) + } else { + None + } + } + gql_parser::ast::UnsignedNumericLiteral::Float(f) => f + .value() + .float + .parse::() + .ok() + .map(|v| ScalarValue::Float64(Some(F64::from(v)))), + }, + Literal::Null => Some(ScalarValue::Null), + _ => None, + } + } + + match expr { + Expr::Value(Value::Literal(l)) => from_literal(l), + Expr::Unary { op, child } => { + let inner = literal_scalar_from_expr(child.value())?; + match op.value() { + UnaryOp::Plus => Some(inner), + UnaryOp::Minus => match inner { + ScalarValue::Int64(Some(v)) => Some(ScalarValue::Int64(Some(-v))), + ScalarValue::Float64(Some(v)) => { + Some(ScalarValue::Float64(Some(F64::from(-v.into_inner())))) + } + _ => None, + }, + UnaryOp::Not => None, + } + } + _ => None, + } +} + +/// Coerce a literal scalar into the declared logical type. Numeric narrowing +/// is allowed when it fits; type families must match. Returns `None` if no +/// safe coercion exists. +fn coerce_scalar_to_type(value: ScalarValue, target: &LogicalType) -> Option { + use minigu_common::value::F32; + + if matches!(value, ScalarValue::Null) { + return Some(ScalarValue::Null); + } + match target { + LogicalType::Int8 => value.to_i8().ok().map(|v| ScalarValue::Int8(Some(v))), + LogicalType::Int16 => value.to_i16().ok().map(|v| ScalarValue::Int16(Some(v))), + LogicalType::Int32 => value.to_i32().ok().map(|v| ScalarValue::Int32(Some(v))), + LogicalType::Int64 => value.to_i64().ok().map(|v| ScalarValue::Int64(Some(v))), + LogicalType::UInt8 => value.to_u8().ok().map(|v| ScalarValue::UInt8(Some(v))), + LogicalType::UInt16 => value.to_u16().ok().map(|v| ScalarValue::UInt16(Some(v))), + LogicalType::UInt32 => value.to_u32().ok().map(|v| ScalarValue::UInt32(Some(v))), + LogicalType::UInt64 => value.to_u64().ok().map(|v| ScalarValue::UInt64(Some(v))), + LogicalType::Float32 => value + .to_f32() + .ok() + .map(|v| ScalarValue::Float32(Some(F32::from(v)))), + LogicalType::Float64 => value + .to_f64() + .ok() + .map(|v| ScalarValue::Float64(Some(minigu_common::value::F64::from(v)))), + LogicalType::Boolean => value.to_bool().ok().map(|v| ScalarValue::Boolean(Some(v))), + LogicalType::String => value.to_string().ok().map(|v| ScalarValue::String(Some(v))), + // Other types (Vector, Vertex, Edge, Record, Null) are not yet + // supported as INSERT literals. + _ => None, + } +} + +fn label_id_to_smol(graph_type: &dyn GraphTypeProvider, id: LabelId) -> SmolStr { + for name in graph_type.label_names() { + if let Ok(Some(other_id)) = graph_type.get_label_id(&name) + && other_id == id + { + return SmolStr::new(name); + } + } + SmolStr::new(format!("#{id:?}")) +} + +fn label_set_to_smol(graph_type: &dyn GraphTypeProvider, set: &LabelSet) -> SmolStr { + // We treat label sets as singletons in this iteration. + if let Some(id) = set.first() { + label_id_to_smol(graph_type, id) + } else { + SmolStr::new("") + } +} + +// Keep imports tidy: VertexTypeRef/EdgeTypeRef brought in for trait method +// access via `graph_type.get_vertex_type(...)` return values. +#[allow(dead_code)] +fn _ensure_traits(_v: VertexTypeRef, _e: EdgeTypeRef) {} diff --git a/minigu/gql/planner/src/binder/error.rs b/minigu/gql/planner/src/binder/error.rs index 69dc14f63..14ad315e4 100644 --- a/minigu/gql/planner/src/binder/error.rs +++ b/minigu/gql/planner/src/binder/error.rs @@ -137,6 +137,69 @@ pub enum BindError { #[error("unexpected bind error")] Unexpected, + #[error("INSERT: vertex type for label {label} not found in current graph")] + InsertVertexTypeNotFound { label: SmolStr }, + + #[error("INSERT: edge type for label {label} not found in current graph")] + InsertEdgeTypeNotFound { label: SmolStr }, + + #[error( + "INSERT: edge {label} expects {expected_src} -> {expected_dst}, got {actual_src} -> {actual_dst}" + )] + InsertEdgeEndpointTypeMismatch { + label: SmolStr, + expected_src: SmolStr, + expected_dst: SmolStr, + actual_src: SmolStr, + actual_dst: SmolStr, + }, + + #[error("INSERT: duplicate variable name `{0}` in the same statement")] + InsertDuplicateVariable(SmolStr), + + #[error("INSERT: edge endpoint `{0}` is not defined as a vertex in this statement")] + InsertEndpointNotDefined(SmolStr), + + #[error("INSERT: vertex must declare a label")] + InsertVertexLabelMissing, + + #[error("INSERT: edge must declare a label")] + InsertEdgeLabelMissing, + + #[error("INSERT: vertex label must be a single name, not a complex label expression")] + InsertComplexLabelNotSupported, + + #[error("INSERT: vertex variable name is required (anonymous vertices are not supported)")] + InsertAnonymousVertexNotSupported, + + #[error("INSERT: WHERE / search-condition predicate is not allowed; use a property list")] + InsertWherePredicateNotAllowed, + + #[error( + "INSERT: property `{property}` on label `{label}` expects type {expected}, got {actual}" + )] + InsertPropertyTypeMismatch { + label: SmolStr, + property: SmolStr, + expected: LogicalType, + actual: LogicalType, + }, + + #[error("INSERT: required property `{property}` on label `{label}` is missing")] + InsertRequiredPropertyMissing { label: SmolStr, property: SmolStr }, + + #[error("INSERT: property `{property}` on label `{label}` does not exist on this type")] + InsertUnknownProperty { label: SmolStr, property: SmolStr }, + + #[error("INSERT: property `{property}` value must be a literal expression")] + InsertNonLiteralProperty { property: SmolStr }, + + #[error("INSERT: undirected edges are not supported yet")] + InsertUndirectedEdgeNotSupported, + + #[error("INSERT: only single-segment paths are accepted (got {0} elements)")] + InsertPathTooComplex(usize), + #[error(transparent)] #[diagnostic(transparent)] NotImplemented(#[from] NotImplemented), diff --git a/minigu/gql/planner/src/binder/mod.rs b/minigu/gql/planner/src/binder/mod.rs index cba622cdb..6c4310980 100644 --- a/minigu/gql/planner/src/binder/mod.rs +++ b/minigu/gql/planner/src/binder/mod.rs @@ -2,6 +2,7 @@ mod catalog; pub mod common; +mod data; pub mod error; mod object_expr; mod object_ref; diff --git a/minigu/gql/planner/src/binder/procedure_spec.rs b/minigu/gql/planner/src/binder/procedure_spec.rs index 7b29392db..b97a1dbbb 100644 --- a/minigu/gql/planner/src/binder/procedure_spec.rs +++ b/minigu/gql/planner/src/binder/procedure_spec.rs @@ -35,7 +35,9 @@ impl Binder<'_> { Statement::Query(statement) => self .bind_composite_query_statement(statement) .map(BoundStatement::Query), - Statement::Data(_) => not_implemented("data-modifying statement".to_string(), None), + Statement::Data(statements) => self + .bind_linear_data_modifying_statement(statements) + .map(BoundStatement::Data), Statement::Utility(utility) => match utility { gql_parser::ast::UtilityStatement::Explain(explain) => self .bind_explain_statement(explain) diff --git a/minigu/gql/planner/src/bound/data.rs b/minigu/gql/planner/src/bound/data.rs new file mode 100644 index 000000000..99dc44716 --- /dev/null +++ b/minigu/gql/planner/src/bound/data.rs @@ -0,0 +1,55 @@ +use minigu_catalog::label_set::LabelSet; +use minigu_common::types::{LabelId, PropertyId}; +use minigu_common::value::ScalarValue; +use serde::Serialize; +use smol_str::SmolStr; + +#[derive(Debug, Clone, Serialize)] +pub enum BoundDataModifyingStatement { + Insert(BoundInsertStatement), +} + +/// An `INSERT` statement, fully resolved against the current graph's type +/// system. Vertices are inserted first in the order they appear, then edges. +/// Edges reference the inserted vertices by index into `vertices`. +#[derive(Debug, Clone, Serialize)] +pub struct BoundInsertStatement { + pub vertices: Vec, + pub edges: Vec, +} + +#[derive(Debug, Clone, Serialize)] +pub struct BoundInsertVertex { + /// User-visible variable name (e.g., `a` in `(a:Person {...})`). + pub variable: SmolStr, + /// Resolved label id (single label per vertex in this iteration). + pub label_id: LabelId, + /// Full label set (currently always a singleton; kept for symmetry with + /// `MemoryGraph` APIs that take a `LabelSet`). + pub labels: LabelSet, + /// Property values aligned with `vertex_type.properties()` order. Each + /// entry carries the resolved property id and a literal value coerced into + /// the property's declared logical type. + pub properties: Vec, +} + +#[derive(Debug, Clone, Serialize)] +pub struct BoundInsertEdge { + /// Optional user-visible variable name. + pub variable: Option, + pub label_id: LabelId, + pub labels: LabelSet, + pub properties: Vec, + /// Index into [`BoundInsertStatement::vertices`] for the source endpoint. + pub src_index: usize, + /// Index into [`BoundInsertStatement::vertices`] for the destination endpoint. + pub dst_index: usize, +} + +#[derive(Debug, Clone, Serialize)] +pub struct BoundInsertProperty { + pub name: SmolStr, + pub property_id: PropertyId, + /// Resolved, type-coerced literal value. + pub value: ScalarValue, +} diff --git a/minigu/gql/planner/src/bound/mod.rs b/minigu/gql/planner/src/bound/mod.rs index 5903444f4..935e1e410 100644 --- a/minigu/gql/planner/src/bound/mod.rs +++ b/minigu/gql/planner/src/bound/mod.rs @@ -1,5 +1,6 @@ mod catalog; mod common; +mod data; mod lexical; mod object_ref; mod procedure_call; @@ -10,6 +11,7 @@ mod value_expr; pub use catalog::*; pub use common::*; +pub use data::*; pub use lexical::*; pub use object_ref::*; pub use procedure_call::*; diff --git a/minigu/gql/planner/src/bound/procedure_spec.rs b/minigu/gql/planner/src/bound/procedure_spec.rs index 8966da5d7..3ce7e1c4f 100644 --- a/minigu/gql/planner/src/bound/procedure_spec.rs +++ b/minigu/gql/planner/src/bound/procedure_spec.rs @@ -2,6 +2,7 @@ use minigu_common::data_type::DataSchemaRef; use serde::Serialize; use super::catalog::BoundCatalogModifyingStatement; +use super::data::BoundDataModifyingStatement; use super::query::BoundCompositeQueryStatement; #[derive(Debug, Clone, Serialize)] @@ -26,7 +27,7 @@ pub enum BoundStatement { Catalog(Vec), Query(BoundCompositeQueryStatement), Utility(Box), - // Data(BoundLinearDataModifyingStatement), + Data(Vec), } #[derive(Debug, Clone, Serialize)] diff --git a/minigu/gql/planner/src/logical_planner/data.rs b/minigu/gql/planner/src/logical_planner/data.rs new file mode 100644 index 000000000..78780cae6 --- /dev/null +++ b/minigu/gql/planner/src/logical_planner/data.rs @@ -0,0 +1,20 @@ +use std::sync::Arc; + +use crate::bound::BoundDataModifyingStatement; +use crate::error::PlanResult; +use crate::logical_planner::LogicalPlanner; +use crate::plan::PlanNode; +use crate::plan::data_modify::Insert; + +impl LogicalPlanner { + pub fn plan_data_modifying_statement( + &self, + statement: BoundDataModifyingStatement, + ) -> PlanResult { + match statement { + BoundDataModifyingStatement::Insert(insert) => { + Ok(PlanNode::PhysicalInsert(Arc::new(Insert::new(insert)))) + } + } + } +} diff --git a/minigu/gql/planner/src/logical_planner/mod.rs b/minigu/gql/planner/src/logical_planner/mod.rs index 98cbe3abd..0b1a2ea5f 100644 --- a/minigu/gql/planner/src/logical_planner/mod.rs +++ b/minigu/gql/planner/src/logical_planner/mod.rs @@ -1,4 +1,5 @@ mod catalog; +mod data; mod procedure_call; mod procedure_spec; mod query; diff --git a/minigu/gql/planner/src/logical_planner/procedure_spec.rs b/minigu/gql/planner/src/logical_planner/procedure_spec.rs index be93b621f..bec8ca1ec 100644 --- a/minigu/gql/planner/src/logical_planner/procedure_spec.rs +++ b/minigu/gql/planner/src/logical_planner/procedure_spec.rs @@ -27,6 +27,16 @@ impl LogicalPlanner { self.plan_catalog_modifying_statement(statement) } BoundStatement::Query(statement) => self.plan_composite_query_statement(statement), + BoundStatement::Data(mut statements) => { + assert!(!statements.is_empty()); + if statements.len() > 1 { + return not_implemented("multiple data-modifying statements", None); + } + let statement = statements + .pop() + .expect("at least one statement should be present"); + self.plan_data_modifying_statement(statement) + } BoundStatement::Utility(utility) => match utility.as_ref() { BoundUtilityStatement::Explain(explain) => self.plan_explain_statement(explain), }, diff --git a/minigu/gql/planner/src/optimizer/mod.rs b/minigu/gql/planner/src/optimizer/mod.rs index 3a452e9d4..99583bc70 100644 --- a/minigu/gql/planner/src/optimizer/mod.rs +++ b/minigu/gql/planner/src/optimizer/mod.rs @@ -236,6 +236,10 @@ fn create_physical_plan_impl(logical_plan: &PlanNode) -> PlanResult { assert!(children.is_empty()); Ok(PlanNode::PhysicalDropGraph(drop_graph.clone())) } + PlanNode::PhysicalInsert(insert) => { + assert!(children.is_empty()); + Ok(PlanNode::PhysicalInsert(insert.clone())) + } _ => unreachable!(), } } diff --git a/minigu/gql/planner/src/plan/data_modify.rs b/minigu/gql/planner/src/plan/data_modify.rs new file mode 100644 index 000000000..5e06f1622 --- /dev/null +++ b/minigu/gql/planner/src/plan/data_modify.rs @@ -0,0 +1,36 @@ +use serde::Serialize; + +use crate::bound::BoundInsertStatement; +use crate::plan::{PlanBase, PlanData}; + +/// Physical plan node for an `INSERT` statement. +#[derive(Debug, Clone, Serialize)] +pub struct Insert { + pub base: PlanBase, + pub statement: BoundInsertStatement, +} + +impl Insert { + pub fn new(statement: BoundInsertStatement) -> Self { + Self { + base: PlanBase::new(None, vec![]), + statement, + } + } +} + +impl PlanData for Insert { + fn base(&self) -> &PlanBase { + &self.base + } + + fn explain(&self, indent: usize) -> Option { + let indent_str = " ".repeat(indent * 2); + Some(format!( + "{}Insert: {} vertices, {} edges\n", + indent_str, + self.statement.vertices.len(), + self.statement.edges.len(), + )) + } +} diff --git a/minigu/gql/planner/src/plan/mod.rs b/minigu/gql/planner/src/plan/mod.rs index 19a2bf64b..98e351332 100644 --- a/minigu/gql/planner/src/plan/mod.rs +++ b/minigu/gql/planner/src/plan/mod.rs @@ -1,6 +1,7 @@ pub mod call; pub mod catalog_modify; pub mod create_vector_index; +pub mod data_modify; pub mod drop_vector_index; pub mod expand; pub mod explain; @@ -24,6 +25,7 @@ use serde::Serialize; use crate::plan::call::Call; use crate::plan::catalog_modify::{CreateGraph, DropGraph}; use crate::plan::create_vector_index::CreateVectorIndex; +use crate::plan::data_modify::Insert; use crate::plan::drop_vector_index::DropVectorIndex; use crate::plan::expand::Expand; use crate::plan::explain::Explain; @@ -122,6 +124,7 @@ pub enum PlanNode { PhysicalDropVectorIndex(Arc), PhysicalCreateGraph(Arc), PhysicalDropGraph(Arc), + PhysicalInsert(Arc), } impl PlanData for PlanNode { @@ -159,6 +162,7 @@ impl PlanData for PlanNode { PlanNode::PhysicalDropVectorIndex(node) => node.base(), PlanNode::PhysicalCreateGraph(node) => node.base(), PlanNode::PhysicalDropGraph(node) => node.base(), + PlanNode::PhysicalInsert(node) => node.base(), } } @@ -196,6 +200,7 @@ impl PlanData for PlanNode { PlanNode::PhysicalDropVectorIndex(node) => node.explain(indent), PlanNode::PhysicalCreateGraph(node) => node.explain(indent), PlanNode::PhysicalDropGraph(node) => node.explain(indent), + PlanNode::PhysicalInsert(node) => node.explain(indent), } } } From a479253363917acb37cca80cb29c736227733fb1 Mon Sep 17 00:00:00 2001 From: qishipengqsp Date: Wed, 27 May 2026 19:02:28 +0800 Subject: [PATCH 4/7] feat(execution): add INSERT executor and wire builder dispatch InsertBuilder follows the existing catalog_modify generator pattern: acquire the current graph's MemoryGraph, open a Serializable transaction, allocate fresh vids/eids via the new storage allocators, build Vertex/Edge values from the bound property records, and commit. The executor yields no rows (StatementComplete) -- INSERT has no output schema in this iteration. ExecutorBuilder dispatches PhysicalInsert to this builder. Co-Authored-By: Claude Opus 4.7 --- minigu/gql/execution/src/builder.rs | 7 ++ .../gql/execution/src/executor/data_modify.rs | 86 +++++++++++++++++++ minigu/gql/execution/src/executor/mod.rs | 1 + 3 files changed, 94 insertions(+) create mode 100644 minigu/gql/execution/src/executor/data_modify.rs diff --git a/minigu/gql/execution/src/builder.rs b/minigu/gql/execution/src/builder.rs index 912a3a77f..c6b812985 100644 --- a/minigu/gql/execution/src/builder.rs +++ b/minigu/gql/execution/src/builder.rs @@ -18,6 +18,7 @@ use crate::evaluator::vector_distance::VectorDistanceEvaluator; use crate::evaluator::vertex_constructor::VertexConstructor; use crate::executor::catalog_modify::{CreateGraphBuilder, DropGraphBuilder}; use crate::executor::create_vector_index::CreateVectorIndexBuilder; +use crate::executor::data_modify::InsertBuilder; use crate::executor::drop_vector_index::DropVectorIndexBuilder; use crate::executor::join::JoinCond; use crate::executor::procedure_call::ProcedureCallBuilder; @@ -321,6 +322,12 @@ impl ExecutorBuilder { let session = self.session.clone(); Box::new(DropGraphBuilder::new(plan, session).into_executor()) } + PlanNode::PhysicalInsert(insert) => { + assert!(children.is_empty()); + let plan = (**insert).clone(); + let session = self.session.clone(); + Box::new(InsertBuilder::new(plan, session).into_executor()) + } _ => unreachable!(), } } diff --git a/minigu/gql/execution/src/executor/data_modify.rs b/minigu/gql/execution/src/executor/data_modify.rs new file mode 100644 index 000000000..64332f376 --- /dev/null +++ b/minigu/gql/execution/src/executor/data_modify.rs @@ -0,0 +1,86 @@ +use std::sync::Arc; + +use minigu_context::graph::{GraphContainer, GraphStorage}; +use minigu_context::session::SessionContext; +use minigu_planner::plan::data_modify::Insert; +use minigu_storage::common::{Edge, PropertyRecord, Vertex}; +use minigu_storage::tp::MemoryGraph; +use minigu_transaction::{GraphTxnManager, IsolationLevel, Transaction}; + +use super::{Executor, IntoExecutor}; +use crate::error::{ExecutionError, ExecutionResult}; + +fn execution_error(msg: impl Into) -> ExecutionError { + ExecutionError::Custom(msg.into().into()) +} + +pub struct InsertBuilder { + plan: Insert, + session: SessionContext, +} + +impl InsertBuilder { + pub fn new(plan: Insert, session: SessionContext) -> Self { + Self { plan, session } + } +} + +impl IntoExecutor for InsertBuilder { + type IntoExecutor = impl Executor; + + fn into_executor(self) -> Self::IntoExecutor { + gen move { + let InsertBuilder { plan, session } = self; + if let Err(e) = insert_impl(&plan, &session) { + yield Err(e); + } + } + .into_executor() + } +} + +fn insert_impl(plan: &Insert, session: &SessionContext) -> ExecutionResult<()> { + let graph_ref = session + .current_graph + .as_ref() + .ok_or_else(|| execution_error("No current graph set for INSERT"))? + .clone(); + let provider = graph_ref.object().clone(); + let container = provider + .downcast_ref::() + .ok_or_else(|| execution_error("Current graph is not an in-memory container"))?; + let memory: Arc = match container.graph_storage() { + GraphStorage::Memory(m) => Arc::clone(m), + }; + + let txn = memory + .txn_manager() + .begin_transaction(IsolationLevel::Serializable) + .map_err(|e| execution_error(format!("failed to begin transaction: {e}")))?; + + // Create vertices first, recording the assigned vid so edges can reference + // their endpoints by index. + let mut vid_map: Vec = Vec::with_capacity(plan.statement.vertices.len()); + for v in &plan.statement.vertices { + let vid = memory.alloc_vertex_id(); + let props = PropertyRecord::new(v.properties.iter().map(|p| p.value.clone()).collect()); + memory + .create_vertex(&txn, Vertex::new(vid, v.label_id, props)) + .map_err(|e| execution_error(format!("create_vertex failed: {e}")))?; + vid_map.push(vid); + } + + for e in &plan.statement.edges { + let eid = memory.alloc_edge_id(); + let props = PropertyRecord::new(e.properties.iter().map(|p| p.value.clone()).collect()); + let src = vid_map[e.src_index]; + let dst = vid_map[e.dst_index]; + memory + .create_edge(&txn, Edge::new(eid, src, dst, e.label_id, props)) + .map_err(|e| execution_error(format!("create_edge failed: {e}")))?; + } + + txn.commit() + .map_err(|e| execution_error(format!("commit failed: {e}")))?; + Ok(()) +} diff --git a/minigu/gql/execution/src/executor/mod.rs b/minigu/gql/execution/src/executor/mod.rs index 9d41a410f..c640ed36b 100644 --- a/minigu/gql/execution/src/executor/mod.rs +++ b/minigu/gql/execution/src/executor/mod.rs @@ -1,6 +1,7 @@ pub mod aggregate; pub mod catalog_modify; pub mod create_vector_index; +pub mod data_modify; pub mod drop_vector_index; pub mod expand; pub mod factorized_filter; From a03c2acecf6615c61790789b88f3ee8b438c24be Mon Sep 17 00:00:00 2001 From: qishipengqsp Date: Wed, 27 May 2026 19:03:00 +0800 Subject: [PATCH 5/7] test(gql): add INSERT sqllogictest suite and helper procedure Adds create_insert_test_graph, a fixture procedure that registers a small schema using only primitive-typed properties (PERSON{name,age}, COMPANY{name,revenue}, KNOWS{since}, WORKS_AT{role}). GQL has no vector-literal syntax yet, so the existing create_test_graph_data schema (with non-nullable vector embeddings) is unusable for INSERT tests; this fixture sidesteps that without disturbing existing vector-search tests. Adds minigu-test/gql/dml/insert.slt covering: - 7 happy paths: single vertex, multiple vertices, vertex+edge, self-type edges, reused vertex variables across edges, zero-value boundary, reverse-direction edge - 8 error paths: unknown label/property, missing required property, property/edge type mismatch, undefined edge endpoint, duplicate variable, edge endpoint type mismatch - 4 MATCH verifications confirming inserted data is readable Updates 8 insta snapshots in ddl/dml/misc whose INSERT statements previously failed at parse time and now reach the binder (where they fail with CurrentGraphNotSpecified because those test programs don't set the current graph before INSERT -- a separate gap). Co-Authored-By: Claude Opus 4.7 --- minigu-test/gql/ddl/ddl_drop@e2e.snap | 52 +- minigu-test/gql/ddl/ddl_drop@parser.snap | 908 ++- minigu-test/gql/ddl/ddl_truncate@e2e.snap | 52 +- minigu-test/gql/ddl/ddl_truncate@parser.snap | 880 ++- minigu-test/gql/dml/dml_dql@e2e.snap | 455 +- minigu-test/gql/dml/dml_dql@parser.snap | 6874 ++++++++++++++++- minigu-test/gql/dml/insert.slt | 137 + minigu-test/gql/misc/vector_index@e2e.snap | 13 +- minigu-test/gql/misc/vector_index@parser.snap | 133 +- .../procedures/create_insert_test_graph.rs | 131 + minigu/core/src/procedures/mod.rs | 5 + 11 files changed, 8802 insertions(+), 838 deletions(-) create mode 100644 minigu-test/gql/dml/insert.slt create mode 100644 minigu/core/src/procedures/create_insert_test_graph.rs diff --git a/minigu-test/gql/ddl/ddl_drop@e2e.snap b/minigu-test/gql/ddl/ddl_drop@e2e.snap index 1bd82e62d..c9f6d279f 100644 --- a/minigu-test/gql/ddl/ddl_drop@e2e.snap +++ b/minigu-test/gql/ddl/ddl_drop@e2e.snap @@ -65,29 +65,15 @@ Error: Parser( ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity {id:'table1001',entity_type:'table',deleted:0,gen_time:0,name:'dml-test',guid:'table1001',status:1,props:'table1001',test1:1001,test2:1,test3:'table1001'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity {id:'table10001',entity_type:'table',deleted:0,gen_time:0,name:'dml-test',guid:'table1001',status:1,props:'table1001',test1:1001,test2:1,test3:'table1001'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- @@ -203,29 +189,15 @@ Error: Parser( ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity {id:'table2001',entity_type:'table',deleted:0,gen_time:0,name:'dml-test',guid:'table2001',status:1,props:'table2001',test1:2001,test2:1,test3:'table2001',test4:'table2001'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity {id:'table20001',entity_type:'table',deleted:0,gen_time:0,name:'dml-test',guid:'table2001',status:1,props:'table2001',test1:2001,test2:1,test3:'table2001',test4:'table2001'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- diff --git a/minigu-test/gql/ddl/ddl_drop@parser.snap b/minigu-test/gql/ddl/ddl_drop@parser.snap index fc887c171..0bb2b85c7 100644 --- a/minigu-test/gql/ddl/ddl_drop@parser.snap +++ b/minigu-test/gql/ddl/ddl_drop@parser.snap @@ -266,24 +266,428 @@ source: minigu-test/src/insta_test.rs position: - 1 - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity {id:'table1001',entity_type:'table',deleted:0,gen_time:0,name:'dml-test',guid:'table1001',status:1,props:'table1001',test1:1001,test2:1,test3:'table1001'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity {id:'table10001',entity_type:'table',deleted:0,gen_time:0,name:'dml-test',guid:'table1001',status:1,props:'table1001',test1:1001,test2:1,test3:'table1001'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - id + - start: 18 + end: 20 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 21 + end: 32 + - start: 18 + end: 32 + - - name: + - entity_type + - start: 33 + end: 44 + value: + - Value: + Literal: + String: + kind: Char + literal: table + - start: 45 + end: 52 + - start: 33 + end: 52 + - - name: + - deleted + - start: 53 + end: 60 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 61 + end: 62 + - start: 61 + end: 62 + - start: 53 + end: 62 + - - name: + - gen_time + - start: 63 + end: 71 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 72 + end: 73 + - start: 72 + end: 73 + - start: 63 + end: 73 + - - name: + - name + - start: 74 + end: 78 + value: + - Value: + Literal: + String: + kind: Char + literal: dml-test + - start: 79 + end: 89 + - start: 74 + end: 89 + - - name: + - guid + - start: 90 + end: 94 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 95 + end: 106 + - start: 90 + end: 106 + - - name: + - status + - start: 107 + end: 113 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 114 + end: 115 + - start: 114 + end: 115 + - start: 107 + end: 115 + - - name: + - props + - start: 116 + end: 121 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 122 + end: 133 + - start: 116 + end: 133 + - - name: + - test1 + - start: 134 + end: 139 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1001" + - start: 140 + end: 144 + - start: 140 + end: 144 + - start: 134 + end: 144 + - - name: + - test2 + - start: 145 + end: 150 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 151 + end: 152 + - start: 151 + end: 152 + - start: 145 + end: 152 + - - name: + - test3 + - start: 153 + end: 158 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 159 + end: 170 + - start: 153 + end: 170 + - start: 17 + end: 171 + - start: 7 + end: 172 + - start: 7 + end: 172 + - start: 0 + end: 172 + - start: 0 + end: 172 + next_statements: [] + - start: 0 + end: 172 + end: ~ + - start: 0 + end: 172 + session_close: false + - start: 0 + end: 172 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - id + - start: 18 + end: 20 + value: + - Value: + Literal: + String: + kind: Char + literal: table10001 + - start: 21 + end: 33 + - start: 18 + end: 33 + - - name: + - entity_type + - start: 34 + end: 45 + value: + - Value: + Literal: + String: + kind: Char + literal: table + - start: 46 + end: 53 + - start: 34 + end: 53 + - - name: + - deleted + - start: 54 + end: 61 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 62 + end: 63 + - start: 62 + end: 63 + - start: 54 + end: 63 + - - name: + - gen_time + - start: 64 + end: 72 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 73 + end: 74 + - start: 73 + end: 74 + - start: 64 + end: 74 + - - name: + - name + - start: 75 + end: 79 + value: + - Value: + Literal: + String: + kind: Char + literal: dml-test + - start: 80 + end: 90 + - start: 75 + end: 90 + - - name: + - guid + - start: 91 + end: 95 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 96 + end: 107 + - start: 91 + end: 107 + - - name: + - status + - start: 108 + end: 114 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 115 + end: 116 + - start: 115 + end: 116 + - start: 108 + end: 116 + - - name: + - props + - start: 117 + end: 122 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 123 + end: 134 + - start: 117 + end: 134 + - - name: + - test1 + - start: 135 + end: 140 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1001" + - start: 141 + end: 145 + - start: 141 + end: 145 + - start: 135 + end: 145 + - - name: + - test2 + - start: 146 + end: 151 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 152 + end: 153 + - start: 152 + end: 153 + - start: 146 + end: 153 + - - name: + - test3 + - start: 154 + end: 159 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 160 + end: 171 + - start: 154 + end: 171 + - start: 17 + end: 172 + - start: 7 + end: 173 + - start: 7 + end: 173 + - start: 0 + end: 173 + - start: 0 + end: 173 + next_statements: [] + - start: 0 + end: 173 + end: ~ + - start: 0 + end: 173 + session_close: false + - start: 0 + end: 173 - Err: Unexpected: input: "MATCH (n:Entity{id:'table10001'}), (m:Entity{id:'table1001'})\nINSERT (n)-[r:Rel{timestamp:0,deleted:0,rel_scene:'0',rel_type:'table2table',gen_time:0,rel_chain:'0',dst_guid:'table1001',src_guid:'table10001',status:0,props:'table10001_table2table_table1001'}]->(m)" @@ -473,24 +877,456 @@ source: minigu-test/src/insta_test.rs position: - 1 - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity {id:'table2001',entity_type:'table',deleted:0,gen_time:0,name:'dml-test',guid:'table2001',status:1,props:'table2001',test1:2001,test2:1,test3:'table2001',test4:'table2001'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity {id:'table20001',entity_type:'table',deleted:0,gen_time:0,name:'dml-test',guid:'table2001',status:1,props:'table2001',test1:2001,test2:1,test3:'table2001',test4:'table2001'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - id + - start: 18 + end: 20 + value: + - Value: + Literal: + String: + kind: Char + literal: table2001 + - start: 21 + end: 32 + - start: 18 + end: 32 + - - name: + - entity_type + - start: 33 + end: 44 + value: + - Value: + Literal: + String: + kind: Char + literal: table + - start: 45 + end: 52 + - start: 33 + end: 52 + - - name: + - deleted + - start: 53 + end: 60 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 61 + end: 62 + - start: 61 + end: 62 + - start: 53 + end: 62 + - - name: + - gen_time + - start: 63 + end: 71 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 72 + end: 73 + - start: 72 + end: 73 + - start: 63 + end: 73 + - - name: + - name + - start: 74 + end: 78 + value: + - Value: + Literal: + String: + kind: Char + literal: dml-test + - start: 79 + end: 89 + - start: 74 + end: 89 + - - name: + - guid + - start: 90 + end: 94 + value: + - Value: + Literal: + String: + kind: Char + literal: table2001 + - start: 95 + end: 106 + - start: 90 + end: 106 + - - name: + - status + - start: 107 + end: 113 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 114 + end: 115 + - start: 114 + end: 115 + - start: 107 + end: 115 + - - name: + - props + - start: 116 + end: 121 + value: + - Value: + Literal: + String: + kind: Char + literal: table2001 + - start: 122 + end: 133 + - start: 116 + end: 133 + - - name: + - test1 + - start: 134 + end: 139 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "2001" + - start: 140 + end: 144 + - start: 140 + end: 144 + - start: 134 + end: 144 + - - name: + - test2 + - start: 145 + end: 150 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 151 + end: 152 + - start: 151 + end: 152 + - start: 145 + end: 152 + - - name: + - test3 + - start: 153 + end: 158 + value: + - Value: + Literal: + String: + kind: Char + literal: table2001 + - start: 159 + end: 170 + - start: 153 + end: 170 + - - name: + - test4 + - start: 171 + end: 176 + value: + - Value: + Literal: + String: + kind: Char + literal: table2001 + - start: 177 + end: 188 + - start: 171 + end: 188 + - start: 17 + end: 189 + - start: 7 + end: 190 + - start: 7 + end: 190 + - start: 0 + end: 190 + - start: 0 + end: 190 + next_statements: [] + - start: 0 + end: 190 + end: ~ + - start: 0 + end: 190 + session_close: false + - start: 0 + end: 190 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - id + - start: 18 + end: 20 + value: + - Value: + Literal: + String: + kind: Char + literal: table20001 + - start: 21 + end: 33 + - start: 18 + end: 33 + - - name: + - entity_type + - start: 34 + end: 45 + value: + - Value: + Literal: + String: + kind: Char + literal: table + - start: 46 + end: 53 + - start: 34 + end: 53 + - - name: + - deleted + - start: 54 + end: 61 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 62 + end: 63 + - start: 62 + end: 63 + - start: 54 + end: 63 + - - name: + - gen_time + - start: 64 + end: 72 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 73 + end: 74 + - start: 73 + end: 74 + - start: 64 + end: 74 + - - name: + - name + - start: 75 + end: 79 + value: + - Value: + Literal: + String: + kind: Char + literal: dml-test + - start: 80 + end: 90 + - start: 75 + end: 90 + - - name: + - guid + - start: 91 + end: 95 + value: + - Value: + Literal: + String: + kind: Char + literal: table2001 + - start: 96 + end: 107 + - start: 91 + end: 107 + - - name: + - status + - start: 108 + end: 114 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 115 + end: 116 + - start: 115 + end: 116 + - start: 108 + end: 116 + - - name: + - props + - start: 117 + end: 122 + value: + - Value: + Literal: + String: + kind: Char + literal: table2001 + - start: 123 + end: 134 + - start: 117 + end: 134 + - - name: + - test1 + - start: 135 + end: 140 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "2001" + - start: 141 + end: 145 + - start: 141 + end: 145 + - start: 135 + end: 145 + - - name: + - test2 + - start: 146 + end: 151 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 152 + end: 153 + - start: 152 + end: 153 + - start: 146 + end: 153 + - - name: + - test3 + - start: 154 + end: 159 + value: + - Value: + Literal: + String: + kind: Char + literal: table2001 + - start: 160 + end: 171 + - start: 154 + end: 171 + - - name: + - test4 + - start: 172 + end: 177 + value: + - Value: + Literal: + String: + kind: Char + literal: table2001 + - start: 178 + end: 189 + - start: 172 + end: 189 + - start: 17 + end: 190 + - start: 7 + end: 191 + - start: 7 + end: 191 + - start: 0 + end: 191 + - start: 0 + end: 191 + next_statements: [] + - start: 0 + end: 191 + end: ~ + - start: 0 + end: 191 + session_close: false + - start: 0 + end: 191 - Err: Unexpected: input: "MATCH (n:Entity{id:'table20001'}), (m:Entity{id:'table2001'})\nINSERT (n)-[r:Rel{timestamp:0,deleted:0,rel_scene:'0',rel_type:'table2table',gen_time:0,rel_chain:'0',dst_guid:'table2001',src_guid:'table20001',status:0,props:'table20001_table2table_table2001', props1:'props1'}]->(m)" diff --git a/minigu-test/gql/ddl/ddl_truncate@e2e.snap b/minigu-test/gql/ddl/ddl_truncate@e2e.snap index a4621fb3e..b938eabb1 100644 --- a/minigu-test/gql/ddl/ddl_truncate@e2e.snap +++ b/minigu-test/gql/ddl/ddl_truncate@e2e.snap @@ -55,29 +55,15 @@ Error: Parser( ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity {id:'table1001',entity_type:'table',deleted:0,gen_time:0,name:'dml-test',guid:'table1001',status:1,props:'table1001',test1:1001,test2:1,test3:'table1001'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity {id:'table10001',entity_type:'table',deleted:0,gen_time:0,name:'dml-test',guid:'table1001',status:1,props:'table1001',test1:1001,test2:1,test3:'table1001'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- @@ -159,29 +145,15 @@ Error: Plan( ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity {id:'table2001',entity_type:'table',deleted:0,gen_time:0,name:'dml-test',guid:'table2001',status:1,props:'table2001',test1:2001,test2:1,test3:'table2001'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity {id:'table20001',entity_type:'table',deleted:0,gen_time:0,name:'dml-test',guid:'table2001',status:1,props:'table2001',test1:2001,test2:1,test3:'table2001'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- diff --git a/minigu-test/gql/ddl/ddl_truncate@parser.snap b/minigu-test/gql/ddl/ddl_truncate@parser.snap index d051da831..d2a9f91f8 100644 --- a/minigu-test/gql/ddl/ddl_truncate@parser.snap +++ b/minigu-test/gql/ddl/ddl_truncate@parser.snap @@ -19,24 +19,428 @@ source: minigu-test/src/insta_test.rs position: - 1 - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity {id:'table1001',entity_type:'table',deleted:0,gen_time:0,name:'dml-test',guid:'table1001',status:1,props:'table1001',test1:1001,test2:1,test3:'table1001'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity {id:'table10001',entity_type:'table',deleted:0,gen_time:0,name:'dml-test',guid:'table1001',status:1,props:'table1001',test1:1001,test2:1,test3:'table1001'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - id + - start: 18 + end: 20 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 21 + end: 32 + - start: 18 + end: 32 + - - name: + - entity_type + - start: 33 + end: 44 + value: + - Value: + Literal: + String: + kind: Char + literal: table + - start: 45 + end: 52 + - start: 33 + end: 52 + - - name: + - deleted + - start: 53 + end: 60 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 61 + end: 62 + - start: 61 + end: 62 + - start: 53 + end: 62 + - - name: + - gen_time + - start: 63 + end: 71 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 72 + end: 73 + - start: 72 + end: 73 + - start: 63 + end: 73 + - - name: + - name + - start: 74 + end: 78 + value: + - Value: + Literal: + String: + kind: Char + literal: dml-test + - start: 79 + end: 89 + - start: 74 + end: 89 + - - name: + - guid + - start: 90 + end: 94 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 95 + end: 106 + - start: 90 + end: 106 + - - name: + - status + - start: 107 + end: 113 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 114 + end: 115 + - start: 114 + end: 115 + - start: 107 + end: 115 + - - name: + - props + - start: 116 + end: 121 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 122 + end: 133 + - start: 116 + end: 133 + - - name: + - test1 + - start: 134 + end: 139 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1001" + - start: 140 + end: 144 + - start: 140 + end: 144 + - start: 134 + end: 144 + - - name: + - test2 + - start: 145 + end: 150 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 151 + end: 152 + - start: 151 + end: 152 + - start: 145 + end: 152 + - - name: + - test3 + - start: 153 + end: 158 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 159 + end: 170 + - start: 153 + end: 170 + - start: 17 + end: 171 + - start: 7 + end: 172 + - start: 7 + end: 172 + - start: 0 + end: 172 + - start: 0 + end: 172 + next_statements: [] + - start: 0 + end: 172 + end: ~ + - start: 0 + end: 172 + session_close: false + - start: 0 + end: 172 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - id + - start: 18 + end: 20 + value: + - Value: + Literal: + String: + kind: Char + literal: table10001 + - start: 21 + end: 33 + - start: 18 + end: 33 + - - name: + - entity_type + - start: 34 + end: 45 + value: + - Value: + Literal: + String: + kind: Char + literal: table + - start: 46 + end: 53 + - start: 34 + end: 53 + - - name: + - deleted + - start: 54 + end: 61 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 62 + end: 63 + - start: 62 + end: 63 + - start: 54 + end: 63 + - - name: + - gen_time + - start: 64 + end: 72 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 73 + end: 74 + - start: 73 + end: 74 + - start: 64 + end: 74 + - - name: + - name + - start: 75 + end: 79 + value: + - Value: + Literal: + String: + kind: Char + literal: dml-test + - start: 80 + end: 90 + - start: 75 + end: 90 + - - name: + - guid + - start: 91 + end: 95 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 96 + end: 107 + - start: 91 + end: 107 + - - name: + - status + - start: 108 + end: 114 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 115 + end: 116 + - start: 115 + end: 116 + - start: 108 + end: 116 + - - name: + - props + - start: 117 + end: 122 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 123 + end: 134 + - start: 117 + end: 134 + - - name: + - test1 + - start: 135 + end: 140 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1001" + - start: 141 + end: 145 + - start: 141 + end: 145 + - start: 135 + end: 145 + - - name: + - test2 + - start: 146 + end: 151 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 152 + end: 153 + - start: 152 + end: 153 + - start: 146 + end: 153 + - - name: + - test3 + - start: 154 + end: 159 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 160 + end: 171 + - start: 154 + end: 171 + - start: 17 + end: 172 + - start: 7 + end: 173 + - start: 7 + end: 173 + - start: 0 + end: 173 + - start: 0 + end: 173 + next_statements: [] + - start: 0 + end: 173 + end: ~ + - start: 0 + end: 173 + session_close: false + - start: 0 + end: 173 - Err: Unexpected: input: "MATCH (n:Entity{id:'table10001'}), (m:Entity{id:'table1001'})\nINSERT (n)-[r:Rel{timestamp:0,deleted:0,rel_scene:'0',rel_type:'table2table',gen_time:0,rel_chain:'0',dst_guid:'table1001',src_guid:'table10001',status:0,props:'table10001_table2table_table1001'}]->(m)" @@ -352,24 +756,428 @@ source: minigu-test/src/insta_test.rs session_close: false - start: 0 end: 67 -- Err: - Unexpected: - input: "INSERT (n:Entity {id:'table2001',entity_type:'table',deleted:0,gen_time:0,name:'dml-test',guid:'table2001',status:1,props:'table2001',test1:2001,test2:1,test3:'table2001'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity {id:'table20001',entity_type:'table',deleted:0,gen_time:0,name:'dml-test',guid:'table2001',status:1,props:'table2001',test1:2001,test2:1,test3:'table2001'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - id + - start: 18 + end: 20 + value: + - Value: + Literal: + String: + kind: Char + literal: table2001 + - start: 21 + end: 32 + - start: 18 + end: 32 + - - name: + - entity_type + - start: 33 + end: 44 + value: + - Value: + Literal: + String: + kind: Char + literal: table + - start: 45 + end: 52 + - start: 33 + end: 52 + - - name: + - deleted + - start: 53 + end: 60 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 61 + end: 62 + - start: 61 + end: 62 + - start: 53 + end: 62 + - - name: + - gen_time + - start: 63 + end: 71 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 72 + end: 73 + - start: 72 + end: 73 + - start: 63 + end: 73 + - - name: + - name + - start: 74 + end: 78 + value: + - Value: + Literal: + String: + kind: Char + literal: dml-test + - start: 79 + end: 89 + - start: 74 + end: 89 + - - name: + - guid + - start: 90 + end: 94 + value: + - Value: + Literal: + String: + kind: Char + literal: table2001 + - start: 95 + end: 106 + - start: 90 + end: 106 + - - name: + - status + - start: 107 + end: 113 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 114 + end: 115 + - start: 114 + end: 115 + - start: 107 + end: 115 + - - name: + - props + - start: 116 + end: 121 + value: + - Value: + Literal: + String: + kind: Char + literal: table2001 + - start: 122 + end: 133 + - start: 116 + end: 133 + - - name: + - test1 + - start: 134 + end: 139 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "2001" + - start: 140 + end: 144 + - start: 140 + end: 144 + - start: 134 + end: 144 + - - name: + - test2 + - start: 145 + end: 150 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 151 + end: 152 + - start: 151 + end: 152 + - start: 145 + end: 152 + - - name: + - test3 + - start: 153 + end: 158 + value: + - Value: + Literal: + String: + kind: Char + literal: table2001 + - start: 159 + end: 170 + - start: 153 + end: 170 + - start: 17 + end: 171 + - start: 7 + end: 172 + - start: 7 + end: 172 + - start: 0 + end: 172 + - start: 0 + end: 172 + next_statements: [] + - start: 0 + end: 172 + end: ~ + - start: 0 + end: 172 + session_close: false + - start: 0 + end: 172 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - id + - start: 18 + end: 20 + value: + - Value: + Literal: + String: + kind: Char + literal: table20001 + - start: 21 + end: 33 + - start: 18 + end: 33 + - - name: + - entity_type + - start: 34 + end: 45 + value: + - Value: + Literal: + String: + kind: Char + literal: table + - start: 46 + end: 53 + - start: 34 + end: 53 + - - name: + - deleted + - start: 54 + end: 61 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 62 + end: 63 + - start: 62 + end: 63 + - start: 54 + end: 63 + - - name: + - gen_time + - start: 64 + end: 72 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 73 + end: 74 + - start: 73 + end: 74 + - start: 64 + end: 74 + - - name: + - name + - start: 75 + end: 79 + value: + - Value: + Literal: + String: + kind: Char + literal: dml-test + - start: 80 + end: 90 + - start: 75 + end: 90 + - - name: + - guid + - start: 91 + end: 95 + value: + - Value: + Literal: + String: + kind: Char + literal: table2001 + - start: 96 + end: 107 + - start: 91 + end: 107 + - - name: + - status + - start: 108 + end: 114 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 115 + end: 116 + - start: 115 + end: 116 + - start: 108 + end: 116 + - - name: + - props + - start: 117 + end: 122 + value: + - Value: + Literal: + String: + kind: Char + literal: table2001 + - start: 123 + end: 134 + - start: 117 + end: 134 + - - name: + - test1 + - start: 135 + end: 140 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "2001" + - start: 141 + end: 145 + - start: 141 + end: 145 + - start: 135 + end: 145 + - - name: + - test2 + - start: 146 + end: 151 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 152 + end: 153 + - start: 152 + end: 153 + - start: 146 + end: 153 + - - name: + - test3 + - start: 154 + end: 159 + value: + - Value: + Literal: + String: + kind: Char + literal: table2001 + - start: 160 + end: 171 + - start: 154 + end: 171 + - start: 17 + end: 172 + - start: 7 + end: 173 + - start: 7 + end: 173 + - start: 0 + end: 173 + - start: 0 + end: 173 + next_statements: [] + - start: 0 + end: 173 + end: ~ + - start: 0 + end: 173 + session_close: false + - start: 0 + end: 173 - Err: Unexpected: input: "MATCH (n:Entity{id:'table20001'}), (m:Entity{id:'table2001'}) INSERT (n)-[r:Rel{timestamp:0,deleted:0,rel_scene:'0',rel_type:'table2table',gen_time:0,rel_chain:'0',dst_guid:'table2001',src_guid:'table20001',status:0,props:'table20001_table2table_table2001'}]->(m)" diff --git a/minigu-test/gql/dml/dml_dql@e2e.snap b/minigu-test/gql/dml/dml_dql@e2e.snap index b35d028a8..8ce3fcaf7 100644 --- a/minigu-test/gql/dml/dml_dql@e2e.snap +++ b/minigu-test/gql/dml/dml_dql@e2e.snap @@ -64,29 +64,15 @@ Error: Parser( ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity {id:'table1001',entity_type:'table',deleted:0,gen_time:0,name:'dml-test',guid:'table1001',status:1,props:'table1001',test1:1001,test2:1,test3:'table1001',test4:'table1001',test5:'table1001',test6:'table1001',test7:'table1001',test8:'table1001',test9:'table1001',test10:'table1001',test11:'table1001',test12:'table1001'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity {id:'table10001',entity_type:'table',deleted:0,gen_time:0,name:'dml-test',guid:'table1001',status:1,props:'table1001',test1:1001,test2:1,test3:'table1001',test4:'table1001',test5:'table1001',test6:'table1001',test7:'table1001',test8:'table1001',test9:'table1001',test10:'table1001',test11:'table1001',test12:'table1001'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- @@ -233,237 +219,111 @@ Error: Parser( ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity {id: 30001, entity_type: 'table30001', deleted: 0, gen_time: 1001, name: 'table30001', guid:'table30001', status: 1, props: 'table30001', test1: 'table30001', test2: 'table30001', test3: 'table30001', test4: 'table30001', test5: 'table30001', test6: 'table30001', test7: 'table30001', test8: 'table30001', test9: 'table30001', test10: 'table30001', test11: 'table30001', test12: 'table30001'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity {id: 30002, entity_type: 'table30002', deleted: 0, gen_time: 1001, name: 'table30002', guid:'table30002', status: 1, props: 'table30002', test1: 'table30002', test2: 'table30002', test3: 'table30002', test4: 'table30002', test5: 'table30002', test6: 'table30002', test7: 'table30002', test8: 'table30002', test9: 'table30002', test10: 'table30002', test11: 'table30002', test12: 'table30002'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity {id: 30003, entity_type: 'table30003', deleted: 0, gen_time: 1001, name: 'table30003', guid:'table30003', status: 1, props: 'table30003', test1: 'table30003', test2: 'table30003', test3: 'table30003', test4: 'table30003', test5: 'table30003', test6: 'table30003', test7: 'table30003', test8: 'table30003', test9: 'table30003', test10: 'table30003', test11: 'table30003', test12: 'table30003'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity {id: 30004, entity_type: 'table30004', deleted: 0, gen_time: 1001, name: 'table30004', guid:'table30004', status: 1, props: 'table30004', test1: 'table30004', test2: 'table30004', test3: 'table30004', test4: 'table30004', test5: 'table30004', test6: 'table30004', test7: 'table30004', test8: 'table30004', test9: 'table30004', test10: 'table30004', test11: 'table30004', test12: 'table30004'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity {id: 30005, entity_type: 'table30005', deleted: 0, gen_time: 1001, name: 'table30005', guid:'table30005', status: 1, props: 'table30005', test1: 'table30005', test2: 'table30005', test3: 'table30005', test4: 'table30005', test5: 'table30005', test6: 'table30005', test7: 'table30005', test8: 'table30005', test9: 'table30005', test10: 'table30005', test11: 'table30005', test12: 'table30005'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity {id: 30006, entity_type: 'table30006', deleted: 0, gen_time: 1001, name: 'table30006', guid:'table30006', status: 1, props: 'table30006', test1: 'table30006', test2: 'table30006', test3: 'table30006', test4: 'table30006', test5: 'table30006', test6: 'table30006', test7: 'table30006', test8: 'table30006', test9: 'table30006', test10: 'table30006', test11: 'table30006', test12: 'table30006'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity {id: 30007, entity_type: 'table30007', deleted: 0, gen_time: 1001, name: 'table30007', guid:'table30007', status: 1, props: 'table30007', test1: 'table30007', test2: 'table30007', test3: 'table30007', test4: 'table30007', test5: 'table30007', test6: 'table30007', test7: 'table30007', test8: 'table30007', test9: 'table30007', test10: 'table30007', test11: 'table30007', test12: 'table30007'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity {id: 30008, entity_type: 'table30008', deleted: 0, gen_time: 1001, name: 'table30008', guid:'table30008', status: 1, props: 'table30008', test1: 'table30008', test2: 'table30008', test3: 'table30008', test4: 'table30008', test5: 'table30008', test6: 'table30008', test7: 'table30008', test8: 'table30008', test9: 'table30008', test10: 'table30008', test11: 'table30008', test12: 'table30008'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity {id: 401, entity_type: 'e', deleted: 0, gen_time: 1001, name: 'table401', guid:'table401', status: 1, props: 'table401', test1: 'FAKE', test2: 'FAKE', test3: 'FAKE', test4: 'FAKE', test5: 'FAKE', test6: 'FAKE', test7: 'FAKE', test8: 'FAKE', test9: 'FAKE', test10: 'FAKE', test11: 'FAKE', test12: 'FAKE'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity {id: 402, entity_type: 'e', deleted: 0, gen_time: 1001, name: 'table402', guid:'table402', status: 1, props: 'table402', test1: 'FAKE', test2: 'FAKE', test3: 'FAKE', test4: 'FAKE', test5: 'FAKE', test6: 'FAKE', test7: 'FAKE', test8: 'FAKE', test9: 'FAKE', test10: 'FAKE', test11: 'FAKE', test12: 'FAKE'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity {id: 403, entity_type: 'e', deleted: 0, gen_time: 1001, name: 'table403', guid:'table403', status: 1, props: 'table403', test1: 'FAKE', test2: 'FAKE', test3: 'FAKE', test4: 'FAKE', test5: 'FAKE', test6: 'FAKE', test7: 'FAKE', test8: 'FAKE', test9: 'FAKE', test10: 'FAKE', test11: 'FAKE', test12: 'FAKE'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity {id: 404, entity_type: 'e', deleted: 0, gen_time: 1001, name: 'table404', guid:'table404', status: 1, props: 'table404', test1: 'FAKE', test2: 'FAKE', test3: 'FAKE', test4: 'FAKE', test5: 'FAKE', test6: 'FAKE', test7: 'FAKE', test8: 'FAKE', test9: 'FAKE', test10: 'FAKE', test11: 'FAKE', test12: 'FAKE'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity1 {id:1000, entity_type: 'Bob1000', deleted:0})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity1 {id:1001, entity_type: 'Bob1001', deleted:0})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity2 {id:1002, entity_type: 'Bob1002', deleted:0, gen_time:1002})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity2 {id:1003, entity_type: 'Bob1003', deleted:0, gen_time:1003})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity2 {id:1004, entity_type: 'Bob1004', deleted:0, gen_time:1004})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity3 {id:1, name: 'Bob'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- @@ -480,120 +340,57 @@ Error: Parser( ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity3 {id:2, name: 'Bob1'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity3 {id:3, name: 'Bob12'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity3 {id:4, name: 'Bob123'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity3 {id:5, name: 'Bob222'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity3 {id:6, name: '666'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity4 {id:7, text: 'hello world'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity4 {id:8, text: '666'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity4 {id:9, text: '{\"a\":1, \"b\":2}'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity4 {id:10, text: '{\"a\":3}'})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- @@ -1156,29 +953,15 @@ Error: Plan( ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity {id: 28, name: 'Bob8', deleted:0, gen_time:99})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity {id: 29, name: 'Bob9', deleted:0, gen_time:100})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- @@ -1195,16 +978,9 @@ Error: Parser( ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity {id: 30, name: 'Bob10', deleted:0, gen_time:100})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- @@ -1221,29 +997,15 @@ Error: Parser( ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity {id: 38, name: 'Bob38', deleted:0, gen_time:99})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity {id: 381, name: 'Bob381', deleted:0, gen_time:99})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- @@ -1260,16 +1022,9 @@ Error: Parser( ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity {id: 39, name: 'Bob39', deleted:0, gen_time:100})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- diff --git a/minigu-test/gql/dml/dml_dql@parser.snap b/minigu-test/gql/dml/dml_dql@parser.snap index 2bc2c0c6f..a2a67f507 100644 --- a/minigu-test/gql/dml/dml_dql@parser.snap +++ b/minigu-test/gql/dml/dml_dql@parser.snap @@ -19,24 +19,680 @@ source: minigu-test/src/insta_test.rs position: - 1 - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity {id:'table1001',entity_type:'table',deleted:0,gen_time:0,name:'dml-test',guid:'table1001',status:1,props:'table1001',test1:1001,test2:1,test3:'table1001',test4:'table1001',test5:'table1001',test6:'table1001',test7:'table1001',test8:'table1001',test9:'table1001',test10:'table1001',test11:'table1001',test12:'table1001'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity {id:'table10001',entity_type:'table',deleted:0,gen_time:0,name:'dml-test',guid:'table1001',status:1,props:'table1001',test1:1001,test2:1,test3:'table1001',test4:'table1001',test5:'table1001',test6:'table1001',test7:'table1001',test8:'table1001',test9:'table1001',test10:'table1001',test11:'table1001',test12:'table1001'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - id + - start: 18 + end: 20 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 21 + end: 32 + - start: 18 + end: 32 + - - name: + - entity_type + - start: 33 + end: 44 + value: + - Value: + Literal: + String: + kind: Char + literal: table + - start: 45 + end: 52 + - start: 33 + end: 52 + - - name: + - deleted + - start: 53 + end: 60 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 61 + end: 62 + - start: 61 + end: 62 + - start: 53 + end: 62 + - - name: + - gen_time + - start: 63 + end: 71 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 72 + end: 73 + - start: 72 + end: 73 + - start: 63 + end: 73 + - - name: + - name + - start: 74 + end: 78 + value: + - Value: + Literal: + String: + kind: Char + literal: dml-test + - start: 79 + end: 89 + - start: 74 + end: 89 + - - name: + - guid + - start: 90 + end: 94 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 95 + end: 106 + - start: 90 + end: 106 + - - name: + - status + - start: 107 + end: 113 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 114 + end: 115 + - start: 114 + end: 115 + - start: 107 + end: 115 + - - name: + - props + - start: 116 + end: 121 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 122 + end: 133 + - start: 116 + end: 133 + - - name: + - test1 + - start: 134 + end: 139 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1001" + - start: 140 + end: 144 + - start: 140 + end: 144 + - start: 134 + end: 144 + - - name: + - test2 + - start: 145 + end: 150 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 151 + end: 152 + - start: 151 + end: 152 + - start: 145 + end: 152 + - - name: + - test3 + - start: 153 + end: 158 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 159 + end: 170 + - start: 153 + end: 170 + - - name: + - test4 + - start: 171 + end: 176 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 177 + end: 188 + - start: 171 + end: 188 + - - name: + - test5 + - start: 189 + end: 194 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 195 + end: 206 + - start: 189 + end: 206 + - - name: + - test6 + - start: 207 + end: 212 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 213 + end: 224 + - start: 207 + end: 224 + - - name: + - test7 + - start: 225 + end: 230 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 231 + end: 242 + - start: 225 + end: 242 + - - name: + - test8 + - start: 243 + end: 248 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 249 + end: 260 + - start: 243 + end: 260 + - - name: + - test9 + - start: 261 + end: 266 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 267 + end: 278 + - start: 261 + end: 278 + - - name: + - test10 + - start: 279 + end: 285 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 286 + end: 297 + - start: 279 + end: 297 + - - name: + - test11 + - start: 298 + end: 304 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 305 + end: 316 + - start: 298 + end: 316 + - - name: + - test12 + - start: 317 + end: 323 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 324 + end: 335 + - start: 317 + end: 335 + - start: 17 + end: 336 + - start: 7 + end: 337 + - start: 7 + end: 337 + - start: 0 + end: 337 + - start: 0 + end: 337 + next_statements: [] + - start: 0 + end: 337 + end: ~ + - start: 0 + end: 337 + session_close: false + - start: 0 + end: 337 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - id + - start: 18 + end: 20 + value: + - Value: + Literal: + String: + kind: Char + literal: table10001 + - start: 21 + end: 33 + - start: 18 + end: 33 + - - name: + - entity_type + - start: 34 + end: 45 + value: + - Value: + Literal: + String: + kind: Char + literal: table + - start: 46 + end: 53 + - start: 34 + end: 53 + - - name: + - deleted + - start: 54 + end: 61 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 62 + end: 63 + - start: 62 + end: 63 + - start: 54 + end: 63 + - - name: + - gen_time + - start: 64 + end: 72 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 73 + end: 74 + - start: 73 + end: 74 + - start: 64 + end: 74 + - - name: + - name + - start: 75 + end: 79 + value: + - Value: + Literal: + String: + kind: Char + literal: dml-test + - start: 80 + end: 90 + - start: 75 + end: 90 + - - name: + - guid + - start: 91 + end: 95 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 96 + end: 107 + - start: 91 + end: 107 + - - name: + - status + - start: 108 + end: 114 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 115 + end: 116 + - start: 115 + end: 116 + - start: 108 + end: 116 + - - name: + - props + - start: 117 + end: 122 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 123 + end: 134 + - start: 117 + end: 134 + - - name: + - test1 + - start: 135 + end: 140 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1001" + - start: 141 + end: 145 + - start: 141 + end: 145 + - start: 135 + end: 145 + - - name: + - test2 + - start: 146 + end: 151 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 152 + end: 153 + - start: 152 + end: 153 + - start: 146 + end: 153 + - - name: + - test3 + - start: 154 + end: 159 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 160 + end: 171 + - start: 154 + end: 171 + - - name: + - test4 + - start: 172 + end: 177 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 178 + end: 189 + - start: 172 + end: 189 + - - name: + - test5 + - start: 190 + end: 195 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 196 + end: 207 + - start: 190 + end: 207 + - - name: + - test6 + - start: 208 + end: 213 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 214 + end: 225 + - start: 208 + end: 225 + - - name: + - test7 + - start: 226 + end: 231 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 232 + end: 243 + - start: 226 + end: 243 + - - name: + - test8 + - start: 244 + end: 249 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 250 + end: 261 + - start: 244 + end: 261 + - - name: + - test9 + - start: 262 + end: 267 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 268 + end: 279 + - start: 262 + end: 279 + - - name: + - test10 + - start: 280 + end: 286 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 287 + end: 298 + - start: 280 + end: 298 + - - name: + - test11 + - start: 299 + end: 305 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 306 + end: 317 + - start: 299 + end: 317 + - - name: + - test12 + - start: 318 + end: 324 + value: + - Value: + Literal: + String: + kind: Char + literal: table1001 + - start: 325 + end: 336 + - start: 318 + end: 336 + - start: 17 + end: 337 + - start: 7 + end: 338 + - start: 7 + end: 338 + - start: 0 + end: 338 + - start: 0 + end: 338 + next_statements: [] + - start: 0 + end: 338 + end: ~ + - start: 0 + end: 338 + session_close: false + - start: 0 + end: 338 - Err: Unexpected: input: "MATCH (n:Entity{id:'table10001'}), (m:Entity{id:'table1001'})\nINSERT (n)-[r:Rel{timestamp:0,deleted:0,rel_scene:'0',rel_type:'table2table',gen_time:0,rel_chain:'0',dst_guid:'table1001',src_guid:'table10001',status:0,props:'table10001_table2table_table1001'}]->(m)" @@ -360,258 +1016,5254 @@ source: minigu-test/src/insta_test.rs position: - 1 - 1 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - id + - start: 18 + end: 20 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "30001" + - start: 22 + end: 27 + - start: 22 + end: 27 + - start: 18 + end: 27 + - - name: + - entity_type + - start: 29 + end: 40 + value: + - Value: + Literal: + String: + kind: Char + literal: table30001 + - start: 42 + end: 54 + - start: 29 + end: 54 + - - name: + - deleted + - start: 56 + end: 63 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 65 + end: 66 + - start: 65 + end: 66 + - start: 56 + end: 66 + - - name: + - gen_time + - start: 68 + end: 76 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1001" + - start: 78 + end: 82 + - start: 78 + end: 82 + - start: 68 + end: 82 + - - name: + - name + - start: 84 + end: 88 + value: + - Value: + Literal: + String: + kind: Char + literal: table30001 + - start: 90 + end: 102 + - start: 84 + end: 102 + - - name: + - guid + - start: 104 + end: 108 + value: + - Value: + Literal: + String: + kind: Char + literal: table30001 + - start: 109 + end: 121 + - start: 104 + end: 121 + - - name: + - status + - start: 123 + end: 129 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 131 + end: 132 + - start: 131 + end: 132 + - start: 123 + end: 132 + - - name: + - props + - start: 134 + end: 139 + value: + - Value: + Literal: + String: + kind: Char + literal: table30001 + - start: 141 + end: 153 + - start: 134 + end: 153 + - - name: + - test1 + - start: 155 + end: 160 + value: + - Value: + Literal: + String: + kind: Char + literal: table30001 + - start: 162 + end: 174 + - start: 155 + end: 174 + - - name: + - test2 + - start: 176 + end: 181 + value: + - Value: + Literal: + String: + kind: Char + literal: table30001 + - start: 183 + end: 195 + - start: 176 + end: 195 + - - name: + - test3 + - start: 197 + end: 202 + value: + - Value: + Literal: + String: + kind: Char + literal: table30001 + - start: 204 + end: 216 + - start: 197 + end: 216 + - - name: + - test4 + - start: 218 + end: 223 + value: + - Value: + Literal: + String: + kind: Char + literal: table30001 + - start: 225 + end: 237 + - start: 218 + end: 237 + - - name: + - test5 + - start: 239 + end: 244 + value: + - Value: + Literal: + String: + kind: Char + literal: table30001 + - start: 246 + end: 258 + - start: 239 + end: 258 + - - name: + - test6 + - start: 260 + end: 265 + value: + - Value: + Literal: + String: + kind: Char + literal: table30001 + - start: 267 + end: 279 + - start: 260 + end: 279 + - - name: + - test7 + - start: 281 + end: 286 + value: + - Value: + Literal: + String: + kind: Char + literal: table30001 + - start: 288 + end: 300 + - start: 281 + end: 300 + - - name: + - test8 + - start: 302 + end: 307 + value: + - Value: + Literal: + String: + kind: Char + literal: table30001 + - start: 309 + end: 321 + - start: 302 + end: 321 + - - name: + - test9 + - start: 323 + end: 328 + value: + - Value: + Literal: + String: + kind: Char + literal: table30001 + - start: 330 + end: 342 + - start: 323 + end: 342 + - - name: + - test10 + - start: 344 + end: 350 + value: + - Value: + Literal: + String: + kind: Char + literal: table30001 + - start: 352 + end: 364 + - start: 344 + end: 364 + - - name: + - test11 + - start: 366 + end: 372 + value: + - Value: + Literal: + String: + kind: Char + literal: table30001 + - start: 374 + end: 386 + - start: 366 + end: 386 + - - name: + - test12 + - start: 388 + end: 394 + value: + - Value: + Literal: + String: + kind: Char + literal: table30001 + - start: 396 + end: 408 + - start: 388 + end: 408 + - start: 17 + end: 409 + - start: 7 + end: 410 + - start: 7 + end: 410 + - start: 0 + end: 410 + - start: 0 + end: 410 + next_statements: [] + - start: 0 + end: 410 + end: ~ + - start: 0 + end: 410 + session_close: false + - start: 0 + end: 410 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - id + - start: 18 + end: 20 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "30002" + - start: 22 + end: 27 + - start: 22 + end: 27 + - start: 18 + end: 27 + - - name: + - entity_type + - start: 29 + end: 40 + value: + - Value: + Literal: + String: + kind: Char + literal: table30002 + - start: 42 + end: 54 + - start: 29 + end: 54 + - - name: + - deleted + - start: 56 + end: 63 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 65 + end: 66 + - start: 65 + end: 66 + - start: 56 + end: 66 + - - name: + - gen_time + - start: 68 + end: 76 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1001" + - start: 78 + end: 82 + - start: 78 + end: 82 + - start: 68 + end: 82 + - - name: + - name + - start: 84 + end: 88 + value: + - Value: + Literal: + String: + kind: Char + literal: table30002 + - start: 90 + end: 102 + - start: 84 + end: 102 + - - name: + - guid + - start: 104 + end: 108 + value: + - Value: + Literal: + String: + kind: Char + literal: table30002 + - start: 109 + end: 121 + - start: 104 + end: 121 + - - name: + - status + - start: 123 + end: 129 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 131 + end: 132 + - start: 131 + end: 132 + - start: 123 + end: 132 + - - name: + - props + - start: 134 + end: 139 + value: + - Value: + Literal: + String: + kind: Char + literal: table30002 + - start: 141 + end: 153 + - start: 134 + end: 153 + - - name: + - test1 + - start: 155 + end: 160 + value: + - Value: + Literal: + String: + kind: Char + literal: table30002 + - start: 162 + end: 174 + - start: 155 + end: 174 + - - name: + - test2 + - start: 176 + end: 181 + value: + - Value: + Literal: + String: + kind: Char + literal: table30002 + - start: 183 + end: 195 + - start: 176 + end: 195 + - - name: + - test3 + - start: 197 + end: 202 + value: + - Value: + Literal: + String: + kind: Char + literal: table30002 + - start: 204 + end: 216 + - start: 197 + end: 216 + - - name: + - test4 + - start: 218 + end: 223 + value: + - Value: + Literal: + String: + kind: Char + literal: table30002 + - start: 225 + end: 237 + - start: 218 + end: 237 + - - name: + - test5 + - start: 239 + end: 244 + value: + - Value: + Literal: + String: + kind: Char + literal: table30002 + - start: 246 + end: 258 + - start: 239 + end: 258 + - - name: + - test6 + - start: 260 + end: 265 + value: + - Value: + Literal: + String: + kind: Char + literal: table30002 + - start: 267 + end: 279 + - start: 260 + end: 279 + - - name: + - test7 + - start: 281 + end: 286 + value: + - Value: + Literal: + String: + kind: Char + literal: table30002 + - start: 288 + end: 300 + - start: 281 + end: 300 + - - name: + - test8 + - start: 302 + end: 307 + value: + - Value: + Literal: + String: + kind: Char + literal: table30002 + - start: 309 + end: 321 + - start: 302 + end: 321 + - - name: + - test9 + - start: 323 + end: 328 + value: + - Value: + Literal: + String: + kind: Char + literal: table30002 + - start: 330 + end: 342 + - start: 323 + end: 342 + - - name: + - test10 + - start: 344 + end: 350 + value: + - Value: + Literal: + String: + kind: Char + literal: table30002 + - start: 352 + end: 364 + - start: 344 + end: 364 + - - name: + - test11 + - start: 366 + end: 372 + value: + - Value: + Literal: + String: + kind: Char + literal: table30002 + - start: 374 + end: 386 + - start: 366 + end: 386 + - - name: + - test12 + - start: 388 + end: 394 + value: + - Value: + Literal: + String: + kind: Char + literal: table30002 + - start: 396 + end: 408 + - start: 388 + end: 408 + - start: 17 + end: 409 + - start: 7 + end: 410 + - start: 7 + end: 410 + - start: 0 + end: 410 + - start: 0 + end: 410 + next_statements: [] + - start: 0 + end: 410 + end: ~ + - start: 0 + end: 410 + session_close: false + - start: 0 + end: 410 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - id + - start: 18 + end: 20 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "30003" + - start: 22 + end: 27 + - start: 22 + end: 27 + - start: 18 + end: 27 + - - name: + - entity_type + - start: 29 + end: 40 + value: + - Value: + Literal: + String: + kind: Char + literal: table30003 + - start: 42 + end: 54 + - start: 29 + end: 54 + - - name: + - deleted + - start: 56 + end: 63 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 65 + end: 66 + - start: 65 + end: 66 + - start: 56 + end: 66 + - - name: + - gen_time + - start: 68 + end: 76 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1001" + - start: 78 + end: 82 + - start: 78 + end: 82 + - start: 68 + end: 82 + - - name: + - name + - start: 84 + end: 88 + value: + - Value: + Literal: + String: + kind: Char + literal: table30003 + - start: 90 + end: 102 + - start: 84 + end: 102 + - - name: + - guid + - start: 104 + end: 108 + value: + - Value: + Literal: + String: + kind: Char + literal: table30003 + - start: 109 + end: 121 + - start: 104 + end: 121 + - - name: + - status + - start: 123 + end: 129 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 131 + end: 132 + - start: 131 + end: 132 + - start: 123 + end: 132 + - - name: + - props + - start: 134 + end: 139 + value: + - Value: + Literal: + String: + kind: Char + literal: table30003 + - start: 141 + end: 153 + - start: 134 + end: 153 + - - name: + - test1 + - start: 155 + end: 160 + value: + - Value: + Literal: + String: + kind: Char + literal: table30003 + - start: 162 + end: 174 + - start: 155 + end: 174 + - - name: + - test2 + - start: 176 + end: 181 + value: + - Value: + Literal: + String: + kind: Char + literal: table30003 + - start: 183 + end: 195 + - start: 176 + end: 195 + - - name: + - test3 + - start: 197 + end: 202 + value: + - Value: + Literal: + String: + kind: Char + literal: table30003 + - start: 204 + end: 216 + - start: 197 + end: 216 + - - name: + - test4 + - start: 218 + end: 223 + value: + - Value: + Literal: + String: + kind: Char + literal: table30003 + - start: 225 + end: 237 + - start: 218 + end: 237 + - - name: + - test5 + - start: 239 + end: 244 + value: + - Value: + Literal: + String: + kind: Char + literal: table30003 + - start: 246 + end: 258 + - start: 239 + end: 258 + - - name: + - test6 + - start: 260 + end: 265 + value: + - Value: + Literal: + String: + kind: Char + literal: table30003 + - start: 267 + end: 279 + - start: 260 + end: 279 + - - name: + - test7 + - start: 281 + end: 286 + value: + - Value: + Literal: + String: + kind: Char + literal: table30003 + - start: 288 + end: 300 + - start: 281 + end: 300 + - - name: + - test8 + - start: 302 + end: 307 + value: + - Value: + Literal: + String: + kind: Char + literal: table30003 + - start: 309 + end: 321 + - start: 302 + end: 321 + - - name: + - test9 + - start: 323 + end: 328 + value: + - Value: + Literal: + String: + kind: Char + literal: table30003 + - start: 330 + end: 342 + - start: 323 + end: 342 + - - name: + - test10 + - start: 344 + end: 350 + value: + - Value: + Literal: + String: + kind: Char + literal: table30003 + - start: 352 + end: 364 + - start: 344 + end: 364 + - - name: + - test11 + - start: 366 + end: 372 + value: + - Value: + Literal: + String: + kind: Char + literal: table30003 + - start: 374 + end: 386 + - start: 366 + end: 386 + - - name: + - test12 + - start: 388 + end: 394 + value: + - Value: + Literal: + String: + kind: Char + literal: table30003 + - start: 396 + end: 408 + - start: 388 + end: 408 + - start: 17 + end: 409 + - start: 7 + end: 410 + - start: 7 + end: 410 + - start: 0 + end: 410 + - start: 0 + end: 410 + next_statements: [] + - start: 0 + end: 410 + end: ~ + - start: 0 + end: 410 + session_close: false + - start: 0 + end: 410 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - id + - start: 18 + end: 20 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "30004" + - start: 22 + end: 27 + - start: 22 + end: 27 + - start: 18 + end: 27 + - - name: + - entity_type + - start: 29 + end: 40 + value: + - Value: + Literal: + String: + kind: Char + literal: table30004 + - start: 42 + end: 54 + - start: 29 + end: 54 + - - name: + - deleted + - start: 56 + end: 63 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 65 + end: 66 + - start: 65 + end: 66 + - start: 56 + end: 66 + - - name: + - gen_time + - start: 68 + end: 76 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1001" + - start: 78 + end: 82 + - start: 78 + end: 82 + - start: 68 + end: 82 + - - name: + - name + - start: 84 + end: 88 + value: + - Value: + Literal: + String: + kind: Char + literal: table30004 + - start: 90 + end: 102 + - start: 84 + end: 102 + - - name: + - guid + - start: 104 + end: 108 + value: + - Value: + Literal: + String: + kind: Char + literal: table30004 + - start: 109 + end: 121 + - start: 104 + end: 121 + - - name: + - status + - start: 123 + end: 129 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 131 + end: 132 + - start: 131 + end: 132 + - start: 123 + end: 132 + - - name: + - props + - start: 134 + end: 139 + value: + - Value: + Literal: + String: + kind: Char + literal: table30004 + - start: 141 + end: 153 + - start: 134 + end: 153 + - - name: + - test1 + - start: 155 + end: 160 + value: + - Value: + Literal: + String: + kind: Char + literal: table30004 + - start: 162 + end: 174 + - start: 155 + end: 174 + - - name: + - test2 + - start: 176 + end: 181 + value: + - Value: + Literal: + String: + kind: Char + literal: table30004 + - start: 183 + end: 195 + - start: 176 + end: 195 + - - name: + - test3 + - start: 197 + end: 202 + value: + - Value: + Literal: + String: + kind: Char + literal: table30004 + - start: 204 + end: 216 + - start: 197 + end: 216 + - - name: + - test4 + - start: 218 + end: 223 + value: + - Value: + Literal: + String: + kind: Char + literal: table30004 + - start: 225 + end: 237 + - start: 218 + end: 237 + - - name: + - test5 + - start: 239 + end: 244 + value: + - Value: + Literal: + String: + kind: Char + literal: table30004 + - start: 246 + end: 258 + - start: 239 + end: 258 + - - name: + - test6 + - start: 260 + end: 265 + value: + - Value: + Literal: + String: + kind: Char + literal: table30004 + - start: 267 + end: 279 + - start: 260 + end: 279 + - - name: + - test7 + - start: 281 + end: 286 + value: + - Value: + Literal: + String: + kind: Char + literal: table30004 + - start: 288 + end: 300 + - start: 281 + end: 300 + - - name: + - test8 + - start: 302 + end: 307 + value: + - Value: + Literal: + String: + kind: Char + literal: table30004 + - start: 309 + end: 321 + - start: 302 + end: 321 + - - name: + - test9 + - start: 323 + end: 328 + value: + - Value: + Literal: + String: + kind: Char + literal: table30004 + - start: 330 + end: 342 + - start: 323 + end: 342 + - - name: + - test10 + - start: 344 + end: 350 + value: + - Value: + Literal: + String: + kind: Char + literal: table30004 + - start: 352 + end: 364 + - start: 344 + end: 364 + - - name: + - test11 + - start: 366 + end: 372 + value: + - Value: + Literal: + String: + kind: Char + literal: table30004 + - start: 374 + end: 386 + - start: 366 + end: 386 + - - name: + - test12 + - start: 388 + end: 394 + value: + - Value: + Literal: + String: + kind: Char + literal: table30004 + - start: 396 + end: 408 + - start: 388 + end: 408 + - start: 17 + end: 409 + - start: 7 + end: 410 + - start: 7 + end: 410 + - start: 0 + end: 410 + - start: 0 + end: 410 + next_statements: [] + - start: 0 + end: 410 + end: ~ + - start: 0 + end: 410 + session_close: false + - start: 0 + end: 410 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - id + - start: 18 + end: 20 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "30005" + - start: 22 + end: 27 + - start: 22 + end: 27 + - start: 18 + end: 27 + - - name: + - entity_type + - start: 29 + end: 40 + value: + - Value: + Literal: + String: + kind: Char + literal: table30005 + - start: 42 + end: 54 + - start: 29 + end: 54 + - - name: + - deleted + - start: 56 + end: 63 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 65 + end: 66 + - start: 65 + end: 66 + - start: 56 + end: 66 + - - name: + - gen_time + - start: 68 + end: 76 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1001" + - start: 78 + end: 82 + - start: 78 + end: 82 + - start: 68 + end: 82 + - - name: + - name + - start: 84 + end: 88 + value: + - Value: + Literal: + String: + kind: Char + literal: table30005 + - start: 90 + end: 102 + - start: 84 + end: 102 + - - name: + - guid + - start: 104 + end: 108 + value: + - Value: + Literal: + String: + kind: Char + literal: table30005 + - start: 109 + end: 121 + - start: 104 + end: 121 + - - name: + - status + - start: 123 + end: 129 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 131 + end: 132 + - start: 131 + end: 132 + - start: 123 + end: 132 + - - name: + - props + - start: 134 + end: 139 + value: + - Value: + Literal: + String: + kind: Char + literal: table30005 + - start: 141 + end: 153 + - start: 134 + end: 153 + - - name: + - test1 + - start: 155 + end: 160 + value: + - Value: + Literal: + String: + kind: Char + literal: table30005 + - start: 162 + end: 174 + - start: 155 + end: 174 + - - name: + - test2 + - start: 176 + end: 181 + value: + - Value: + Literal: + String: + kind: Char + literal: table30005 + - start: 183 + end: 195 + - start: 176 + end: 195 + - - name: + - test3 + - start: 197 + end: 202 + value: + - Value: + Literal: + String: + kind: Char + literal: table30005 + - start: 204 + end: 216 + - start: 197 + end: 216 + - - name: + - test4 + - start: 218 + end: 223 + value: + - Value: + Literal: + String: + kind: Char + literal: table30005 + - start: 225 + end: 237 + - start: 218 + end: 237 + - - name: + - test5 + - start: 239 + end: 244 + value: + - Value: + Literal: + String: + kind: Char + literal: table30005 + - start: 246 + end: 258 + - start: 239 + end: 258 + - - name: + - test6 + - start: 260 + end: 265 + value: + - Value: + Literal: + String: + kind: Char + literal: table30005 + - start: 267 + end: 279 + - start: 260 + end: 279 + - - name: + - test7 + - start: 281 + end: 286 + value: + - Value: + Literal: + String: + kind: Char + literal: table30005 + - start: 288 + end: 300 + - start: 281 + end: 300 + - - name: + - test8 + - start: 302 + end: 307 + value: + - Value: + Literal: + String: + kind: Char + literal: table30005 + - start: 309 + end: 321 + - start: 302 + end: 321 + - - name: + - test9 + - start: 323 + end: 328 + value: + - Value: + Literal: + String: + kind: Char + literal: table30005 + - start: 330 + end: 342 + - start: 323 + end: 342 + - - name: + - test10 + - start: 344 + end: 350 + value: + - Value: + Literal: + String: + kind: Char + literal: table30005 + - start: 352 + end: 364 + - start: 344 + end: 364 + - - name: + - test11 + - start: 366 + end: 372 + value: + - Value: + Literal: + String: + kind: Char + literal: table30005 + - start: 374 + end: 386 + - start: 366 + end: 386 + - - name: + - test12 + - start: 388 + end: 394 + value: + - Value: + Literal: + String: + kind: Char + literal: table30005 + - start: 396 + end: 408 + - start: 388 + end: 408 + - start: 17 + end: 409 + - start: 7 + end: 410 + - start: 7 + end: 410 + - start: 0 + end: 410 + - start: 0 + end: 410 + next_statements: [] + - start: 0 + end: 410 + end: ~ + - start: 0 + end: 410 + session_close: false + - start: 0 + end: 410 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - id + - start: 18 + end: 20 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "30006" + - start: 22 + end: 27 + - start: 22 + end: 27 + - start: 18 + end: 27 + - - name: + - entity_type + - start: 29 + end: 40 + value: + - Value: + Literal: + String: + kind: Char + literal: table30006 + - start: 42 + end: 54 + - start: 29 + end: 54 + - - name: + - deleted + - start: 56 + end: 63 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 65 + end: 66 + - start: 65 + end: 66 + - start: 56 + end: 66 + - - name: + - gen_time + - start: 68 + end: 76 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1001" + - start: 78 + end: 82 + - start: 78 + end: 82 + - start: 68 + end: 82 + - - name: + - name + - start: 84 + end: 88 + value: + - Value: + Literal: + String: + kind: Char + literal: table30006 + - start: 90 + end: 102 + - start: 84 + end: 102 + - - name: + - guid + - start: 104 + end: 108 + value: + - Value: + Literal: + String: + kind: Char + literal: table30006 + - start: 109 + end: 121 + - start: 104 + end: 121 + - - name: + - status + - start: 123 + end: 129 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 131 + end: 132 + - start: 131 + end: 132 + - start: 123 + end: 132 + - - name: + - props + - start: 134 + end: 139 + value: + - Value: + Literal: + String: + kind: Char + literal: table30006 + - start: 141 + end: 153 + - start: 134 + end: 153 + - - name: + - test1 + - start: 155 + end: 160 + value: + - Value: + Literal: + String: + kind: Char + literal: table30006 + - start: 162 + end: 174 + - start: 155 + end: 174 + - - name: + - test2 + - start: 176 + end: 181 + value: + - Value: + Literal: + String: + kind: Char + literal: table30006 + - start: 183 + end: 195 + - start: 176 + end: 195 + - - name: + - test3 + - start: 197 + end: 202 + value: + - Value: + Literal: + String: + kind: Char + literal: table30006 + - start: 204 + end: 216 + - start: 197 + end: 216 + - - name: + - test4 + - start: 218 + end: 223 + value: + - Value: + Literal: + String: + kind: Char + literal: table30006 + - start: 225 + end: 237 + - start: 218 + end: 237 + - - name: + - test5 + - start: 239 + end: 244 + value: + - Value: + Literal: + String: + kind: Char + literal: table30006 + - start: 246 + end: 258 + - start: 239 + end: 258 + - - name: + - test6 + - start: 260 + end: 265 + value: + - Value: + Literal: + String: + kind: Char + literal: table30006 + - start: 267 + end: 279 + - start: 260 + end: 279 + - - name: + - test7 + - start: 281 + end: 286 + value: + - Value: + Literal: + String: + kind: Char + literal: table30006 + - start: 288 + end: 300 + - start: 281 + end: 300 + - - name: + - test8 + - start: 302 + end: 307 + value: + - Value: + Literal: + String: + kind: Char + literal: table30006 + - start: 309 + end: 321 + - start: 302 + end: 321 + - - name: + - test9 + - start: 323 + end: 328 + value: + - Value: + Literal: + String: + kind: Char + literal: table30006 + - start: 330 + end: 342 + - start: 323 + end: 342 + - - name: + - test10 + - start: 344 + end: 350 + value: + - Value: + Literal: + String: + kind: Char + literal: table30006 + - start: 352 + end: 364 + - start: 344 + end: 364 + - - name: + - test11 + - start: 366 + end: 372 + value: + - Value: + Literal: + String: + kind: Char + literal: table30006 + - start: 374 + end: 386 + - start: 366 + end: 386 + - - name: + - test12 + - start: 388 + end: 394 + value: + - Value: + Literal: + String: + kind: Char + literal: table30006 + - start: 396 + end: 408 + - start: 388 + end: 408 + - start: 17 + end: 409 + - start: 7 + end: 410 + - start: 7 + end: 410 + - start: 0 + end: 410 + - start: 0 + end: 410 + next_statements: [] + - start: 0 + end: 410 + end: ~ + - start: 0 + end: 410 + session_close: false + - start: 0 + end: 410 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - id + - start: 18 + end: 20 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "30007" + - start: 22 + end: 27 + - start: 22 + end: 27 + - start: 18 + end: 27 + - - name: + - entity_type + - start: 29 + end: 40 + value: + - Value: + Literal: + String: + kind: Char + literal: table30007 + - start: 42 + end: 54 + - start: 29 + end: 54 + - - name: + - deleted + - start: 56 + end: 63 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 65 + end: 66 + - start: 65 + end: 66 + - start: 56 + end: 66 + - - name: + - gen_time + - start: 68 + end: 76 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1001" + - start: 78 + end: 82 + - start: 78 + end: 82 + - start: 68 + end: 82 + - - name: + - name + - start: 84 + end: 88 + value: + - Value: + Literal: + String: + kind: Char + literal: table30007 + - start: 90 + end: 102 + - start: 84 + end: 102 + - - name: + - guid + - start: 104 + end: 108 + value: + - Value: + Literal: + String: + kind: Char + literal: table30007 + - start: 109 + end: 121 + - start: 104 + end: 121 + - - name: + - status + - start: 123 + end: 129 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 131 + end: 132 + - start: 131 + end: 132 + - start: 123 + end: 132 + - - name: + - props + - start: 134 + end: 139 + value: + - Value: + Literal: + String: + kind: Char + literal: table30007 + - start: 141 + end: 153 + - start: 134 + end: 153 + - - name: + - test1 + - start: 155 + end: 160 + value: + - Value: + Literal: + String: + kind: Char + literal: table30007 + - start: 162 + end: 174 + - start: 155 + end: 174 + - - name: + - test2 + - start: 176 + end: 181 + value: + - Value: + Literal: + String: + kind: Char + literal: table30007 + - start: 183 + end: 195 + - start: 176 + end: 195 + - - name: + - test3 + - start: 197 + end: 202 + value: + - Value: + Literal: + String: + kind: Char + literal: table30007 + - start: 204 + end: 216 + - start: 197 + end: 216 + - - name: + - test4 + - start: 218 + end: 223 + value: + - Value: + Literal: + String: + kind: Char + literal: table30007 + - start: 225 + end: 237 + - start: 218 + end: 237 + - - name: + - test5 + - start: 239 + end: 244 + value: + - Value: + Literal: + String: + kind: Char + literal: table30007 + - start: 246 + end: 258 + - start: 239 + end: 258 + - - name: + - test6 + - start: 260 + end: 265 + value: + - Value: + Literal: + String: + kind: Char + literal: table30007 + - start: 267 + end: 279 + - start: 260 + end: 279 + - - name: + - test7 + - start: 281 + end: 286 + value: + - Value: + Literal: + String: + kind: Char + literal: table30007 + - start: 288 + end: 300 + - start: 281 + end: 300 + - - name: + - test8 + - start: 302 + end: 307 + value: + - Value: + Literal: + String: + kind: Char + literal: table30007 + - start: 309 + end: 321 + - start: 302 + end: 321 + - - name: + - test9 + - start: 323 + end: 328 + value: + - Value: + Literal: + String: + kind: Char + literal: table30007 + - start: 330 + end: 342 + - start: 323 + end: 342 + - - name: + - test10 + - start: 344 + end: 350 + value: + - Value: + Literal: + String: + kind: Char + literal: table30007 + - start: 352 + end: 364 + - start: 344 + end: 364 + - - name: + - test11 + - start: 366 + end: 372 + value: + - Value: + Literal: + String: + kind: Char + literal: table30007 + - start: 374 + end: 386 + - start: 366 + end: 386 + - - name: + - test12 + - start: 388 + end: 394 + value: + - Value: + Literal: + String: + kind: Char + literal: table30007 + - start: 396 + end: 408 + - start: 388 + end: 408 + - start: 17 + end: 409 + - start: 7 + end: 410 + - start: 7 + end: 410 + - start: 0 + end: 410 + - start: 0 + end: 410 + next_statements: [] + - start: 0 + end: 410 + end: ~ + - start: 0 + end: 410 + session_close: false + - start: 0 + end: 410 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - id + - start: 18 + end: 20 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "30008" + - start: 22 + end: 27 + - start: 22 + end: 27 + - start: 18 + end: 27 + - - name: + - entity_type + - start: 29 + end: 40 + value: + - Value: + Literal: + String: + kind: Char + literal: table30008 + - start: 42 + end: 54 + - start: 29 + end: 54 + - - name: + - deleted + - start: 56 + end: 63 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 65 + end: 66 + - start: 65 + end: 66 + - start: 56 + end: 66 + - - name: + - gen_time + - start: 68 + end: 76 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1001" + - start: 78 + end: 82 + - start: 78 + end: 82 + - start: 68 + end: 82 + - - name: + - name + - start: 84 + end: 88 + value: + - Value: + Literal: + String: + kind: Char + literal: table30008 + - start: 90 + end: 102 + - start: 84 + end: 102 + - - name: + - guid + - start: 104 + end: 108 + value: + - Value: + Literal: + String: + kind: Char + literal: table30008 + - start: 109 + end: 121 + - start: 104 + end: 121 + - - name: + - status + - start: 123 + end: 129 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 131 + end: 132 + - start: 131 + end: 132 + - start: 123 + end: 132 + - - name: + - props + - start: 134 + end: 139 + value: + - Value: + Literal: + String: + kind: Char + literal: table30008 + - start: 141 + end: 153 + - start: 134 + end: 153 + - - name: + - test1 + - start: 155 + end: 160 + value: + - Value: + Literal: + String: + kind: Char + literal: table30008 + - start: 162 + end: 174 + - start: 155 + end: 174 + - - name: + - test2 + - start: 176 + end: 181 + value: + - Value: + Literal: + String: + kind: Char + literal: table30008 + - start: 183 + end: 195 + - start: 176 + end: 195 + - - name: + - test3 + - start: 197 + end: 202 + value: + - Value: + Literal: + String: + kind: Char + literal: table30008 + - start: 204 + end: 216 + - start: 197 + end: 216 + - - name: + - test4 + - start: 218 + end: 223 + value: + - Value: + Literal: + String: + kind: Char + literal: table30008 + - start: 225 + end: 237 + - start: 218 + end: 237 + - - name: + - test5 + - start: 239 + end: 244 + value: + - Value: + Literal: + String: + kind: Char + literal: table30008 + - start: 246 + end: 258 + - start: 239 + end: 258 + - - name: + - test6 + - start: 260 + end: 265 + value: + - Value: + Literal: + String: + kind: Char + literal: table30008 + - start: 267 + end: 279 + - start: 260 + end: 279 + - - name: + - test7 + - start: 281 + end: 286 + value: + - Value: + Literal: + String: + kind: Char + literal: table30008 + - start: 288 + end: 300 + - start: 281 + end: 300 + - - name: + - test8 + - start: 302 + end: 307 + value: + - Value: + Literal: + String: + kind: Char + literal: table30008 + - start: 309 + end: 321 + - start: 302 + end: 321 + - - name: + - test9 + - start: 323 + end: 328 + value: + - Value: + Literal: + String: + kind: Char + literal: table30008 + - start: 330 + end: 342 + - start: 323 + end: 342 + - - name: + - test10 + - start: 344 + end: 350 + value: + - Value: + Literal: + String: + kind: Char + literal: table30008 + - start: 352 + end: 364 + - start: 344 + end: 364 + - - name: + - test11 + - start: 366 + end: 372 + value: + - Value: + Literal: + String: + kind: Char + literal: table30008 + - start: 374 + end: 386 + - start: 366 + end: 386 + - - name: + - test12 + - start: 388 + end: 394 + value: + - Value: + Literal: + String: + kind: Char + literal: table30008 + - start: 396 + end: 408 + - start: 388 + end: 408 + - start: 17 + end: 409 + - start: 7 + end: 410 + - start: 7 + end: 410 + - start: 0 + end: 410 + - start: 0 + end: 410 + next_statements: [] + - start: 0 + end: 410 + end: ~ + - start: 0 + end: 410 + session_close: false + - start: 0 + end: 410 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - id + - start: 18 + end: 20 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "401" + - start: 22 + end: 25 + - start: 22 + end: 25 + - start: 18 + end: 25 + - - name: + - entity_type + - start: 27 + end: 38 + value: + - Value: + Literal: + String: + kind: Char + literal: e + - start: 40 + end: 43 + - start: 27 + end: 43 + - - name: + - deleted + - start: 45 + end: 52 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 54 + end: 55 + - start: 54 + end: 55 + - start: 45 + end: 55 + - - name: + - gen_time + - start: 57 + end: 65 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1001" + - start: 67 + end: 71 + - start: 67 + end: 71 + - start: 57 + end: 71 + - - name: + - name + - start: 73 + end: 77 + value: + - Value: + Literal: + String: + kind: Char + literal: table401 + - start: 79 + end: 89 + - start: 73 + end: 89 + - - name: + - guid + - start: 91 + end: 95 + value: + - Value: + Literal: + String: + kind: Char + literal: table401 + - start: 96 + end: 106 + - start: 91 + end: 106 + - - name: + - status + - start: 108 + end: 114 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 116 + end: 117 + - start: 116 + end: 117 + - start: 108 + end: 117 + - - name: + - props + - start: 119 + end: 124 + value: + - Value: + Literal: + String: + kind: Char + literal: table401 + - start: 126 + end: 136 + - start: 119 + end: 136 + - - name: + - test1 + - start: 138 + end: 143 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 145 + end: 151 + - start: 138 + end: 151 + - - name: + - test2 + - start: 153 + end: 158 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 160 + end: 166 + - start: 153 + end: 166 + - - name: + - test3 + - start: 168 + end: 173 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 175 + end: 181 + - start: 168 + end: 181 + - - name: + - test4 + - start: 183 + end: 188 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 190 + end: 196 + - start: 183 + end: 196 + - - name: + - test5 + - start: 198 + end: 203 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 205 + end: 211 + - start: 198 + end: 211 + - - name: + - test6 + - start: 213 + end: 218 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 220 + end: 226 + - start: 213 + end: 226 + - - name: + - test7 + - start: 228 + end: 233 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 235 + end: 241 + - start: 228 + end: 241 + - - name: + - test8 + - start: 243 + end: 248 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 250 + end: 256 + - start: 243 + end: 256 + - - name: + - test9 + - start: 258 + end: 263 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 265 + end: 271 + - start: 258 + end: 271 + - - name: + - test10 + - start: 273 + end: 279 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 281 + end: 287 + - start: 273 + end: 287 + - - name: + - test11 + - start: 289 + end: 295 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 297 + end: 303 + - start: 289 + end: 303 + - - name: + - test12 + - start: 305 + end: 311 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 313 + end: 319 + - start: 305 + end: 319 + - start: 17 + end: 320 + - start: 7 + end: 321 + - start: 7 + end: 321 + - start: 0 + end: 321 + - start: 0 + end: 321 + next_statements: [] + - start: 0 + end: 321 + end: ~ + - start: 0 + end: 321 + session_close: false + - start: 0 + end: 321 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - id + - start: 18 + end: 20 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "402" + - start: 22 + end: 25 + - start: 22 + end: 25 + - start: 18 + end: 25 + - - name: + - entity_type + - start: 27 + end: 38 + value: + - Value: + Literal: + String: + kind: Char + literal: e + - start: 40 + end: 43 + - start: 27 + end: 43 + - - name: + - deleted + - start: 45 + end: 52 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 54 + end: 55 + - start: 54 + end: 55 + - start: 45 + end: 55 + - - name: + - gen_time + - start: 57 + end: 65 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1001" + - start: 67 + end: 71 + - start: 67 + end: 71 + - start: 57 + end: 71 + - - name: + - name + - start: 73 + end: 77 + value: + - Value: + Literal: + String: + kind: Char + literal: table402 + - start: 79 + end: 89 + - start: 73 + end: 89 + - - name: + - guid + - start: 91 + end: 95 + value: + - Value: + Literal: + String: + kind: Char + literal: table402 + - start: 96 + end: 106 + - start: 91 + end: 106 + - - name: + - status + - start: 108 + end: 114 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 116 + end: 117 + - start: 116 + end: 117 + - start: 108 + end: 117 + - - name: + - props + - start: 119 + end: 124 + value: + - Value: + Literal: + String: + kind: Char + literal: table402 + - start: 126 + end: 136 + - start: 119 + end: 136 + - - name: + - test1 + - start: 138 + end: 143 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 145 + end: 151 + - start: 138 + end: 151 + - - name: + - test2 + - start: 153 + end: 158 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 160 + end: 166 + - start: 153 + end: 166 + - - name: + - test3 + - start: 168 + end: 173 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 175 + end: 181 + - start: 168 + end: 181 + - - name: + - test4 + - start: 183 + end: 188 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 190 + end: 196 + - start: 183 + end: 196 + - - name: + - test5 + - start: 198 + end: 203 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 205 + end: 211 + - start: 198 + end: 211 + - - name: + - test6 + - start: 213 + end: 218 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 220 + end: 226 + - start: 213 + end: 226 + - - name: + - test7 + - start: 228 + end: 233 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 235 + end: 241 + - start: 228 + end: 241 + - - name: + - test8 + - start: 243 + end: 248 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 250 + end: 256 + - start: 243 + end: 256 + - - name: + - test9 + - start: 258 + end: 263 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 265 + end: 271 + - start: 258 + end: 271 + - - name: + - test10 + - start: 273 + end: 279 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 281 + end: 287 + - start: 273 + end: 287 + - - name: + - test11 + - start: 289 + end: 295 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 297 + end: 303 + - start: 289 + end: 303 + - - name: + - test12 + - start: 305 + end: 311 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 313 + end: 319 + - start: 305 + end: 319 + - start: 17 + end: 320 + - start: 7 + end: 321 + - start: 7 + end: 321 + - start: 0 + end: 321 + - start: 0 + end: 321 + next_statements: [] + - start: 0 + end: 321 + end: ~ + - start: 0 + end: 321 + session_close: false + - start: 0 + end: 321 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - id + - start: 18 + end: 20 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "403" + - start: 22 + end: 25 + - start: 22 + end: 25 + - start: 18 + end: 25 + - - name: + - entity_type + - start: 27 + end: 38 + value: + - Value: + Literal: + String: + kind: Char + literal: e + - start: 40 + end: 43 + - start: 27 + end: 43 + - - name: + - deleted + - start: 45 + end: 52 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 54 + end: 55 + - start: 54 + end: 55 + - start: 45 + end: 55 + - - name: + - gen_time + - start: 57 + end: 65 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1001" + - start: 67 + end: 71 + - start: 67 + end: 71 + - start: 57 + end: 71 + - - name: + - name + - start: 73 + end: 77 + value: + - Value: + Literal: + String: + kind: Char + literal: table403 + - start: 79 + end: 89 + - start: 73 + end: 89 + - - name: + - guid + - start: 91 + end: 95 + value: + - Value: + Literal: + String: + kind: Char + literal: table403 + - start: 96 + end: 106 + - start: 91 + end: 106 + - - name: + - status + - start: 108 + end: 114 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 116 + end: 117 + - start: 116 + end: 117 + - start: 108 + end: 117 + - - name: + - props + - start: 119 + end: 124 + value: + - Value: + Literal: + String: + kind: Char + literal: table403 + - start: 126 + end: 136 + - start: 119 + end: 136 + - - name: + - test1 + - start: 138 + end: 143 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 145 + end: 151 + - start: 138 + end: 151 + - - name: + - test2 + - start: 153 + end: 158 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 160 + end: 166 + - start: 153 + end: 166 + - - name: + - test3 + - start: 168 + end: 173 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 175 + end: 181 + - start: 168 + end: 181 + - - name: + - test4 + - start: 183 + end: 188 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 190 + end: 196 + - start: 183 + end: 196 + - - name: + - test5 + - start: 198 + end: 203 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 205 + end: 211 + - start: 198 + end: 211 + - - name: + - test6 + - start: 213 + end: 218 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 220 + end: 226 + - start: 213 + end: 226 + - - name: + - test7 + - start: 228 + end: 233 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 235 + end: 241 + - start: 228 + end: 241 + - - name: + - test8 + - start: 243 + end: 248 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 250 + end: 256 + - start: 243 + end: 256 + - - name: + - test9 + - start: 258 + end: 263 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 265 + end: 271 + - start: 258 + end: 271 + - - name: + - test10 + - start: 273 + end: 279 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 281 + end: 287 + - start: 273 + end: 287 + - - name: + - test11 + - start: 289 + end: 295 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 297 + end: 303 + - start: 289 + end: 303 + - - name: + - test12 + - start: 305 + end: 311 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 313 + end: 319 + - start: 305 + end: 319 + - start: 17 + end: 320 + - start: 7 + end: 321 + - start: 7 + end: 321 + - start: 0 + end: 321 + - start: 0 + end: 321 + next_statements: [] + - start: 0 + end: 321 + end: ~ + - start: 0 + end: 321 + session_close: false + - start: 0 + end: 321 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - id + - start: 18 + end: 20 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "404" + - start: 22 + end: 25 + - start: 22 + end: 25 + - start: 18 + end: 25 + - - name: + - entity_type + - start: 27 + end: 38 + value: + - Value: + Literal: + String: + kind: Char + literal: e + - start: 40 + end: 43 + - start: 27 + end: 43 + - - name: + - deleted + - start: 45 + end: 52 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 54 + end: 55 + - start: 54 + end: 55 + - start: 45 + end: 55 + - - name: + - gen_time + - start: 57 + end: 65 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1001" + - start: 67 + end: 71 + - start: 67 + end: 71 + - start: 57 + end: 71 + - - name: + - name + - start: 73 + end: 77 + value: + - Value: + Literal: + String: + kind: Char + literal: table404 + - start: 79 + end: 89 + - start: 73 + end: 89 + - - name: + - guid + - start: 91 + end: 95 + value: + - Value: + Literal: + String: + kind: Char + literal: table404 + - start: 96 + end: 106 + - start: 91 + end: 106 + - - name: + - status + - start: 108 + end: 114 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 116 + end: 117 + - start: 116 + end: 117 + - start: 108 + end: 117 + - - name: + - props + - start: 119 + end: 124 + value: + - Value: + Literal: + String: + kind: Char + literal: table404 + - start: 126 + end: 136 + - start: 119 + end: 136 + - - name: + - test1 + - start: 138 + end: 143 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 145 + end: 151 + - start: 138 + end: 151 + - - name: + - test2 + - start: 153 + end: 158 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 160 + end: 166 + - start: 153 + end: 166 + - - name: + - test3 + - start: 168 + end: 173 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 175 + end: 181 + - start: 168 + end: 181 + - - name: + - test4 + - start: 183 + end: 188 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 190 + end: 196 + - start: 183 + end: 196 + - - name: + - test5 + - start: 198 + end: 203 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 205 + end: 211 + - start: 198 + end: 211 + - - name: + - test6 + - start: 213 + end: 218 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 220 + end: 226 + - start: 213 + end: 226 + - - name: + - test7 + - start: 228 + end: 233 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 235 + end: 241 + - start: 228 + end: 241 + - - name: + - test8 + - start: 243 + end: 248 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 250 + end: 256 + - start: 243 + end: 256 + - - name: + - test9 + - start: 258 + end: 263 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 265 + end: 271 + - start: 258 + end: 271 + - - name: + - test10 + - start: 273 + end: 279 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 281 + end: 287 + - start: 273 + end: 287 + - - name: + - test11 + - start: 289 + end: 295 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 297 + end: 303 + - start: 289 + end: 303 + - - name: + - test12 + - start: 305 + end: 311 + value: + - Value: + Literal: + String: + kind: Char + literal: FAKE + - start: 313 + end: 319 + - start: 305 + end: 319 + - start: 17 + end: 320 + - start: 7 + end: 321 + - start: 7 + end: 321 + - start: 0 + end: 321 + - start: 0 + end: 321 + next_statements: [] + - start: 0 + end: 321 + end: ~ + - start: 0 + end: 321 + session_close: false + - start: 0 + end: 321 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity1 + - start: 10 + end: 17 + predicate: + - Property: + - - name: + - id + - start: 19 + end: 21 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1000" + - start: 22 + end: 26 + - start: 22 + end: 26 + - start: 19 + end: 26 + - - name: + - entity_type + - start: 28 + end: 39 + value: + - Value: + Literal: + String: + kind: Char + literal: Bob1000 + - start: 41 + end: 50 + - start: 28 + end: 50 + - - name: + - deleted + - start: 52 + end: 59 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 60 + end: 61 + - start: 60 + end: 61 + - start: 52 + end: 61 + - start: 18 + end: 62 + - start: 7 + end: 63 + - start: 7 + end: 63 + - start: 0 + end: 63 + - start: 0 + end: 63 + next_statements: [] + - start: 0 + end: 63 + end: ~ + - start: 0 + end: 63 + session_close: false + - start: 0 + end: 63 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity1 + - start: 10 + end: 17 + predicate: + - Property: + - - name: + - id + - start: 19 + end: 21 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1001" + - start: 22 + end: 26 + - start: 22 + end: 26 + - start: 19 + end: 26 + - - name: + - entity_type + - start: 28 + end: 39 + value: + - Value: + Literal: + String: + kind: Char + literal: Bob1001 + - start: 41 + end: 50 + - start: 28 + end: 50 + - - name: + - deleted + - start: 52 + end: 59 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 60 + end: 61 + - start: 60 + end: 61 + - start: 52 + end: 61 + - start: 18 + end: 62 + - start: 7 + end: 63 + - start: 7 + end: 63 + - start: 0 + end: 63 + - start: 0 + end: 63 + next_statements: [] + - start: 0 + end: 63 + end: ~ + - start: 0 + end: 63 + session_close: false + - start: 0 + end: 63 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity2 + - start: 10 + end: 17 + predicate: + - Property: + - - name: + - id + - start: 19 + end: 21 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1002" + - start: 22 + end: 26 + - start: 22 + end: 26 + - start: 19 + end: 26 + - - name: + - entity_type + - start: 28 + end: 39 + value: + - Value: + Literal: + String: + kind: Char + literal: Bob1002 + - start: 41 + end: 50 + - start: 28 + end: 50 + - - name: + - deleted + - start: 52 + end: 59 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 60 + end: 61 + - start: 60 + end: 61 + - start: 52 + end: 61 + - - name: + - gen_time + - start: 63 + end: 71 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1002" + - start: 72 + end: 76 + - start: 72 + end: 76 + - start: 63 + end: 76 + - start: 18 + end: 77 + - start: 7 + end: 78 + - start: 7 + end: 78 + - start: 0 + end: 78 + - start: 0 + end: 78 + next_statements: [] + - start: 0 + end: 78 + end: ~ + - start: 0 + end: 78 + session_close: false + - start: 0 + end: 78 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity2 + - start: 10 + end: 17 + predicate: + - Property: + - - name: + - id + - start: 19 + end: 21 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1003" + - start: 22 + end: 26 + - start: 22 + end: 26 + - start: 19 + end: 26 + - - name: + - entity_type + - start: 28 + end: 39 + value: + - Value: + Literal: + String: + kind: Char + literal: Bob1003 + - start: 41 + end: 50 + - start: 28 + end: 50 + - - name: + - deleted + - start: 52 + end: 59 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 60 + end: 61 + - start: 60 + end: 61 + - start: 52 + end: 61 + - - name: + - gen_time + - start: 63 + end: 71 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1003" + - start: 72 + end: 76 + - start: 72 + end: 76 + - start: 63 + end: 76 + - start: 18 + end: 77 + - start: 7 + end: 78 + - start: 7 + end: 78 + - start: 0 + end: 78 + - start: 0 + end: 78 + next_statements: [] + - start: 0 + end: 78 + end: ~ + - start: 0 + end: 78 + session_close: false + - start: 0 + end: 78 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity2 + - start: 10 + end: 17 + predicate: + - Property: + - - name: + - id + - start: 19 + end: 21 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1004" + - start: 22 + end: 26 + - start: 22 + end: 26 + - start: 19 + end: 26 + - - name: + - entity_type + - start: 28 + end: 39 + value: + - Value: + Literal: + String: + kind: Char + literal: Bob1004 + - start: 41 + end: 50 + - start: 28 + end: 50 + - - name: + - deleted + - start: 52 + end: 59 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 60 + end: 61 + - start: 60 + end: 61 + - start: 52 + end: 61 + - - name: + - gen_time + - start: 63 + end: 71 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1004" + - start: 72 + end: 76 + - start: 72 + end: 76 + - start: 63 + end: 76 + - start: 18 + end: 77 + - start: 7 + end: 78 + - start: 7 + end: 78 + - start: 0 + end: 78 + - start: 0 + end: 78 + next_statements: [] + - start: 0 + end: 78 + end: ~ + - start: 0 + end: 78 + session_close: false + - start: 0 + end: 78 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity3 + - start: 10 + end: 17 + predicate: + - Property: + - - name: + - id + - start: 19 + end: 21 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "1" + - start: 22 + end: 23 + - start: 22 + end: 23 + - start: 19 + end: 23 + - - name: + - name + - start: 25 + end: 29 + value: + - Value: + Literal: + String: + kind: Char + literal: Bob + - start: 31 + end: 36 + - start: 25 + end: 36 + - start: 18 + end: 37 + - start: 7 + end: 38 + - start: 7 + end: 38 + - start: 0 + end: 38 + - start: 0 + end: 38 + next_statements: [] + - start: 0 + end: 38 + end: ~ + - start: 0 + end: 38 + session_close: false + - start: 0 + end: 38 - Err: Unexpected: - input: "INSERT (n:Entity {id: 30001, entity_type: 'table30001', deleted: 0, gen_time: 1001, name: 'table30001', guid:'table30001', status: 1, props: 'table30001', test1: 'table30001', test2: 'table30001', test3: 'table30001', test4: 'table30001', test5: 'table30001', test6: 'table30001', test7: 'table30001', test8: 'table30001', test9: 'table30001', test10: 'table30001', test11: 'table30001', test12: 'table30001'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity {id: 30002, entity_type: 'table30002', deleted: 0, gen_time: 1001, name: 'table30002', guid:'table30002', status: 1, props: 'table30002', test1: 'table30002', test2: 'table30002', test3: 'table30002', test4: 'table30002', test5: 'table30002', test6: 'table30002', test7: 'table30002', test8: 'table30002', test9: 'table30002', test10: 'table30002', test11: 'table30002', test12: 'table30002'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity {id: 30003, entity_type: 'table30003', deleted: 0, gen_time: 1001, name: 'table30003', guid:'table30003', status: 1, props: 'table30003', test1: 'table30003', test2: 'table30003', test3: 'table30003', test4: 'table30003', test5: 'table30003', test6: 'table30003', test7: 'table30003', test8: 'table30003', test9: 'table30003', test10: 'table30003', test11: 'table30003', test12: 'table30003'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity {id: 30004, entity_type: 'table30004', deleted: 0, gen_time: 1001, name: 'table30004', guid:'table30004', status: 1, props: 'table30004', test1: 'table30004', test2: 'table30004', test3: 'table30004', test4: 'table30004', test5: 'table30004', test6: 'table30004', test7: 'table30004', test8: 'table30004', test9: 'table30004', test10: 'table30004', test11: 'table30004', test12: 'table30004'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity {id: 30005, entity_type: 'table30005', deleted: 0, gen_time: 1001, name: 'table30005', guid:'table30005', status: 1, props: 'table30005', test1: 'table30005', test2: 'table30005', test3: 'table30005', test4: 'table30005', test5: 'table30005', test6: 'table30005', test7: 'table30005', test8: 'table30005', test9: 'table30005', test10: 'table30005', test11: 'table30005', test12: 'table30005'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity {id: 30006, entity_type: 'table30006', deleted: 0, gen_time: 1001, name: 'table30006', guid:'table30006', status: 1, props: 'table30006', test1: 'table30006', test2: 'table30006', test3: 'table30006', test4: 'table30006', test5: 'table30006', test6: 'table30006', test7: 'table30006', test8: 'table30006', test9: 'table30006', test10: 'table30006', test11: 'table30006', test12: 'table30006'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity {id: 30007, entity_type: 'table30007', deleted: 0, gen_time: 1001, name: 'table30007', guid:'table30007', status: 1, props: 'table30007', test1: 'table30007', test2: 'table30007', test3: 'table30007', test4: 'table30007', test5: 'table30007', test6: 'table30007', test7: 'table30007', test8: 'table30007', test9: 'table30007', test10: 'table30007', test11: 'table30007', test12: 'table30007'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity {id: 30008, entity_type: 'table30008', deleted: 0, gen_time: 1001, name: 'table30008', guid:'table30008', status: 1, props: 'table30008', test1: 'table30008', test2: 'table30008', test3: 'table30008', test4: 'table30008', test5: 'table30008', test6: 'table30008', test7: 'table30008', test8: 'table30008', test9: 'table30008', test10: 'table30008', test11: 'table30008', test12: 'table30008'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity {id: 401, entity_type: 'e', deleted: 0, gen_time: 1001, name: 'table401', guid:'table401', status: 1, props: 'table401', test1: 'FAKE', test2: 'FAKE', test3: 'FAKE', test4: 'FAKE', test5: 'FAKE', test6: 'FAKE', test7: 'FAKE', test8: 'FAKE', test9: 'FAKE', test10: 'FAKE', test11: 'FAKE', test12: 'FAKE'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity {id: 402, entity_type: 'e', deleted: 0, gen_time: 1001, name: 'table402', guid:'table402', status: 1, props: 'table402', test1: 'FAKE', test2: 'FAKE', test3: 'FAKE', test4: 'FAKE', test5: 'FAKE', test6: 'FAKE', test7: 'FAKE', test8: 'FAKE', test9: 'FAKE', test10: 'FAKE', test11: 'FAKE', test12: 'FAKE'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity {id: 403, entity_type: 'e', deleted: 0, gen_time: 1001, name: 'table403', guid:'table403', status: 1, props: 'table403', test1: 'FAKE', test2: 'FAKE', test3: 'FAKE', test4: 'FAKE', test5: 'FAKE', test6: 'FAKE', test7: 'FAKE', test8: 'FAKE', test9: 'FAKE', test10: 'FAKE', test11: 'FAKE', test12: 'FAKE'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity {id: 404, entity_type: 'e', deleted: 0, gen_time: 1001, name: 'table404', guid:'table404', status: 1, props: 'table404', test1: 'FAKE', test2: 'FAKE', test3: 'FAKE', test4: 'FAKE', test5: 'FAKE', test6: 'FAKE', test7: 'FAKE', test8: 'FAKE', test9: 'FAKE', test10: 'FAKE', test11: 'FAKE', test12: 'FAKE'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity1 {id:1000, entity_type: 'Bob1000', deleted:0})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity1 {id:1001, entity_type: 'Bob1001', deleted:0})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity2 {id:1002, entity_type: 'Bob1002', deleted:0, gen_time:1002})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity2 {id:1003, entity_type: 'Bob1003', deleted:0, gen_time:1003})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity2 {id:1004, entity_type: 'Bob1004', deleted:0, gen_time:1004})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity3 {id:1, name: 'Bob'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "MATCH (n:Entity3{id:1}), (m:Entity3{id:1}) INSERT (n)-[r:Rel_3_3{timestamp:4}]->(m)" - span: - start: 0 - end: 5 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity3 {id:2, name: 'Bob1'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity3 {id:3, name: 'Bob12'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity3 {id:4, name: 'Bob123'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity3 {id:5, name: 'Bob222'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity3 {id:6, name: '666'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity4 {id:7, text: 'hello world'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity4 {id:8, text: '666'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity4 {id:9, text: '{\"a\":1, \"b\":2}'})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity4 {id:10, text: '{\"a\":3}'})" + input: "MATCH (n:Entity3{id:1}), (m:Entity3{id:1}) INSERT (n)-[r:Rel_3_3{timestamp:4}]->(m)" span: start: 0 - end: 6 + end: 5 position: - 1 - 1 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity3 + - start: 10 + end: 17 + predicate: + - Property: + - - name: + - id + - start: 19 + end: 21 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "2" + - start: 22 + end: 23 + - start: 22 + end: 23 + - start: 19 + end: 23 + - - name: + - name + - start: 25 + end: 29 + value: + - Value: + Literal: + String: + kind: Char + literal: Bob1 + - start: 31 + end: 37 + - start: 25 + end: 37 + - start: 18 + end: 38 + - start: 7 + end: 39 + - start: 7 + end: 39 + - start: 0 + end: 39 + - start: 0 + end: 39 + next_statements: [] + - start: 0 + end: 39 + end: ~ + - start: 0 + end: 39 + session_close: false + - start: 0 + end: 39 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity3 + - start: 10 + end: 17 + predicate: + - Property: + - - name: + - id + - start: 19 + end: 21 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "3" + - start: 22 + end: 23 + - start: 22 + end: 23 + - start: 19 + end: 23 + - - name: + - name + - start: 25 + end: 29 + value: + - Value: + Literal: + String: + kind: Char + literal: Bob12 + - start: 31 + end: 38 + - start: 25 + end: 38 + - start: 18 + end: 39 + - start: 7 + end: 40 + - start: 7 + end: 40 + - start: 0 + end: 40 + - start: 0 + end: 40 + next_statements: [] + - start: 0 + end: 40 + end: ~ + - start: 0 + end: 40 + session_close: false + - start: 0 + end: 40 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity3 + - start: 10 + end: 17 + predicate: + - Property: + - - name: + - id + - start: 19 + end: 21 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "4" + - start: 22 + end: 23 + - start: 22 + end: 23 + - start: 19 + end: 23 + - - name: + - name + - start: 25 + end: 29 + value: + - Value: + Literal: + String: + kind: Char + literal: Bob123 + - start: 31 + end: 39 + - start: 25 + end: 39 + - start: 18 + end: 40 + - start: 7 + end: 41 + - start: 7 + end: 41 + - start: 0 + end: 41 + - start: 0 + end: 41 + next_statements: [] + - start: 0 + end: 41 + end: ~ + - start: 0 + end: 41 + session_close: false + - start: 0 + end: 41 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity3 + - start: 10 + end: 17 + predicate: + - Property: + - - name: + - id + - start: 19 + end: 21 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "5" + - start: 22 + end: 23 + - start: 22 + end: 23 + - start: 19 + end: 23 + - - name: + - name + - start: 25 + end: 29 + value: + - Value: + Literal: + String: + kind: Char + literal: Bob222 + - start: 31 + end: 39 + - start: 25 + end: 39 + - start: 18 + end: 40 + - start: 7 + end: 41 + - start: 7 + end: 41 + - start: 0 + end: 41 + - start: 0 + end: 41 + next_statements: [] + - start: 0 + end: 41 + end: ~ + - start: 0 + end: 41 + session_close: false + - start: 0 + end: 41 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity3 + - start: 10 + end: 17 + predicate: + - Property: + - - name: + - id + - start: 19 + end: 21 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "6" + - start: 22 + end: 23 + - start: 22 + end: 23 + - start: 19 + end: 23 + - - name: + - name + - start: 25 + end: 29 + value: + - Value: + Literal: + String: + kind: Char + literal: "666" + - start: 31 + end: 36 + - start: 25 + end: 36 + - start: 18 + end: 37 + - start: 7 + end: 38 + - start: 7 + end: 38 + - start: 0 + end: 38 + - start: 0 + end: 38 + next_statements: [] + - start: 0 + end: 38 + end: ~ + - start: 0 + end: 38 + session_close: false + - start: 0 + end: 38 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity4 + - start: 10 + end: 17 + predicate: + - Property: + - - name: + - id + - start: 19 + end: 21 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "7" + - start: 22 + end: 23 + - start: 22 + end: 23 + - start: 19 + end: 23 + - - name: + - text + - start: 25 + end: 29 + value: + - Value: + Literal: + String: + kind: Char + literal: hello world + - start: 31 + end: 44 + - start: 25 + end: 44 + - start: 18 + end: 45 + - start: 7 + end: 46 + - start: 7 + end: 46 + - start: 0 + end: 46 + - start: 0 + end: 46 + next_statements: [] + - start: 0 + end: 46 + end: ~ + - start: 0 + end: 46 + session_close: false + - start: 0 + end: 46 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity4 + - start: 10 + end: 17 + predicate: + - Property: + - - name: + - id + - start: 19 + end: 21 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "8" + - start: 22 + end: 23 + - start: 22 + end: 23 + - start: 19 + end: 23 + - - name: + - text + - start: 25 + end: 29 + value: + - Value: + Literal: + String: + kind: Char + literal: "666" + - start: 31 + end: 36 + - start: 25 + end: 36 + - start: 18 + end: 37 + - start: 7 + end: 38 + - start: 7 + end: 38 + - start: 0 + end: 38 + - start: 0 + end: 38 + next_statements: [] + - start: 0 + end: 38 + end: ~ + - start: 0 + end: 38 + session_close: false + - start: 0 + end: 38 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity4 + - start: 10 + end: 17 + predicate: + - Property: + - - name: + - id + - start: 19 + end: 21 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "9" + - start: 22 + end: 23 + - start: 22 + end: 23 + - start: 19 + end: 23 + - - name: + - text + - start: 25 + end: 29 + value: + - Value: + Literal: + String: + kind: Char + literal: "{\"a\":1, \"b\":2}" + - start: 31 + end: 47 + - start: 25 + end: 47 + - start: 18 + end: 48 + - start: 7 + end: 49 + - start: 7 + end: 49 + - start: 0 + end: 49 + - start: 0 + end: 49 + next_statements: [] + - start: 0 + end: 49 + end: ~ + - start: 0 + end: 49 + session_close: false + - start: 0 + end: 49 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity4 + - start: 10 + end: 17 + predicate: + - Property: + - - name: + - id + - start: 19 + end: 21 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "10" + - start: 22 + end: 24 + - start: 22 + end: 24 + - start: 19 + end: 24 + - - name: + - text + - start: 26 + end: 30 + value: + - Value: + Literal: + String: + kind: Char + literal: "{\"a\":3}" + - start: 32 + end: 41 + - start: 26 + end: 41 + - start: 18 + end: 42 + - start: 7 + end: 43 + - start: 7 + end: 43 + - start: 0 + end: 43 + - start: 0 + end: 43 + next_statements: [] + - start: 0 + end: 43 + end: ~ + - start: 0 + end: 43 + session_close: false + - start: 0 + end: 43 - Err: Unexpected: input: "MATCH (n:Entity{id: 30001}), (m:Entity{id: 30002}) INSERT (n)-[r:Rel{timestamp:0,deleted:0,rel_scene:'0',rel_type:'rel1',gen_time:0,rel_chain:'0',dst_guid:'table30002',src_guid:'table30001',status:0,props:'rel1'}]->(m)" @@ -5143,24 +10795,220 @@ source: minigu-test/src/insta_test.rs session_close: false - start: 0 end: 114 -- Err: - Unexpected: - input: "INSERT (n:Entity {id: 28, name: 'Bob8', deleted:0, gen_time:99})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity {id: 29, name: 'Bob9', deleted:0, gen_time:100})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - id + - start: 18 + end: 20 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "28" + - start: 22 + end: 24 + - start: 22 + end: 24 + - start: 18 + end: 24 + - - name: + - name + - start: 26 + end: 30 + value: + - Value: + Literal: + String: + kind: Char + literal: Bob8 + - start: 32 + end: 38 + - start: 26 + end: 38 + - - name: + - deleted + - start: 40 + end: 47 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 48 + end: 49 + - start: 48 + end: 49 + - start: 40 + end: 49 + - - name: + - gen_time + - start: 51 + end: 59 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "99" + - start: 60 + end: 62 + - start: 60 + end: 62 + - start: 51 + end: 62 + - start: 17 + end: 63 + - start: 7 + end: 64 + - start: 7 + end: 64 + - start: 0 + end: 64 + - start: 0 + end: 64 + next_statements: [] + - start: 0 + end: 64 + end: ~ + - start: 0 + end: 64 + session_close: false + - start: 0 + end: 64 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - id + - start: 18 + end: 20 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "29" + - start: 22 + end: 24 + - start: 22 + end: 24 + - start: 18 + end: 24 + - - name: + - name + - start: 26 + end: 30 + value: + - Value: + Literal: + String: + kind: Char + literal: Bob9 + - start: 32 + end: 38 + - start: 26 + end: 38 + - - name: + - deleted + - start: 40 + end: 47 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 48 + end: 49 + - start: 48 + end: 49 + - start: 40 + end: 49 + - - name: + - gen_time + - start: 51 + end: 59 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "100" + - start: 60 + end: 63 + - start: 60 + end: 63 + - start: 51 + end: 63 + - start: 17 + end: 64 + - start: 7 + end: 65 + - start: 7 + end: 65 + - start: 0 + end: 65 + - start: 0 + end: 65 + next_statements: [] + - start: 0 + end: 65 + end: ~ + - start: 0 + end: 65 + session_close: false + - start: 0 + end: 65 - Err: Unexpected: input: "MATCH (n:Entity{id: 28}), (m:Entity{id: 29}) INSERT (n)-[r:Rel{timestamp: 7,deleted:0}]->(m)" @@ -5170,15 +11018,113 @@ source: minigu-test/src/insta_test.rs position: - 1 - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity {id: 30, name: 'Bob10', deleted:0, gen_time:100})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - id + - start: 18 + end: 20 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "30" + - start: 22 + end: 24 + - start: 22 + end: 24 + - start: 18 + end: 24 + - - name: + - name + - start: 26 + end: 30 + value: + - Value: + Literal: + String: + kind: Char + literal: Bob10 + - start: 32 + end: 39 + - start: 26 + end: 39 + - - name: + - deleted + - start: 41 + end: 48 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 49 + end: 50 + - start: 49 + end: 50 + - start: 41 + end: 50 + - - name: + - gen_time + - start: 52 + end: 60 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "100" + - start: 61 + end: 64 + - start: 61 + end: 64 + - start: 52 + end: 64 + - start: 17 + end: 65 + - start: 7 + end: 66 + - start: 7 + end: 66 + - start: 0 + end: 66 + - start: 0 + end: 66 + next_statements: [] + - start: 0 + end: 66 + end: ~ + - start: 0 + end: 66 + session_close: false + - start: 0 + end: 66 - Err: Unexpected: input: "MATCH (n:Entity{id: 29}), (m:Entity{id: 30}) INSERT (n)-[r:Rel{timestamp: 8,deleted:0}]->(m)" @@ -5188,24 +11134,220 @@ source: minigu-test/src/insta_test.rs position: - 1 - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity {id: 38, name: 'Bob38', deleted:0, gen_time:99})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity {id: 381, name: 'Bob381', deleted:0, gen_time:99})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - id + - start: 18 + end: 20 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "38" + - start: 22 + end: 24 + - start: 22 + end: 24 + - start: 18 + end: 24 + - - name: + - name + - start: 26 + end: 30 + value: + - Value: + Literal: + String: + kind: Char + literal: Bob38 + - start: 32 + end: 39 + - start: 26 + end: 39 + - - name: + - deleted + - start: 41 + end: 48 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 49 + end: 50 + - start: 49 + end: 50 + - start: 41 + end: 50 + - - name: + - gen_time + - start: 52 + end: 60 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "99" + - start: 61 + end: 63 + - start: 61 + end: 63 + - start: 52 + end: 63 + - start: 17 + end: 64 + - start: 7 + end: 65 + - start: 7 + end: 65 + - start: 0 + end: 65 + - start: 0 + end: 65 + next_statements: [] + - start: 0 + end: 65 + end: ~ + - start: 0 + end: 65 + session_close: false + - start: 0 + end: 65 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - id + - start: 18 + end: 20 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "381" + - start: 22 + end: 25 + - start: 22 + end: 25 + - start: 18 + end: 25 + - - name: + - name + - start: 27 + end: 31 + value: + - Value: + Literal: + String: + kind: Char + literal: Bob381 + - start: 33 + end: 41 + - start: 27 + end: 41 + - - name: + - deleted + - start: 43 + end: 50 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 51 + end: 52 + - start: 51 + end: 52 + - start: 43 + end: 52 + - - name: + - gen_time + - start: 54 + end: 62 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "99" + - start: 63 + end: 65 + - start: 63 + end: 65 + - start: 54 + end: 65 + - start: 17 + end: 66 + - start: 7 + end: 67 + - start: 7 + end: 67 + - start: 0 + end: 67 + - start: 0 + end: 67 + next_statements: [] + - start: 0 + end: 67 + end: ~ + - start: 0 + end: 67 + session_close: false + - start: 0 + end: 67 - Err: Unexpected: input: "MATCH (n:Entity{id: 38}), (m:Entity{id: 381}) INSERT (n)-[r:Rel{timestamp: 7,deleted:0}]->(m)" @@ -5215,15 +11357,113 @@ source: minigu-test/src/insta_test.rs position: - 1 - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity {id: 39, name: 'Bob39', deleted:0, gen_time:100})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - id + - start: 18 + end: 20 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "39" + - start: 22 + end: 24 + - start: 22 + end: 24 + - start: 18 + end: 24 + - - name: + - name + - start: 26 + end: 30 + value: + - Value: + Literal: + String: + kind: Char + literal: Bob39 + - start: 32 + end: 39 + - start: 26 + end: 39 + - - name: + - deleted + - start: 41 + end: 48 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "0" + - start: 49 + end: 50 + - start: 49 + end: 50 + - start: 41 + end: 50 + - - name: + - gen_time + - start: 52 + end: 60 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "100" + - start: 61 + end: 64 + - start: 61 + end: 64 + - start: 52 + end: 64 + - start: 17 + end: 65 + - start: 7 + end: 66 + - start: 7 + end: 66 + - start: 0 + end: 66 + - start: 0 + end: 66 + next_statements: [] + - start: 0 + end: 66 + end: ~ + - start: 0 + end: 66 + session_close: false + - start: 0 + end: 66 - Err: Unexpected: input: "MATCH (n:Entity{id: 38}), (m:Entity{id: 39}) INSERT (n)-[r:Rel{timestamp: 7,deleted:0}]->(m)" diff --git a/minigu-test/gql/dml/insert.slt b/minigu-test/gql/dml/insert.slt new file mode 100644 index 000000000..d4ec77259 --- /dev/null +++ b/minigu-test/gql/dml/insert.slt @@ -0,0 +1,137 @@ +# INSERT statement tests +# +# Schema produced by `create_insert_test_graph`: +# PERSON (name: String, age: Int32) +# COMPANY (name: String, revenue: Int64) +# KNOWS PERSON -> PERSON (since: Int32) +# WORKS_AT PERSON -> COMPANY (role: String) + +statement ok +CALL create_insert_test_graph('g') + +statement ok +SESSION SET GRAPH g + +# --------------------------------------------------------------- +# Section 1: INSERT — happy paths +# --------------------------------------------------------------- + +# 1.1 single vertex +statement ok +INSERT (a:PERSON {name: 'Alice', age: 30}) + +# 1.2 multiple vertices in one statement +statement ok +INSERT (b:PERSON {name: 'Bob', age: 25}), (c:COMPANY {name: 'Acme', revenue: 1000000}) + +# 1.3 vertex + edge in the same statement (both endpoints defined inline) +statement ok +INSERT (p:PERSON {name: 'Carol', age: 22})-[:WORKS_AT {role: 'eng'}]->(co:COMPANY {name: 'Beta', revenue: 500000}) + +# 1.4 edge between two new PERSON vertices (self-type edge) +statement ok +INSERT (x:PERSON {name: 'Dan', age: 40})-[:KNOWS {since: 2020}]->(y:PERSON {name: 'Eve', age: 38}) + +# 1.5 two new vertices reused across two edges (bidirectional KNOWS) +statement ok +INSERT (p:PERSON {name: 'Frank', age: 35}), + (q:PERSON {name: 'Grace', age: 33}), + (p)-[:KNOWS {since: 2018}]->(q), + (q)-[:KNOWS {since: 2019}]->(p) + +# 1.6 COMPANY with a zero numeric property (boundary value) +statement ok +INSERT (h:COMPANY {name: 'Hub', revenue: 0}) + +# 1.7 reverse-direction edge: `(a)<-[..]-(b)` means b -> a +statement ok +INSERT (a:PERSON {name: 'I', age: 20})<-[:KNOWS {since: 2021}]-(b:PERSON {name: 'J', age: 21}) + +# --------------------------------------------------------------- +# Section 2: INSERT — error paths +# --------------------------------------------------------------- + +# 2.1 unknown vertex label +statement error +INSERT (x:UNKNOWN_LABEL {name: 'x'}) + +# 2.2 property name not in the vertex type +statement error +INSERT (x:PERSON {name: 'X', nonexistent_prop: 1}) + +# 2.3 missing a required (non-nullable) property +statement error +INSERT (x:PERSON {name: 'NoAge'}) + +# 2.4 property value type mismatch (Int expected, String given) +statement error +INSERT (x:PERSON {name: 'X', age: 'thirty'}) + +# 2.5 edge endpoint variable not defined in this statement +statement error +INSERT (a:PERSON {name: 'A', age: 1})-[:KNOWS {since: 2020}]->(ghost) + +# 2.6 duplicate variable name within the same INSERT +statement error +INSERT (a:PERSON {name: 'X', age: 1}), (a:PERSON {name: 'Y', age: 2}) + +# 2.7 edge type endpoint mismatch (KNOWS expects PERSON->PERSON; got COMPANY->PERSON) +statement error +INSERT (c:COMPANY {name: 'C', revenue: 1})-[:KNOWS {since: 2020}]->(p:PERSON {name: 'P', age: 1}) + +# 2.8 edge property value type mismatch (since: Int32 expected, String given) +statement error +INSERT (a:PERSON {name: 'A', age: 1})-[:KNOWS {since: 'recent'}]->(b:PERSON {name: 'B', age: 2}) + +# --------------------------------------------------------------- +# Section 3: end-to-end verification — inserted data is visible to MATCH +# --------------------------------------------------------------- +# +# Successfully inserted (Sections 1.1–1.7): +# PERSON (9): Alice, Bob, Carol, Dan, Eve, Frank, Grace, I, J +# COMPANY (3): Acme, Beta, Hub +# KNOWS (4): Dan->Eve, Frank->Grace, Grace->Frank, J->I +# WORKS_AT (1): Carol->Beta +# +# NOTE: aggregate functions, binary expressions (`WHERE p.name = 'x'`), +# and ORDER BY on property paths are not yet implemented in the binder. +# Once they land, this section can be extended with `count(p)`, +# `WHERE`-filtered checks, and deterministic ordering. For now we use +# `query TI rowsort` so the comparison ignores row order. + +# All inserted PERSON rows. +query TI rowsort +MATCH (p:PERSON) RETURN p.name, p.age +---- +Alice 30 +Bob 25 +Carol 22 +Dan 40 +Eve 38 +Frank 35 +Grace 33 +I 20 +J 21 + +# All inserted COMPANY rows. +query TI rowsort +MATCH (c:COMPANY) RETURN c.name, c.revenue +---- +Acme 1000000 +Beta 500000 +Hub 0 + +# WORKS_AT edge connects PERSON to COMPANY with the right endpoints. +query TT rowsort +MATCH (p:PERSON)-[:WORKS_AT]->(co:COMPANY) RETURN p.name, co.name +---- +Carol Beta + +# All KNOWS edges (4 inserted). +query TT rowsort +MATCH (src:PERSON)-[:KNOWS]->(dst:PERSON) RETURN src.name, dst.name +---- +Dan Eve +Frank Grace +Grace Frank +J I diff --git a/minigu-test/gql/misc/vector_index@e2e.snap b/minigu-test/gql/misc/vector_index@e2e.snap index be9c19922..faa5e4b70 100644 --- a/minigu-test/gql/misc/vector_index@e2e.snap +++ b/minigu-test/gql/misc/vector_index@e2e.snap @@ -37,16 +37,9 @@ Error: Parser( ), ) --- -Error: Parser( - Unexpected( - UnexpectedError { - input: "INSERT (n:Entity {id: 30001, embedding: VECTOR [1.0, -2.5, 3.14, -0.5]})", - span: 0..6, - position: ( - 1, - 1, - ), - }, +Error: Plan( + Bind( + CurrentGraphNotSpecified, ), ) --- diff --git a/minigu-test/gql/misc/vector_index@parser.snap b/minigu-test/gql/misc/vector_index@parser.snap index 23a0b569c..869c217dd 100644 --- a/minigu-test/gql/misc/vector_index@parser.snap +++ b/minigu-test/gql/misc/vector_index@parser.snap @@ -19,15 +19,130 @@ source: minigu-test/src/insta_test.rs position: - 1 - 1 -- Err: - Unexpected: - input: "INSERT (n:Entity {id: 30001, embedding: VECTOR [1.0, -2.5, 3.14, -0.5]})" - span: - start: 0 - end: 6 - position: - - 1 - - 1 +- Ok: + - activity: + - Transaction: + start: ~ + procedure: + - at: ~ + binding_variable_defs: [] + statement: + - Data: + - - Insert: + paths: + - - elements: + - - Node: + variable: + - n + - start: 8 + end: 9 + label: + - Label: Entity + - start: 10 + end: 16 + predicate: + - Property: + - - name: + - id + - start: 18 + end: 20 + value: + - Value: + Literal: + Numeric: + Integer: + - kind: Decimal + integer: "30001" + - start: 22 + end: 27 + - start: 22 + end: 27 + - start: 18 + end: 27 + - - name: + - embedding + - start: 29 + end: 38 + value: + - Value: + Literal: + Vector: + elems: + - - Value: + Literal: + Numeric: + Float: + - float: "1.0" + - start: 48 + end: 51 + - start: 48 + end: 51 + - - Unary: + op: + - Minus + - start: 53 + end: 54 + child: + - Value: + Literal: + Numeric: + Float: + - float: "2.5" + - start: 54 + end: 57 + - start: 54 + end: 57 + - start: 53 + end: 57 + - - Value: + Literal: + Numeric: + Float: + - float: "3.14" + - start: 59 + end: 63 + - start: 59 + end: 63 + - - Unary: + op: + - Minus + - start: 65 + end: 66 + child: + - Value: + Literal: + Numeric: + Float: + - float: "0.5" + - start: 66 + end: 69 + - start: 66 + end: 69 + - start: 65 + end: 69 + - start: 40 + end: 70 + - start: 29 + end: 70 + - start: 17 + end: 71 + - start: 7 + end: 72 + - start: 7 + end: 72 + - start: 0 + end: 72 + - start: 0 + end: 72 + next_statements: [] + - start: 0 + end: 72 + end: ~ + - start: 0 + end: 72 + session_close: false + - start: 0 + end: 72 - Ok: - activity: - Transaction: diff --git a/minigu/core/src/procedures/create_insert_test_graph.rs b/minigu/core/src/procedures/create_insert_test_graph.rs new file mode 100644 index 000000000..2665f5c66 --- /dev/null +++ b/minigu/core/src/procedures/create_insert_test_graph.rs @@ -0,0 +1,131 @@ +//! Test fixture procedure for the INSERT statement test suite. +//! +//! Builds a small graph with only primitive-typed (String / Int) properties so +//! INSERT can populate it from GQL literals (no vector literal syntax exists yet). +//! +//! Schema: +//! PERSON (name: String, age: Int32) +//! COMPANY (name: String, revenue: Int64) +//! KNOWS PERSON -> PERSON (since: Int32) +//! WORKS_AT PERSON -> COMPANY (role: String) +//! +//! The procedure registers the graph in the current schema and sets it as the +//! session's current graph, but inserts no data — INSERT test cases are +//! responsible for populating their own data. + +use std::sync::Arc; + +use minigu_catalog::label_set::LabelSet; +use minigu_catalog::memory::graph_type::{ + MemoryEdgeTypeCatalog, MemoryGraphTypeCatalog, MemoryVertexTypeCatalog, +}; +use minigu_catalog::named_ref::NamedGraphRef; +use minigu_catalog::property::Property; +use minigu_common::data_type::LogicalType; +use minigu_context::graph::{GraphContainer, GraphStorage}; +use minigu_context::procedure::Procedure; +use minigu_storage::tp::MemoryGraph; + +pub fn build_procedure() -> Procedure { + let parameters = vec![LogicalType::String]; + + Procedure::new(parameters, None, move |mut context, args| { + if args.len() != 1 { + return Err(anyhow::anyhow!( + "create_insert_test_graph expects 1 argument, got {}", + args.len() + ) + .into()); + } + let graph_name = args[0] + .try_as_string() + .ok_or_else(|| anyhow::anyhow!("graph name must be a string"))? + .as_ref() + .ok_or_else(|| anyhow::anyhow!("graph name cannot be null"))? + .to_string(); + + let schema = context + .current_schema + .as_ref() + .ok_or_else(|| anyhow::anyhow!("current schema not set"))?; + + let graph = MemoryGraph::in_memory_with_options(context.database().config().txn_options); + let mut graph_type = MemoryGraphTypeCatalog::new(); + + // Labels + let person_label_id = graph_type + .add_label("PERSON".to_string()) + .ok_or_else(|| anyhow::anyhow!("failed to register PERSON label"))?; + let company_label_id = graph_type + .add_label("COMPANY".to_string()) + .ok_or_else(|| anyhow::anyhow!("failed to register COMPANY label"))?; + let knows_label_id = graph_type + .add_label("KNOWS".to_string()) + .ok_or_else(|| anyhow::anyhow!("failed to register KNOWS label"))?; + let works_at_label_id = graph_type + .add_label("WORKS_AT".to_string()) + .ok_or_else(|| anyhow::anyhow!("failed to register WORKS_AT label"))?; + + // Vertex types + let person_label_set: LabelSet = vec![person_label_id].into_iter().collect(); + let person = Arc::new(MemoryVertexTypeCatalog::new( + person_label_set.clone(), + vec![ + Property::new("name".to_string(), LogicalType::String, false), + Property::new("age".to_string(), LogicalType::Int32, false), + ], + )); + + let company_label_set: LabelSet = vec![company_label_id].into_iter().collect(); + let company = Arc::new(MemoryVertexTypeCatalog::new( + company_label_set.clone(), + vec![ + Property::new("name".to_string(), LogicalType::String, false), + Property::new("revenue".to_string(), LogicalType::Int64, false), + ], + )); + + // Edge types + let knows_label_set: LabelSet = vec![knows_label_id].into_iter().collect(); + let knows = Arc::new(MemoryEdgeTypeCatalog::new( + knows_label_set.clone(), + person.clone(), + person.clone(), + vec![Property::new( + "since".to_string(), + LogicalType::Int32, + false, + )], + )); + + let works_at_label_set: LabelSet = vec![works_at_label_id].into_iter().collect(); + let works_at = Arc::new(MemoryEdgeTypeCatalog::new( + works_at_label_set.clone(), + person.clone(), + company.clone(), + vec![Property::new( + "role".to_string(), + LogicalType::String, + false, + )], + )); + + graph_type.add_vertex_type(person_label_set, person); + graph_type.add_vertex_type(company_label_set, company); + graph_type.add_edge_type(knows_label_set, knows); + graph_type.add_edge_type(works_at_label_set, works_at); + + let container = Arc::new(GraphContainer::new( + Arc::new(graph_type), + GraphStorage::Memory(graph.clone()), + )); + + if !schema.add_graph(graph_name.clone(), container.clone()) { + return Err(anyhow::anyhow!("graph `{graph_name}` already exists").into()); + } + + context.current_graph = Some(NamedGraphRef::new(graph_name.into(), container.clone())); + + Ok(vec![]) + }) +} diff --git a/minigu/core/src/procedures/mod.rs b/minigu/core/src/procedures/mod.rs index 26f743340..dfdb9f372 100644 --- a/minigu/core/src/procedures/mod.rs +++ b/minigu/core/src/procedures/mod.rs @@ -1,4 +1,5 @@ mod common; +mod create_insert_test_graph; mod create_test_graph; mod create_test_graph_data; mod echo; @@ -28,6 +29,10 @@ pub fn build_predefined_procedures() -> Vec<(String, Procedure)> { "create_test_graph_data".to_string(), create_test_graph_data::build_procedure(), ), + ( + "create_insert_test_graph".to_string(), + create_insert_test_graph::build_procedure(), + ), // Show graph in current schema. ("show_graph".to_string(), show_graph::build_procedure()), ]; From 8e1676d4c00e532e0b8f7f30535a928ef897f4d4 Mon Sep 17 00:00:00 2001 From: qishipengqsp Date: Wed, 27 May 2026 19:08:29 +0800 Subject: [PATCH 6/7] style: apply nightly rustfmt Co-Authored-By: Claude Opus 4.7 --- minigu/gql/parser/src/ast/data.rs | 2 +- minigu/gql/parser/src/parser/impls/data.rs | 5 ++- minigu/gql/planner/src/binder/data.rs | 40 +++++++++++++--------- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/minigu/gql/parser/src/ast/data.rs b/minigu/gql/parser/src/ast/data.rs index 404987eaf..87cbcbbca 100644 --- a/minigu/gql/parser/src/ast/data.rs +++ b/minigu/gql/parser/src/ast/data.rs @@ -1,6 +1,6 @@ //! AST definitions for *data-modifying statements*. -use super::{ElementPattern}; +use super::ElementPattern; use crate::macros::base; use crate::span::{Spanned, VecSpanned}; diff --git a/minigu/gql/parser/src/parser/impls/data.rs b/minigu/gql/parser/src/parser/impls/data.rs index a955415a4..570a10708 100644 --- a/minigu/gql/parser/src/parser/impls/data.rs +++ b/minigu/gql/parser/src/parser/impls/data.rs @@ -44,9 +44,8 @@ fn insert_statement(input: &mut TokenStream) -> ModalResult ModalResult> { ( node_pattern, - repeat(0.., (edge_pattern, node_pattern)).map( - |pairs: Vec<(Spanned, Spanned)>| pairs, - ), + repeat(0.., (edge_pattern, node_pattern)) + .map(|pairs: Vec<(Spanned, Spanned)>| pairs), ) .map(|(first, rest)| { let mut elements: VecSpanned = Vec::with_capacity(1 + rest.len() * 2); diff --git a/minigu/gql/planner/src/binder/data.rs b/minigu/gql/planner/src/binder/data.rs index c3d78109f..639e3cadd 100644 --- a/minigu/gql/planner/src/binder/data.rs +++ b/minigu/gql/planner/src/binder/data.rs @@ -75,7 +75,9 @@ impl Binder<'_> { // Insert paths have shape `Node (Edge Node)*` so the first element // is a node and after that pairs of (edge, node). let mut iter = path.elements.iter().peekable(); - let first = iter.next().ok_or_else(|| BindError::InsertPathTooComplex(0))?; + let first = iter + .next() + .ok_or_else(|| BindError::InsertPathTooComplex(0))?; let first_var = self.bind_insert_vertex( first.value(), graph_type.as_ref(), @@ -176,11 +178,11 @@ impl Binder<'_> { let label_id = bind_single_label(filler.label.as_ref(), graph_type) .ok_or(BindError::InsertVertexLabelMissing)??; let label_set: LabelSet = LabelSet::from_iter([label_id]); - let vertex_type = graph_type - .get_vertex_type(&label_set)? - .ok_or_else(|| BindError::InsertVertexTypeNotFound { + let vertex_type = graph_type.get_vertex_type(&label_set)?.ok_or_else(|| { + BindError::InsertVertexTypeNotFound { label: label_id_to_smol(graph_type, label_id), - })?; + } + })?; let label_name = label_id_to_smol(graph_type, label_id); let properties = bind_property_list( @@ -240,8 +242,11 @@ impl Binder<'_> { } let label_name = label_id_to_smol(graph_type, label_id); - let properties = - bind_property_list(filler.predicate.as_ref(), edge_type.properties(), &label_name)?; + let properties = bind_property_list( + filler.predicate.as_ref(), + edge_type.properties(), + &label_name, + )?; let variable = filler .variable @@ -309,20 +314,21 @@ fn bind_property_list( label: label.clone(), property: SmolStr::new(name), })?; + let value = literal_scalar_from_expr(field.value().value.value()).ok_or_else(|| { + BindError::InsertNonLiteralProperty { + property: SmolStr::new(name), + } + })?; let value = - literal_scalar_from_expr(field.value().value.value()).ok_or_else(|| { - BindError::InsertNonLiteralProperty { + coerce_scalar_to_type(value, declared_prop.logical_type()).ok_or_else(|| { + BindError::InsertPropertyTypeMismatch { + label: label.clone(), property: SmolStr::new(name), + expected: declared_prop.logical_type().clone(), + actual: LogicalType::Null, /* best-effort; precise actual omitted to keep msg + * simple */ } })?; - let value = coerce_scalar_to_type(value, declared_prop.logical_type()).ok_or_else( - || BindError::InsertPropertyTypeMismatch { - label: label.clone(), - property: SmolStr::new(name), - expected: declared_prop.logical_type().clone(), - actual: LogicalType::Null, // best-effort; precise actual omitted to keep msg simple - }, - )?; by_name.insert( declared_prop.name(), BoundInsertProperty { From e7dd51e0f4ffda81fa333681b9dc01bc8d8e0dff Mon Sep 17 00:00:00 2001 From: qishipengqsp Date: Wed, 27 May 2026 19:17:58 +0800 Subject: [PATCH 7/7] fix(parser): import Vec from crate::imports for no_std build CI builds gql-parser with --no-default-features against aarch64-unknown-none, where the prelude does not provide alloc's Vec. Other parser modules use `use crate::imports::Vec;` for this; bring the INSERT parser in line. Co-Authored-By: Claude Opus 4.7 --- minigu/gql/parser/src/parser/impls/data.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/minigu/gql/parser/src/parser/impls/data.rs b/minigu/gql/parser/src/parser/impls/data.rs index 570a10708..936187cdc 100644 --- a/minigu/gql/parser/src/parser/impls/data.rs +++ b/minigu/gql/parser/src/parser/impls/data.rs @@ -6,6 +6,7 @@ use crate::ast::{ DataModifyingStatement, ElementPattern, InsertPath, InsertStatement, LinearDataModifyingStatement, }; +use crate::imports::Vec; use crate::lexer::TokenKind; use crate::parser::token::{TokenStream, any}; use crate::parser::utils::{SpannedParserExt, ToSpanned};