Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: use alias as table function's column name (#10311) #10405

Merged
merged 3 commits into from
Jun 20, 2023
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
16 changes: 16 additions & 0 deletions e2e_test/batch/basic/range.slt.part
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,19 @@ SELECT * FROM range(0.1::numeric, 2.1::numeric, 0.5::numeric)
0.6
1.1
1.6

# test table function with aliases
query I
SELECT alias from range(1,2) alias;
----
1

query I
SELECT alias.alias from range(1,2) alias;
----
1

query I
SELECT alias.col from range(1,2) alias(col);
----
1
20 changes: 19 additions & 1 deletion src/frontend/src/binder/relation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,10 +462,28 @@ impl Binder {
.into());
};
let columns = if let DataType::Struct(s) = tf.return_type() {
// If the table function returns a struct, it's fields can be accessed just
// like a table's columns.
let schema = Schema::from(&*s);
schema.fields.into_iter().map(|f| (false, f)).collect_vec()
} else {
vec![(false, Field::with_name(tf.return_type(), tf.name()))]
// If there is an table alias, we should use the alias as the table function's
// column name. If column aliases are also provided, they
// are handled in bind_table_to_context.
//
// Note: named return value should take precedence over table alias.
// But we don't support it yet.
// e.g.,
// ```
// > create function foo(ret out int) language sql as 'select 1';
// > select t.ret from foo() as t;
// ```
let col_name = if let Some(alias) = &alias {
alias.name.real_value()
} else {
tf.name().to_string()
};
vec![(false, Field::with_name(tf.return_type(), col_name))]
};

self.bind_table_to_context(columns, tf.name().to_string(), alias)?;
Expand Down