Skip to content

Commit 45baf14

Browse files
authored
Merge branch 'main' into fix-offset-overflow
2 parents ef9b92c + 840da05 commit 45baf14

61 files changed

Lines changed: 2908 additions & 657 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

datafusion-cli/src/exec.rs

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -423,16 +423,17 @@ async fn create_plan(
423423

424424
// Expose stdin (e.g. `cat data.csv | datafusion-cli`) as a `stdin://`
425425
// object store, registered like any other scheme in `get_object_store`.
426-
cmd.location = StdinUtils::rewrite_location(&cmd.location, format.as_ref());
427-
428-
register_object_store_and_config_extensions(
429-
ctx,
430-
&cmd.location,
431-
&cmd.options,
432-
format,
433-
resolve_region,
434-
)
435-
.await?;
426+
for location in &mut cmd.locations {
427+
*location = StdinUtils::rewrite_location(location, format.as_ref());
428+
register_object_store_and_config_extensions(
429+
ctx,
430+
location,
431+
&cmd.options,
432+
format.clone(),
433+
resolve_region,
434+
)
435+
.await?;
436+
}
436437
}
437438

438439
if let LogicalPlan::Copy(copy_to) = &mut plan {
@@ -535,14 +536,16 @@ mod tests {
535536

536537
if let LogicalPlan::Ddl(DdlStatement::CreateExternalTable(cmd)) = &plan {
537538
let format = config_file_type_from_str(&cmd.file_type);
538-
register_object_store_and_config_extensions(
539-
&ctx,
540-
&cmd.location,
541-
&cmd.options,
542-
format,
543-
false,
544-
)
545-
.await?;
539+
for location in &cmd.locations {
540+
register_object_store_and_config_extensions(
541+
&ctx,
542+
location,
543+
&cmd.options,
544+
format.clone(),
545+
false,
546+
)
547+
.await?;
548+
}
546549
} else {
547550
return plan_err!("LogicalPlan is not a CreateExternalTable");
548551
}

datafusion-examples/examples/dataframe/cache_factory.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use datafusion::error::Result;
2929
use datafusion::execution::context::QueryPlanner;
3030
use datafusion::execution::session_state::CacheFactory;
3131
use datafusion::execution::{SessionState, SessionStateBuilder};
32+
use datafusion::logical_expr::physical_planning_context::PhysicalPlanningContext;
3233
use datafusion::logical_expr::{
3334
Extension, LogicalPlan, UserDefinedLogicalNode, UserDefinedLogicalNodeCore,
3435
};
@@ -146,6 +147,7 @@ impl ExtensionPlanner for CacheNodePlanner {
146147
logical_inputs: &[&LogicalPlan],
147148
physical_inputs: &[Arc<dyn ExecutionPlan>],
148149
session_state: &SessionState,
150+
_planning_ctx: &PhysicalPlanningContext,
149151
) -> Result<Option<Arc<dyn ExecutionPlan>>> {
150152
if let Some(cache_node) = node.as_any().downcast_ref::<CacheNode>() {
151153
assert_eq!(logical_inputs.len(), 1, "Inconsistent number of inputs");

datafusion-examples/examples/query_planning/expr_api.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ use datafusion::functions_aggregate::first_last::first_value_udaf;
3333
use datafusion::logical_expr::execution_props::ExecutionProps;
3434
use datafusion::logical_expr::expr::BinaryExpr;
3535
use datafusion::logical_expr::interval_arithmetic::Interval;
36+
use datafusion::logical_expr::physical_planning_context::PhysicalPlanningContext;
3637
use datafusion::logical_expr::simplify::SimplifyContext;
3738
use datafusion::logical_expr::{ColumnarValue, ExprFunctionExt, ExprSchemable, Operator};
3839
use datafusion::optimizer::analyzer::type_coercion::TypeCoercionRewriter;
@@ -541,8 +542,12 @@ fn type_coercion_demo() -> Result<()> {
541542

542543
// Evaluation with an expression that has not been type coerced cannot succeed.
543544
let props = ExecutionProps::default();
544-
let physical_expr =
545-
datafusion::physical_expr::create_physical_expr(&expr, &df_schema, &props)?;
545+
let physical_expr = datafusion::physical_expr::create_physical_expr(
546+
&expr,
547+
&df_schema,
548+
&props,
549+
&PhysicalPlanningContext::default(),
550+
)?;
546551
let e = physical_expr.evaluate(&batch).unwrap_err();
547552
assert!(
548553
e.find_root()
@@ -566,6 +571,7 @@ fn type_coercion_demo() -> Result<()> {
566571
&coerced_expr,
567572
&df_schema,
568573
&props,
574+
&PhysicalPlanningContext::default(),
569575
)?;
570576
assert!(physical_expr.evaluate(&batch).is_ok());
571577

@@ -578,6 +584,7 @@ fn type_coercion_demo() -> Result<()> {
578584
&coerced_expr,
579585
&df_schema,
580586
&props,
587+
&PhysicalPlanningContext::default(),
581588
)?;
582589
assert!(physical_expr.evaluate(&batch).is_ok());
583590

@@ -606,6 +613,7 @@ fn type_coercion_demo() -> Result<()> {
606613
&coerced_expr,
607614
&df_schema,
608615
&props,
616+
&PhysicalPlanningContext::default(),
609617
)?;
610618
assert!(physical_expr.evaluate(&batch).is_ok());
611619

datafusion-examples/examples/query_planning/pruning.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use datafusion::common::pruning::PruningStatistics;
2626
use datafusion::common::{DFSchema, ScalarValue};
2727
use datafusion::error::Result;
2828
use datafusion::execution::context::ExecutionProps;
29+
use datafusion::logical_expr::physical_planning_context::PhysicalPlanningContext;
2930
use datafusion::physical_expr::create_physical_expr;
3031
use datafusion::physical_optimizer::pruning::PruningPredicate;
3132
use datafusion::prelude::*;
@@ -194,7 +195,13 @@ impl PruningStatistics for MyCatalog {
194195
fn create_pruning_predicate(expr: Expr, schema: &SchemaRef) -> PruningPredicate {
195196
let df_schema = DFSchema::try_from(Arc::clone(schema)).unwrap();
196197
let props = ExecutionProps::new();
197-
let physical_expr = create_physical_expr(&expr, &df_schema, &props).unwrap();
198+
let physical_expr = create_physical_expr(
199+
&expr,
200+
&df_schema,
201+
&props,
202+
&PhysicalPlanningContext::default(),
203+
)
204+
.unwrap();
198205
PruningPredicate::try_new(physical_expr, Arc::clone(schema)).unwrap()
199206
}
200207

datafusion-examples/examples/relation_planner/table_sample.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ use datafusion_common::{
119119
DFSchemaRef, DataFusionError, Result, Statistics, internal_err, not_impl_err,
120120
plan_datafusion_err, plan_err,
121121
};
122+
use datafusion_expr::physical_planning_context::PhysicalPlanningContext;
122123
use datafusion_expr::{
123124
UserDefinedLogicalNode, UserDefinedLogicalNodeCore,
124125
logical_plan::{Extension, LogicalPlan, LogicalPlanBuilder},
@@ -587,6 +588,7 @@ impl ExtensionPlanner for TableSampleExtensionPlanner {
587588
_logical_inputs: &[&LogicalPlan],
588589
physical_inputs: &[Arc<dyn ExecutionPlan>],
589590
_session_state: &SessionState,
591+
_planning_ctx: &PhysicalPlanningContext,
590592
) -> Result<Option<Arc<dyn ExecutionPlan>>> {
591593
let Some(sample_node) = node.as_any().downcast_ref::<TableSamplePlanNode>()
592594
else {

datafusion/catalog-listing/src/helpers.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ use arrow::{
3434
record_batch::RecordBatch,
3535
};
3636
use datafusion_expr::execution_props::ExecutionProps;
37+
use datafusion_expr::physical_planning_context::PhysicalPlanningContext;
3738
use futures::stream::FuturesUnordered;
3839
use futures::{StreamExt, TryStreamExt, stream::BoxStream};
3940
use log::{debug, trace};
@@ -328,7 +329,12 @@ pub fn filter_partitioned_file(
328329

329330
let filter = utils::conjunction(filters.iter().cloned()).unwrap_or_else(|| lit(true));
330331
let props = ExecutionProps::new();
331-
let expr = create_physical_expr(&filter, df_schema, &props)?;
332+
let expr = create_physical_expr(
333+
&filter,
334+
df_schema,
335+
&props,
336+
&PhysicalPlanningContext::default(),
337+
)?;
332338

333339
// Since we're only operating on a single file, our batch and resulting "array" holds only one
334340
// value indicating if the input file matches the provided filters

datafusion/catalog-listing/src/table.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ use datafusion_execution::cache::cache_manager::{
4444
};
4545
use datafusion_expr::dml::InsertOp;
4646
use datafusion_expr::execution_props::ExecutionProps;
47+
use datafusion_expr::physical_planning_context::PhysicalPlanningContext;
4748
use datafusion_expr::{
4849
Expr, Partitioning as LogicalPartitioning, TableProviderFilterPushDown, TableType,
4950
};
@@ -54,7 +55,7 @@ use datafusion_physical_plan::ExecutionPlan;
5455
use datafusion_physical_plan::empty::EmptyExec;
5556
use futures::{Stream, StreamExt, TryStreamExt, future, stream};
5657
use object_store::ObjectStore;
57-
use std::collections::HashMap;
58+
use std::collections::{HashMap, HashSet};
5859
use std::sync::Arc;
5960

6061
/// Result of a file listing operation from [`ListingTable::list_files_for_scan`].
@@ -614,6 +615,7 @@ impl TableProvider for ListingTable {
614615
output_partitioning,
615616
&df_schema,
616617
state.execution_props(),
618+
&PhysicalPlanningContext::default(),
617619
)?
618620
}
619621
};
@@ -816,7 +818,15 @@ impl ListingTable {
816818
.await?;
817819
let meta_fetch_concurrency =
818820
ctx.config_options().execution.meta_fetch_concurrency.get();
819-
let file_list = stream::iter(file_list).flatten_unordered(meta_fetch_concurrency);
821+
// Table paths can overlap, for example when one path is a directory and
822+
// another names a file inside it. A ListingTable uses one object store,
823+
// so the object path uniquely identifies a file within this scan.
824+
let mut seen_files = HashSet::new();
825+
let file_list = stream::iter(file_list)
826+
.flatten_unordered(meta_fetch_concurrency)
827+
.try_filter(move |file| {
828+
future::ready(seen_files.insert(file.object_meta.location.clone()))
829+
});
820830
// collect the statistics and ordering if required by the config
821831
let files = file_list
822832
.map(|part_file| async {

datafusion/catalog/src/memory/table.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ use datafusion_datasource::memory::{MemSink, MemorySourceConfig};
3636
use datafusion_datasource::sink::DataSinkExec;
3737
use datafusion_datasource::source::DataSourceExec;
3838
use datafusion_expr::dml::InsertOp;
39+
use datafusion_expr::physical_planning_context::PhysicalPlanningContext;
3940
use datafusion_expr::{Expr, SortExpr, TableType};
4041
use datafusion_physical_expr::{
4142
LexOrdering, PhysicalExpr, create_physical_expr, create_physical_sort_exprs,
@@ -209,8 +210,12 @@ impl TableProvider for MemTable {
209210
let eqp = state.execution_props();
210211
let mut file_sort_order = vec![];
211212
for sort_exprs in sort_order.iter() {
212-
let physical_exprs =
213-
create_physical_sort_exprs(sort_exprs, &df_schema, eqp)?;
213+
let physical_exprs = create_physical_sort_exprs(
214+
sort_exprs,
215+
&df_schema,
216+
eqp,
217+
&PhysicalPlanningContext::default(),
218+
)?;
214219
file_sort_order.extend(LexOrdering::new(physical_exprs));
215220
}
216221
source = source.try_with_sort_information(file_sort_order)?;
@@ -356,8 +361,12 @@ impl TableProvider for MemTable {
356361
let physical_assignments: HashMap<String, Arc<dyn PhysicalExpr>> = assignments
357362
.iter()
358363
.map(|(name, expr)| {
359-
let physical_expr =
360-
create_physical_expr(expr, &df_schema, state.execution_props())?;
364+
let physical_expr = create_physical_expr(
365+
expr,
366+
&df_schema,
367+
state.execution_props(),
368+
&PhysicalPlanningContext::default(),
369+
)?;
361370
Ok((name.clone(), physical_expr))
362371
})
363372
.collect::<Result<_>>()?;
@@ -470,8 +479,12 @@ fn evaluate_filters_to_mask(
470479
let mut combined_mask: Option<BooleanArray> = None;
471480

472481
for filter_expr in filters {
473-
let physical_expr =
474-
create_physical_expr(filter_expr, df_schema, execution_props)?;
482+
let physical_expr = create_physical_expr(
483+
filter_expr,
484+
df_schema,
485+
execution_props,
486+
&PhysicalPlanningContext::default(),
487+
)?;
475488

476489
let result = physical_expr.evaluate(batch)?;
477490
let array = result.into_array(batch.num_rows())?;

datafusion/catalog/src/stream.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,15 @@ impl TableProviderFactory for StreamTableFactory {
5353
cmd: &CreateExternalTable,
5454
) -> Result<Arc<dyn TableProvider>> {
5555
let schema: SchemaRef = Arc::clone(cmd.schema.inner());
56-
let location = cmd.location.clone();
56+
let location = match cmd.locations.as_slice() {
57+
[single] => single.clone(),
58+
_ => {
59+
return config_err!(
60+
"Stream tables support exactly one location; \
61+
use a listing table to read multiple files"
62+
);
63+
}
64+
};
5765
let encoding = cmd.file_type.parse()?;
5866
let header = if let Ok(opt) = cmd
5967
.options

datafusion/catalog/src/streaming.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use std::sync::Arc;
2222
use arrow::datatypes::SchemaRef;
2323
use async_trait::async_trait;
2424
use datafusion_common::{DFSchema, Result, plan_err};
25+
use datafusion_expr::physical_planning_context::PhysicalPlanningContext;
2526
use datafusion_expr::{Expr, SortExpr, TableType};
2627
use datafusion_physical_expr::equivalence::project_ordering;
2728
use datafusion_physical_expr::projection::ProjectionMapping;
@@ -131,8 +132,12 @@ impl TableProvider for StreamingTable {
131132
let df_schema = DFSchema::try_from(Arc::clone(&self.schema))?;
132133
let eqp = state.execution_props();
133134

134-
let original_sort_exprs =
135-
create_physical_sort_exprs(&self.sort_order, &df_schema, eqp)?;
135+
let original_sort_exprs = create_physical_sort_exprs(
136+
&self.sort_order,
137+
&df_schema,
138+
eqp,
139+
&PhysicalPlanningContext::default(),
140+
)?;
136141

137142
if let Some(p) = projection {
138143
// When performing a projection, the output columns will not match

0 commit comments

Comments
 (0)