Skip to content

fix: ensure mutual compatibility of the two input schemas from recursive CTEs - #9795

Merged
alamb merged 2 commits into
apache:mainfrom
jonahgao:cte_schema
Mar 27, 2024
Merged

alamb merged 2 commits into
apache:mainfrom
jonahgao:cte_schema

Conversation

@jonahgao

Copy link
Copy Markdown
Member

Which issue does this PR close?

Closes #9794.

Rationale for this change

Make the schema of the recursive term compatible with the static term.

This differs from the handling of the ordinary union operator. We can't change the static term's schema, otherwise we would have to recreate the logic plan of the recursive term, as it depends on the static term through the work table.

That is to say, we use the schema of the static term as the final schema for CTE.
DuckDB also adopted a similar approach.

D WITH RECURSIVE my_cte AS(
        SELECT 1::int AS a
        UNION ALL
        SELECT a::bigint+2 FROM my_cte WHERE a<3
    ) SELECT a,typeof(a) FROM my_cte;
┌───────┬───────────┐
│   a   │ typeof(a) │
│ int32 │  varchar  │
├───────┼───────────┤
│     1 │ INTEGER   │
│     3 │ INTEGER   │
└───────┴───────────┘

The output type is INTEGER from the static term, not BIGINT.

What changes are included in this PR?

Check and coerce the schemas of recursive CTE's inputs.

Are these changes tested?

Yes

Are there any user-facing changes?

No

@github-actions github-actions Bot added logical-expr Logical plan and expressions sqllogictest SQL Logic Tests (.slt) labels Mar 25, 2024
static_fields_len, recurive_fields_len
);
}
// Ensure that the recursive term has the same field types as the static term

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Not sure if it's necessary to ensure that the field names are the same.I tested some queries, and none of them failed.

The union operator uses project_with_column_index only ensures the field names of projection plans are the same.

DataFusion CLI v36.0.0
❯ -- The field names of the two input are the same.
explain select 1 union all select 2;
+--------------+------------------------------------+
| plan_type    | plan                               |
+--------------+------------------------------------+
| logical_plan | Union                              |
|              |   Projection: Int64(1) AS Int64(1) |
|              |     EmptyRelation                  |
|              |   Projection: Int64(2) AS Int64(1) |
|              |     EmptyRelation                  |
+--------------+------------------------------------+

❯ -- The field names of the two input are different.
explain select 1 union all values(2);
+--------------+------------------------------------+
| plan_type    | plan                               |
+--------------+------------------------------------+
| logical_plan | Union                              |
|              |   Projection: Int64(1) AS Int64(1) |
|              |     EmptyRelation                  |
|              |   Values: (Int64(2))               |
+--------------+------------------------------------+

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Given the tests all pass this seems like a good plan to me.

@alamb alamb left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thank you @jonahgao

static_fields_len, recurive_fields_len
);
}
// Ensure that the recursive term has the same field types as the static term

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Given the tests all pass this seems like a good plan to me.

@alamb
alamb merged commit 75caa9c into apache:main Mar 27, 2024
@jonahgao
jonahgao deleted the cte_schema branch March 27, 2024 13:29
Lordworms pushed a commit to Lordworms/arrow-datafusion that referenced this pull request Apr 1, 2024
…ive CTEs (apache#9795)

* fix: Ensure mutual compatibility of the two input schemas from recursive CTEs

* fix typo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

logical-expr Logical plan and expressions sqllogictest SQL Logic Tests (.slt)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CTE: Non-recursive term and recursive term should have the same schema

2 participants