(
ctx: &SessionContext,
columns: &[String],
exprs: &[String],
cow_table_name: &str,
update: &Update,
writer: &mut CopyOnWriteMergeWriter,
)
| 221 | } |
| 222 | |
| 223 | async fn execute_cow_update_inner( |
| 224 | ctx: &SessionContext, |
| 225 | columns: &[String], |
| 226 | exprs: &[String], |
| 227 | cow_table_name: &str, |
| 228 | update: &Update, |
| 229 | writer: &mut CopyOnWriteMergeWriter, |
| 230 | ) -> DFResult<u64> { |
| 231 | let select_parts: Vec<String> = |
| 232 | std::iter::once("\"__paimon_file_idx\"".to_string()) |
| 233 | .chain(std::iter::once("\"__paimon_row_offset\"".to_string())) |
| 234 | .chain(columns.iter().zip(exprs.iter()).map(|(col, expr)| { |
| 235 | format!("{expr} AS {}", quote_identifier(&format!("__upd_{col}"))) |
| 236 | })) |
| 237 | .collect(); |
| 238 | |
| 239 | let select_clause = select_parts.join(", "); |
| 240 | let where_clause = match &update.selection { |
| 241 | Some(expr) => format!(" WHERE {expr}"), |
| 242 | None => String::new(), |
| 243 | }; |
| 244 | |
| 245 | // Safety: where_clause comes from sqlparser AST to_string(), not raw user input. |
| 246 | let query_sql = format!("SELECT {select_clause} FROM {cow_table_name}{where_clause}"); |
| 247 | let join_result = ctx.sql(&query_sql).await?.collect().await?; |
| 248 | |
| 249 | let mut update_value_batches: Vec<RecordBatch> = Vec::new(); |
| 250 | let mut batch_counter: usize = 0; |
| 251 | let mut total_count: u64 = 0; |
| 252 | |
| 253 | for batch in &join_result { |
| 254 | if batch.num_rows() == 0 { |
| 255 | continue; |
| 256 | } |
| 257 | |
| 258 | let (file_idx_col, row_offset_col) = extract_tracking_columns(batch)?; |
| 259 | |
| 260 | let mut upd_fields = Vec::new(); |
| 261 | let mut upd_columns: Vec<Arc<dyn Array>> = Vec::new(); |
| 262 | for col in columns { |
| 263 | let prefixed = format!("__upd_{col}"); |
| 264 | let idx = batch.schema().index_of(&prefixed).map_err(|e| { |
| 265 | DataFusionError::Internal(format!("Column {prefixed} not found: {e}")) |
| 266 | })?; |
| 267 | upd_fields.push(Field::new( |
| 268 | col, |
| 269 | batch.schema().field(idx).data_type().clone(), |
| 270 | true, |
| 271 | )); |
| 272 | upd_columns.push(batch.column(idx).clone()); |
| 273 | } |
| 274 | let upd_schema = Arc::new(Schema::new(upd_fields)); |
| 275 | let upd_batch = RecordBatch::try_new(upd_schema, upd_columns)?; |
| 276 | |
| 277 | let current_batch_idx = batch_counter; |
| 278 | update_value_batches.push(upd_batch); |
| 279 | batch_counter += 1; |
| 280 |
no test coverage detected