[
https://issues.apache.org/jira/browse/IMPALA-7741?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16667658#comment-16667658
]
Paul Rogers commented on IMPALA-7741:
-------------------------------------
We can solve the n^2 arguments problem by providing a custom function
description class. For example:
{code:java}
/**
* Special case for
* <code>nvl2(type1 expr, type2 ifNotNull, type2 ifNull)</code>.
* Type check on the second and third arguments, since that drives the
* return type. Accept any type for the first. This works because
* <code>nvl2()</code> is rewritten to use <code>CASE</code>.
*/
public static class Nvl2Function extends ScalarFunction {
public Nvl2Function(Type retType) {
super(new FunctionName(BuiltinsDb.NAME, "nvl2"),
Lists.newArrayList(Type.NULL, retType, retType), retType, true);
}
@Override
protected boolean isIndistinguishable(Function o) {
return
o.getArgs()[1].matchesType(this.getArgs()[1]) &&
o.getArgs()[2].matchesType(this.getArgs()[2]);
}
@Override
protected boolean isSuperTypeOf(Function other, boolean strict) {
return
Type.isImplicitlyCastable(
other.getArgs()[1], this.getArgs()[1], strict, strict) &&
Type.isImplicitlyCastable(
other.getArgs()[2], this.getArgs()[2], strict, strict);
}
}
{code}
Then, add custom code to register this function:
{code:java}
/**
* Create entries for the odd-duck NVL2 function:
* type1 nvl2(type2 expr, type1 ifNotNull, type1 ifNull).
* The types form an n^2 matrix that can't easily be represented.
* Instead, we define a special function that matches on the
* second and third arguments, since they determine the return
* type. We then ignore the first argument since we only care if
* it is null, and CASE will take care of the details.
*/
public static void initBuiltins(Db db) {
for (Type t: Type.getSupportedTypes()) {
if (t.isNull()) continue;
if (t.isScalarType(PrimitiveType.CHAR)) continue;
db.addBuiltin(new ScalarFunction.Nvl2Function(t));
}
}
{code}
With that, {{nvl2()}} acts like any other function and appears in the builtin
functions table. It no longer needs custom rewrite rules in the parser; it can
be rewritten in {{RewriteConditionalFnsRule()}} along with other functions.
That is, remove the following from {{FunctionCallExpr}}:
{code:java}
if (functionNameEqualsBuiltin(fnName, "nvl2")) {
List<Expr> plist = Lists.newArrayList(params.exprs());
if (!plist.isEmpty()) {
plist.set(0, new IsNullPredicate(plist.get(0), true));
}
return new FunctionCallExpr("if", plist);
}
{code}
> Functions nvl2(), decode(), nullif() not listed in _impala_builtins
> -------------------------------------------------------------------
>
> Key: IMPALA-7741
> URL: https://issues.apache.org/jira/browse/IMPALA-7741
> Project: IMPALA
> Issue Type: Improvement
> Affects Versions: Impala 3.0
> Reporter: Paul Rogers
> Priority: Major
>
> The
> [docs|https://impala.apache.org/docs/build3x/html/topics/impala_show.html]
> for {{SHOW FUNCTIONS}} says that we can use the following to list all
> built-in functions:
> {code:sql}
> show functions in _impala_builtins like '*week*';
> {code}
> However several Impala functions are removed early in the FE planning process
> and thus do not appear in the FE's function table in {{ScalarBuiltins}}:
> {{nvl2()}}, {{decode()}}, and {{nullif()}}. For example:
> {noformat}
> show functions in _impala_builtins like '*decode**'
> +-------------+------------------------------+-------------+---------------+
> | return type | signature | binary type | is persistent |
> +-------------+------------------------------+-------------+---------------+
> | STRING | base64decode(STRING) | BUILTIN | true |
> | STRING | madlib_decode_vector(STRING) | BUILTIN | true |
> +-------------+------------------------------+-------------+---------------+
> {noformat}
> However, since these three are perfectly valid functions, would have expected
> them to appear in the table. How they are processed internally is an
> implementation detail unimportant to the end user.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]