public class ScalarFunctionDescriptor extends Object
ScalarValuedFunction
, a function
can be defined using a ScalarFunctionDescriptor
.
A definition can be created by using one of the static factory methods
provided by this class.
A ScalarValuedFunction
abstractly consists of four pieces:
This class provides a number of static methods for defining functions by providing a description of the implementation. An evaluator class must be implemented. Any special logic is handled by providing additional classes, though default implementations covering a number of common cases are provided. Some basic type checking logic is provided as well, so that functions which only require simple assignability checks do not require any additional classes beyond the evaluator.
Typical practice is to wrap the definition of a function with a static method (or methods). The static method(s) can restrict arguments to appropriate types. While the method(s) do not need to validate subexpression arguments (as they lack sufficient context until bound to a record value), they should validate other arguments. When defining a function, simple type bounds checks can be declared on subexpressions. These will be automatically validated by the descriptor at appropriate times. Lists and arrays of subexpressions can only be used in the final argument position. These will be flattened into the argument list for purposes of validation and evaluator construction.
FunctionEvaluator
,
FunctionTyper
,
EvaluatorFactory
Modifier and Type | Class and Description |
---|---|
static class |
ScalarFunctionDescriptor.SubexpressionBound
Specifies a bound on subexpressions used as arguments to a function.
|
Modifier and Type | Method and Description |
---|---|
static ScalarFunctionDescriptor.SubexpressionBound |
arg(ScalarValuedFunction subexpr,
ScalarTokenType type)
Declares the given subexpression has the specified type bound.
|
static ScalarValuedFunction |
define(String name,
FunctionTyper typer,
Class<? extends FunctionEvaluator> evaluator,
Object... args)
Defines an instance of a function returning a result using an evaluator of the given class,
but with complex type restrictions and/or variable output type.
|
static ScalarValuedFunction |
define(String name,
FunctionTyper typer,
EvaluatorFactory factory,
Object... args)
Defines an instance of a function requiring complex logic for
determining result type and/or checking function arguments, as well as
needing to choose between possible evaluator implementations.
|
static ScalarValuedFunction |
define(String name,
ScalarTokenType resultType,
Class<? extends FunctionEvaluator> evaluator,
Object... args)
Defines an instance of a function returning a result of the specified type
and using an evaluator of the given class.
|
static ScalarValuedFunction |
define(String name,
ScalarTokenType resultType,
EvaluatorFactory factory,
Object... args)
Defines an instance of a function returning a result of the specified type
but needing to choose between possible evaluator implementations.
|
String |
getName()
Gets the label associated with the function.
|
static ScalarFunctionDescriptor.SubexpressionBound |
varargs(List<? extends ScalarValuedFunction> subexprs,
ScalarTokenType type)
Declares a variable number of arguments, all having the specified type bound.
|
public static ScalarValuedFunction define(String name, ScalarTokenType resultType, Class<? extends FunctionEvaluator> evaluator, Object... args)
Use this when a function always returns the same type, requires no argument checking beyond the bounds check, and uses the same evaluator regardless of arguments. This describes a large majority of functions; for example, string length always returns an integer, expects its argument is a string, and only needs a single implementation.
name
- an identifier to associate with the function. This will be
used in errors generated during validation of the function.resultType
- the output type of the function.evaluator
- the class of the function evaluator to use. This will
be invoked reflectively. Refer to ReflectiveFactory
for more
details on constructor requirements for using this.args
- the arguments to pass to the evaluator and other associated
classes. Subexpressions which have type bounds should be tagged using
a ScalarFunctionDescriptor.SubexpressionBound
.public static ScalarValuedFunction define(String name, FunctionTyper typer, Class<? extends FunctionEvaluator> evaluator, Object... args)
Use this when a function always uses the same evaluator, but has special logic for determining the output type or requires checks on subexpressions beyond a simple type bound. This describes the second largest group of functions; for example, value comparisons always return a boolean, but must check that the arguments are of comparable types (with no addition restriction), and can be implemented using a single class.
name
- an identifier to associate with the function. This will be
used in errors generated during validation of the function.typer
- the typer used to determine the output type of the function
based on the provided arguments.evaluator
- the class of the function evaluator to use. This will
be invoked reflectively. Refer to ReflectiveFactory
for more
details on constructor requirements for using this.args
- the arguments to pass to the evaluator and other associated
classes. Subexpressions which have type bounds should be tagged using
a ScalarFunctionDescriptor.SubexpressionBound
.public static ScalarValuedFunction define(String name, ScalarTokenType resultType, EvaluatorFactory factory, Object... args)
Use this when a function always returns the same type and requires no argument checking beyond the bounds check, but requires special logic for determining the evaluator to use.
name
- an identifier to associate with the function. This will be
used in errors generated during validation of the function.resultType
- the output type of the functionfactory
- the factory for constructing the evaluator to use for
a functionargs
- the arguments to pass to the evaluator and other associated
classes. Subexpressions which have type bounds should be tagged using
a ScalarFunctionDescriptor.SubexpressionBound
.public static ScalarValuedFunction define(String name, FunctionTyper typer, EvaluatorFactory factory, Object... args)
This provides the maximum flexibility, at the cost of requiring the implementation of two additional classes beyond the function evaluator. An example of such a case is polymorphic addition, which determines its value based on the argument types (automatically widening) and chooses an appropriate evaluator based on the result type.
name
- an identifier to associate with the function. This will be
used in errors generated during validation of the function.typer
- the typer used to determine the output type of the function
based on the provided arguments.factory
- the factory for constructing the evaluator to use for
a functionargs
- the arguments to pass to the evaluator and other associated
classes. Subexpressions which have type bounds should be tagged using
a ScalarFunctionDescriptor.SubexpressionBound
.public static ScalarFunctionDescriptor.SubexpressionBound arg(ScalarValuedFunction subexpr, ScalarTokenType type)
subexpr
- the subexpression being boundedtype
- the bound on the subexpression result typepublic static ScalarFunctionDescriptor.SubexpressionBound varargs(List<? extends ScalarValuedFunction> subexprs, ScalarTokenType type)
The list will be flattened into the argument array passed to the evaluator.
subexprs
- the subexpressions being boundedtype
- the bound on the subexpression result typepublic String getName()
define
function.Copyright © 2021 Actian Corporation. All rights reserved.