Skip to content
Draft
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
422 changes: 211 additions & 211 deletions native/Cargo.lock

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions native/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ edition = "2021"
rust-version = "1.88"

[workspace.dependencies]
arrow = { version = "58.4.0", features = ["prettyprint", "ffi", "chrono-tz"] }
arrow = { version = "59.1.0", features = ["prettyprint", "ffi", "chrono-tz"] }
async-trait = { version = "0.1" }
bytes = { version = "1.11.1" }
parquet = { version = "58.4.0", default-features = false, features = ["experimental"] }
datafusion = { version = "54.1.0", default-features = false, features = ["unicode_expressions", "crypto_expressions", "nested_expressions", "parquet"] }
datafusion-datasource = { version = "54.1.0" }
datafusion-physical-expr-adapter = { version = "54.1.0" }
datafusion-spark = { version = "54.1.0", features = ["core"] }
parquet = { version = "59.1.0", default-features = false, features = ["experimental"] }
datafusion = { git = "https://github.com/apache/datafusion.git", rev = "70c26a06716eb552f0fc1d2115957a4089504f11", default-features = false, features = ["unicode_expressions", "crypto_expressions", "nested_expressions", "parquet"] }
datafusion-datasource = { git = "https://github.com/apache/datafusion.git", rev = "70c26a06716eb552f0fc1d2115957a4089504f11" }
datafusion-physical-expr-adapter = { git = "https://github.com/apache/datafusion.git", rev = "70c26a06716eb552f0fc1d2115957a4089504f11" }
datafusion-spark = { git = "https://github.com/apache/datafusion.git", rev = "70c26a06716eb552f0fc1d2115957a4089504f11", features = ["core"] }
datafusion-comet-spark-expr = { path = "spark-expr" }
datafusion-comet-common = { path = "common" }
datafusion-comet-jni-bridge = { path = "jni-bridge" }
Expand All @@ -58,8 +58,8 @@ object_store = { version = "0.13.2", features = ["gcp", "azure", "aws", "http"]
url = "2.2"
aws-config = "1.8.18"
aws-credential-types = "1.2.13"
iceberg = { git = "https://github.com/apache/iceberg-rust", rev = "3d84c81353b1b23b6e4ae8eea8f8a021cc6927a7" }
iceberg-storage-opendal = { git = "https://github.com/apache/iceberg-rust", rev = "3d84c81353b1b23b6e4ae8eea8f8a021cc6927a7", features = ["opendal-memory", "opendal-fs", "opendal-s3", "opendal-gcs", "opendal-oss", "opendal-azdls"] }
iceberg = { git = "https://github.com/mbutrovich/iceberg-rust", rev = "07de8fc8d650f7439b251d57a55613f7de693eb8" }
iceberg-storage-opendal = { git = "https://github.com/mbutrovich/iceberg-rust", rev = "07de8fc8d650f7439b251d57a55613f7de693eb8", features = ["opendal-memory", "opendal-fs", "opendal-s3", "opendal-gcs", "opendal-oss", "opendal-azdls"] }
reqsign-core = "3"

[profile.release]
Expand Down
6 changes: 3 additions & 3 deletions native/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ aws-config = { workspace = true }
aws-credential-types = { workspace = true }
parking_lot = "0.12.5"
reqwest = { version = "0.12", default-features = false, features = ["rustls-tls-native-roots", "http2"] }
object_store_opendal = { version = "0.57.0", optional = true }
object_store_opendal = { version = "0.58.0", optional = true }
hdfs-sys = {version = "0.3", optional = true, features = ["hdfs_3_3"]}
opendal = { version = "0.57.0", optional = true, features = ["services-hdfs"] }
opendal = { version = "0.58.1", optional = true, features = ["services-hdfs"] }
iceberg = { workspace = true }
iceberg-storage-opendal = { workspace = true }
reqsign-core = { workspace = true }
Expand All @@ -91,7 +91,7 @@ jni = { version = "0.22.4", features = ["invocation"] }
lazy_static = "1.4"
assertables = "10"
hex = "0.4.3"
datafusion-functions-nested = { version = "54.1.0" }
datafusion-functions-nested = { git = "https://github.com/apache/datafusion.git", rev = "70c26a06716eb552f0fc1d2115957a4089504f11" }

[features]
backtrace = ["datafusion/backtrace"]
Expand Down
13 changes: 8 additions & 5 deletions native/core/src/execution/columnar_to_row.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2491,11 +2491,14 @@ mod tests {
let schema = vec![DataType::FixedSizeBinary(3)];
let mut ctx = ColumnarToRowContext::new(schema, 100);

let array: ArrayRef = Arc::new(FixedSizeBinaryArray::from(vec![
Some(&[1u8, 2, 3][..]),
Some(&[4u8, 5, 6][..]),
None, // Test null handling
]));
let array: ArrayRef = Arc::new(
FixedSizeBinaryArray::try_from(vec![
Some(&[1u8, 2, 3][..]),
Some(&[4u8, 5, 6][..]),
None, // Test null handling
])
.unwrap(),
);
let arrays = vec![array];

let (ptr, offsets, lengths) = ctx.convert(&arrays, 3).unwrap();
Expand Down
18 changes: 14 additions & 4 deletions native/core/src/execution/merge_as_partial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,20 +210,30 @@ impl GroupsAccumulator for MergeAsPartialGroupsAccumulator {
opt_filter: Option<&BooleanArray>,
total_num_groups: usize,
) -> Result<()> {
// Redirect update to merge — this is the key trick.
// Redirect update to merge — this is the key trick. Spark's PartialMerge mode
// never applies a filter (filters apply once, at the Partial stage), so there's
// nothing to forward into merge_batch, which no longer accepts one.
debug_assert!(opt_filter.is_none());
self.inner
.merge_batch(values, group_indices, opt_filter, total_num_groups)
.merge_batch(values, group_indices, total_num_groups)
}

fn merge_batch(
&mut self,
values: &[ArrayRef],
group_indices: &[usize],
opt_filter: Option<&BooleanArray>,
total_num_groups: usize,
) -> Result<()> {
self.inner
.merge_batch(values, group_indices, opt_filter, total_num_groups)
.merge_batch(values, group_indices, total_num_groups)
}

fn convert_to_state(
&self,
_values: &[ArrayRef],
_opt_filter: Option<&BooleanArray>,
) -> Result<Vec<ArrayRef>> {
datafusion::common::not_impl_err!("Input batch conversion to state not implemented")
}

fn evaluate(&mut self, emit_to: EmitTo) -> Result<ArrayRef> {
Expand Down
8 changes: 6 additions & 2 deletions native/core/src/execution/operators/copy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ pub(crate) fn copy_array(array: &dyn Array) -> ArrayRef {

let mut mutable = MutableArrayData::new(vec![&data], false, capacity);

mutable.extend(0, 0, capacity);
mutable
.try_extend(0, 0, capacity)
.expect("extend failed due to offset overflow");

if matches!(array.data_type(), DataType::Dictionary(_, _)) {
let copied_dict = make_array(mutable.freeze());
Expand All @@ -50,7 +52,9 @@ pub(crate) fn copy_array(array: &dyn Array) -> ArrayRef {
let data = values.to_data();

let mut mutable = MutableArrayData::new(vec![&data], false, values.len());
mutable.extend(0, 0, values.len());
mutable
.try_extend(0, 0, values.len())
.expect("extend failed due to offset overflow");

let copied_dict = ref_copied_dict.with_values(make_array(mutable.freeze()));
Arc::new(copied_dict)
Expand Down
2 changes: 2 additions & 0 deletions native/core/src/execution/operators/iceberg_scan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,8 @@ mod tests {
start: 0,
length: 0,
record_count: None,
first_row_id: None,
data_sequence_number: None,
data_file_path: "data.parquet".to_string(),
data_file_format: DataFileFormat::Parquet,
schema: Arc::new(Schema::builder().build().unwrap()),
Expand Down
20 changes: 8 additions & 12 deletions native/core/src/execution/operators/parquet_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ enum ParquetWriter {
/// The opendal::Writer is created lazily on first write
#[cfg(feature = "hdfs-opendal")]
Remote(
ArrowWriter<Cursor<Vec<u8>>>,
Box<ArrowWriter<Cursor<Vec<u8>>>>,
Option<opendal::Writer>,
Operator,
String,
Expand Down Expand Up @@ -338,7 +338,7 @@ impl ParquetWriterExec {
// HDFS writer will be created lazily on first write
// Use the path from prepare_object_store_with_configs
Ok(ParquetWriter::Remote(
arrow_parquet_buffer_writer,
Box::new(arrow_parquet_buffer_writer),
None,
op,
object_store_path.to_string(),
Expand Down Expand Up @@ -656,11 +656,9 @@ mod tests {

// Create OpenDAL HDFS operator
let builder = Hdfs::default().name_node(namenode);
let op = Operator::new(builder)
.map_err(|e| {
DataFusionError::Execution(format!("Failed to create HDFS operator: {}", e))
})?
.finish();
let op = Operator::new(builder).map_err(|e| {
DataFusionError::Execution(format!("Failed to create HDFS operator: {}", e))
})?;

let mut hdfs_writer = op.writer(output_path).await.map_err(|e| {
DataFusionError::Execution(format!("Failed to create HDFS writer: {}", e))
Expand Down Expand Up @@ -707,11 +705,9 @@ mod tests {

// Create OpenDAL HDFS operator
let builder = Hdfs::default().name_node(namenode);
let op = Operator::new(builder)
.map_err(|e| {
DataFusionError::Execution(format!("Failed to create HDFS operator: {}", e))
})?
.finish();
let op = Operator::new(builder).map_err(|e| {
DataFusionError::Execution(format!("Failed to create HDFS operator: {}", e))
})?;

// Create a single HDFS writer for the entire file
let mut hdfs_writer = op.writer(output_path).await.map_err(|e| {
Expand Down
10 changes: 8 additions & 2 deletions native/core/src/execution/planner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ use arrow::array::{
use arrow::buffer::{BooleanBuffer, NullBuffer, OffsetBuffer};
use arrow::row::{OwnedRow, RowConverter, SortField};
use datafusion::common::utils::SingleRowListArrayBuilder;
use datafusion::common::UnnestOptions;
use datafusion::common::{NullHandling, UnnestOptions};
use datafusion::physical_plan::filter::FilterExec;
use datafusion::physical_plan::joins::NestedLoopJoinExec;
use datafusion::physical_plan::limit::GlobalLimitExec;
Expand Down Expand Up @@ -2069,7 +2069,11 @@ impl PhysicalPlanner {
});

let unnest_options = UnnestOptions {
preserve_nulls: explode.outer,
null_handling: if explode.outer {
NullHandling::Preserve
} else {
NullHandling::Drop
},
recursions: vec![],
};

Expand Down Expand Up @@ -4139,6 +4143,8 @@ fn parse_file_scan_tasks_from_common(
start: proto_task.start,
length: proto_task.length,
record_count: proto_task.record_count,
first_row_id: None,
data_sequence_number: None,
data_file_format,
schema: schema_ref,
project_field_ids,
Expand Down
6 changes: 3 additions & 3 deletions native/core/src/parquet/eager_page_index_reader_factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@ use std::sync::Arc;
#[derive(Debug)]
pub struct EagerPageIndexReaderFactory {
store: Arc<dyn ObjectStore>,
metadata_cache: Arc<dyn FileMetadataCache>,
metadata_cache: Arc<FileMetadataCache>,
}

impl EagerPageIndexReaderFactory {
pub fn new(store: Arc<dyn ObjectStore>, metadata_cache: Arc<dyn FileMetadataCache>) -> Self {
pub fn new(store: Arc<dyn ObjectStore>, metadata_cache: Arc<FileMetadataCache>) -> Self {
Self {
store,
metadata_cache,
Expand Down Expand Up @@ -118,7 +118,7 @@ struct EagerPageIndexReader {
store: Arc<dyn ObjectStore>,
inner: ParquetObjectReader,
partitioned_file: PartitionedFile,
metadata_cache: Arc<dyn FileMetadataCache>,
metadata_cache: Arc<FileMetadataCache>,
metadata_size_hint: Option<usize>,
}

Expand Down
11 changes: 6 additions & 5 deletions native/core/src/parquet/parquet_exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use crate::parquet::eager_page_index_reader_factory::EagerPageIndexReaderFactory
use crate::parquet::encryption_support::{CometEncryptionConfig, ENCRYPTION_FACTORY_ID};
use crate::parquet::parquet_support::SparkParquetOptions;
use crate::parquet::schema_adapter::SparkPhysicalExprAdapterFactory;
use arrow::datatypes::{Field, SchemaRef};
use arrow::datatypes::{Field, FieldRef, SchemaRef};
use datafusion::config::{ParquetOptions, TableParquetOptions};
use datafusion::datasource::listing::PartitionedFile;
use datafusion::datasource::physical_plan::{
Expand Down Expand Up @@ -128,13 +128,14 @@ pub(crate) fn init_datasource_exec(
}
_ => (Arc::clone(&required_schema), None),
};
let partition_fields: Vec<_> = partition_schema
let partition_fields: Vec<FieldRef> = partition_schema
.iter()
.flat_map(|s| s.fields().iter())
.map(|f| Arc::new(Field::new(f.name(), f.data_type().clone(), f.is_nullable())) as _)
.map(|f| Arc::new(Field::new(f.name(), f.data_type().clone(), f.is_nullable())))
.collect();
let table_schema =
TableSchema::from_file_schema(base_schema).with_table_partition_cols(partition_fields);
let table_schema = TableSchema::builder(base_schema)
.with_table_partition_cols(partition_fields)
.build();

let mut parquet_source = ParquetSource::new(table_schema)
.with_table_parquet_options(table_parquet_options)
Expand Down
10 changes: 4 additions & 6 deletions native/core/src/parquet/parquet_support.rs
Original file line number Diff line number Diff line change
Expand Up @@ -445,12 +445,10 @@ pub(crate) fn create_hdfs_operator(url: &Url) -> Result<opendal::Operator, objec
let name_node = get_name_node_uri(url)?;
let builder = opendal::services::Hdfs::default().name_node(&name_node);

opendal::Operator::new(builder)
.map_err(|error| object_store::Error::Generic {
store: "hdfs-opendal",
source: error.into(),
})
.map(|op| op.finish())
opendal::Operator::new(builder).map_err(|error| object_store::Error::Generic {
store: "hdfs-opendal",
source: error.into(),
})
}

// Creates an HDFS object store from a URL using OpenDAL
Expand Down
Loading
Loading