risingwave_frontend/binder/relation/
table_function.rs1use std::str::FromStr;
16
17use itertools::Itertools;
18use risingwave_common::bail_not_implemented;
19use risingwave_common::catalog::{Field, RW_INTERNAL_TABLE_FUNCTION_NAME, Schema};
20use risingwave_common::types::DataType;
21use risingwave_sqlparser::ast::{Function, FunctionArg, FunctionArgList, ObjectName, TableAlias};
22
23use super::watermark::is_watermark_func;
24use super::{Binder, Relation, Result, WindowTableFunctionKind};
25use crate::binder::bind_context::Clause;
26use crate::error::ErrorCode;
27use crate::expr::{Expr, ExprImpl};
28
29impl Binder {
30 pub(super) fn bind_table_function(
37 &mut self,
38 name: &ObjectName,
39 alias: Option<&TableAlias>,
40 args: &[FunctionArg],
41 with_ordinality: bool,
42 ) -> Result<Relation> {
43 let func_name = &name.0[0].real_value();
44 {
46 if func_name.eq_ignore_ascii_case(RW_INTERNAL_TABLE_FUNCTION_NAME) {
47 if with_ordinality {
48 bail_not_implemented!(
49 "WITH ORDINALITY for internal/system table function {}",
50 func_name
51 );
52 }
53 return self.bind_internal_table(args, alias);
54 }
55 }
56 if let Ok(kind) = WindowTableFunctionKind::from_str(func_name) {
58 if with_ordinality {
59 return Err(ErrorCode::InvalidInputSyntax(format!(
60 "WITH ORDINALITY for window table function {}",
61 func_name
62 ))
63 .into());
64 }
65 return Ok(Relation::WindowTableFunction(Box::new(
66 self.bind_window_table_function(alias, kind, args)?,
67 )));
68 }
69 if func_name.eq_ignore_ascii_case("gap_fill") {
71 if with_ordinality {
72 return Err(ErrorCode::InvalidInputSyntax(
73 "WITH ORDINALITY for gap_fill".to_owned(),
74 )
75 .into());
76 }
77 return Ok(Relation::GapFill(Box::new(
78 self.bind_gap_fill(alias, args)?,
79 )));
80 }
81 if is_watermark_func(func_name) {
83 if with_ordinality {
84 return Err(ErrorCode::InvalidInputSyntax(
85 "WITH ORDINALITY for watermark".to_owned(),
86 )
87 .into());
88 }
89 return Ok(Relation::Watermark(Box::new(
90 self.bind_watermark(alias, args)?,
91 )));
92 };
93
94 self.push_context();
95 let mut clause = Some(Clause::From);
96 std::mem::swap(&mut self.context.clause, &mut clause);
97 let func = self.bind_function(&Function {
98 scalar_as_agg: false,
99 name: name.clone(),
100 arg_list: FunctionArgList::args_only(args.to_vec()),
101 over: None,
102 filter: None,
103 within_group: None,
104 });
105 self.context.clause = clause;
106 self.pop_context()?;
107 let func = func?;
108
109 if let ExprImpl::TableFunction(func) = &func
110 && func.args.iter().any(|arg| arg.has_subquery())
111 {
112 return Err(ErrorCode::InvalidInputSyntax(
114 format!("Only table-in-out functions can have subquery parameters. The table function has subquery parameters is {}", func.name()),
115 )
116 .into());
117 }
118
119 let mut columns = if let DataType::Struct(s) = func.return_type() {
121 let schema = Schema::from(&s);
123 schema.fields.into_iter().map(|f| (false, f)).collect_vec()
124 } else {
125 let col_name = if let Some(alias) = &alias {
138 alias.name.real_value()
139 } else {
140 func_name.clone()
141 };
142 vec![(false, Field::with_name(func.return_type(), col_name))]
143 };
144 if with_ordinality {
145 columns.push((false, Field::with_name(DataType::Int64, "ordinality")));
146 }
147
148 self.bind_table_to_context(columns, func_name.clone(), alias)?;
149
150 Ok(Relation::TableFunction {
151 expr: func,
152 with_ordinality,
153 })
154 }
155}