Skip to content

Invalid schema for unions in ViewTable #15134

Closed
@Friede80

Description

@Friede80

Describe the bug

When a ViewTable is created, the plan is run through the Analyzer with the ExpandWildcardRule and TypeCoercion rules. When this ViewTable is later inlined, it is run though the Analyzer again, but this second pass of TypeCoercion can drop the qualifier information in the DFSchema for fields of a union if a field had previously been cast.

To Reproduce

Below is a test case that demonstrates the error

    #[test]
    fn test_coerce_union() -> Result<()> {
        let left_plan = Arc::new(LogicalPlan::EmptyRelation(EmptyRelation {
            produce_one_row: false,
            schema: Arc::new(
                DFSchema::try_from_qualified_schema(
                    TableReference::full("datafusion", "test", "foo"),
                    &Schema::new(vec![Field::new("a", DataType::Int32, false)]),
                )
                .unwrap(),
            ),
        }));
        let right_plan = Arc::new(LogicalPlan::EmptyRelation(EmptyRelation {
            produce_one_row: false,
            schema: Arc::new(
                DFSchema::try_from_qualified_schema(
                    TableReference::full("datafusion", "test", "foo"),
                    &Schema::new(vec![Field::new("a", DataType::Int64, false)]),
                )
                .unwrap(),
            ),
        }));
        let union = LogicalPlan::Union(Union::try_new_with_loose_types(vec![
            left_plan, right_plan,
        ])?);
        let analyzed_union = Analyzer::with_rules(vec![Arc::new(TypeCoercion::new())])
            .execute_and_check(union, &ConfigOptions::default(), |_, _| {})?;
        let top_level_plan = LogicalPlan::Projection(Projection::try_new(
            vec![wildcard()],
            Arc::new(analyzed_union),
        )?);
        let expanded_plan =
            Analyzer::with_rules(vec![Arc::new(ExpandWildcardRule::new())])
                .execute_and_check(
                    top_level_plan,
                    &ConfigOptions::default(),
                    |_, _| {},
                )?;

        let expected = "Projection: datafusion.test.foo.a\n  Union\n    Projection: CAST(datafusion.test.foo.a AS Int64) AS a\n      EmptyRelation\n    EmptyRelation";
        assert_analyzed_plan_eq(Arc::new(TypeCoercion::new()), expanded_plan, expected)
    }

This will fail with:

Error: Context("type_coercion", SchemaError(FieldNotFound { field: Column { relation: Some(Full { catalog: "datafusion", schema: "test", table: "foo" }), name: "a" }, valid_fields: [Column { relation: None, name: "a" }] }, Some("")))

Expected behavior

The above test should succeed.

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions