1818package org .apache .doris .nereids .trees .plans .commands ;
1919
2020import org .apache .doris .analysis .SetType ;
21+ import org .apache .doris .catalog .AggregateFunction ;
22+ import org .apache .doris .catalog .AliasFunction ;
2123import org .apache .doris .catalog .Column ;
2224import org .apache .doris .catalog .Database ;
2325import org .apache .doris .catalog .DatabaseIf ;
2426import org .apache .doris .catalog .Env ;
25- import org .apache .doris .catalog .FunctionRegistry ;
27+ import org .apache .doris .catalog .Function ;
2628import org .apache .doris .catalog .FunctionUtil ;
29+ import org .apache .doris .catalog .ScalarFunction ;
2730import org .apache .doris .catalog .ScalarType ;
2831import org .apache .doris .common .AnalysisException ;
2932import org .apache .doris .common .ErrorCode ;
3336import org .apache .doris .common .util .Util ;
3437import org .apache .doris .datasource .InternalCatalog ;
3538import org .apache .doris .mysql .privilege .PrivPredicate ;
36- import org .apache .doris .nereids .trees .expressions .functions .FunctionBuilder ;
3739import org .apache .doris .nereids .trees .plans .PlanType ;
3840import org .apache .doris .nereids .trees .plans .visitor .PlanVisitor ;
3941import org .apache .doris .qe .ConnectContext ;
4547import com .google .common .base .Strings ;
4648import com .google .common .collect .Lists ;
4749
48- import java .util .ArrayList ;
4950import java .util .Collections ;
50- import java .util .HashMap ;
5151import java .util .HashSet ;
52+ import java .util .LinkedHashMap ;
5253import java .util .List ;
5354import java .util .Map ;
5455import java .util .Set ;
56+ import java .util .stream .Collectors ;
5557
5658/**
5759 * show functions command
@@ -97,21 +99,21 @@ public ShowFunctionsCommand(boolean isVerbose, String likeCondition, boolean isG
9799 * get Info by nereids.
98100 * To make the code in nereids more concise, all irrelevant information here will use an empty string.
99101 */
100- private List <Comparable > getInfo (boolean isVerbose , String funcName ) {
102+ private List <Comparable > getInfo (boolean isVerbose , Function function ) {
101103 List <Comparable > row = Lists .newArrayList ();
102104 if (isVerbose ) {
103105 // signature
104- row .add (funcName );
106+ row .add (function . signatureString () );
105107 // return type
106- row .add ("" );
108+ row .add (function . getReturnType (). toString () );
107109 // function type
108110 // intermediate type
109- row .add ("" );
110- row .add ("" );
111+ row .add (buildFunctionType ( function ) );
112+ row .add (buildIntermediateType ( function ) );
111113 // property
112- row .add ("" );
114+ row .add (buildProperties ( function ) );
113115 } else {
114- row .add (funcName );
116+ row .add (function . functionName () );
115117 }
116118 return row ;
117119 }
@@ -126,13 +128,13 @@ protected boolean like(String funcName, String likeCondition) {
126128 * get resultRowSet
127129 */
128130 @ VisibleForTesting
129- protected List <List <String >> getResultRowSetByFunctions (List <String > functions ) {
131+ protected List <List <String >> getResultRowSetByFunctions (List <Function > functions ) {
130132 List <List <String >> resultRowSet = Lists .newArrayList ();
131133 List <List <Comparable >> rowSet = Lists .newArrayList ();
132- for (String function : functions ) {
134+ for (Function function : functions ) {
133135 List <Comparable > row = getInfo (isVerbose , function );
134136 // like predicate
135- if (likeCondition == null || like (function , likeCondition )) {
137+ if (likeCondition == null || like (function . functionName () , likeCondition )) {
136138 rowSet .add (row );
137139 }
138140 }
@@ -163,7 +165,7 @@ protected List<List<String>> getResultRowSetByFunctions(List<String> functions)
163165 * get resultRowSet
164166 */
165167 private List <List <String >> getResultRowSet (ConnectContext ctx ) throws AnalysisException {
166- List <String > functions = getFunctions (ctx );
168+ List <Function > functions = getFunctions (ctx );
167169 return getResultRowSetByFunctions (functions );
168170 }
169171
@@ -172,23 +174,23 @@ private List<List<String>> getResultRowSet(ConnectContext ctx) throws AnalysisEx
172174 * All functions including builtin and udf are registered in FunctionRegistry
173175 */
174176 @ VisibleForTesting
175- protected List <String > getFunctions (ConnectContext ctx ) throws AnalysisException {
176- List <String > functions = Lists .newArrayList ();
177+ protected List <Function > getFunctions (ConnectContext ctx ) throws AnalysisException {
178+ List <Function > functions = Lists .newArrayList ();
177179 if (ctx == null || ctx .getEnv () == null || ctx .getEnv ().getFunctionRegistry () == null ) {
178180 return functions ;
179181 }
180182
181- FunctionRegistry functionRegistry = ctx .getEnv ().getFunctionRegistry ();
182- Map <String , Map <String , List <FunctionBuilder >>> udfFunctions = functionRegistry .getName2UdfBuilders ();
183+ if (!FunctionUtil .isGlobalFunction (type )) {
184+ dbName = reAcquireDbName (ctx , dbName );
185+ }
186+
183187 if (FunctionUtil .isGlobalFunction (type )) {
184- // handle show global functions
185- functions = new ArrayList <>(udfFunctions
186- .getOrDefault (functionRegistry .getGlobalFunctionDbName (), new HashMap <>()).keySet ());
188+ functions = Env .getCurrentEnv ().getGlobalFunctionMgr ().getFunctions ();
187189 } else {
188190 Util .prohibitExternalCatalog (ctx .getDefaultCatalog (), this .getClass ().getSimpleName ());
189191 DatabaseIf db = ctx .getCurrentCatalog ().getDbOrAnalysisException (dbName );
190192 if (db instanceof Database ) {
191- functions = new ArrayList <>( udfFunctions . getOrDefault ( dbName , new HashMap <>()). keySet () );
193+ functions = (( Database ) db ). getFunctions ( );
192194 }
193195 }
194196 return functions ;
@@ -244,4 +246,102 @@ public <R, C> R accept(PlanVisitor<R, C> visitor, C context) {
244246 return visitor .visitShowFunctionsCommand (this , context );
245247 }
246248
249+ private String buildFunctionType (Function function ) {
250+ if (function instanceof AggregateFunction ) {
251+ return "AGGREGATE/" + function .getBinaryType ();
252+ }
253+ if (function .isUDTFunction ()) {
254+ return "UDTF/" + function .getBinaryType ();
255+ }
256+ if (function instanceof AliasFunction ) {
257+ return "ALIAS/" + function .getBinaryType ();
258+ }
259+ return "SCALAR/" + function .getBinaryType ();
260+ }
261+
262+ private String buildIntermediateType (Function function ) {
263+ if (function instanceof AggregateFunction ) {
264+ AggregateFunction aggregateFunction = (AggregateFunction ) function ;
265+ return aggregateFunction .getIntermediateType () == null
266+ ? ""
267+ : aggregateFunction .getIntermediateType ().toString ();
268+ }
269+ return "" ;
270+ }
271+
272+ private String buildProperties (Function function ) {
273+ Map <String , String > properties = new LinkedHashMap <>();
274+ if (function .getId () > 0 ) {
275+ properties .put ("ID" , String .valueOf (function .getId ()));
276+ }
277+ if (!Strings .isNullOrEmpty (function .getChecksum ())) {
278+ properties .put ("CHECKSUM" , function .getChecksum ());
279+ }
280+ if (function .getLocation () != null ) {
281+ String locationKey = function .getBinaryType () == null
282+ || function .getBinaryType ().name ().startsWith ("JAVA" )
283+ ? "FILE"
284+ : "OBJECT_FILE" ;
285+ properties .put (locationKey , function .getLocation ().toString ());
286+ }
287+ properties .put ("NULLABLE_MODE" , function .getNullableMode ().name ());
288+ if (function .isStaticLoad ()) {
289+ properties .put ("STATIC_LOAD" , String .valueOf (function .isStaticLoad ()));
290+ }
291+ if (!Strings .isNullOrEmpty (function .getRuntimeVersion ())) {
292+ properties .put ("RUNTIME_VERSION" , function .getRuntimeVersion ());
293+ }
294+
295+ if (function instanceof ScalarFunction ) {
296+ ScalarFunction scalarFunction = (ScalarFunction ) function ;
297+ properties .put ("SYMBOL" , Strings .nullToEmpty (scalarFunction .getSymbolName ()));
298+ if (scalarFunction .getPrepareFnSymbol () != null ) {
299+ properties .put ("PREPARE_FN" , scalarFunction .getPrepareFnSymbol ());
300+ }
301+ if (scalarFunction .getCloseFnSymbol () != null ) {
302+ properties .put ("CLOSE_FN" , scalarFunction .getCloseFnSymbol ());
303+ }
304+ }
305+
306+ if (function instanceof AggregateFunction ) {
307+ AggregateFunction aggregateFunction = (AggregateFunction ) function ;
308+ properties .put ("INIT_FN" , Strings .nullToEmpty (aggregateFunction .getInitFnSymbol ()));
309+ properties .put ("UPDATE_FN" , Strings .nullToEmpty (aggregateFunction .getUpdateFnSymbol ()));
310+ properties .put ("MERGE_FN" , Strings .nullToEmpty (aggregateFunction .getMergeFnSymbol ()));
311+ if (aggregateFunction .getSerializeFnSymbol () != null ) {
312+ properties .put ("SERIALIZE_FN" , aggregateFunction .getSerializeFnSymbol ());
313+ }
314+ if (aggregateFunction .getFinalizeFnSymbol () != null ) {
315+ properties .put ("FINALIZE_FN" , aggregateFunction .getFinalizeFnSymbol ());
316+ }
317+ if (aggregateFunction .getGetValueFnSymbol () != null ) {
318+ properties .put ("GET_VALUE_FN" , aggregateFunction .getGetValueFnSymbol ());
319+ }
320+ if (aggregateFunction .getRemoveFnSymbol () != null ) {
321+ properties .put ("REMOVE_FN" , aggregateFunction .getRemoveFnSymbol ());
322+ }
323+ if (aggregateFunction .getSymbolName () != null ) {
324+ properties .put ("SYMBOL" , aggregateFunction .getSymbolName ());
325+ }
326+ }
327+
328+ if (function instanceof AliasFunction ) {
329+ AliasFunction aliasFunction = (AliasFunction ) function ;
330+ properties .put ("ALIAS_OF" , aliasFunction .getOriginFunction ().toSqlWithoutTbl ());
331+ if (aliasFunction .getParameters () != null && !aliasFunction .getParameters ().isEmpty ()) {
332+ properties .put ("PARAMETERS" , String .join ("," , aliasFunction .getParameters ()));
333+ }
334+ }
335+
336+ // inline python UDF/UDTF/UDAF code
337+ if (function .getBinaryType () != null && function .getBinaryType ().name ().contains ("PYTHON" )
338+ && !Strings .isNullOrEmpty (function .getFunctionCode ())) {
339+ properties .put ("INLINE_CODE" , function .getFunctionCode ());
340+ }
341+
342+ return properties .entrySet ().stream ()
343+ .map (entry -> entry .getKey () + "=" + entry .getValue ())
344+ .collect (Collectors .joining (", " ));
345+ }
346+
247347}
0 commit comments