presto-main/src/main/java/io/prestosql/sql/rewrite/ShowQueriesRewrite.java/ShowQueriesRewrite/visitShowFunctions
class ShowQueriesRewrite:        @Override
        protected Node visitShowFunctions(ShowFunctions node, Void context)
        {
            List<Expression> rows = metadata.listFunctions().stream()
                    .filter(function -> !function.isHidden())
                    .map(function -> row(
                            new StringLiteral(function.getSignature().getName()),
                            new StringLiteral(function.getSignature().getReturnType().toString()),
                            new StringLiteral(Joiner.on(", ").join(function.getSignature().getArgumentTypes())),
                            new StringLiteral(getFunctionType(function)),
                            function.isDeterministic() ? TRUE_LITERAL : FALSE_LITERAL,
                            new StringLiteral(nullToEmpty(function.getDescription()))))
                    .collect(toImmutableList());

            Map<String, String> columns = ImmutableMap.<String, String>builder()
                    .put("function_name", "Function")
                    .put("return_type", "Return Type")
                    .put("argument_types", "Argument Types")
                    .put("function_type", "Function Type")
                    .put("deterministic", "Deterministic")
                    .put("description", "Description")
                    .build();

            return simpleQuery(
                    selectAll(columns.entrySet().stream()
                            .map(entry -> aliasedName(entry.getKey(), entry.getValue()))
                            .collect(toImmutableList())),
                    aliased(new Values(rows), "functions", ImmutableList.copyOf(columns.keySet())),
                    node.getLikePattern().map(like ->
                            new LikePredicate(
                                    identifier("function_name"),
                                    new StringLiteral(like),
                                    node.getEscape().map(StringLiteral::new)))
                            .map(Expression.class::cast)
                            .orElse(TRUE_LITERAL),
                    ordering(
                            new SortItem(
                                    functionCall("lower", identifier("function_name")),
                                    SortItem.Ordering.ASCENDING,
                                    SortItem.NullOrdering.UNDEFINED),
                            ascending("return_type"),
                            ascending("argument_types"),
                            ascending("function_type")));
        }