Class UserDefinedFunction

java.lang.Object
adql.query.operand.function.ADQLFunction
adql.query.operand.function.UserDefinedFunction
All Implemented Interfaces:
ADQLObject, ADQLOperand, UnknownType
Direct Known Subclasses:
DefaultUDF

public class UserDefinedFunction extends ADQLFunction implements UnknownType
Custom function defined by an ADQL service provider.

Abstract to concrete class

Since ADQL-Lib v2.0, this class is no longer abstract. DefaultUDF has been merged into UserDefinedFunction which then became a concrete class. Most of the 'final' functions in DefaultUDF are no longer 'final' in UserDefinedFunction.

Warning: DefaultUDF is now deprecated and should not be used any more.

Language feature

As any optional feature of ADQL (since ADQL-2.1), an explicit ID and description have to be provided in the capabilities of an ADQL service (like TAP). This is represented here by a LanguageFeature. In UserDefinedFunction it is automatically generated by generateLanguageFeature() at creation (by UserDefinedFunction(String, ADQLOperand[])) or when NO definition is explicitly set (by setDefinition(FunctionDef)). Otherwise, when setting a non NULL definition, a Language Feature is created using this definition (with LanguageFeature(FunctionDef)).

Function definition

ADQL allows the usage of User Defined Function (UDF), but as such there is no definition (mainly a name and signature) available. However, TAPRegExt lets return a definition and human description of UDFs. In the ADQL tree, a such definition is represented by a FunctionDef. It is not mandatory to set one, but recommended anyway. To do so, call setDefinition(FunctionDef).

Custom extension

It is expected that this class may be extended in order to cover special custom User Defined Function. That's why most of the defined function are not 'final', as attributes are not too.

Recommendation: It is recommended, when possible, to update the protected attributes directly instead of their corresponding getter function.

The empty constructor is protected only for extension purpose. That way, it is up to the developer to decide whether he/she wants to call the super class's empty constructor or the default one (UserDefinedFunction(String, ADQLOperand[])). However, the extension class SHOULD have at least one constructor with 2 arguments: String for the UDF name, ADQLOperand[] for its parameters.

Warning: If this constructor does not exist or is not desired, ADQLQueryFactory.createUserDefinedFunction(String, ADQLOperand[]) will have to be overwritten. Also be careful that the definition set to this extension class has no custom UDF class, otherwise, there will be an attempt to replace it by an instance of this UDF class ; and this will probably end with an error because of the missing constructor.

  • Field Details

    • languageFeature

      protected LanguageFeature languageFeature
      Description of this ADQL Feature.
      Since:
      2.0
    • definition

      protected FunctionDef definition
      Define/Describe this user defined function. This object gives the return type and the number and type of all parameters.

      Note: NULL if the function name is invalid. See FunctionDef.FunctionDef(..., ADQLVersion) for more details.

      Since:
      2.0
    • parameters

      protected ADQLList<ADQLOperand> parameters
      Its parsed parameters.
      Since:
      2.0
    • functionName

      protected String functionName
      Parsed name of this UDF.

      Important: This attribute should never be NULL.

      Since:
      2.0
  • Constructor Details

    • UserDefinedFunction

      protected UserDefinedFunction()
      Creates a UDF with no name and no parameter.

      Implementation note 1: By default functionName is not set to NULL, but to "<unnamed>" in order to avoid NullPointerException (especially when generating a LanguageFeature).

      Implementation note 2: The purpose of this constructor is just allow more flexibility when extending this class. However, it is highly recommended to set at least a non-null function name. This can be done in at least 3 ways:

      1. calling the super constructor: UserDefinedFunction(String, ADQLOperand[])
      2. setting the protected attribute functionName
      3. overwriting the function getName()
    • UserDefinedFunction

      public UserDefinedFunction(String name, ADQLOperand[] params) throws NullPointerException
      Creates a user function.
      Parameters:
      params - Parameters of the function.
      Throws:
      NullPointerException
      Since:
      2.0
    • UserDefinedFunction

      public UserDefinedFunction(UserDefinedFunction toCopy) throws Exception
      Builds a UserFunction by copying the given one.
      Parameters:
      toCopy - The UserFunction to copy.
      Throws:
      Exception - If there is an error during the copy.
      Since:
      2.0
  • Method Details

    • getExpectedType

      public final char getExpectedType()
      Description copied from interface: UnknownType
      Get the type expected by the syntactic parser according to the context.
      Specified by:
      getExpectedType in interface UnknownType
      Returns:
      Expected type: 'n' or 'N' for numeric, 's' or 'S' for string, 'g' or 'G' for geometry.
    • setExpectedType

      public final void setExpectedType(char c)
      Description copied from interface: UnknownType
      Set the type expected for this operand.
      Specified by:
      setExpectedType in interface UnknownType
      Parameters:
      c - Expected type: 'n' or 'N' for numeric, 's' or 'S' for string, 'g' or 'G' for geometry.
    • getFeatureDescription

      public final LanguageFeature getFeatureDescription()
      Description copied from interface: ADQLObject
      Get the description of this ADQL's Language Feature.

      Note: Getting this description is generally only useful when discovery optional features so that determining if they are allowed to be used in ADQL queries.

      Specified by:
      getFeatureDescription in interface ADQLObject
      Returns:
      Description of this ADQL object as an ADQL's feature.
    • getDefinition

      public final FunctionDef getDefinition()
      Get the signature/definition/description of this user defined function. The returned object provides information on the return type and the number and type of parameters.
      Returns:
      Definition of this function. (MAY be NULL)
      Since:
      2.0
    • setDefinition

      public void setDefinition(FunctionDef def) throws IllegalArgumentException
      Let set the signature/definition/description of this user defined function.

      IMPORTANT: No particular checks are done here except on the function name which MUST be the same (case insensitive) as the name of the given definition. Advanced checks must have been done before calling this setter.

      Parameters:
      def - The definition applying to this parsed UDF, or NULL if none has been found.
      Throws:
      IllegalArgumentException - If the name in the given definition does not match the name of this parsed function.
      Since:
      2.0
    • generateLanguageFeature

      protected void generateLanguageFeature()
      Generate and set a default LanguageFeature for this ADQL function.

      Note: Knowing neither the parameters name nor their type, the generated LanguageFeature will just set an unknown type and set a default parameter name (index prefixed with `$`).

      Since:
      2.0
    • isNumeric

      public boolean isNumeric()
      Description copied from interface: ADQLOperand
      Tell whether this operand is numeric or not.
      Specified by:
      isNumeric in interface ADQLOperand
      Returns:
      true if this operand is numeric, false otherwise.
    • isString

      public boolean isString()
      Description copied from interface: ADQLOperand
      Tell whether this operand is a string or not.
      Specified by:
      isString in interface ADQLOperand
      Returns:
      true if this operand is a string, false otherwise.
    • isGeometry

      public boolean isGeometry()
      Description copied from interface: ADQLOperand
      Tell whether this operand is a geometrical region or not.
      Specified by:
      isGeometry in interface ADQLOperand
      Returns:
      true if this operand is a geometry, false otherwise.
    • getCopy

      public ADQLObject getCopy() throws Exception
      Description copied from interface: ADQLObject
      Gets a (deep) copy of this ADQL object.
      Specified by:
      getCopy in interface ADQLObject
      Returns:
      The copy of this ADQL object.
      Throws:
      Exception - If there is any error during the copy.
    • getName

      public String getName()
      Description copied from interface: ADQLObject
      Gets the name of this object in ADQL.
      Specified by:
      getName in interface ADQLObject
      Returns:
      The name of this ADQL object.
    • getParameters

      public ADQLOperand[] getParameters()
      Description copied from class: ADQLFunction
      Gets the list of all parameters of this function.
      Specified by:
      getParameters in class ADQLFunction
      Returns:
      Its parameters list.
    • getNbParameters

      public int getNbParameters()
      Description copied from class: ADQLFunction
      Gets the number of parameters this function has.
      Specified by:
      getNbParameters in class ADQLFunction
      Returns:
      Number of parameters.
    • getParameter

      public ADQLOperand getParameter(int index) throws ArrayIndexOutOfBoundsException
      Description copied from class: ADQLFunction
      Gets the index-th parameter.
      Specified by:
      getParameter in class ADQLFunction
      Parameters:
      index - Parameter number.
      Returns:
      The corresponding parameter.
      Throws:
      ArrayIndexOutOfBoundsException - If the index is incorrect (index < 0 || index >= getNbParameters()).
    • setParameter

      public ADQLOperand setParameter(int index, ADQLOperand replacer) throws ArrayIndexOutOfBoundsException, NullPointerException, Exception
      Function to override if you want to check the parameters of this user defined function.
      Specified by:
      setParameter in class ADQLFunction
      Parameters:
      index - Index of the parameter to replace.
      replacer - The replacer.
      Returns:
      The replaced parameter.
      Throws:
      ArrayIndexOutOfBoundsException - If the index is incorrect (index < 0 || index >= getNbParameters()).
      NullPointerException - If a required parameter must be replaced by a NULL object.
      Exception - If another error occurs.
      Since:
      2.0
      See Also:
    • translate

      public String translate(ADQLTranslator caller) throws TranslationException
      Translate this User Defined Function into the language supported by the given translator.

      VERY IMPORTANT: This function MUST NOT use ADQLTranslator.translate(UserDefinedFunction) to translate itself. The given ADQLTranslator must be used ONLY to translate UDF's operands.

      Implementation example:

       public String translate(final ADQLTranslator caller) throws TranslationException{
              StringBuilder sql = new StringBuilder(functionName);
              sql.append('(');
              for(int i = 0; i < parameters.size(); i++){
                      if (i > 0)
                              sql.append(',').append(' ');
                      sql.append(caller.translate(parameters.get(i)));
              }
              sql.append(')');
              return sql.toString();
       }
       
      Parameters:
      caller - Translator to use in order to translate ONLY function parameters.
      Returns:
      The translation of this UDF into the language supported by the given translator, or NULL to let the calling translator apply a default translation.
      Throws:
      TranslationException - If one of the parameters can not be translated.
      Since:
      1.3