MCPcopy Create free account
hub / github.com/apache/paimon-rust / execute_update_once

Function execute_update_once

crates/integrations/datafusion/src/update.rs:88–160  ·  view source on GitHub ↗

Single attempt of UPDATE execution.

(
    ctx: &SQLContext,
    update: &Update,
    table: &Table,
)

Source from the content-addressed store, hash-verified

86
87/// Single attempt of UPDATE execution.
88async fn execute_update_once(
89 ctx: &SQLContext,
90 update: &Update,
91 table: &Table,
92) -> DFResult<DataFrame> {
93 // 1. Extract SET assignments
94 let mut columns = Vec::new();
95 let mut exprs = Vec::new();
96 for assignment in &update.assignments {
97 let col_name = match &assignment.target {
98 AssignmentTarget::ColumnName(name) => name
99 .0
100 .last()
101 .and_then(|p| p.as_ident())
102 .map(|id| id.value.clone())
103 .ok_or_else(|| {
104 DataFusionError::Plan(format!("Invalid column name in SET: {name}"))
105 })?,
106 AssignmentTarget::Tuple(_) => {
107 return Err(DataFusionError::Plan(
108 "Tuple assignment in UPDATE SET is not supported".to_string(),
109 ));
110 }
111 };
112 columns.push(col_name);
113 exprs.push(assignment.value.to_string());
114 }
115
116 // 2. Create DataEvolutionWriter (validates preconditions)
117 let mut writer =
118 DataEvolutionWriter::new(table, columns.clone()).map_err(to_datafusion_error)?;
119
120 // 3. Query the target table directly with WHERE filter.
121 let table_ref = update.table.to_string();
122
123 let select_parts: Vec<String> =
124 std::iter::once("\"_ROW_ID\"".to_string())
125 .chain(columns.iter().zip(exprs.iter()).map(|(col, expr)| {
126 format!("{expr} AS {}", quote_identifier(&format!("__upd_{col}")))
127 }))
128 .collect();
129
130 let select_clause = select_parts.join(", ");
131 let where_clause = match &update.selection {
132 Some(expr) => format!(" WHERE {expr}"),
133 None => String::new(),
134 };
135
136 let query_sql = format!("SELECT {select_clause} FROM {table_ref}{where_clause}");
137 let batches = ctx.ctx().sql(&query_sql).await?.collect().await?;
138
139 // 4. Project update columns (rename __upd_X → X)
140 let total_count: u64 = batches.iter().map(|b| b.num_rows() as u64).sum();
141 if total_count == 0 {
142 return ok_result(ctx.ctx(), 0);
143 }
144
145 let update_batches = project_update_columns(&batches, &columns)?;

Callers 1

Calls 13

project_update_columnsFunction · 0.85
ctxMethod · 0.80
num_rowsMethod · 0.80
add_matched_batchMethod · 0.80
new_commitMethod · 0.80
new_write_builderMethod · 0.80
ok_resultFunction · 0.70
PlanClass · 0.50
iterMethod · 0.45
sqlMethod · 0.45
prepare_commitMethod · 0.45
is_emptyMethod · 0.45

Tested by

no test coverage detected