fresh-borzoni commented on code in PR #239:
URL: https://github.com/apache/fluss-rust/pull/239#discussion_r2763940281
##########
bindings/python/src/table.rs:
##########
@@ -516,11 +690,237 @@ fn python_value_to_datum(
}
}
+/// Convert Rust Datum to Python value based on data type.
+/// This is the reverse of python_value_to_datum.
+pub fn datum_to_python_value(
+ py: Python,
+ row: &dyn fcore::row::InternalRow,
+ pos: usize,
+ data_type: &fcore::metadata::DataType,
+) -> PyResult<Py<PyAny>> {
+ use fcore::metadata::DataType;
+
+ // Check for null first
+ if row.is_null_at(pos) {
+ return Ok(py.None());
+ }
+
+ match data_type {
+ DataType::Boolean(_) => Ok(row
+ .get_boolean(pos)
+ .into_pyobject(py)?
+ .to_owned()
+ .into_any()
+ .unbind()),
+ DataType::TinyInt(_) => Ok(row
+ .get_byte(pos)
+ .into_pyobject(py)?
+ .to_owned()
+ .into_any()
+ .unbind()),
+ DataType::SmallInt(_) => Ok(row
+ .get_short(pos)
+ .into_pyobject(py)?
+ .to_owned()
+ .into_any()
+ .unbind()),
+ DataType::Int(_) => Ok(row
+ .get_int(pos)
+ .into_pyobject(py)?
+ .to_owned()
+ .into_any()
+ .unbind()),
+ DataType::BigInt(_) => Ok(row
+ .get_long(pos)
+ .into_pyobject(py)?
+ .to_owned()
+ .into_any()
+ .unbind()),
+ DataType::Float(_) => Ok(row
+ .get_float(pos)
+ .into_pyobject(py)?
+ .to_owned()
+ .into_any()
+ .unbind()),
+ DataType::Double(_) => Ok(row
+ .get_double(pos)
+ .into_pyobject(py)?
+ .to_owned()
+ .into_any()
+ .unbind()),
+ DataType::String(_) => {
+ let s = row.get_string(pos);
+ Ok(s.into_pyobject(py)?.into_any().unbind())
+ }
+ DataType::Char(char_type) => {
+ let s = row.get_char(pos, char_type.length() as usize);
+ Ok(s.into_pyobject(py)?.into_any().unbind())
+ }
+ DataType::Bytes(_) => {
+ let b = row.get_bytes(pos);
+ Ok(pyo3::types::PyBytes::new(py, b).into_any().unbind())
+ }
+ DataType::Binary(binary_type) => {
+ let b = row.get_binary(pos, binary_type.length());
+ Ok(pyo3::types::PyBytes::new(py, b).into_any().unbind())
+ }
+ DataType::Decimal(decimal_type) => {
+ let decimal = row.get_decimal(
+ pos,
+ decimal_type.precision() as usize,
+ decimal_type.scale() as usize,
+ );
+ rust_decimal_to_python(py, &decimal)
+ }
+ DataType::Date(_) => {
+ let date = row.get_date(pos);
+ rust_date_to_python(py, date)
+ }
+ DataType::Time(_) => {
+ let time = row.get_time(pos);
+ rust_time_to_python(py, time)
+ }
+ DataType::Timestamp(ts_type) => {
+ let ts = row.get_timestamp_ntz(pos, ts_type.precision());
+ rust_timestamp_ntz_to_python(py, ts)
+ }
+ DataType::TimestampLTz(ts_type) => {
+ let ts = row.get_timestamp_ltz(pos, ts_type.precision());
+ rust_timestamp_ltz_to_python(py, ts)
+ }
+ _ => Err(FlussError::new_err(format!(
+ "Unsupported data type for conversion to Python: {data_type}"
+ ))),
+ }
+}
+
+/// Convert Rust Decimal to Python decimal.Decimal
+fn rust_decimal_to_python(py: Python, decimal: &fcore::row::Decimal) ->
PyResult<Py<PyAny>> {
+ let decimal_ty = get_decimal_type(py)?;
+ let decimal_str = decimal.to_string();
+ let py_decimal = decimal_ty.call1((decimal_str,))?;
+ Ok(py_decimal.into_any().unbind())
+}
+
+/// Convert Rust Date (days since epoch) to Python datetime.date
+fn rust_date_to_python(py: Python, date: fcore::row::Date) ->
PyResult<Py<PyAny>> {
+ use pyo3::types::PyDate;
+
+ let days_since_epoch = date.get_inner();
+ let epoch = jiff::civil::date(1970, 1, 1);
+ let civil_date = epoch + jiff::Span::new().days(days_since_epoch as i64);
+
+ let py_date = PyDate::new(
+ py,
+ civil_date.year() as i32,
+ civil_date.month() as u8,
+ civil_date.day() as u8,
+ )?;
+ Ok(py_date.into_any().unbind())
+}
+
+/// Convert Rust Time (millis since midnight) to Python datetime.time
+fn rust_time_to_python(py: Python, time: fcore::row::Time) ->
PyResult<Py<PyAny>> {
+ use pyo3::types::PyTime;
+
+ let millis = time.get_inner() as i64;
+ let hours = millis / MILLIS_PER_HOUR;
+ let minutes = (millis % MILLIS_PER_HOUR) / MILLIS_PER_MINUTE;
+ let seconds = (millis % MILLIS_PER_MINUTE) / MILLIS_PER_SECOND;
+ let microseconds = (millis % MILLIS_PER_SECOND) * MICROS_PER_MILLI;
+
+ let py_time = PyTime::new(
+ py,
+ hours as u8,
+ minutes as u8,
+ seconds as u8,
+ microseconds as u32,
Review Comment:
we trust fluss storage here
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]