nodedb_physical/physical_plan/document/update_value.rs
1// SPDX-License-Identifier: Apache-2.0
2
3//! Right-hand side of an UPDATE ... SET field = <...> assignment.
4
5/// Right-hand side of an UPDATE ... SET field = <...> assignment.
6///
7/// The planner turns each assignment into one of these before it crosses
8/// the SPSC bridge:
9///
10/// - `Literal` — pre-encoded msgpack bytes for constant RHS. This is the
11/// fast path: the Data Plane can merge these at the binary level for
12/// non-strict collections without decoding the current row.
13/// - `Expr` — a `SqlExpr` that must be evaluated against the *current*
14/// document at apply time. Used for arithmetic (`col + 1`), functions
15/// (`LOWER(col)`, `NOW()`), `CASE`, concatenation, and anything else
16/// whose result depends on the row being updated.
17#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
18pub enum UpdateValue {
19 Literal(Vec<u8>),
20 Expr(nodedb_query::expr::SqlExpr),
21}
22
23impl zerompk::ToMessagePack for UpdateValue {
24 fn write<W: zerompk::Write>(&self, writer: &mut W) -> zerompk::Result<()> {
25 writer.write_array_len(2)?;
26 match self {
27 UpdateValue::Literal(bytes) => {
28 writer.write_u8(0)?;
29 bytes.write(writer)
30 }
31 UpdateValue::Expr(expr) => {
32 writer.write_u8(1)?;
33 expr.write(writer)
34 }
35 }
36 }
37}
38
39impl<'a> zerompk::FromMessagePack<'a> for UpdateValue {
40 fn read<R: zerompk::Read<'a>>(reader: &mut R) -> zerompk::Result<Self> {
41 reader.check_array_len(2)?;
42 let tag = reader.read_u8()?;
43 match tag {
44 0 => Ok(UpdateValue::Literal(Vec::<u8>::read(reader)?)),
45 1 => Ok(UpdateValue::Expr(nodedb_query::expr::SqlExpr::read(
46 reader,
47 )?)),
48 _ => Err(zerompk::Error::InvalidMarker(tag)),
49 }
50 }
51}