MCPcopy Create free account
hub / github.com/apache/datafusion / unparse_table_scan_pushdown

Method unparse_table_scan_pushdown

datafusion/sql/src/unparser/plan.rs:1663–1815  ·  view source on GitHub ↗

Try to unparse a table scan with pushdown operations into a new subquery plan. If the table scan is without any pushdown operations, return None.

(
        &self,
        plan: &LogicalPlan,
        alias: Option<TableReference>,
        already_projected: bool,
    )

Source from the content-addressed store, hash-verified

1661 /// Try to unparse a table scan with pushdown operations into a new subquery plan.
1662 /// If the table scan is without any pushdown operations, return None.
1663 fn unparse_table_scan_pushdown(
1664 &self,
1665 plan: &LogicalPlan,
1666 alias: Option<TableReference>,
1667 already_projected: bool,
1668 ) -> Result<Option<LogicalPlan>> {
1669 match plan {
1670 LogicalPlan::TableScan(table_scan) => {
1671 if !Self::is_scan_with_pushdown(table_scan) {
1672 return Ok(None);
1673 }
1674 let table_schema = table_scan.source.schema();
1675 let mut filter_alias_rewriter =
1676 alias.as_ref().map(|alias_name| TableAliasRewriter {
1677 table_schema: &table_schema,
1678 alias_name: alias_name.clone(),
1679 });
1680
1681 let mut builder = LogicalPlanBuilder::scan(
1682 table_scan.table_name.clone(),
1683 Arc::clone(&table_scan.source),
1684 None,
1685 )?;
1686 // We will rebase the column references to the new alias if it exists.
1687 // If the projection or filters are empty, we will append alias to the table scan.
1688 //
1689 // Example:
1690 // select t1.c1 from t1 where t1.c1 > 1 -> select a.c1 from t1 as a where a.c1 > 1
1691 if let Some(ref alias) = alias
1692 && (table_scan.projection.is_some() || !table_scan.filters.is_empty())
1693 {
1694 builder = builder.alias(alias.clone())?;
1695 }
1696
1697 // Avoid creating a duplicate Projection node, which would result in an additional subquery if a projection already exists.
1698 // For example, if the `optimize_projection` rule is applied, there will be a Projection node, and duplicate projection
1699 // information included in the TableScan node.
1700 if !already_projected && let Some(project_vec) = &table_scan.projection {
1701 if project_vec.is_empty() {
1702 builder = builder.project(self.empty_projection_fallback())?;
1703 } else {
1704 let project_columns = project_vec
1705 .iter()
1706 .cloned()
1707 .map(|i| {
1708 let schema = table_scan.source.schema();
1709 let field = schema.field(i);
1710 if alias.is_some() {
1711 Column::new(alias.clone(), field.name().clone())
1712 } else {
1713 Column::new(
1714 Some(table_scan.table_name.clone()),
1715 field.name().clone(),
1716 )
1717 }
1718 })
1719 .collect::<Vec<_>>();
1720 builder = builder.project(project_columns)?;

Callers 1

Calls 15

newFunction · 0.85
is_noneMethod · 0.80
as_arrowMethod · 0.80
scanFunction · 0.50
schemaMethod · 0.45
mapMethod · 0.45
as_refMethod · 0.45
cloneMethod · 0.45
is_emptyMethod · 0.45
aliasMethod · 0.45
projectMethod · 0.45

Tested by

no test coverage detected