Skip to content

Commit

Permalink
add udtf fe
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangstar333 committed Apr 12, 2024
1 parent 62a5bc3 commit 62cae74
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 42 deletions.
92 changes: 52 additions & 40 deletions fe/fe-core/src/main/cup/sql_parser.cup
Original file line number Diff line number Diff line change
Expand Up @@ -927,8 +927,8 @@ nonterminal ParseNode load_property;
nonterminal List<ParseNode> opt_load_property_list;

// Boolean
nonterminal Boolean opt_negative, opt_is_allow_null, opt_is_key, opt_read_only, opt_aggregate, opt_local;
nonterminal String opt_from_rollup, opt_to_rollup;
nonterminal Boolean opt_negative, opt_is_allow_null, opt_is_key, opt_read_only, opt_local;
nonterminal String opt_from_rollup, function_type, opt_to_rollup;
nonterminal ColumnPosition opt_col_pos;

// Alter statement
Expand Down Expand Up @@ -964,7 +964,7 @@ nonterminal List<Map<String, String>> opt_with_analysis_properties;
nonterminal String opt_db, procedure_or_function, opt_comment, opt_comment_null, opt_engine;
nonterminal ColumnDef.DefaultValue opt_default_value;
nonterminal Boolean opt_if_exists, opt_if_not_exists;
nonterminal Boolean opt_external;
nonterminal Boolean externalable_table, externalable_resource;
nonterminal Boolean opt_force;
nonterminal Boolean opt_cached;
nonterminal IndexDef.IndexType opt_index_type;
Expand Down Expand Up @@ -1025,7 +1025,8 @@ precedence right KW_TEMPORARY;
precedence right LBRACKET;
precedence right LBRACE;
precedence left KW_ENGINE;

precedence left KW_FUNCTION;
precedence left KW_TABLE;
// unused
// nonterminal Expr where_clause_without_null, List<String> col_list, opt_charset_name;

Expand Down Expand Up @@ -1792,30 +1793,30 @@ create_stmt ::=
RESULT = new CreateCatalogStmt(ifNotExists, catalogName, resourceName, properties, comment);
:}
/* Function */
| KW_CREATE opt_var_type:type opt_aggregate:isAggregate KW_FUNCTION opt_if_not_exists:ifNotExists function_name:functionName LPAREN func_args_def:args RPAREN
| KW_CREATE opt_var_type:type function_type:functionType opt_if_not_exists:ifNotExists function_name:functionName LPAREN func_args_def:args RPAREN
KW_RETURNS type_def:returnType opt_intermediate_type:intermediateType opt_properties:properties
{:
RESULT = new CreateFunctionStmt(type, ifNotExists, isAggregate, functionName, args, returnType, intermediateType, properties);
RESULT = new CreateFunctionStmt(type, ifNotExists, functionType, functionName, args, returnType, intermediateType, properties);
:}
| KW_CREATE opt_var_type:type KW_ALIAS KW_FUNCTION opt_if_not_exists:ifNotExists function_name:functionName LPAREN func_args_def:args RPAREN
KW_WITH KW_PARAMETER LPAREN opt_ident_list:parameters RPAREN KW_AS expr:func
{:
RESULT = new CreateFunctionStmt(type, ifNotExists, functionName, args, parameters, func);
:}
/* Table */
| KW_CREATE opt_external:isExternal KW_TABLE opt_if_not_exists:ifNotExists table_name:name KW_LIKE table_name:existed_name KW_WITH KW_ROLLUP LPAREN ident_list:rollupNames RPAREN
| KW_CREATE externalable_table:isExternal opt_if_not_exists:ifNotExists table_name:name KW_LIKE table_name:existed_name KW_WITH KW_ROLLUP LPAREN ident_list:rollupNames RPAREN
{:
RESULT = new CreateTableLikeStmt(ifNotExists, name, existed_name, rollupNames, false);
:}
| KW_CREATE opt_external:isExternal KW_TABLE opt_if_not_exists:ifNotExists table_name:name KW_LIKE table_name:existed_name KW_WITH KW_ROLLUP
| KW_CREATE externalable_table:isExternal opt_if_not_exists:ifNotExists table_name:name KW_LIKE table_name:existed_name KW_WITH KW_ROLLUP
{:
RESULT = new CreateTableLikeStmt(ifNotExists, name, existed_name, null, true);
:}
| KW_CREATE opt_external:isExternal KW_TABLE opt_if_not_exists:ifNotExists table_name:name KW_LIKE table_name:existed_name
| KW_CREATE externalable_table:isExternal opt_if_not_exists:ifNotExists table_name:name KW_LIKE table_name:existed_name
{:
RESULT = new CreateTableLikeStmt(ifNotExists, name, existed_name, null, false);
:}
| KW_CREATE opt_external:isExternal KW_TABLE opt_if_not_exists:ifNotExists table_name:name
| KW_CREATE externalable_table:isExternal opt_if_not_exists:ifNotExists table_name:name
LPAREN column_definition_list:columns RPAREN opt_engine:engineName
opt_keys:keys
opt_comment:tableComment
Expand All @@ -1828,7 +1829,7 @@ create_stmt ::=
RESULT = new CreateTableStmt(ifNotExists, isExternal, name, columns, engineName, keys, partition,
distribution, tblProperties, extProperties, tableComment, index);
:}
| KW_CREATE opt_external:isExternal KW_TABLE opt_if_not_exists:ifNotExists table_name:name
| KW_CREATE externalable_table:isExternal opt_if_not_exists:ifNotExists table_name:name
LPAREN column_definition_list:columns COMMA RPAREN opt_engine:engineName
opt_keys:keys
opt_comment:tableComment
Expand All @@ -1841,7 +1842,7 @@ create_stmt ::=
RESULT = new CreateTableStmt(ifNotExists, isExternal, name, columns, null, engineName, keys, partition,
distribution, tblProperties, extProperties, tableComment, index);
:}
| KW_CREATE opt_external:isExternal KW_TABLE opt_if_not_exists:ifNotExists table_name:name
| KW_CREATE externalable_table:isExternal opt_if_not_exists:ifNotExists table_name:name
LPAREN column_definition_list:columns COMMA index_definition_list:indexes RPAREN opt_engine:engineName
opt_keys:keys
opt_comment:tableComment
Expand All @@ -1854,7 +1855,7 @@ create_stmt ::=
RESULT = new CreateTableStmt(ifNotExists, isExternal, name, columns, indexes, engineName, keys, partition,
distribution, tblProperties, extProperties, tableComment, index);
:}
| KW_CREATE opt_external:isExternal KW_TABLE opt_if_not_exists:ifNotExists table_name:name
| KW_CREATE externalable_table:isExternal opt_if_not_exists:ifNotExists table_name:name
LPAREN column_definition_list:columns COMMA index_definition_list:indexes COMMA RPAREN opt_engine:engineName
opt_keys:keys
opt_comment:tableComment
Expand All @@ -1867,7 +1868,7 @@ create_stmt ::=
RESULT = new CreateTableStmt(ifNotExists, isExternal, name, columns, indexes, engineName, keys, partition,
distribution, tblProperties, extProperties, tableComment, index);
:}
| KW_CREATE opt_external:isExternal KW_TABLE opt_if_not_exists:ifNotExists table_name:name
| KW_CREATE externalable_table:isExternal opt_if_not_exists:ifNotExists table_name:name
opt_col_list:columns
opt_engine:engineName
opt_keys:keys
Expand Down Expand Up @@ -1921,15 +1922,10 @@ create_stmt ::=
{:
RESULT = new AlterTableStmt(tableName, Lists.newArrayList(new CreateIndexClause(tableName, new IndexDef(indexName, ifNotExists, cols, indexType, properties, comment), false)));
:}
/* external resource */
| KW_CREATE KW_EXTERNAL KW_RESOURCE opt_if_not_exists:ifNotExists ident_or_text:resourceName opt_properties:properties
{:
RESULT = new CreateResourceStmt(true, ifNotExists, resourceName, properties);
:}
/* resource */
| KW_CREATE KW_RESOURCE opt_if_not_exists:ifNotExists ident_or_text:resourceName opt_properties:properties
/* resource or external resource */
| KW_CREATE externalable_resource:isExternal opt_if_not_exists:ifNotExists ident_or_text:resourceName opt_properties:properties
{:
RESULT = new CreateResourceStmt(false, ifNotExists, resourceName, properties);
RESULT = new CreateResourceStmt(isExternal, ifNotExists, resourceName, properties);
:}
/* storage vault */
| KW_CREATE KW_STORAGE KW_VAULT opt_if_not_exists:ifNotExists ident_or_text:storageVaultName opt_properties:properties
Expand Down Expand Up @@ -2041,14 +2037,19 @@ job_name ::=
:}
;

opt_aggregate ::=
{:
RESULT = false;
:}
| KW_AGGREGATE
{:
RESULT = true;
:}
function_type ::=
KW_FUNCTION
{:
RESULT = "scalar";
:}
| KW_TABLE:table KW_FUNCTION
{:
RESULT = "table";
:}
| KW_AGGREGATE:aggregate KW_FUNCTION
{:
RESULT = "aggregate";
:}
;

storage_backend ::=
Expand Down Expand Up @@ -3918,16 +3919,27 @@ opt_if_not_exists ::=
:}
;

opt_external ::=
/* empty */
{:
RESULT = false;
:}
| KW_EXTERNAL
{:
RESULT = true;
:}
;
externalable_table ::=
KW_TABLE
{:
RESULT = false;
:}
| KW_EXTERNAL KW_TABLE
{:
RESULT = true;
:}
;

externalable_resource ::=
KW_RESOURCE
{:
RESULT = false;
:}
| KW_EXTERNAL KW_RESOURCE
{:
RESULT = true;
:}
;

opt_cached ::=
/* empty */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ public class CreateFunctionStmt extends DdlStmt {
private final boolean ifNotExists;
private final FunctionName functionName;
private final boolean isAggregate;
private final boolean isTableFunction;
private final boolean isAlias;
private final FunctionArgsDef argsDef;
private final TypeDef returnType;
Expand All @@ -124,13 +125,14 @@ public class CreateFunctionStmt extends DdlStmt {
// timeout for both connection and read. 10 seconds is long enough.
private static final int HTTP_TIMEOUT_MS = 10000;

public CreateFunctionStmt(SetType type, boolean ifNotExists, boolean isAggregate, FunctionName functionName,
public CreateFunctionStmt(SetType type, boolean ifNotExists, String functionType, FunctionName functionName,
FunctionArgsDef argsDef,
TypeDef returnType, TypeDef intermediateType, Map<String, String> properties) {
this.type = type;
this.ifNotExists = ifNotExists;
this.functionName = functionName;
this.isAggregate = isAggregate;
this.isAggregate = functionType.equalsIgnoreCase("AGGREGATE");
this.isTableFunction = functionType.equalsIgnoreCase("TABLE");
this.argsDef = argsDef;
this.returnType = returnType;
this.intermediateType = intermediateType;
Expand Down Expand Up @@ -158,6 +160,7 @@ public CreateFunctionStmt(SetType type, boolean ifNotExists, FunctionName functi
}
this.originFunction = originFunction;
this.isAggregate = false;
this.isTableFunction = false;
this.returnType = new TypeDef(Type.VARCHAR);
this.properties = ImmutableSortedMap.of();
}
Expand Down Expand Up @@ -208,6 +211,8 @@ public void analyze(Analyzer analyzer) throws UserException {
analyzeUda();
} else if (isAlias) {
analyzeAliasFunction();
} else if (isTableFunction) {
analyzeTableFunction();
} else {
analyzeUdf();
}
Expand Down Expand Up @@ -301,6 +306,14 @@ private void computeObjectChecksum() throws IOException, NoSuchAlgorithmExceptio
}
}

private void analyzeTableFunction() throws AnalysisException {
String symbol = properties.get(SYMBOL_KEY);
if (Strings.isNullOrEmpty(symbol)) {
throw new AnalysisException("No 'symbol' in properties");
}
analyzeJavaUdf(symbol);
}

private void analyzeUda() throws AnalysisException {
AggregateFunction.AggregateFunctionBuilder builder
= AggregateFunction.AggregateFunctionBuilder.createUdfBuilder();
Expand Down

0 comments on commit 62cae74

Please sign in to comment.