Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 44 additions & 66 deletions fluss-rust/bindings/cpp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2155,12 +2155,12 @@ unsafe fn delete_append_writer(writer: *mut AppendWriter) {
impl AppendWriter {
fn append(&mut self, row: &GenericRowInner) -> ffi::FfiPtrResult {
let schema = self.table_info.get_schema();
let generic_row = match types::resolve_row_types(&row.row, Some(schema)) {
let generic_row = match types::resolve_row_types(&row.row, Some(schema), 0) {
Ok(r) => r,
Err(e) => return client_err_ptr(e.to_string()),
};

let result_future = match self.inner.append(&generic_row) {
let result_future = match self.inner.append(generic_row.as_ref()) {
Ok(f) => f,
Err(e) => return err_ptr_from_core(&e),
};
Expand Down Expand Up @@ -2243,25 +2243,17 @@ unsafe fn delete_upsert_writer(writer: *mut UpsertWriter) {
}

impl UpsertWriter {
/// Pad row with Null to full schema width.
/// This allows callers to only set the fields they care about.
fn pad_row<'a>(&self, mut row: fcore::row::GenericRow<'a>) -> fcore::row::GenericRow<'a> {
let num_columns = self.table_info.get_schema().columns().len();
if row.values.len() < num_columns {
row.values.resize(num_columns, fcore::row::Datum::Null);
}
row
}

fn upsert(&mut self, row: &GenericRowInner) -> ffi::FfiPtrResult {
let schema = self.table_info.get_schema();
let generic_row = match types::resolve_row_types(&row.row, Some(schema)) {
Ok(r) => r,
Err(e) => return client_err_ptr(e.to_string()),
};
let generic_row = self.pad_row(generic_row);
// Resolve types and pad to full schema width, so callers may set only
// the fields they care about.
let generic_row =
match types::resolve_row_types(&row.row, Some(schema), schema.columns().len()) {
Ok(r) => r,
Err(e) => return client_err_ptr(e.to_string()),
};

let result_future = match self.inner.upsert(&generic_row) {
let result_future = match self.inner.upsert(generic_row.as_ref()) {
Ok(f) => f,
Err(e) => return err_ptr_from_core(&e),
};
Expand All @@ -2274,13 +2266,15 @@ impl UpsertWriter {

fn delete_row(&mut self, row: &GenericRowInner) -> ffi::FfiPtrResult {
let schema = self.table_info.get_schema();
let generic_row = match types::resolve_row_types(&row.row, Some(schema)) {
Ok(r) => r,
Err(e) => return client_err_ptr(e.to_string()),
};
let generic_row = self.pad_row(generic_row);
// Resolve types and pad to full schema width, so callers may set only
// the fields they care about.
let generic_row =
match types::resolve_row_types(&row.row, Some(schema), schema.columns().len()) {
Ok(r) => r,
Err(e) => return client_err_ptr(e.to_string()),
};

let result_future = match self.inner.delete(&generic_row) {
let result_future = match self.inner.delete(generic_row.as_ref()) {
Ok(f) => f,
Err(e) => return err_ptr_from_core(&e),
};
Expand Down Expand Up @@ -2311,35 +2305,24 @@ unsafe fn delete_lookuper(lookuper: *mut Lookuper) {
}

impl Lookuper {
/// Build a dense PK-only row from a (possibly sparse) input row.
/// The user may set PK values at their full schema positions (e.g. [0, 2])
/// via name-based Set(). We compact them into [0, 1, …] to match
/// the lookup_row_type the core KeyEncoder expects.
fn dense_pk_row<'a>(&self, mut row: fcore::row::GenericRow<'a>) -> fcore::row::GenericRow<'a> {
let pk_indices = self.table_info.get_schema().primary_key_indexes();
let mut dense = fcore::row::GenericRow::new(pk_indices.len());
for (dense_idx, &schema_idx) in pk_indices.iter().enumerate() {
if schema_idx < row.values.len() {
dense.values[dense_idx] =
std::mem::replace(&mut row.values[schema_idx], fcore::row::Datum::Null);
}
}
dense
}

fn lookup(&mut self, pk_row: &GenericRowInner) -> Box<LookupResultInner> {
let schema = self.table_info.get_schema();
let generic_row = match types::resolve_row_types(&pk_row.row, Some(schema)) {
Ok(r) => self.dense_pk_row(r),
Err(e) => {
return Box::new(LookupResultInner::from_error(
CLIENT_ERROR_CODE,
e.to_string(),
));
}
};
// Compact PK values (set at their full schema positions, e.g. [0, 2])
// into the dense PK-only row the core KeyEncoder expects. Skips the
// rebuild when the row is already dense and needs no conversion.
let pk_indices = schema.primary_key_indexes();
let generic_row =
match types::resolve_dense_row_types(&pk_row.row, Some(schema), &pk_indices) {
Ok(r) => r,
Err(e) => {
return Box::new(LookupResultInner::from_error(
CLIENT_ERROR_CODE,
e.to_string(),
));
}
};

let lookup_result = match RUNTIME.block_on(self.inner.lookup(&generic_row)) {
let lookup_result = match RUNTIME.block_on(self.inner.lookup(generic_row.as_ref())) {
Ok(r) => r,
Err(e) => {
let ffi_err = err_from_core_error(&e);
Expand Down Expand Up @@ -2391,23 +2374,18 @@ unsafe fn delete_prefix_lookuper(lookuper: *mut PrefixLookuper) {
}

impl PrefixLookuper {
/// Compact a sparse input row (prefix columns set at their schema positions)
/// into the dense, lookup-column-ordered row the core prefix encoder expects.
fn dense_prefix_row<'a>(&self, mut row: GenericRow<'a>) -> GenericRow<'a> {
let mut dense = GenericRow::new(self.lookup_column_indices.len());
for (dense_idx, &schema_idx) in self.lookup_column_indices.iter().enumerate() {
if schema_idx < row.values.len() {
dense.values[dense_idx] =
std::mem::replace(&mut row.values[schema_idx], Datum::Null);
}
}
dense
}

fn prefix_lookup(&mut self, prefix_row: &GenericRowInner) -> Box<PrefixLookupResultInner> {
let schema = self.table_info.get_schema();
let generic_row = match types::resolve_row_types(&prefix_row.row, Some(schema)) {
Ok(r) => self.dense_prefix_row(r),
// Compact prefix values (set at their full schema positions) into the
// dense, lookup-column-ordered row the core prefix encoder expects.
// Skips the rebuild when the row is already dense and needs no
// conversion.
let generic_row = match types::resolve_dense_row_types(
&prefix_row.row,
Some(schema),
&self.lookup_column_indices,
) {
Ok(r) => r,
Err(e) => {
return Box::new(PrefixLookupResultInner::from_error(
CLIENT_ERROR_CODE,
Expand All @@ -2416,7 +2394,7 @@ impl PrefixLookuper {
}
};

let lookup_result = match RUNTIME.block_on(self.inner.lookup(&generic_row)) {
let lookup_result = match RUNTIME.block_on(self.inner.lookup(generic_row.as_ref())) {
Ok(r) => r,
Err(e) => {
let ffi_err = err_from_core_error(&e);
Expand Down
Loading
Loading