Skip to main content

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}