diff --git a/src/adql/db/FunctionDef.java b/src/adql/db/FunctionDef.java
index 55d9ef4a6f993dc3c2650f513279fcb316e7b388..b1e27b1ca9bdd1c39ba781b79385ea19e693afa1 100644
--- a/src/adql/db/FunctionDef.java
+++ b/src/adql/db/FunctionDef.java
@@ -15,7 +15,7 @@ package adql.db;
  *
  * You should have received a copy of the GNU Lesser General Public License
  * along with ADQLLibrary.  If not, see <http://www.gnu.org/licenses/>.
- *
+ * 
  * Copyright 2015-2020 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
  *                       Astronomisches Rechen Institut (ARI)
  */
@@ -26,6 +26,7 @@ import java.util.regex.Pattern;
 
 import adql.db.DBType.DBDatatype;
 import adql.parser.ParseException;
+import adql.parser.feature.LanguageFeature;
 import adql.query.operand.ADQLOperand;
 import adql.query.operand.function.ADQLFunction;
 import adql.query.operand.function.DefaultUDF;
@@ -51,10 +52,10 @@ import adql.query.operand.function.UserDefinedFunction;
  * 	A description of this function may be set thanks to the public class
  * 	attribute {@link #description}.
  * </p>
- *
+ * 
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
  * @version 2.0 (08/2020)
- *
+ * 
  * @since 1.3
  */
 public class FunctionDef implements Comparable<FunctionDef> {
@@ -194,12 +195,12 @@ public class FunctionDef implements Comparable<FunctionDef> {
 
 	/**
 	 * Translation to apply for this User Defined Function.
-	 *
+	 * 
 	 * <p>
 	 * 	It can be any string. Any <code>$i</code> substring (i being an integer
 	 * 	&gt;0) will be replaced by the corresponding function argument.
 	 * </p>
-	 *
+	 * 
 	 * <p>For instance, for the UDF signature</p>
 	 * <pre>foo(p1 VARCHAR, p2 DOUBLE)</pre>
 	 * <p>, the translation pattern</p>
@@ -287,13 +288,13 @@ public class FunctionDef implements Comparable<FunctionDef> {
 
 	/**
 	 * Create a function definition.
-	 *
+	 * 
 	 * <p>
 	 * 	The created function will have <b>no return type</b> and some parameters
 	 * 	(except if the given array is NULL or empty).
 	 * </p>
-	 *
-	 * @param fctName	Name of the function.
+	 * 
+	 * @param fctName		Name of the function.
 	 * @param params	Parameters of this function.
 	 *              	<i>If NULL or empty, this function will have no
 	 *              	parameter.</i>
@@ -367,14 +368,14 @@ public class FunctionDef implements Comparable<FunctionDef> {
 
 	/**
 	 * Tell whether this function returns an unknown type.
-	 *
+	 * 
 	 * <p>
 	 * 	If this function returns <code>true</code>, {@link #isNumeric()},
 	 * 	{@link #isString()} and {@link #isGeometry()} <b>MUST ALL</b> return
 	 * 	<code>false</code>. Otherwise, one of these 3 last functions MUST
 	 * 	return <code>true</code>.
-	 * </p>
-	 *
+	 * </p> 
+	 * 
 	 * @return	<code>true</code> if this function returns an unknown/unresolved
 	 *        	/unsupported type,
 	 *        	<code>false</code> otherwise.
@@ -414,7 +415,7 @@ public class FunctionDef implements Comparable<FunctionDef> {
 	/**
 	 * Get the class of the {@link UserDefinedFunction} able to represent the
 	 * function defined here in an ADQL tree.
-	 *
+	 * 
 	 * <p><i><b>Note:</b>
 	 * 	This getter should return always NULL if the function defined here is
 	 * 	not a user defined function.
@@ -426,7 +427,7 @@ public class FunctionDef implements Comparable<FunctionDef> {
 	 * 	instance) of the defined function has a different signature (e.g. a
 	 * 	different name) in the target language (e.g. SQL).
 	 * </i></p>
-	 *
+	 * 
 	 * @return	The corresponding {@link UserDefinedFunction}.
 	 *        	<i>MAY BE NULL</i>
 	 */
@@ -437,7 +438,7 @@ public class FunctionDef implements Comparable<FunctionDef> {
 	/**
 	 * Set the class of the {@link UserDefinedFunction} able to represent the
 	 * function defined here in an ADQL tree.
-	 *
+	 * 
 	 * <p><i><b>Note:</b>
 	 * 	If this {@link FunctionDef} defines an ordinary ADQL function - and not
 	 * 	a user defined function - no class should be set here.
@@ -450,12 +451,12 @@ public class FunctionDef implements Comparable<FunctionDef> {
 	 * 	will be created on the fly by the library when needed if it turns out
 	 * 	that no UDF class is set.
 	 * </i></p>
-	 *
+	 * 
 	 * <p><i><b>WARNING:</b>
 	 * 	If successful, this operation will reset to NULL any translation pattern
 	 * 	already set with {@link #setTranslationPattern(String)}.
 	 * </i></p>
-	 *
+	 * 
 	 * @param udfClass	Class to use to represent in an ADQL tree the User
 	 *                	Defined Function defined in this {@link FunctionDef}.
 	 *
@@ -479,7 +480,7 @@ public class FunctionDef implements Comparable<FunctionDef> {
 			// Set to NULL the translation pattern (if any):
 			this.translationPattern = null;
 
-		} catch(SecurityException e) {
+		}catch(SecurityException e){
 			throw new IllegalArgumentException("A security problem occurred while trying to get constructor from the class " + udfClass.getName() + ": " + e.getMessage());
 		} catch(NoSuchMethodException e) {
 			throw new IllegalArgumentException("The given class (" + udfClass.getName() + ") does not provide any constructor with a single parameter of type ADQLOperand[]!");
@@ -489,7 +490,7 @@ public class FunctionDef implements Comparable<FunctionDef> {
 	/**
 	 * Get the translation pattern to apply on any ADQL function implementing
 	 * this UDF definition.
-	 *
+	 * 
 	 * @return	The corresponding {@link UserDefinedFunction}.
 	 *        	<i>NULL if no translation pattern is defined.</i>
 	 *
@@ -724,6 +725,18 @@ public class FunctionDef implements Comparable<FunctionDef> {
 		}
 	}
 
+	/**
+	 * Create a {@link LanguageFeature} corresponding and linked to this
+	 * {@link FunctionDef}.
+	 *
+	 * @return	The corresponding LanguageFeature.
+	 *
+	 * @since 2.0
+	 */
+	public final LanguageFeature toLanguageFeature() {
+		return new LanguageFeature(this);
+	}
+
 	@Override
 	public String toString() {
 		return serializedForm;
diff --git a/src/adql/parser/feature/FeatureSet.java b/src/adql/parser/feature/FeatureSet.java
index dafea9a89c703a413374e3747692ba150cc5cd54..04b7a61544de50c57fe929e6b692b1ead2477e85 100644
--- a/src/adql/parser/feature/FeatureSet.java
+++ b/src/adql/parser/feature/FeatureSet.java
@@ -19,6 +19,7 @@ package adql.parser.feature;
  * Copyright 2019 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
  */
 
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -26,6 +27,7 @@ import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Set;
 
+import adql.db.FunctionDef;
 import adql.query.operand.function.geometry.AreaFunction;
 import adql.query.operand.function.geometry.BoxFunction;
 import adql.query.operand.function.geometry.CentroidFunction;
@@ -550,6 +552,22 @@ public class FeatureSet implements Iterable<LanguageFeature> {
 		return getSupportedFeatures();
 	}
 
+	/**
+	 * Get the list of the definition of all declared UDFs.
+	 *
+	 * @return	List of all supported UDFs.
+	 */
+	public final Collection<FunctionDef> getSupportedUDFList() {
+		Set<LanguageFeature> supportedUDFs = supportedFeatures.get(LanguageFeature.TYPE_UDF);
+		if (supportedUDFs != null) {
+			Set<FunctionDef> definitions = new HashSet<FunctionDef>(supportedUDFs.size());
+			for(LanguageFeature feature : supportedUDFs)
+				definitions.add(feature.udfDefinition);
+			return definitions;
+		} else
+			return new HashSet<FunctionDef>(0);
+	}
+
 	/* **********************************************************************
 	   *                                                                    *
 	   *    ALL AVAILABLE FEATURES (according to the ADQL Language)         *
@@ -557,22 +575,22 @@ public class FeatureSet implements Iterable<LanguageFeature> {
 	   ********************************************************************** */
 
 	/*public static final LanguageFeature ILIKE = new LanguageFeature(FeatureType.ADQL_STRING, "ILIKE"); // TODO ILIKE
-	
+
 	public static final LanguageFeature UNION = new LanguageFeature(FeatureType.ADQL_SETS, "UNION"); // TODO UNION
 	public static final LanguageFeature EXCEPT = new LanguageFeature(FeatureType.ADQL_SETS, "EXCEPT"); // TODO EXCEPT
 	public static final LanguageFeature INTERSECT = new LanguageFeature(FeatureType.ADQL_SETS, "INTERSECT");  // TODO INTERSECT
-	
+
 	public static final LanguageFeature WITH = new LanguageFeature(FeatureType.ADQL_COMMON_TABLE, "WITH");  // TODO WITH
-	
+
 	public static final LanguageFeature CAST = new LanguageFeature(FeatureType.ADQL_TYPE, "CAST");  // TODO CAST
-	
+
 	public static final LanguageFeature IN_UNIT = new LanguageFeature(FeatureType.ADQL_UNIT, "IN_UNIT");  // TODO IN_UNIT
-	
+
 	public static final LanguageFeature BIT_AND = new LanguageFeature(FeatureType.ADQL_BITWISE, "BIT_AND");  // TODO BIT_AND
 	public static final LanguageFeature BIT_OR = new LanguageFeature(FeatureType.ADQL_BITWISE, "BIT_OR");  // TODO BIT_OR
 	public static final LanguageFeature BIT_XOR = new LanguageFeature(FeatureType.ADQL_BITWISE, "BIT_XOR");  // TODO BIT_XOR
 	public static final LanguageFeature BIT_NOT = new LanguageFeature(FeatureType.ADQL_BITWISE, "BIT_NOT");  // TODO BIT_NOT
-	
+
 	public static final LanguageFeature OFFSET = new LanguageFeature(FeatureType.ADQL_OFFSET, "OFFSET");  // TODO OFFSET*/
 
 	/** All standard features available.
diff --git a/src/adql/parser/feature/LanguageFeature.java b/src/adql/parser/feature/LanguageFeature.java
index f4c0a470810fff22453f82e3e1d8bc887488cb2a..abca273c8114c1ff5ad5721dd52e960f32b1fcd0 100644
--- a/src/adql/parser/feature/LanguageFeature.java
+++ b/src/adql/parser/feature/LanguageFeature.java
@@ -21,6 +21,8 @@ package adql.parser.feature;
 
 import java.util.Objects;
 
+import adql.db.FunctionDef;
+
 /**
  * Description of an ADQL's language feature.
  *
@@ -42,13 +44,20 @@ import java.util.Objects;
  * 	set to NULL.
  * </i></p>
  *
+ * <p><i><b>IMPORTANT note about UDF:</b>
+ * 	To create a UDF feature (i.e. a {@link LanguageFeature} with the type
+ * 	{@link #TYPE_UDF}), ONLY ONE constructor can be used:
+ * 	{@link #LanguageFeature(FunctionDef, String)}. Any attempt with another
+ * 	public constructor will fail.
+ * </i></p>
+ *
  * @author Gr&eacute;gory Mantelet (CDS)
  * @version 2.0 (07/2019)
  * @since 2.0
  *
  * @see FeatureSet
  */
-public class LanguageFeature {
+public final class LanguageFeature {
 
 	/** Unique identifier of this language feature.
 	 * <p><i><b>MANDATORY</b></i></p>
@@ -96,6 +105,10 @@ public class LanguageFeature {
 	 * </ul> */
 	public final String form;
 
+	/** Definition of the UDF represented by this {@link LanguageFeature}.
+	 * <p><i><b>OPTIONAL</b></i></p> */
+	public final FunctionDef udfDefinition;
+
 	/** Is this feature optional in the ADQL grammar?
 	 * <p><i><b>MANDATORY</b></i></p>
 	 * <p>
@@ -113,17 +126,18 @@ public class LanguageFeature {
 	public final boolean optional;
 
 	/** Description of this feature.
-	 * <p><i><b>OPTIONAL</b></i></p>
-	 * <p><i><b>Note:</b>
-	 * 	This field is generally set when declaring a User Defined Function
-	 * 	(UDF).
-	 * </i></p> */
-	public final String description;
+	 * <p><i><b>OPTIONAL</b></i></p> */
+	public String description;
 
 	/**
 	 * Create a <em>de-facto supported</em> (i.e. non-optional) language
 	 * feature.
 	 *
+	 * <p><i><b>IMPORTANT note:</b>
+	 * 	To create a UDF feature, DO NOT use this constructor.
+	 * 	You MUST use instead {@link #LanguageFeature(FunctionDef, String)}.
+	 * </i></p>
+	 *
 	 * @param type			[OPTIONAL] Category of the language feature.
 	 *            			<em>(see all static attributes starting with
 	 *            			<code>TYPE_</code>)</em>
@@ -139,6 +153,11 @@ public class LanguageFeature {
 	/**
 	 * Create a language feature.
 	 *
+	 * <p><i><b>IMPORTANT note:</b>
+	 * 	To create a UDF feature, DO NOT use this constructor.
+	 * 	You MUST use instead {@link #LanguageFeature(FunctionDef, String)}.
+	 * </i></p>
+	 *
 	 * @param type			[OPTIONAL] Category of the language feature.
 	 *            			<em>(see all static attributes starting with
 	 *            			<code>TYPE_</code>)</em>
@@ -158,6 +177,11 @@ public class LanguageFeature {
 	/**
 	 * Create a language feature.
 	 *
+	 * <p><i><b>IMPORTANT note:</b>
+	 * 	To create a UDF feature, DO NOT use this constructor.
+	 * 	You MUST use instead {@link #LanguageFeature(FunctionDef, String)}.
+	 * </i></p>
+	 *
 	 * @param type			[OPTIONAL] Category of the language feature.
 	 *            			<em>(see all static attributes starting with
 	 *            			<code>TYPE_</code>)</em>
@@ -172,12 +196,69 @@ public class LanguageFeature {
 	 * @throws NullPointerException	If given form is missing.
 	 */
 	public LanguageFeature(final String type, final String form, final boolean optional, final String description) throws NullPointerException {
+		this(type, form, null, optional, description);
+	}
+
+	/**
+	 * Create a UDF feature.
+	 *
+	 * @param udfDef		[REQUIRED] Detailed definition of the UDF feature.
+	 *
+	 * @throws NullPointerException	If given {@link FunctionDef} is missing.
+	 */
+	public LanguageFeature(final FunctionDef udfDef) throws NullPointerException {
+		this(udfDef, null);
+	}
+
+	/**
+	 * Create a UDF feature.
+	 *
+	 * @param udfDef		[REQUIRED] Detailed definition of the UDF feature.
+	 * @param description	[OPTIONAL] Description overwriting the description
+	 *                   	provided in the given {@link FunctionDef}.
+	 *                   	<em>If NULL, the description of the
+	 *                   	{@link FunctionDef} will be used. If empty string,
+	 *                   	no description will be set.</em>
+	 *
+	 * @throws NullPointerException	If given {@link FunctionDef} is missing.
+	 */
+	public LanguageFeature(final FunctionDef udfDef, final String description) throws NullPointerException {
+		this(LanguageFeature.TYPE_UDF, udfDef.toString(), udfDef, true, (description == null ? udfDef.description : (description.trim().isEmpty() ? null : description)));
+	}
+
+	/**
+	 * Create a language feature.
+	 *
+	 * <p><i><b>IMPORTANT note:</b>
+	 * 	To create a UDF feature, the parameter udfDef MUST be NON-NULL.
+	 * </i></p>
+	 *
+	 * @param type			[OPTIONAL] Category of the language feature.
+	 *            			<em>(see all static attributes starting with
+	 *            			<code>TYPE_</code>)</em>
+	 * @param form			[REQUIRED] Name (or function signature) of the
+	 *            			language feature.
+	 * @param udfDef		[REQUIRED if type=UDF] Detailed definition of the
+	 *              		UDF feature.
+	 * @param optional		[REQUIRED] <code>true</code> if the feature is by
+	 *                		default supported in the ADQL standard,
+	 *                		<code>false</code> if the ADQL client must declare
+	 *                		it as supported in order to use it.
+	 * @param description	[OPTIONAL] Description of this feature.
+	 *
+	 * @throws NullPointerException	If given form or udfDef is missing.
+	 */
+	private LanguageFeature(final String type, final String form, final FunctionDef udfDef, final boolean optional, final String description) throws NullPointerException {
 		this.type = (type == null || type.trim().isEmpty()) ? null : type.trim();
 
 		if (form == null || form.trim().isEmpty())
 			throw new NullPointerException("Missing form/name of the language feature to create!");
 		this.form = form.trim();
 
+		if (TYPE_UDF.equals(this.type) && udfDef == null)
+			throw new NullPointerException("Missing UDF definition! To declare a UDF feature, you MUST use the constructor LanguageFeature(FunctionDef, ...) with a non-NULL FunctionDef instance.");
+		this.udfDefinition = udfDef;
+
 		this.id = (this.type == null ? "" : this.type) + "!" + this.form;
 
 		this.optional = optional;
@@ -187,15 +268,25 @@ public class LanguageFeature {
 
 	@Override
 	public boolean equals(final Object obj) {
-		if ((obj != null) && (obj instanceof LanguageFeature))
-			return id.equals(((LanguageFeature)obj).id);
-		else
-			return false;
+		if ((obj != null) && (obj instanceof LanguageFeature)) {
+			// Equals IF SAME ID:
+			if (id.equals(((LanguageFeature)obj).id))
+				return true;
+			// If UDF, equals IF SAME NAME and SAME NB PARAMETERS:
+			else if (TYPE_UDF.equals(type) && type.equals(((LanguageFeature)obj).type)) {
+				FunctionDef udfDefinition2 = ((LanguageFeature)obj).udfDefinition;
+				return udfDefinition.name.equalsIgnoreCase(udfDefinition2.name) && (udfDefinition.nbParams == udfDefinition2.nbParams);
+			}
+		}
+		return false;
 	}
 
 	@Override
 	public int hashCode() {
-		return Objects.hash(id, form);
+		if (udfDefinition != null)
+			return Objects.hash(type, udfDefinition.name.toLowerCase(), udfDefinition.nbParams);
+		else
+			return Objects.hash(type, form, -1);
 	}
 
 	@Override
diff --git a/src/adql/query/operand/function/DefaultUDF.java b/src/adql/query/operand/function/DefaultUDF.java
index 01e2bec5f61635fecd81c5eb1751bd720ecf8cd5..b67b40d2bbdad6ea3b48cac93c7d0be58909320c 100644
--- a/src/adql/query/operand/function/DefaultUDF.java
+++ b/src/adql/query/operand/function/DefaultUDF.java
@@ -22,7 +22,10 @@ import java.util.regex.Matcher;
  *                       Astronomisches Rechen Institut (ARI)
  */
 
+import adql.db.DBType;
+import adql.db.DBType.DBDatatype;
 import adql.db.FunctionDef;
+import adql.db.FunctionDef.FunctionParam;
 import adql.parser.feature.LanguageFeature;
 import adql.query.ADQLList;
 import adql.query.ADQLObject;
@@ -67,7 +70,7 @@ public final class DefaultUDF extends UserDefinedFunction {
 			for(ADQLOperand p : params)
 				parameters.add(p);
 		}
-		languageFeature = new LanguageFeature(LanguageFeature.TYPE_UDF, functionName + "(...)", true, null);
+		generateLanguageFeature();
 	}
 
 	/**
@@ -122,11 +125,49 @@ public final class DefaultUDF extends UserDefinedFunction {
 	 * @since 1.3
 	 */
 	public final void setDefinition(final FunctionDef def) throws IllegalArgumentException {
+		// Ensure the definition is compatible with this ADQL function:
 		if (def != null && (def.name == null || !functionName.equalsIgnoreCase(def.name)))
 			throw new IllegalArgumentException("The parsed function name (" + functionName + ") does not match to the name of the given UDF definition (" + def.name + ").");
 
+		// Set the new definition (may be NULL):
 		this.definition = def;
-		languageFeature = new LanguageFeature(LanguageFeature.TYPE_UDF, this.definition.toString(), true, this.definition.description);
+
+		// Update the Language Feature of this ADQL function:
+		// ...if no definition, generate a default LanguageFeature:
+		if (this.definition == null)
+			generateLanguageFeature();
+		// ...otherwise, use the definition to set the LanguageFeature:
+		else
+			languageFeature = new LanguageFeature(this.definition);
+	}
+
+	/**
+	 * Generate and set a default {@link LanguageFeature} for this ADQL
+	 * function.
+	 *
+	 * <p><i><b>Note:</b>
+	 * 	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 `$`).
+	 * </i></p>
+	 *
+	 * @since 2.0
+	 */
+	private void generateLanguageFeature() {
+		// Create an unknown DBType:
+		DBType unknownType = new DBType(DBDatatype.UNKNOWN);
+		unknownType.type.setCustomType("type");
+
+		// Create the list of input parameters:
+		FunctionParam[] inputParams = new FunctionParam[parameters.size()];
+		for(int i = 1; i <= parameters.size(); i++)
+			inputParams[i - 1] = new FunctionParam("param" + i, unknownType);
+
+		// Create the Function Definition:
+		FunctionDef fctDef = new FunctionDef(functionName, unknownType, inputParams);
+
+		// Finally create the LanguageFeature:
+		languageFeature = new LanguageFeature(fctDef);
 	}
 
 	@Override
diff --git a/test/adql/db/TestDBChecker.java b/test/adql/db/TestDBChecker.java
index cb602976ef94ef22bef51634f5fa430ee3e9b437..72ca3dde2ecf9969fce90bb1520fbfbd68fb596c 100644
--- a/test/adql/db/TestDBChecker.java
+++ b/test/adql/db/TestDBChecker.java
@@ -267,6 +267,7 @@ public class TestDBChecker {
 	public void testUDFManagement() {
 		// UNKNOWN FUNCTIONS ARE NOT ALLOWED:
 		ADQLParser parser = parserFactory.createParser();
+		parser.getSupportedFeatures().allowAnyUdf(true);
 		parser.setQueryChecker(new DBChecker(tables, new ArrayList<FunctionDef>(0)));
 
 		// Test with a simple ADQL query without unknown or user defined function:
@@ -291,6 +292,7 @@ public class TestDBChecker {
 		// DECLARE THE UDFs:
 		FunctionDef[] udfs = new FunctionDef[]{ new FunctionDef("toto", new DBType(DBDatatype.VARCHAR)), new FunctionDef("tata", new DBType(DBDatatype.INTEGER)) };
 		parser = parserFactory.createParser();
+		parser.getSupportedFeatures().allowAnyUdf(true);
 		parser.setQueryChecker(new DBChecker(tables, Arrays.asList(udfs)));
 
 		// Test again:
@@ -341,6 +343,7 @@ public class TestDBChecker {
 		udfs = new FunctionDef[]{ new FunctionDef("toto", new DBType(DBDatatype.VARCHAR), new FunctionParam[]{ new FunctionParam("txt", new DBType(DBDatatype.VARCHAR)) }) };
 		udfs[0].setUDFClass(UDFToto.class);
 		parser = parserFactory.createParser();
+		parser.getSupportedFeatures().allowAnyUdf(true);
 		parser.setQueryChecker(new DBChecker(tables, Arrays.asList(udfs)));
 		try {
 			ADQLQuery query = parser.parseQuery("SELECT toto('blabla') FROM foo;");
@@ -374,6 +377,7 @@ public class TestDBChecker {
 		udfs = new FunctionDef[]{ new FunctionDef("toto", new DBType(DBDatatype.VARCHAR), new FunctionParam[]{ new FunctionParam("txt", new DBType(DBDatatype.VARCHAR)) }) };
 		udfs[0].setUDFClass(WrongUDFToto.class);
 		parser = parserFactory.createParser();
+		parser.getSupportedFeatures().allowAnyUdf(true);
 		parser.setQueryChecker(new DBChecker(tables, Arrays.asList(udfs)));
 		try {
 			parser.parseQuery("SELECT toto('blabla') FROM foo;");
@@ -893,7 +897,7 @@ public class TestDBChecker {
 	}
 
 	public static class UDFToto extends UserDefinedFunction {
-		private LanguageFeature FEATURE = new LanguageFeature(LanguageFeature.TYPE_UDF, getName() + "(VARCHAR) -> VARCHAR");
+		private LanguageFeature FEATURE = (new FunctionDef(getName(), new DBType(DBDatatype.VARCHAR), new FunctionParam[]{ new FunctionParam("txt", new DBType(DBDatatype.VARCHAR)) })).toLanguageFeature();
 
 		protected StringConstant fakeParam;
 
diff --git a/test/adql/parser/feature/TestFeatureSet.java b/test/adql/parser/feature/TestFeatureSet.java
index e58fb7575ae2dab97dc5a63f9adbd8f51b993d3d..3d256aabac445d26aeb3545a4d0188e3b703447c 100644
--- a/test/adql/parser/feature/TestFeatureSet.java
+++ b/test/adql/parser/feature/TestFeatureSet.java
@@ -11,6 +11,9 @@ import java.util.Set;
 
 import org.junit.Test;
 
+import adql.db.DBType;
+import adql.db.DBType.DBDatatype;
+import adql.db.FunctionDef;
 import adql.query.ColumnReference;
 import adql.query.operand.function.geometry.BoxFunction;
 import adql.query.operand.function.geometry.PolygonFunction;
@@ -217,7 +220,7 @@ public class TestFeatureSet {
 
 		/* here is a custom Language Feature (i.e. not part of the
 		 * availableFeatures list): */
-		set.support(new LanguageFeature(LanguageFeature.TYPE_UDF, "foo(VARCHAR) -> BOOLEAN", true));
+		set.support(new LanguageFeature(new FunctionDef("foo", new DBType(DBDatatype.SMALLINT), new FunctionDef.FunctionParam[]{ new FunctionDef.FunctionParam("", new DBType(DBDatatype.VARCHAR)) })));
 
 		// unsupport all currently supported features:
 		set.unsupportAll();