use super::*;
#[test]
fn a_columnar_statement_clones_no_store() {
use crate::graph::storage::column_store::{column_store_clones, reset_column_store_clones};
let mut graph = wide_columnar();
reset_column_store_clones();
run(&mut graph, "MATCH (n:Item {id: 1}) SET n.qty = 111");
let first = column_store_clones();
reset_column_store_clones();
run(&mut graph, "MATCH (n:Item {id: 2}) SET n.qty = 222");
let second = column_store_clones();
assert_eq!(
(first, second),
(0, 0),
"a columnar statement must copy no column store: writing one cell of a \
{WIDE_ITEMS}-row type copied ({first}, {second}) whole stores. A \
non-zero reading means something is holding a second handle on the \
master across the write — the O(rows x cols)-per-statement tax this \
phase removed, back again."
);
assert_eq!(
graph
.graph
.node_view(
graph
.graph
.node_indices()
.find(|i| graph.graph.get_node_id(*i) == Some(Value::Int64(2)))
.expect("node 2")
)
.and_then(|n| n.get_property_value("qty")),
Some(Value::Int64(222)),
);
}
#[test]
fn a_rolled_back_columnar_statement_clones_no_store() {
use crate::graph::storage::column_store::{column_store_clones, reset_column_store_clones};
let mut graph = wide_columnar();
reset_column_store_clones();
expect_failure(
&mut graph,
"MATCH (n:Item {id: 1}) SET n.qty = 111 \
WITH n MATCH (m:Item {id: 2}) SET m.qty = duration({months: 2147483648})",
None,
);
let cloned = column_store_clones();
assert_eq!(
cloned, 0,
"a rolled-back columnar statement copied {cloned} whole store(s); \
capture *and* replay must both be O(cells changed)"
);
assert_eq!(
graph
.graph
.node_view(
graph
.graph
.node_indices()
.find(|i| graph.graph.get_node_id(*i) == Some(Value::Int64(1)))
.expect("node 1")
)
.and_then(|n| n.get_property_value("qty")),
Some(Value::Int64(1)),
"the fixture seeds qty = id, and the failed SET must not have stuck"
);
}
#[test]
fn a_transactions_first_write_copies_only_the_column_it_writes() {
use crate::graph::session::Session;
use crate::graph::storage::column_store::{column_clones, reset_column_clones};
let session = Session::new(wide_schema_columnar());
let mut tx = session.begin();
let working = tx.working_mut().expect("begin() is read-write");
reset_column_clones();
run(working, "MATCH (i:Item {id: 7}) SET i.p0 = 111");
let first = column_clones();
reset_column_clones();
run(working, "MATCH (i:Item {id: 8}) SET i.p0 = 222");
let second = column_clones();
assert_eq!(
(first, second),
(1, 0),
"a transaction's first one-cell write must deep-copy exactly one column \
of a {WIDE_SCHEMA_COLUMNS}-property type and its later writes none; \
copied ({first}, {second}). A first reading near {} is the whole-store \
fork — O(rows x columns) to write one cell. A first reading of 0 means \
the base is not sharing the store and the pin is vacuous.",
WIDE_SCHEMA_COLUMNS + 2
);
assert_eq!(
item_prop(working, 7, "p0"),
Some(Value::Int64(111)),
"the transaction's write must be visible to the transaction"
);
assert_eq!(
item_prop(&session.snapshot(), 7, "p0"),
Some(Value::Int64(7)),
"the fixture seeds p0 = id; an uncommitted transaction write that \
reached the base is a copy-on-write failure, not an optimisation"
);
}