use nodedb_sql::types::{SqlExpr, SqlValue};
use crate::control::planner::sql_plan_convert::convert::ConvertContext;
use crate::control::planner::sql_plan_convert::value::row_to_msgpack;
pub(in crate::control::planner::sql_plan_convert::dml) fn document_collection_is_crdt(
ctx: &ConvertContext,
collection: &str,
) -> crate::Result<bool> {
let Some(credentials) = ctx.credentials.as_ref() else {
return Ok(false);
};
let catalog = credentials.catalog();
Ok(catalog
.get_collection(ctx.database_id, ctx.tenant_id.as_u64(), collection)?
.map(|c| c.crdt)
.unwrap_or(false))
}
pub(in crate::control::planner::sql_plan_convert::dml) fn row_to_fields_json(
row: &[(String, SqlValue)],
) -> crate::Result<String> {
let mpk = row_to_msgpack(row)?;
let json = nodedb_types::json_from_msgpack(&mpk).map_err(|e| crate::Error::Serialization {
format: "json".into(),
detail: format!("crdt fields_json encode: {e}"),
})?;
sonic_rs::to_string(&json).map_err(|e| crate::Error::Serialization {
format: "json".into(),
detail: format!("crdt fields_json encode: {e}"),
})
}
pub(in crate::control::planner::sql_plan_convert::dml) fn literal_assignments_to_fields_json(
assignments: &[(String, SqlExpr)],
) -> crate::Result<String> {
let mut row: Vec<(String, SqlValue)> = Vec::with_capacity(assignments.len());
for (field, expr) in assignments {
match expr {
SqlExpr::Literal(v) => row.push((field.clone(), v.clone())),
_ => {
return Err(crate::Error::BadRequest {
detail: format!(
"UPDATE with non-literal RHS on CRDT collection (field '{field}') \
is not supported; use a literal value"
),
});
}
}
}
row_to_fields_json(&row)
}