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
37 changes: 37 additions & 0 deletions datafusion/core/tests/sqllogictests/test_files/ddl.slt
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,43 @@ select * from "foo.bar.baz";
statement ok
drop view "foo.bar.baz"

##########
# Query views in other schemas.
##########

statement ok
CREATE SCHEMA foo_schema;

# Should be able to create view in "foo_schema".
statement ok
CREATE VIEW foo_schema.bar AS (SELECT 1 as a, 2 as b);

# And be able to query it.
query II
SELECT * FROM foo_schema.bar;
----
1 2

# Make sure we can query individual columns with various qualifications.

query I
SELECT a FROM foo_schema.bar;
----
1

query I
SELECT bar.a FROM foo_schema.bar;
----
1

query I
SELECT foo_schema.bar.a FROM foo_schema.bar;
----
1

# TODO: Drop schema for cleanup, see #6027
# statement ok
# DROP SCHEMA foo_schema;

##########
# Drop view error tests
Expand Down
4 changes: 2 additions & 2 deletions datafusion/expr/src/logical_plan/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ impl LogicalPlanBuilder {
}

/// Apply an alias
pub fn alias(self, alias: impl Into<String>) -> Result<Self> {
pub fn alias(self, alias: impl Into<OwnedTableReference>) -> Result<Self> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 this change makes a lot of sense to me and is consistent with creating names of other relations (like CreateExternalTable)

https://docs.rs/datafusion-expr/22.0.0/datafusion_expr/logical_plan/struct.CreateExternalTable.html

Ok(Self::from(subquery_alias(self.plan, alias)?))
}

Expand Down Expand Up @@ -1236,7 +1236,7 @@ pub fn project(
/// Create a SubqueryAlias to wrap a LogicalPlan.
pub fn subquery_alias(
plan: LogicalPlan,
alias: impl Into<String>,
alias: impl Into<OwnedTableReference>,
) -> Result<LogicalPlan> {
Ok(LogicalPlan::SubqueryAlias(SubqueryAlias::try_new(
plan, alias,
Expand Down
18 changes: 9 additions & 9 deletions datafusion/expr/src/logical_plan/plan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use datafusion_common::tree_node::{
};
use datafusion_common::{
plan_err, Column, DFSchema, DFSchemaRef, DataFusionError, OwnedTableReference,
Result, ScalarValue, TableReference,
Result, ScalarValue,
};
use std::collections::{HashMap, HashSet};
use std::fmt::{self, Debug, Display, Formatter};
Expand Down Expand Up @@ -1304,20 +1304,20 @@ pub struct SubqueryAlias {
/// The incoming logical plan
pub input: Arc<LogicalPlan>,
/// The alias for the input relation
pub alias: String,
pub alias: OwnedTableReference,
/// The schema with qualified field names
pub schema: DFSchemaRef,
}

impl SubqueryAlias {
pub fn try_new(plan: LogicalPlan, alias: impl Into<String>) -> Result<Self> {
pub fn try_new(
plan: LogicalPlan,
alias: impl Into<OwnedTableReference>,
) -> Result<Self> {
let alias = alias.into();
let table_ref = TableReference::bare(&alias);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

let schema: Schema = plan.schema().as_ref().clone().into();
let schema = DFSchemaRef::new(DFSchema::try_from_qualified_schema(
table_ref.to_owned_reference(),
&schema,
)?);
let schema =
DFSchemaRef::new(DFSchema::try_from_qualified_schema(&alias, &schema)?);
Ok(SubqueryAlias {
input: Arc::new(plan),
alias,
Expand Down Expand Up @@ -1913,7 +1913,7 @@ mod tests {
use crate::{col, exists, in_subquery, lit};
use arrow::datatypes::{DataType, Field, Schema};
use datafusion_common::tree_node::TreeNodeVisitor;
use datafusion_common::DFSchema;
use datafusion_common::{DFSchema, TableReference};
use std::collections::HashMap;

fn employee_schema() -> Schema {
Expand Down
14 changes: 4 additions & 10 deletions datafusion/optimizer/src/analyzer/inline_table_scan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,10 @@ fn analyze_internal(plan: LogicalPlan) -> Result<Transformed<LogicalPlan>> {
let projection_exprs = generate_projection_expr(&projection, sub_plan)?;
let plan = LogicalPlanBuilder::from(sub_plan.clone())
.project(projection_exprs)?
// Since this This is creating a subquery like:
//```sql
// ...
// FROM <view definition> as "table_name"
// ```
//
// it doesn't make sense to have a qualified
// reference (e.g. "foo"."bar") -- this convert to
// string
.alias(table_name.to_string())?
// Ensures that the reference to the inlined table remains the
// same, meaning we don't have to change any of the parent nodes
// that reference this table.
.alias(table_name)?
.build()?;
Transformed::Yes(plan)
}
Expand Down
2 changes: 1 addition & 1 deletion datafusion/optimizer/src/decorrelate_where_in.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ fn optimize_where_in(

let right = LogicalPlanBuilder::from(subquery_input)
.project(projection_exprs)?
.alias(&subquery_alias)?
.alias(subquery_alias.clone())?
.build()?;

// join our sub query into the main plan
Expand Down
2 changes: 1 addition & 1 deletion datafusion/optimizer/src/scalar_subquery_to_join.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ fn optimize_scalar(
let subqry_plan = subqry_plan
.aggregate(group_by, aggr.aggr_expr.clone())?
.project(proj)?
.alias(&subqry_alias)?
.alias(subqry_alias.clone())?
.build()?;

// qualify the join columns for outside the subquery
Expand Down
3 changes: 2 additions & 1 deletion datafusion/proto/proto/datafusion.proto
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,9 @@ message SelectionExecNode {
}

message SubqueryAliasNode {
reserved 2; // Was string alias
LogicalPlanNode input = 1;
string alias = 2;
OwnedTableReference alias = 3;
}

// logical expressions
Expand Down
10 changes: 5 additions & 5 deletions datafusion/proto/src/generated/pbjson.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions datafusion/proto/src/generated/prost.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 8 additions & 5 deletions datafusion/proto/src/logical_plan/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,8 @@ impl AsLogicalPlan for LogicalPlanNode {
Some(a) => match a {
protobuf::projection_node::OptionalAlias::Alias(alias) => {
Ok(LogicalPlan::SubqueryAlias(SubqueryAlias::try_new(
new_proj, alias,
new_proj,
alias.clone(),
)?))
}
},
Expand Down Expand Up @@ -593,9 +594,11 @@ impl AsLogicalPlan for LogicalPlanNode {
LogicalPlanType::SubqueryAlias(aliased_relation) => {
let input: LogicalPlan =
into_logical_plan!(aliased_relation.input, ctx, extension_codec)?;
LogicalPlanBuilder::from(input)
.alias(&aliased_relation.alias)?
.build()
let alias = from_owned_table_reference(
aliased_relation.alias.as_ref(),
"SubqueryAlias",
)?;
LogicalPlanBuilder::from(input).alias(alias)?.build()
}
LogicalPlanType::Limit(limit) => {
let input: LogicalPlan =
Expand Down Expand Up @@ -1069,7 +1072,7 @@ impl AsLogicalPlan for LogicalPlanNode {
logical_plan_type: Some(LogicalPlanType::SubqueryAlias(Box::new(
protobuf::SubqueryAliasNode {
input: Some(Box::new(input)),
alias: alias.clone(),
alias: Some(alias.to_owned_reference().into()),
},
))),
})
Expand Down