diff --git a/src/tap/ADQLExecutor.java b/src/tap/ADQLExecutor.java
index c1327eb3c1baae9418012b3212a8f8966c289277..689a152a2ffa4fbfa55643660b00e7647a7a12e2 100644
--- a/src/tap/ADQLExecutor.java
+++ b/src/tap/ADQLExecutor.java
@@ -2,21 +2,21 @@ package tap;
 
 /*
  * This file is part of TAPLibrary.
- * 
+ *
  * TAPLibrary is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
- * 
+ *
  * TAPLibrary is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU Lesser General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Lesser General Public License
  * along with TAPLibrary.  If not, see <http://www.gnu.org/licenses/>.
- * 
- * Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *
+ * Copyright 2012-2019 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
  *                       Astronomisches Rechen Institut (ARI)
  */
 
@@ -49,7 +49,7 @@ import uws.service.log.UWSLog.LogLevel;
 
 /**
  * <p>Let process completely an ADQL query.</p>
- * 
+ *
  * <p>Thus, this class aims to apply the following actions (in the given order):</p>
  * <ol>
  * 	<li>Upload the user tables, if any</li>
@@ -58,54 +58,54 @@ import uws.service.log.UWSLog.LogLevel;
  * 	<li>Format and write the result</li>
  * 	<li>Drop all uploaded tables from the "database"</li>
  * </ol>
- * 
+ *
  * <h3>Job execution mode</h3>
- * 
+ *
  * <p>
  * 	This executor is able to process queries coming from a synchronous job (the result must be written directly in the HTTP response)
  * 	and from an asynchronous job (the result must be written, generally, in a file). Two start(...) functions let deal with
  * 	the differences between the two job execution modes: {@link #start(AsyncThread)} for asynchronous jobs
  * 	and {@link #start(Thread, String, TAPParameters, HttpServletResponse)} for synchronous jobs.
  * </p>
- * 
+ *
  * <h3>Input/Output formats</h3>
- * 
+ *
  * <p>Uploaded tables must be provided in VOTable format.</p>
- * 
+ *
  * <p>
  * 	Query results must be formatted in the format specified by the user in the job parameters. A corresponding formatter ({@link OutputFormat})
  * 	is asked to the description of the TAP service ({@link ServiceConnection}). If none can be found, VOTable will be chosen by default.
  * </p>
- * 
+ *
  * <h3>Executor customization</h3>
- * 
+ *
  * <p>It is totally possible to customize some parts of the ADQL query processing. However, the main algorithm must remain the same and is implemented
  * 	by {@link #start()}. This function is final, like {@link #start(AsyncThread)} and {@link #start(Thread, String, TAPParameters, HttpServletResponse)},
  * 	which are just preparing the execution for {@link #start()} in function of the job execution mode (asynchronous or synchronous).
  * </p>
- * 
+ *
  * <p><i>Note:
  * 	{@link #start()} is using the Template Method Design Pattern: it defines the skeleton/algorithm of the processing, and defers some steps
  * 	to other functions.
  * </i></p>
- * 
+ *
  * <p>
  * 	So, you are able to customize almost all individual steps of the ADQL query processing: {@link #parseADQL()}, {@link #executeADQL(ADQLQuery)} and
  * 	{@link #writeResult(TableIterator, OutputFormat, OutputStream)}.
  * </p>
- * 
+ *
  * <p><i>Note:
  * 	Note that the formatting of the result is done by an OutputFormat and that the executor is just calling the appropriate function of the formatter.
  * </i></p>
- * 
+ *
  * <p>
  * 	There is no way in this executor to customize the upload. However, it does not mean it can not be customized.
  * 	Indeed you can do it easily by extending {@link Uploader} and by providing the new class inside your {@link TAPFactory} implementation
  * (see {@link TAPFactory#createUploader(DBConnection)}).
  * </p>
- * 
+ *
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 2.1 (04/2017)
+ * @version 2.3 (03/2019)
  */
 public class ADQLExecutor {
 
@@ -139,7 +139,7 @@ public class ADQLExecutor {
 
 	/**
 	 * Build an {@link ADQLExecutor}.
-	 * 
+	 *
 	 * @param service	The description of the TAP service.
 	 */
 	public ADQLExecutor(final ServiceConnection service){
@@ -149,7 +149,7 @@ public class ADQLExecutor {
 
 	/**
 	 * Get the logger used by this executor.
-	 * 
+	 *
 	 * @return	The used logger.
 	 */
 	public final TAPLog getLogger(){
@@ -158,12 +158,12 @@ public class ADQLExecutor {
 
 	/**
 	 * <p>Get the report of the query execution. It helps indicating the execution progression and the duration of each step.</p>
-	 * 
+	 *
 	 * <p><i>Note:
 	 * 	Before starting the execution (= before the call of a "start(...)" function), this function will return NULL.
 	 * 	It is set when the query processing starts and remains not NULL after that (even when the execution is finished).
 	 * </i></p>
-	 * 
+	 *
 	 * @return	The execution report.
 	 */
 	public final TAPExecutionReport getExecReport(){
@@ -173,11 +173,11 @@ public class ADQLExecutor {
 	/**
 	 * <p>Get the object to use in order to write the query result in the appropriate format
 	 * (either the asked one, or else VOTable).</p>
-	 * 
+	 *
 	 * @return	The appropriate result formatter to use. <i>Can not be NULL!</i>
-	 * 
+	 *
 	 * @throws TAPException	If no format corresponds to the asked one and if no default format (for VOTable) can be found.
-	 * 
+	 *
 	 * @see ServiceConnection#getOutputFormat(String)
 	 */
 	protected OutputFormat getFormatter() throws TAPException{
@@ -196,19 +196,19 @@ public class ADQLExecutor {
 
 	/**
 	 * <p>Start the asynchronous processing of the ADQL query.</p>
-	 * 
+	 *
 	 * <p>
 	 * 	This function initialize the execution report, get the execution parameters (including the query to process)
 	 * 	and then call {@link #start()}.
 	 * </p>
-	 * 
+	 *
 	 * @param thread	The asynchronous thread which asks the query processing.
-	 * 
+	 *
 	 * @return	The resulting execution report.
-	 * 
+	 *
 	 * @throws UWSException			If any error occurs while executing the ADQL query.
 	 * @throws InterruptedException	If the job has been interrupted (by the user or a time-out).
-	 * 
+	 *
 	 * @see #start()
 	 */
 	public final TAPExecutionReport start(final AsyncThread thread) throws UWSException, InterruptedException{
@@ -244,16 +244,16 @@ public class ADQLExecutor {
 
 	/**
 	 * <p>Create the database connection required for the ADQL execution.</p>
-	 * 
+	 *
 	 * <p><i>Note: This function has no effect if the DB connection already exists.</i></p>
-	 * 
+	 *
 	 * @param jobID	ID of the job which will be executed by this {@link ADQLExecutor}.
 	 *             	This ID will be the database connection ID.
-	 * 
+	 *
 	 * @throws TAPException	If the DB connection creation fails.
-	 * 
+	 *
 	 * @see TAPFactory#getConnection(String)
-	 * 
+	 *
 	 * @since 2.0
 	 */
 	public final void initDBConnection(final String jobID) throws TAPException{
@@ -264,7 +264,7 @@ public class ADQLExecutor {
 	/**
 	 * Cancel the current SQL query execution or result set fetching if any is currently running.
 	 * If no such process is on going, this function has no effect.
-	 * 
+	 *
 	 * @since 2.1
 	 */
 	public final void cancelQuery(){
@@ -274,20 +274,20 @@ public class ADQLExecutor {
 
 	/**
 	 * <p>Start the synchronous processing of the ADQL query.</p>
-	 * 
+	 *
 	 * <p>This function initialize the execution report and then call {@link #start()}.</p>
-	 * 
+	 *
 	 * @param thread	The synchronous thread which asks the query processing.
 	 * @param jobId		ID of the corresponding job.
 	 * @param params	All execution parameters (including the query to process).
 	 * @param response	Object in which the result or the error must be written.
-	 * 
+	 *
 	 * @return	The resulting execution report.
-	 * 
+	 *
 	 * @throws TAPException			If any error occurs while executing the ADQL query.
 	 * @throws IOException			If any error occurs while writing the result in the given {@link HttpServletResponse}.
 	 * @throws InterruptedException	If the job has been interrupted (by the user or a time-out).
-	 * 
+	 *
 	 * @see #start()
 	 */
 	public final TAPExecutionReport start(final Thread thread, final String jobId, final TAPParameters params, final HttpServletResponse response) throws TAPException, IOException, InterruptedException{
@@ -308,7 +308,7 @@ public class ADQLExecutor {
 
 	/**
 	 * <p>Process the ADQL query.</p>
-	 * 
+	 *
 	 * <p>This function calls the following function (in the same order):</p>
 	 * <ol>
 	 * 	<li>{@link TAPFactory#getConnection(String)}</li>
@@ -319,16 +319,16 @@ public class ADQLExecutor {
 	 * 	<li>{@link #dropUploadedTables()}</li>
 	 * 	<li>{@link TAPFactory#freeConnection(DBConnection)}</li>
 	 * </ol>
-	 * 
+	 *
 	 * <p>
 	 * 	The execution report is updated gradually. Besides a job parameter - progression - is set at each step of the process in order to
 	 * 	notify the user of the progression of the query execution. This parameter is removed at the end of the execution if it is successful.
 	 * </p>
-	 * 
+	 *
 	 * <p>The "interrupted" flag of the associated thread is often tested so that stopping the execution as soon as possible.</p>
-	 * 
+	 *
 	 * @return	The updated execution report.
-	 * 
+	 *
 	 * @throws TAPException			If any error occurs while executing the ADQL query.
 	 * @throws UWSException			If any error occurs while executing the ADQL query.
 	 * @throws IOException			If an error happens while writing the result in the specified {@link HttpServletResponse}.
@@ -434,18 +434,18 @@ public class ADQLExecutor {
 	/**
 	 * <p>Memorize the time at which the step starts, the step ID and update the job parameter "progression"
 	 * (to notify the user about the progression of the query processing).</p>
-	 * 
+	 *
 	 * <p><i>Note:
 	 * 	If for some reason the job parameter "progression" can not be updated, no error will be thrown. A WARNING message
 	 * 	will be just written in the log.
 	 * </i></p>
-	 * 
+	 *
 	 * <p><i>Note:
 	 * 	This function is designed to work with {@link #endStep()}, which must be called after it, when the step is finished (successfully or not).
 	 * </i></p>
-	 * 
+	 *
 	 * @param progression	ID of the starting step.
-	 * 
+	 *
 	 * @see #endStep()
 	 */
 	private void startStep(final ExecutionProgression progression){
@@ -464,16 +464,16 @@ public class ADQLExecutor {
 
 	/**
 	 * <p>Set the duration of the current step in the execution report.</p>
-	 * 
+	 *
 	 * <p><i>Note:
 	 * 	The start time and the ID of the step are then forgotten.
 	 * </i></p>
-	 * 
+	 *
 	 * <p><i>Note:
 	 * 	This function is designed to work with {@link #startStep(ExecutionProgression)}, which must be called before it, when the step is starting.
 	 * 	It marks the end of a step.
 	 * </i></p>
-	 * 
+	 *
 	 * @see #startStep(ExecutionProgression)
 	 */
 	private void endStep(){
@@ -489,11 +489,11 @@ public class ADQLExecutor {
 
 	/**
 	 * <p>Create in the "database" all tables uploaded by the user (only for this specific query execution).</p>
-	 * 
+	 *
 	 * <p><i>Note:
 	 * 	Obviously, nothing is done if no table has been uploaded.
 	 * </i></p>
-	 * 
+	 *
 	 * @throws TAPException	If any error occurs while reading the uploaded table
 	 *                     	or while importing them in the database.
 	 */
@@ -510,23 +510,23 @@ public class ADQLExecutor {
 
 	/**
 	 * <p>Parse the ADQL query provided in the parameters by the user.</p>
-	 * 
+	 *
 	 * <p>The query factory and the query checker are got from the TAP factory.</p>
-	 * 
+	 *
 	 * <p>
 	 * 	The configuration of this TAP service list all allowed coordinate systems. These are got here and provided to the query checker
 	 * 	in order to ensure the coordinate systems used in the query are in this list.
 	 * </p>
-	 * 
+	 *
 	 * <p>
 	 * 	The row limit specified in the ADQL query (with TOP) is checked and adjusted (if needed). Indeed, this limit
 	 * 	can not exceed MAXREC given in parameter and the maximum value specified in the configuration of this TAP service.
 	 * 	In the case no row limit is specified in the query or the given value is greater than MAXREC, (MAXREC+1) is used by default.
 	 * 	The "+1" aims to detect overflows.
 	 * </p>
-	 * 
+	 *
 	 * @return	The object representation of the ADQL query.
-	 * 
+	 *
 	 * @throws ParseException			If the given ADQL query can not be parsed or if the construction of the object representation has failed.
 	 * @throws InterruptedException		If the thread has been interrupted.
 	 * @throws TAPException				If the TAP factory is unable to create the ADQL factory or the query checker.
@@ -551,7 +551,30 @@ public class ADQLExecutor {
 			parser.setQueryChecker(service.getFactory().createQueryChecker(uploadSchema));
 
 		// Parse the ADQL query:
-		ADQLQuery query = parser.parseQuery(tapParams.getQuery());
+		ADQLQuery query = null;
+		// if the fixOnFail option is enabled...
+		if (service.fixOnFailEnabled()){
+			try{
+				// try parsing the query:
+				query = parser.parseQuery(tapParams.getQuery());
+			}catch(ParseException pe){
+				// if it fails...
+				// ...log the auto fix attempt:
+				logger.logTAP(LogLevel.INFO, report, "PARSING", "Parse attempt of the original input query failed! Trying auto-fix...", null);
+				// ...try fixing the query:
+				String fixedQuery = parser.tryQuickFix(tapParams.getQuery());
+				// ...log the auto fixed query, if successful:
+				logger.logTAP(LogLevel.INFO, report, "PARSING", "Auto-fixed query: " + fixedQuery.replaceAll("(\t|\r?\n)+", " "), null);
+				// ...keep this fixed query in the exec report:
+				report.fixedQuery = fixedQuery;
+				// ...and finally try parsing it a last time:
+				query = parser.parseQuery(fixedQuery);
+			}
+		}
+		// if not enabled, parse immediately the query:
+		else{
+			query = parser.parseQuery(tapParams.getQuery());
+		}
 
 		// Set or check the row limit:
 		final int limit = query.getSelect().getLimit();
@@ -566,22 +589,22 @@ public class ADQLExecutor {
 
 	/**
 	 * <p>Execute in "database" the given object representation of an ADQL query.</p>
-	 * 
+	 *
 	 * <p>By default, this function is just calling {@link DBConnection#executeQuery(ADQLQuery)} and then it returns the value returned by this call.</p>
-	 * 
+	 *
 	 * <p><i>Note:
 	 * 	An INFO message is logged at the end of the query execution in order to report the result status (success or error)
 	 * 	and the execution duration.
 	 * </i></p>
-	 * 
+	 *
 	 * @param adql	The object representation of the ADQL query to execute.
-	 * 
+	 *
 	 * @return	The result of the query.
-	 * 
+	 *
 	 * @throws InterruptedException	If the thread has been interrupted.
 	 * @throws DBCancelledException	If the inner DB connection has been canceled.
 	 * @throws TAPException			If the {@link DBConnection} has failed to deal with the given ADQL query.
-	 * 
+	 *
 	 * @see DBConnection#executeQuery(ADQLQuery)
 	 */
 	protected TableIterator executeADQL(final ADQLQuery adql) throws InterruptedException, DBCancelledException, TAPException{
@@ -617,21 +640,21 @@ public class ADQLExecutor {
 	/**
 	 * <p>Write the given query result into the appropriate format in the appropriate output
 	 * (HTTP response for a synchronous execution, otherwise a file or any output provided by UWS).</p>
-	 * 
+	 *
 	 * <p>This function prepare the output in function of the execution type (synchronous or asynchronous).
 	 * 	Once prepared, the result, the output and the formatter to use are given to {@link #writeResult(TableIterator, OutputFormat, OutputStream)}
 	 * 	which will really process the result formatting and writing.
 	 * </p>
-	 * 
+	 *
 	 * @param queryResult	The result of the query execution in database.
-	 * 
+	 *
 	 * @throws InterruptedException	If the thread has been interrupted.
 	 * @throws IOException			If an error happens while writing the result in the {@link HttpServletResponse}.
 	 *                    			<i>That kind of error can be thrown only in synchronous mode.
 	 *                    			In asynchronous, the error is stored as job error report and is never propagated.</i>
 	 * @throws TAPException			If an error occurs while getting the appropriate formatter or while formatting or writing (synchronous execution) the result.
 	 * @throws UWSException			If an error occurs while getting the output stream or while writing (asynchronous execution) the result.
-	 * 
+	 *
 	 * @see #writeResult(TableIterator, OutputFormat, OutputStream)
 	 */
 	protected final void writeResult(final TableIterator queryResult) throws InterruptedException, IOException, TAPException, UWSException{
@@ -707,18 +730,18 @@ public class ADQLExecutor {
 
 	/**
 	 * <p>Format and write the given result in the given output with the given formatter.</p>
-	 * 
+	 *
 	 * <p>By default, this function is just calling {@link OutputFormat#writeResult(TableIterator, OutputStream, TAPExecutionReport, Thread)}.</p>
-	 * 
+	 *
 	 * <p><i>Note:
 	 * 	{@link OutputFormat#writeResult(TableIterator, OutputStream, TAPExecutionReport, Thread)} is often testing the "interrupted" flag of the
 	 * 	thread in order to stop as fast as possible if the user has cancelled the job or if the thread has been interrupted for another reason.
 	 * </i></p>
-	 * 
+	 *
 	 * @param queryResult	Query result to format and to output.
 	 * @param formatter		The object able to write the result in the appropriate format.
 	 * @param output		The stream in which the result must be written.
-	 * 
+	 *
 	 * @throws InterruptedException	If the thread has been interrupted.
 	 * @throws IOException			If there is an error while writing the result in the given stream.
 	 * @throws TAPException			If there is an error while formatting the result.
@@ -729,11 +752,11 @@ public class ADQLExecutor {
 
 	/**
 	 * <p>Drop all tables uploaded by the user from the database.</p>
-	 * 
+	 *
 	 * <p><i>Note:
 	 * 	By default, if an error occurs while dropping a table from the database, the error will just be logged ; it won't be thrown/propagated.
 	 * </i></p>
-	 * 
+	 *
 	 * @throws TAPException	If a grave error occurs. <i>By default, no exception is thrown ; they are just logged.</i>
 	 */
 	protected void dropUploadedTables() throws TAPException{
diff --git a/src/tap/ServiceConnection.java b/src/tap/ServiceConnection.java
index 6545b5f3cc6df64e2e01499da27cc65d78b3ed4d..e22e657ff2f9df9bd32b6e16e367b7d7154ec39d 100644
--- a/src/tap/ServiceConnection.java
+++ b/src/tap/ServiceConnection.java
@@ -16,7 +16,7 @@ package tap;
  * You should have received a copy of the GNU Lesser General Public License
  * along with TAPLibrary.  If not, see <http://www.gnu.org/licenses/>.
  *
- * Copyright 2012-2018 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ * Copyright 2012-2019 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
  *                       Astronomisches Rechen Institut (ARI)
  */
 
@@ -44,7 +44,7 @@ import uws.service.file.UWSFileManager;
  * </p>
  *
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 2.3 (09/2018)
+ * @version 2.3 (03/2019)
  */
 public interface ServiceConnection {
 
@@ -744,4 +744,17 @@ public interface ServiceConnection {
 	 */
 	public int[] getFetchSize();
 
+	/**
+	 * <i><b>[MANDATORY]</b></i>
+	 * <p>This function tells whether TAP-Lib should automatically try to fix a
+	 * query whose parsing failed because of a token error. After this fix
+	 * attempt the query is parsed again for a last time.</p>
+	 *
+	 * @return	<i>true</i> to allow automatic fix attempt in case of error,
+	 *        	<i>false</i> to disable this option.
+	 *
+	 * @since 2.3
+	 */
+	public boolean fixOnFailEnabled();
+
 }
diff --git a/src/tap/TAPExecutionReport.java b/src/tap/TAPExecutionReport.java
index fe2733f07ac4fe4fc6e2bbb3be59de678e503fb5..5e4db034912c8d6d701c216ac275547df1f5128b 100644
--- a/src/tap/TAPExecutionReport.java
+++ b/src/tap/TAPExecutionReport.java
@@ -1,49 +1,66 @@
 package tap;
 
+import adql.db.DBColumn;
+
 /*
  * This file is part of TAPLibrary.
- * 
+ *
  * TAPLibrary is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
- * 
+ *
  * TAPLibrary is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU Lesser General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Lesser General Public License
  * along with TAPLibrary.  If not, see <http://www.gnu.org/licenses/>.
- * 
- * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *
+ * Copyright 2012-2019 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
  *                       Astronomisches Rechen Institut (ARI)
  */
 
 import tap.parameters.TAPParameters;
-import adql.db.DBColumn;
 
 /**
- * <p>Report the execution (including the parsing and the output writing) of an ADQL query.
- * It gives information on the job parameters, the job ID, whether it is a synchronous task or not, times of each execution step (uploading, parsing, executing and writing),
- * the resulting columns and the success or not of the execution.</p>
- * 
- * <p>This report is completely filled by {@link ADQLExecutor}, and aims to be used/read only at the end of the job or when it is definitely finished.</p>
- * 
+ * Report the execution (including the parsing and the output writing) of an
+ * ADQL query.
+ *
+ * <p>
+ * 	It gives information on the job parameters, the job ID, whether it is a
+ * 	synchronous task or not, times of each execution step (uploading, parsing,
+ * 	executing and writing), the resulting columns and the success or not of the
+ * 	execution.
+ * </p>
+ *
+ * <p>
+ * 	This report is completely filled by {@link ADQLExecutor}, and aims to be
+ * 	used/read only at the end of the job or when it is definitely finished.
+ * </p>
+ *
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 2.0 (04/2015)
+ * @version 2.3 (03/2019)
  */
 public class TAPExecutionReport {
 
 	/** ID of the job whose the execution is reported here. */
 	public final String jobID;
 
-	/** Indicate whether this execution is done in a synchronous or asynchronous job. */
+	/** Indicate whether this execution is done in a synchronous or asynchronous
+	 * job. */
 	public final boolean synchronous;
 
 	/** List of all parameters provided in the user request. */
 	public final TAPParameters parameters;
 
+	/** Input ADQL query after an automatic fix by TAP-Lib.
+	 * <p>This field is set only if the option fix_on_fail is enabled in the TAP
+	 * configuration and that a query has been fixed.</p>
+	 * @since 2.3 */
+	public String fixedQuery = null;
+
 	/** List of all resulting columns. <i>Empty array, if not yet known.</i> */
 	public DBColumn[] resultingColumns = new DBColumn[0];
 
@@ -51,21 +68,26 @@ public class TAPExecutionReport {
 	 * @since 2.0 */
 	public long nbRows = -1;
 
-	/** Duration of all execution steps. <i>For the moment only 4 steps (in the order): uploading, parsing, executing and writing.</i> */
-	protected final long[] durations = new long[]{-1,-1,-1,-1};
+	/** Duration of all execution steps. <i>For the moment only 4 steps (in the
+	 * order): uploading, parsing, executing and writing.</i> */
+	protected final long[] durations = new long[]{ -1, -1, -1, -1 };
 
 	/** Total duration of the job execution. */
 	protected long totalDuration = -1;
 
-	/** Indicate whether this job has ended successfully or not. <i>At the beginning or while executing, this field is always FALSE.</i> */
+	/** Indicate whether this job has ended successfully or not.
+	 * <i>At the beginning or while executing, this field is always FALSE.</i> */
 	public boolean success = false;
 
 	/**
 	 * Build an empty execution report.
-	 * 
-	 * @param jobID			ID of the job whose the execution must be described here.
-	 * @param synchronous	<i>true</i> if the job is synchronous, <i>false</i> otherwise.
-	 * @param params		List of all parameters provided by the user for the execution.
+	 *
+	 * @param jobID			ID of the job whose the execution must be described
+	 *             			here.
+	 * @param synchronous	<i>true</i> if the job is synchronous,
+	 *                   	<i>false</i> otherwise.
+	 * @param params		List of all parameters provided by the user for the
+	 *              		execution.
 	 */
 	public TAPExecutionReport(final String jobID, final boolean synchronous, final TAPParameters params){
 		this.jobID = jobID;
@@ -74,14 +96,20 @@ public class TAPExecutionReport {
 	}
 
 	/**
-	 * <p>Map the execution progression with an index inside the {@link #durations} array.</p>
-	 * 
-	 * <p><i><b>Warning:</b> for the moment, only {@link ExecutionProgression#UPLOADING}, {@link ExecutionProgression#PARSING},
-	 * {@link ExecutionProgression#EXECUTING_ADQL} and {@link ExecutionProgression#WRITING_RESULT} are managed.</i></p>
-	 * 
+	 * Map the execution progression with an index inside the {@link #durations}
+	 * array.
+	 *
+	 * <p><i><b>Warning:</b>
+	 * 	for the moment, only {@link ExecutionProgression#UPLOADING},
+	 * 	{@link ExecutionProgression#PARSING},
+	 * 	{@link ExecutionProgression#EXECUTING_ADQL} and
+	 * 	{@link ExecutionProgression#WRITING_RESULT} are managed.
+	 * </i></p>
+	 *
 	 * @param tapProgression	Execution progression.
-	 * 
-	 * @return	Index in the array {@link #durations}, or -1 if the given execution progression is not managed.
+	 *
+	 * @return	Index in the array {@link #durations},
+	 *        	or -1 if the given execution progression is not managed.
 	 */
 	protected int getIndexDuration(final ExecutionProgression tapProgression){
 		switch(tapProgression){
@@ -100,11 +128,12 @@ public class TAPExecutionReport {
 
 	/**
 	 * Get the duration corresponding to the given job execution step.
-	 * 
+	 *
 	 * @param tapStep	Job execution step.
-	 * 
-	 * @return	The corresponding duration (in ms), or -1 if this step has not been (yet) processed.
-	 * 
+	 *
+	 * @return	The corresponding duration (in ms), or -1 if this step has not
+	 *        	been (yet) processed.
+	 *
 	 * @see #getIndexDuration(ExecutionProgression)
 	 */
 	public final long getDuration(final ExecutionProgression tapStep){
@@ -117,7 +146,7 @@ public class TAPExecutionReport {
 
 	/**
 	 * Set the duration corresponding to the given execution step.
-	 * 
+	 *
 	 * @param tapStep	Job execution step.
 	 * @param duration	Duration (in ms) of the given execution step.
 	 */
diff --git a/src/tap/config/ConfigurableServiceConnection.java b/src/tap/config/ConfigurableServiceConnection.java
index 09e2ce7dec8821ea0f727bb3e77edb88d06951fb..f9213925cdb9c52f54d6bc2d2cc779ecea78d577 100644
--- a/src/tap/config/ConfigurableServiceConnection.java
+++ b/src/tap/config/ConfigurableServiceConnection.java
@@ -16,13 +16,14 @@ package tap.config;
  * You should have received a copy of the GNU Lesser General Public License
  * along with TAPLibrary.  If not, see <http://www.gnu.org/licenses/>.
  *
- * Copyright 2016-2018 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ * Copyright 2016-2019 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
  *                       Astronomisches Rechen Institut (ARI)
  */
 
 import static tap.config.TAPConfiguration.DEFAULT_ASYNC_FETCH_SIZE;
 import static tap.config.TAPConfiguration.DEFAULT_DIRECTORY_PER_USER;
 import static tap.config.TAPConfiguration.DEFAULT_EXECUTION_DURATION;
+import static tap.config.TAPConfiguration.DEFAULT_FIX_ON_FAIL;
 import static tap.config.TAPConfiguration.DEFAULT_GROUP_USER_DIRECTORIES;
 import static tap.config.TAPConfiguration.DEFAULT_LOGGER;
 import static tap.config.TAPConfiguration.DEFAULT_MAX_ASYNC_JOBS;
@@ -39,6 +40,7 @@ import static tap.config.TAPConfiguration.KEY_DEFAULT_UPLOAD_LIMIT;
 import static tap.config.TAPConfiguration.KEY_DIRECTORY_PER_USER;
 import static tap.config.TAPConfiguration.KEY_FILE_MANAGER;
 import static tap.config.TAPConfiguration.KEY_FILE_ROOT_PATH;
+import static tap.config.TAPConfiguration.KEY_FIX_ON_FAIL;
 import static tap.config.TAPConfiguration.KEY_GEOMETRIES;
 import static tap.config.TAPConfiguration.KEY_GROUP_USER_DIRECTORIES;
 import static tap.config.TAPConfiguration.KEY_LOGGER;
@@ -126,15 +128,17 @@ import uws.service.file.UWSFileManager;
 import uws.service.log.UWSLog.LogLevel;
 
 /**
- * <p>Concrete implementation of {@link ServiceConnection}, fully parameterized with a TAP configuration file.</p>
+ * Concrete implementation of {@link ServiceConnection}, fully parameterized
+ * with a TAP configuration file.
  *
  * <p>
- * 	Every aspects of the TAP service are configured here. This instance is also creating the {@link TAPFactory} using the
- * 	TAP configuration file thanks to the implementation {@link ConfigurableTAPFactory}.
+ * 	Every aspects of the TAP service are configured here. This instance is also
+ * 	creating the {@link TAPFactory} using the TAP configuration file thanks to
+ * 	the implementation {@link ConfigurableTAPFactory}.
  * </p>
  *
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 2.3 (11/2018)
+ * @version 2.3 (03/2019)
  * @since 2.0
  */
 public final class ConfigurableServiceConnection implements ServiceConnection {
@@ -142,10 +146,12 @@ public final class ConfigurableServiceConnection implements ServiceConnection {
 	/** File manager to use in the TAP service. */
 	private UWSFileManager fileManager;
 
-	/** Object to use in the TAP service in order to log different types of messages (e.g. DEBUG, INFO, WARNING, ERROR, FATAL). */
+	/** Object to use in the TAP service in order to log different types of
+	 * messages (e.g. DEBUG, INFO, WARNING, ERROR, FATAL). */
 	private TAPLog logger;
 
-	/** Factory which can create different types of objects for the TAP service (e.g. database connection). */
+	/** Factory which can create different types of objects for the TAP service
+	 * (e.g. database connection). */
 	private TAPFactory tapFactory;
 
 	/** Object gathering all metadata of this TAP service. */
@@ -175,9 +181,11 @@ public final class ConfigurableServiceConnection implements ServiceConnection {
 	private final ArrayList<OutputFormat> outputFormats;
 
 	/** Array of 2 integers: resp. default and maximum output limit.
-	 * <em>Each limit is expressed in a unit specified in the array {@link #outputLimitTypes}.</em> */
+	 * <em>Each limit is expressed in a unit specified in the array
+	 * {@link #outputLimitTypes}.</em> */
 	private int[] outputLimits = new int[]{ -1, -1 };
-	/** Array of 2 limit units: resp. unit of the default output limit and unit of the maximum output limit. */
+	/** Array of 2 limit units: resp. unit of the default output limit and unit
+	 * of the maximum output limit. */
 	private LimitUnit[] outputLimitTypes = new LimitUnit[2];
 
 	/** Indicate whether the UPLOAD feature is enabled or not. */
@@ -201,20 +209,31 @@ public final class ConfigurableServiceConnection implements ServiceConnection {
 	private UserIdentifier userIdentifier = null;
 
 	/** List of all allowed coordinate systems.
-	 * <em>If NULL, all coord. sys. are allowed. If empty list, none is allowed.</em> */
+	 * <em>
+	 * 	If NULL, all coord. sys. are allowed. If empty list, none is allowed.
+	 * </em> */
 	private ArrayList<String> lstCoordSys = null;
 
 	/** List of all allowed ADQL geometrical functions.
-	 * <em>If NULL, all geometries are allowed. If empty list, none is allowed.</em> */
+	 * <em>
+	 * 	If NULL, all geometries are allowed. If empty list, none is allowed.
+	 * </em> */
 	private ArrayList<String> geometries = null;
 	private final String GEOMETRY_REGEXP = "(AREA|BOX|CENTROID|CIRCLE|CONTAINS|DISTANCE|COORD1|COORD2|COORDSYS|INTERSECTS|POINT|POLYGON|REGION)";
 
 	/** List of all known and allowed User Defined Functions.
-	 * <em>If NULL, any unknown function is allowed. If empty list, none is allowed.</em> */
+	 * <em>If NULL, any unknown function is allowed. If empty list, none is
+	 * allowed.</em> */
 	private Collection<FunctionDef> udfs = new ArrayList<FunctionDef>(0);
 
+	/** Indicate whether the input ADQL query should be automatically fixed
+	 * if its parsing fails because of an incorrect tokenization.
+	 * @since 2.3 */
+	private boolean isFixOnFailEnabled = DEFAULT_FIX_ON_FAIL;
+
 	/**
-	 * Create a TAP service description thanks to the given TAP configuration file.
+	 * Create a TAP service description thanks to the given TAP configuration
+	 * file.
 	 *
 	 * @param tapConfig	The content of the TAP configuration file.
 	 *
@@ -226,12 +245,15 @@ public final class ConfigurableServiceConnection implements ServiceConnection {
 	}
 
 	/**
-	 * Create a TAP service description thanks to the given TAP configuration file.
+	 * Create a TAP service description thanks to the given TAP configuration
+	 * file.
 	 *
 	 * @param tapConfig		The content of the TAP configuration file.
-	 * @param webAppRootDir	The directory of the Web Application running this TAP service.
-	 *                     	<em>In this directory another directory may be created in order to store all TAP service files
-	 *                     	if none is specified in the given TAP configuration file.</em>
+	 * @param webAppRootDir	The directory of the Web Application running this
+	 *                     	TAP service. <em>In this directory another directory
+	 *                     	may be created in order to store all TAP service
+	 *                     	files if none is specified in the given TAP
+	 *                     	configuration file.</em>
 	 *
 	 * @throws NullPointerException	If the given properties set is NULL.
 	 * @throws TAPException			If a property is wrong or missing.
@@ -284,6 +306,7 @@ public final class ConfigurableServiceConnection implements ServiceConnection {
 		initCoordSys(tapConfig);
 		initADQLGeometries(tapConfig);
 		initUDFs(tapConfig);
+		isFixOnFailEnabled = Boolean.parseBoolean(getProperty(tapConfig, KEY_FIX_ON_FAIL));
 	}
 
 	/**
@@ -1735,4 +1758,9 @@ public final class ConfigurableServiceConnection implements ServiceConnection {
 		return fetchSize;
 	}
 
+	@Override
+	public boolean fixOnFailEnabled(){
+		return isFixOnFailEnabled;
+	}
+
 }
diff --git a/src/tap/config/TAPConfiguration.java b/src/tap/config/TAPConfiguration.java
index fa350036313337edf60c54d9c739ae252830d13e..b8eeeeef95f017e6d2ef35b12ec0fc8c66fbe4f3 100644
--- a/src/tap/config/TAPConfiguration.java
+++ b/src/tap/config/TAPConfiguration.java
@@ -16,7 +16,7 @@ package tap.config;
  * You should have received a copy of the GNU Lesser General Public License
  * along with TAPLibrary.  If not, see <http://www.gnu.org/licenses/>.
  *
- * Copyright 2015-2018 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ * Copyright 2015-2019 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
  *                       Astronomisches Rechen Institut (ARI)
  */
 
@@ -41,7 +41,7 @@ import tap.backup.DefaultTAPBackupManager;
  * </i></p>
  *
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 2.3 (11/2018)
+ * @version 2.3 (03/2019)
  * @since 2.0
  */
 public final class TAPConfiguration {
@@ -172,6 +172,15 @@ public final class TAPConfiguration {
 	public final static String KEY_ASYNC_FETCH_SIZE = "async_fetch_size";
 	/** Default value of the property {@link #KEY_ASYNC_FETCH_SIZE}: {@value #DEFAULT_ASYNC_FETCH_SIZE}. */
 	public final static int DEFAULT_ASYNC_FETCH_SIZE = 10000;
+	/** Name/Key of the property specifying whether the fixOnFail option is
+	 * enabled or not. This option lets automatically fix the input ADQL query
+	 * if its tokenization fails.
+	 * @since 2.3  */
+	public final static String KEY_FIX_ON_FAIL = "fix_on_fail";
+	/** Default value of the property {@link #KEY_FIX_ON_FAIL}:
+	 * {@value #DEFAULT_FIX_ON_FAIL}.
+	 * @since 2.3  */
+	public final static boolean DEFAULT_FIX_ON_FAIL = false;
 	/** Name/Key of the property specifying the name of the DataSource into the JDNI. */
 	public final static String KEY_DATASOURCE_JNDI_NAME = "datasource_jndi_name";
 	/** Name/Key of the property specifying the full class name of the JDBC driver.
diff --git a/src/tap/config/tap_configuration_file.html b/src/tap/config/tap_configuration_file.html
index a5fedc4615a310d850d83a237b6ac0a8013a02fe..65e54ebb31051d58040eb49e2183db143ca64b20 100644
--- a/src/tap/config/tap_configuration_file.html
+++ b/src/tap/config/tap_configuration_file.html
@@ -212,6 +212,44 @@
 				</td>
 				<td><ul><li>10000 <em>(default)</em><li>0 <em>(wait for the the whole result)</em></li><li>1000000</li></ul></td>
 			</tr>
+			<tr class="optional">
+				<td class="done">fix_on_fail</td>
+				<td></td>
+				<td>boolean</td>
+				<td>
+					<p>If enabled, this option lets automatically try fixing a query whose parsing
+					failed because of a token error. This is particularly useful in the following
+					cases:</p>
+					<ul>
+						<li>when a column/table identifier/alias has an incorrect syntax
+							(e.g. <code>_RAJ2000</code>, <code>2mass</code>)</li>
+						<li>if the name of an ADQL function is used as a column/table identifier/alias
+							(e.g. <code>distance</code>, <code>point</code>, <code>min</code>)</li>
+						<li>if the name of a reserved SQL keyword is used as a column/table
+							identifier/alias
+							(e.g. <code>public</code>, <code>date</code>, <code>year</code>, <code>user</code>)</li>
+					</ul>
+					<p>In all these cases, the name/identifier/alias will be surrounded between
+					double quotes if the option <code>fix_on_fail</code> is enabled.</p>
+					<p>This feature is also able to fix some incorrect Unicode characters
+					(e.g. LaTeX alternatives for underscores, spaces and double/single quotes,
+					copy-pasted from a PDF into a TAP query field).</p>
+					<p><b>Warning:</b>
+						since this option alters the query provided by the query, it is
+						possible that, after fix attempt, the query parses and runs but might
+						generate an output different from what was expected. So, if this
+						option is enabled, it should made be clear to the user that the TAP
+						server might alter the query to make it work.
+					</p>
+					<p><i><b>Note:</b>
+						when an input query is fixed and run successfully, the fixed ADQL query
+						is reported in an INFO element named <code>QUERY_AFTER_AUTO_FIX</code> inside the
+						output VOTable.
+					</i></p>
+					<p><em>Default: <code>fix_on_fail=false</code></em></p>
+				</td>
+				<td><ul><li>false <em>(default)</em><li>true</li></ul></td>
+			</tr>
 			
 			<tr><td colspan="5">&#10551; JNDI datasource <i>(only if database_access=jndi)</i></td></tr>
 			<tr class="mandatory">
diff --git a/src/tap/config/tap_full.properties b/src/tap/config/tap_full.properties
index f6a410f1fa4ad978b9fafdb09394c5af7f7ed830..a80320fbb72ace17cf3f6ad83bc36bec2df65d7b 100644
--- a/src/tap/config/tap_full.properties
+++ b/src/tap/config/tap_full.properties
@@ -1,825 +1,858 @@
-################################################################################
-#                        FULL TAP CONFIGURATION FILE                           #
-#                                                                              #
-# TAP Version: 2.3                                                             #
-# Date: 13 Nov. 2018                                                           #
-# Author: Gregory Mantelet (CDS;ARI)                                           #
-#                                                                              #
-################################################################################ 
-
-###########
-# GENERAL #
-###########
-
-# [OPTIONAL]
-# This property lets set a custom home page.
-# 
-# 4 different kinds of value are accepted:
-#     * nothing (default): the default home page provided by the library (just
-#                          a simple HTML page displaying a list of all available
-#                          TAP resources).
-#     * name or relative path of a file: this method MUST be chosen if the new
-#                                        home page is a JSP file. This file MUST
-#                                        be inside the directory WebContent of
-#                                        your web application.
-#     * a URI starting with file://: in this method the local file pointed by
-#                                    the URI will be merely returned when the
-#                                    home page will be requested.
-#     * a URL: here, a redirection toward this URL will be made at each request
-#              on the home page
-#     * a class name: the class name of an extension of tap.resource.HomePage
-#                     which must replace the default home page resource. This
-#                     class MUST have at least one constructor with exactly one
-#                     parameter not NULL of type tap.resource.TAP.
-home_page = 
-
-# [OPTIONAL]
-# MIME type of the service home page.
-# 
-# This property is used only if the specified "home_page" is a local file path
-# (i.e. if "home_page=file://...").
-# 
-# If no value is provided "text/html" will be set by default.
-# 
-# Default: text/html
-home_page_mime_type = 
-
-############
-# PROVIDER #
-############
-
-# [OPTIONAL]
-# Name of the provider of the TAP Service.
-provider_name = CDS
-
-# [OPTIONAL]
-# Description of the TAP Service.
-service_description = My TAP Service is so amazing! You should use it with your favorite TAP client.
-
-############
-# DATABASE #
-############
-
-# [MANDATORY]
-# Method to use in order to create database connections.
-# 
-# Only two values are supported:
-#     * jndi: database connections will be supplied by a Datasource whose the
-#             JNDI name must be given. This method may propose connection
-#             pooling in function of the datasource configuration.
-#     * jdbc: the library will create itself connections when they will be
-#             needed thanks to the below JDBC parameters. This method does not
-#             propose any connection pooling.
-# 
-# Allowed values: jndi, jdbc.
-database_access = 
-
-# [MANDATORY]
-# The translator to use in order to translate ADQL to a SQL compatible with the
-# used DBMS and its spatial extension.
-# 
-# The TAP library supports only Postgresql (no spatial extension),
-# PostgreSQL+PgSphere, SQLServer (no spatial extension), MySQL (no spatial
-# extension) and H2 (no spatial extension) for the moment. But you can provide
-# your own SQL translator (even if it does not have spatial features), by
-# providing the name of a class (within brackets: {...}) that implements
-# ADQLTranslator (for instance: {apackage.MyADQLTranslator}) and which have at
-# least an empty constructor.
-# 
-# Allowed values: postgres, pgsphere, sqlserver, mysql, h2, a class name
-sql_translator = postgres
-
-# [OPTIONAL]
-# Size of result blocks to fetch from the database when a ADQL query is executed
-# in Synchronous mode.
-# 
-# Rather than fetching a query result in a whole, it may be possible to specify
-# to the database that results may be retrieved by blocks whose the size can be
-# specified with this property. If supported by the DBMS and the JDBC driver,
-# this feature may help sparing memory and avoid too much waiting time from the
-# TAP /sync users (and thus, avoiding some HTTP client timeouts).
-# 
-# A negative or null value means that the default value of the JDBC driver will
-# be used. Generally, it means that the database must wait to have collected all
-# data before sending them to the library.
-# 
-# Default: sync_fetch_size=10000
-sync_fetch_size = 1000
-
-# [OPTIONAL]
-# Size of result blocks to fetch from the database when an ADQL query is
-# executed in Asynchronous mode.
-# 
-# Rather than fetching a query result in a whole, it may be possible to specify
-# to the database that results may be retrieved by blocks whose the size can be
-# specified with this property. If supported by the DBMS and the JDBC driver,
-# this feature may help sparing memory.
-# 
-# A negative or null value means that the default value of the JDBC driver will
-# be used. Generally, it means that the database must wait to have collected all
-# data before sending them to the library.
-# 
-# Default: async_fetch_size=100000
-async_fetch_size=10000
-
-#############################
-# IF DATABASE ACCESS = JNDI #
-#############################
-
-# [MANDATORY]
-# JNDI name of the datasource pointing toward the database to use.
-# It should be defined in the web application (e.g. in the META-INF/context.xml
-# file in tomcat).
-datasource_jndi_name = 
-
-#############################
-# IF DATABASE ACCESS = JDBC #
-#############################
-
-# [MANDATORY]
-# JDBC driver URL pointing toward the database to use.
-# 
-# Note: The username, password or other parameters may be included in it, but
-#       in this case, the corresponding properties should leave empty or not
-#       provided at all.
-jdbc_url =  
-
-# [OPTIONAL]
-# JDBC driver path.
-# 
-# By default, it is guessed in function of the database name provided in the
-# jdbc_url property. It MUST be provided if another DBMS is used or if the
-# JDBC driver path does not match the following ones:
-#     * Oracle    : oracle.jdbc.OracleDriver
-#     * PostgreSQL: org.postgresql.Driver
-#     * MySQL     : com.mysql.jdbc.Driver
-#     * SQLite    : org.sqlite.JDBC
-#     * H2        : org.h2.Driver
-#jdbc_driver = 
-
-# [MANDATORY]
-# [Mandatory if the username is not already provided in jdbc_url]
-#
-# Username used to access to the database.
-db_username = 
-
-# [MANDATORY]
-# [Mandatory if the password is not already provided in jdbc_url]
-#
-# Password used by db_username to access to the database.
-# 
-# Note: No password encryption can be done in this configuration file for the
-#       moment.
-db_password = 
-
-############
-# METADATA #
-############
-
-# [MANDATORY]
-# Metadata fetching method.
-# 
-# The value of this key defines the way the library will get the list of all
-# schemas, tables and columns to publish and all their metadata (e.g. utype,
-# description, type, ...).
-# 
-# In its current state, the library proposes three methods:
-#    1/ Parse a TableSet XML document and load its content into the database
-#       schema TAP_SCHEMA (note: this schema is first erased and rebuilt by the
-#       library).
-#    2/ Get all metadata from the database schema TAP_SCHEMA.
-#    3/ Build yourself the metadata of your service by creating an extension of
-#       tap.metadata.TAPMetadata. This extension must have either an empty
-#       constructor or a constructor with exactly 3 parameters of type
-#       UWSFileManager, TAPFactory and TAPLog ; if both constructor are
-#       provided, only the one with parameters will be used.
-# 
-# For the two first methods, it is also possible to specify an extension of
-# tap.metadata.TAPMetadata which will wrap a default TAPMetadata objects created
-# using the specified methods (i.e. XML tableset or TAP_SCHEMA). In this way, it
-# is possible to get the "default" metadata from an XML file or the database
-# and then add/remove/modify some of them, or to change the output of the
-# 'tables' resource. The extension of tap.metadata.TAPMetadata must have at
-# least one constructor with the following parameters: (TAPMetadata) or
-# (TAPMetadata, UWSFileManager, TAPFactory, TAPLog).
-#  
-# Allowed values: xml, xml {myTAPMetadata}, db, db {myTAPMetadata}
-#                 or a full class name (between {}).
-metadata = 
-
-# [MANDATORY]
-# [Mandatory if the value of "metadata" is "xml".]
-#
-# Local file path to the TableSet XML document.
-#
-# The XML document must implement the schema TableSet defined by VODataService.
-# The file path must be either an absolute local file path or a file path
-# relative to WebContent (i.e. the web application directory in which there are
-# WEB-INF and META-INF).
-metadata_file =   
-
-# [OPTIONAL]
-# [ONLY USED IF metadata = db]
-#
-# Mapping between TAP_SCHEMA ADQL names and their names in the database.
-# 
-# Any property named exactly (case sensitive) like TAP_SCHEMA items will be
-# considered as a mapping between its ADQL name and its DB name.
-#
-# Examples: "TAP_SCHEMA = TAP_SCHEMA2"
-#           or "TAP_SCHEMA.columns.column_name = name"
-#
-# The property value MUST be NOT qualified. Just the item name is required.
-# The value will be used as provided (with the same case).
-#
-# Note:
-#     The column dbName in the database TAP_SCHEMA declaring the standard
-#     TAP_SCHEMA entries (e.g. TAP_SCHEMA.schemas.dbName) is now ignored. Thus,
-#     only the mapping defined here, in the configuration file, is taken into
-#     account.
-# 
-# TAP_SCHEMA = 
-
-#########
-# FILES #
-#########
-
-# [MANDATORY]
-# Type of the file manager.
-# 
-# Accepted values are: local (to manage files on the local system). You can also
-# add another way to manage files by providing the name (within brackets: {...})
-# of a class implementing TAPFileManager and having at least one constructor
-# with only a java.util.Properties parameter.
-# 
-# Allowed values: local, a class name.
-file_manager = local
-
-# [MANDATORY]
-# Local file path of the directory in which all TAP files (logs, errors, job
-# results, backup, ...) must be.
-# 
-# The file path must be either an absolute local directory path or a directory
-# path relative to WebContent (i.e. the web application directory in which there
-# are WEB-INF and META-INF).
-file_root_path = 
-
-# [OPTIONAL]
-# Tells whether a directory should be created for each user.
-# 
-# If yes, the user directory will be named with the user ID. In this directory,
-# there will be error files, job results and it may be the backup file of the
-# user.
-# 
-# Allowed values: true (default), false.
-directory_per_user = true
-
-# [OPTIONAL]
-# Tells whether user directories must be grouped.
-# 
-# If yes, directories are grouped by the first letter found in the user ID.
-# 
-# Allowed values: true (default), false.
-group_user_dir = true
-
-# [OPTIONAL]
-# The default period (in seconds) to keep query results.
-# 
-# The prefix "default" means here that this value is put by default by the TAP
-# Service if the client does not provide a value for it.
-# 
-# The default period MUST be less or equals to the maximum retention period. If
-# this rule is not respected, the default retention period is set immediately to
-# the maximum retention period.
-# 
-# A negative or null value means there is no restriction on the default
-# retention period: job results will be kept forever. Float values are not
-# allowed.
-# 
-# Default: 0 (results kept forever).
-default_retention_period = 0
-
-# [OPTIONAL]
-# The maximum period (in seconds) to keep query results.
-# 
-# The prefix "max" means here that the client can not set a retention period
-# greater than this one.
-# 
-# The maximum period MUST be greater or equals to the default retention period.
-# If this rule is not respected, the default retention period is set immediately
-# to the maximum retention period.
-# 
-# A negative or null value means there is no restriction on the maximum
-# retention period: the job results will be kept forever. Float values are not
-# allowed.
-# 
-# Default: 0 (results kept forever).
-max_retention_period = 0
-
-#############
-# LOG FILES #
-#############
-
-# [OPTIONAL]
-# Logging method to use.
-# 
-# Only two possibilities are already implemented.
-#
-#     * default: default logger provided by the library. Any logged message
-#                will be appended in the file 'service.log' inside the root
-#                directory of this service (cf property 'file_root_path').
-#
-#     * slf4j: wrapper for SLF4J (https://www.slf4j.org). All log messages will
-#              be forwarded to SLF4J. It is up to the implementor to add the
-#              suitable JAR files in the Java class-path. Exactly two JAR files
-#              are expected by SLF4J to work as expected:
-#                  - slf4j-api-{version}.jar (the main API)
-#                  - and the slf4j-{binding}-{version}.jar.
-#              Depending on the chosen SLF4J binding, you may also add another
-#              JAR file (e.g. Log4J, LogBack, ...) in the Java class-path.
-#              A configuration file might also be needed. There, it will be
-#              possible to configure the  the following loggers:
-#                  - "tap.service" (general/root purpose log),
-#                  - "tap.service.UWS" (UWS actions),
-#                  - "tap.service.HTTP" (HTTP requests and responses),
-#                  - "tap.service.JOB" (UWS's jobs actions),
-#                  - "tap.service.THREAD" (job's thread actions),
-#                  - "tap.service.TAP" (TAP actions)
-#                  - and "tap.service.DB" (DB actions).
-#
-#     * {...}: a custom logger. A class name MUST be provided
-#              (between {...}). The specified class must reference
-#              an implementation of tap.log.TAPLog. This implementation
-#              must have at least one constructor with a single parameter of
-#              type uws.service.file.UWSFileManager.
-# 
-# Default: 'default' (i.e. tap.log.DefaultTAPLog)
-logger = 
-
-# [OPTIONAL]
-# Minimum level that a message must have in order to be logged by the default
-# logger.
-#
-# 5 possible values:
-#     * DEBUG: every messages are logged.
-#     * INFO: every messages EXCEPT DEBUG are logged.
-#     * WARNING: every messages EXCEPT DEBUG and INFO are logged.
-#     * ERROR: only ERROR and FATAL messages are logged.
-#     * FATAL: only FATAL messages are logged.
-#
-# Note: this property is ignored if `logger != default`.
-#
-# Default: DEBUG (every messages are logged)
-min_log_level = 
-
-# [OPTIONAL]
-# Frequency of the log file rotation performed by the default logger.
-# That's to say, logs will be written in a new file after this period. This
-# avoid having too big log files. Old log files are renamed so that highlighting
-# its logging period.
-# 
-# The frequency string must respect the following syntax:
-#     'D' hh mm: daily schedule at hh:mm
-#     'W' dd hh mm: weekly schedule at the given day of the week
-#                   (1:sunday, 2:monday, ..., 7:saturday) at hh:mm
-#     'M' dd hh mm: monthly schedule at the given day of the month at hh:mm
-#     'h' mm: hourly schedule at the given minute
-#     'm': scheduled every minute (for completness :-))
-# 
-# Where: hh = integer between 0 and 23,
-#        mm = integer between 0 and 59,
-#        dd (for 'W') = integer between 1 and 7
-#        (1:sunday, 2:monday, ..., 7:saturday),
-#        dd (for 'M') = integer between 1 and 31.
-# 
-# Warning: The frequency type is case sensitive! Then you should particularly
-#          pay attention at the case when using the frequency types 'M'
-#          (monthly) and 'm' (every minute).
-# 
-# Note 1: this property is ignored if the file manager is not any more an
-#         extension of uws.service.file.LocalUWSFileManager.
-#
-# Note 2: this property is ignored if `logger != default`.
-# 
-# Default: D 0 0 (daily at midnight)
-log_rotation = 
-
-##############
-# UWS_BACKUP #
-##############
-
-# [OPTIONAL]
-# Frequency at which the UWS service (that's to say, all its users and jobs)
-# must be backuped.
-# 
-# Allowed values: never (no backup will never be done ; default), user_action
-#                 (each time a user does a writing action, like creating or
-#                 execution a job), a time (must be positive and not null) in
-#                 milliseconds.
-# 
-# The value user_action can be used ONLY IF backup_by_user=true.
-# 
-# Default: never
-backup_frequency = never
-
-# [OPTIONAL]
-# Tells whether the backup must be one file for every user (false), or one file
-# for each user (true). This second option should be chosen if your TAP Service
-# is organizing its files by user directories ; see the property
-# directory_per_user.
-# 
-# This option can be enabled ONLY IF a user identification method is provided ;
-# see property user_identifier.
-# 
-# Default: false
-backup_by_user = false
-
-#####################
-# ASYNCHRONOUS JOBS #
-#####################
-
-# [OPTIONAL]
-# Maximum number of asynchronous jobs that can run simultaneously.
-# 
-# A negative or null value means there is no restriction on the number of
-# running asynchronous jobs.
-# 
-# Default: there is no restriction => max_async_jobs=0.
-max_async_jobs = 0
-
-###################
-# QUERY_EXECUTION #
-###################
-
-# [OPTIONAL]
-# Default time (in milliseconds) for query execution.
-# 
-# The prefix "default" means here that the execution duration will be this one
-# if the client does not set one.
-# 
-# The default duration MUST be less or equals to the maximum execution duration.
-# If this rule is not respected, the default execution duration is set
-# immediately to the maximum execution duration.
-# 
-# A negative or null value means there is no restriction on the default
-# execution duration: the execution could never end. Float values are not
-# allowed.
-# 
-# Default: there is no restriction => default_execution_duration=0.
-default_execution_duration = 0
-
-# [OPTIONAL]
-# Maximum time (in milliseconds) for query execution.
-# 
-# The prefix "max" means here that the client can not set a time greater than
-# this one.
-# 
-# The maximum duration MUST be greater or equals to the default execution
-# duration. If this rule is not respected, the default execution duration is set
-# immediately to the maximum execution duration.
-# 
-# A negative or null value means there is no restriction on the maximum
-# execution duration: the execution could never end. Float values are not
-# allowed.
-# 
-# Default: there is no restriction => max_execution_duration=0.
-max_execution_duration = 0
-
-##########
-# OUTPUT #
-##########
-
-# [OPTIONAL]
-# Comma separated list of output formats for query results.
-# 
-# Allowed values are: votable (or 'vot'), fits, text, csv, tsv, json and html.
-# 
-# The VOTable format may be more detailed with the following syntax:
-# (serialization,version):mime_type:short_mime_type.
-# The MIME type part and the parameters part may be omitted
-# (e.g. votable:application/xml:votable , votable(td,1.3)]).
-# Empty string values are allowed for each values (e.g. votable():: ,
-# votable(td)::votable).
-#
-# The default VOTable format (i.e. serialization and version) is the one defined
-# with the short form `votable`. It is be default set to
-# `vot(binary,1.3)::votable` (see the special value `ALL` below). To change it
-# just define a VOTable format with the short form `votable`. 
-# 
-# It is also possible to define a custom Separated Value format, different from
-# CSV and TSV, thanks to the following syntax:
-# sv(separator):mime_type:short_mime_type. On the contrary to the VOTable
-# syntax, the parameter (i.e. separator) MUST BE provided. The MIME type part
-# may be omitted ; then the MIME type will be set by default to text/plain.
-# 
-# There is finally a last possible value: a class name of a class implementing
-# OutputFormat and having at least one constructor with exactly one parameter of
-# type tap.ServiceConnection.
-#
-# The special value "ALL" will select all formats provided by the library. It is
-# equivalent to the following:
-#  output_formats = vot(binary,1.3)::votable, vot(td,1.3)::votable/td,
-#                   vot(binary,1.3)::votable/b, vot(binary2,1.3)::votable/b2,
-#                   vot(fits,1.3)::votable/fits, fits, csv, tsv, text, html,
-#                   json
-# 
-# Default: ALL
-output_formats = ALL
-
-# [OPTIONAL]
-# Default limit for the result output.
-# 
-# The prefix "default" means here that this value will be set if the client does
-# not provide one.
-# 
-# This limit can be expressed in only one unit: rows.
-# 
-# A negative value means there is no restriction on this limit. Float values are
-# not allowed.
-# 
-# Obviously this limit MUST be less or equal than output_max_limit.
-# 
-# Default: there is no restriction: output_default_limit=-1
-output_default_limit = -1
-
-# [OPTIONAL]
-# Maximum limit for the result output. The prefix "max" means here that the
-# client can not set a limit greater than this one.
-# 
-# This limit can be expressed in only one unit: rows.
-# 
-# A negative value means there is no restriction on this limit. Float values are
-# not allowed.
-# 
-# Obviously this limit MUST be greater or equal than output_default_limit.
-# 
-# Default: there is no restriction => output_max_limit=-1
-output_max_limit = -1
-
-##########
-# UPLOAD #
-##########
-
-# [OPTIONAL]
-# Tells whether the Upload must be enabled.
-# 
-# If enabled, files can be uploaded in the file_root_path, the corresponding
-# tables can be added inside the UPLOAD_SCHEMA of the database, queried and then
-# deleted.
-#
-# NOTE: Before being stored in the directory file_root_path, it is first
-#       uploaded in the temporary directory (defined in the JVM ; generally
-#       `/tmp` on Unix system and `c:\temp` ; it can be changed at start of the
-#       JVM with the property `java.io.tmpdir`). When the upload is complete,
-#       the file is finally moved in file_root_path.
-# 
-# Allowed values: true, false (default).
-upload_enabled = false
-
-# [OPTIONAL]
-# Maximum limit for the number of uploaded records that can be inserted inside
-# the database.
-# 
-# This limit can be expressed with 2 types: rows or bytes. For rows, you just
-# have to suffix the value by a "r" (upper- or lower-case), with nothing (by
-# default, nothing will mean "rows"). For bytes, you have to suffix the numeric
-# value by "b", "kb", "Mb" or "Gb". Here, unit is case sensitive (except for the
-# last character: "b"). No other storage unit is allowed.
-# 
-# A negative value means there is no restriction on this limit. Float values are
-# not allowed.
-#
-# IMPORTANT NOTE: the specified limit will be checked at a different step of
-#                 a query processing in function of its unit.
-#                 If expressed in bytes, the file size will be checked when
-#                 uploading the file on disk. Thus, when the uploading file
-#                 starts to exceed the set limit, it will be no longer uploaded
-#                 and the whole request will be immediately rejected.
-#                 On the contrary, if the limit is expressed in rows, it will
-#                 be tested only when ingesting the whole uploaded file
-#                 (whatever is its size) in the database ; so, after it has been
-#                 uploaded. As soon as, the rows insertion in the database
-#                 exceeds the limit, the query is rejected.
-#                 Consequently, a very huge file could potentially be
-#                 completely uploaded before being rejected if this property is
-#                 expressed in rows. Then, it is very important to set the
-#                 property `upload_max_request_size` limiting the size of a
-#                 whole HTTP request in order to better preserve your machine
-#                 from running out of disk space.
-# 
-# Default: upload_max_db_limit=1000000r (i.e. 1 million rows)
-upload_max_db_limit = 1000000r
-
-
-# [OPTIONAL]
-# Maximum allowed size for a whole HTTP multipart request (i.e. request with
-# uploads).
-# 
-# This limit MUST be expressed in bytes. Thus, you have to suffix the numeric
-# value by "B", "kB", "MB" or "GB". Here, unit is case sensitive. No other
-# storage unit is allowed.
-# 
-# A negative value means there is no restriction on this limit. Float values are
-# not allowed.
-# 
-# Warning: It is highly recommended to set this property in order to prevent
-#          exceeding the disk storage space/quota (especially if
-#          `upload_max_db_limit` is not set or is set in rows). 
-# 
-# Default: upload_max_request_size=250MB
-upload_max_request_size = 250MB
-
-# [OPTIONAL ; DEPRECATED since v2.3]
-# Default limit for the number of uploaded records that can be inserted inside
-# the database.
-# 
-# This property is DEPRECATED. You should use `upload_max_db_limit` instead.
-# If it is set anyway, its value will be used as value for
-# `upload_max_db_limit` ONLY IF this latter is not set.
-# 
-# Default: upload_default_db_limit=-1 (i.e. unlimited)
-upload_default_db_limit = -1
-
-# [OPTIONAL ; DEPRECATED since v2.3]
-# Maximum allowed size for the uploaded file.
-# 
-# This property is DEPRECATED. You should use `upload_max_db_limit` with a value
-# expressed in bytes if you wanted to limit the size of each uploaded file, or
-# `upload_max_request_size` if your goal was to limit the input HTTP request
-# size. If it is set anyway, its value will be used as value for
-# `upload_max_request_size` ONLY IF this latter is not set.
-# 
-# Default: upload_max_file_size=-1 (i.e. unlimited)
-upload_max_file_size = -1
-
-#######################
-# USER IDENTIFICATION #
-#######################
-
-# [OPTIONAL]
-# Class to use in order to identify a user of the TAP service.
-# 
-# The same instance of this class will be used for every request sent to the
-# service.
-# 
-# The value of this property MUST be a class name (with brackets: {...}) of a
-# class implementing the interface uws.service.UserIdentifier. This class MUST
-# have one of its constructors with no parameter.
-# 
-# Default: no identification is performed => all users are then anonymous and
-#          their jobs can be seen by everybody.
-user_identifier = 
-
-######################
-# COORDINATE SYSTEMS #
-######################
-
-# [OPTIONAL]
-# Comma-separated list of all allowed coordinate systems.
-# 
-# Each item of the list be a kind of regular expression respecting the following
-# syntax: Frame RefPos Flavor. In other words, it must be a string of exactly 3
-# parts. Each of this part is a single value, a list of allowed values
-# or a * meaning all values. A list of values must be indicated between
-# parenthesis and values must be separated by a pipe.
-# 
-# Allowed values for Frame are: ICRS, FK4, FK5, J2000, ECLIPTIC, GALACTIC
-#                               and UNKNOWNFRAME.
-# Allowed values for RefPos are: BARYCENTER, GEOCENTER, HELIOCENTER, LSR,
-#                                TOPOCENTER, RELOCATABLE and UNKNOWNREFPOS.
-# Allowed values for Flavor are: CARTESIAN2, CARTESIAN3 and SPHERICAL2.
-# 
-# If the special value NONE is given instead of a list of allowed coordinate
-# systems, no coordinate system will be allowed. And if the list is empty, any
-# coordinate system will be allowed.
-# 
-# By default, any coordinate system is allowed.
-coordinate_systems = 
-
-##############
-# GEOMETRIES #
-##############
-
-# [OPTIONAL]
-# Comma-separated list of all allowed geometries.
-# 
-# Each item of the list must be the name (whatever is the case) of an ADQL
-# geometrical function (e.g. INTERSECTS, COORDSYS, POINT) to allow.
-# If the list is empty (no item), all functions are allowed. And if the special
-# value NONE is given, no ADQL function will be allowed.
-# 
-# Default: all ADQL geometrical functions are allowed.
-geometries = 
-
-#################################
-# USER DEFINED FUNCTIONS (UDFs) #
-#################################
-
-# [OPTIONAL]
-# Comma-separated list of all allowed UDFs (User Defined Functions).
-# 
-# Each item of the list must have the following syntax: [fct_signature],
-# [fct_signature, className] or [fct_signature, className, description].
-# fct_function is the function signature. Its syntax is the same as in
-# TAPRegExt. className is the name of a class extending UserDefinedFunction.
-# An instance of this class will replace any reference of a UDF written in an
-# ADQL function with the associated signature. A class name must be specified if
-# the function to represent has a signature (and more particularly a name)
-# different in ADQL and in SQL. description is the human description of the
-# function to be displayed in the /capabilities of the TAP service. It must be
-# written between double quotes.
-# 
-# Example: udfs = [ivo_healpix_index(hpxOrder integer, ra double, dec double)
-#                  -> bigint, {adql.query.operand.function.healpix.HealpixIndex}
-#                  , "Compute the index of the \"Healpix cell\" containing the
-#                     specified position at the given Healpix order."],
-#                 [trim(txt String) -> String],
-#                 [newFct(x double)-&gt;double, {apackage.MyNewFunction}],
-#                 [random() -> DOUBLE,,"Generate a random number."]
-# 
-# If the list is empty (no item), all unknown functions are forbidden. And if
-# the special value ANY is given, any unknown function is allowed ; consequently
-# the unknown ADQL functions will be translated into SQL as they are in ADQL.
-# 
-# Default: no unknown function is allowed.
-udfs = 
-
-########################
-# ADDITIONAL RESOURCES #
-########################
-
-# [OPTIONAL]
-# URL of the XSLT stylesheet to link with the XML output of /capabilities.
-# 
-# By default, no XSLT stylesheet is defined.
-capabilities_stylesheet = 
-
-# [OPTIONAL]
-# URL of the XSLT stylesheet to link with the XML output of /tables.
-# 
-# By default, no XSLT stylesheet is defined.
-tables_stylesheet = 
-
-# [OPTIONAL]
-# This property lets add an <code>/examples</code> endpoint by specifying an
-# XHTML-RDFa document listing TAP query examples using the syntax specified by
-# TAPNotes 1.0 DALI 1.0.
-# 
-# 3 different kinds of value are accepted:
-#     * nothing (default): no /examples endpoint.
-#     * name or relative path of a file: this method MUST be chosen if the
-#       endpoint content is a JSP file. This file MUST be inside the directory
-#       WebContent of your web application.
-#     * URI starting with file://: in this method the local file pointed by the
-#       URI will be merely returned when the endpoint will be requested.
-#     * a URL: here, a redirection toward this URL will be made at each request
-#       on the endpoint
-# 
-# If you want a custom /examples endpoint (i.e. you do not)
-# want to forward/redirect to a file/URL), you can create a class which
-# implements TAPResource AND VOSIResource. The function getName() must return
-# "examples". Then, just append the classpath to the property
-# "additional_resources" of the TAP configuration file.
-# 
-# By default, the TAP service does not have any <code>/examples</code> endpoint.
-examples = 
-
-# [OPTIONAL]
-# Comma-separated list of additional TAP resources/end-point.
-# 
-# By default, the following standard TAP resources are already existing: /sync,
-# /async, /tables, /capabilities and /availability. With this property, you can
-# add a custom resource to your TAP service (e.g. /adqlValidator, /admin).
-# 
-# Each item of the list MUST be the name of a class implementing
-# tap.resource.TAPResource. This class MUST have at least one constructor with
-# exactly one parameter of type tap.resource.TAP.
-# 
-# The string returned by tap.resource.TAPResource.getName() will be the
-# resource name, following the root TAP service URL (e.g. if getName() returns
-# "foo", then its access URL will "{tapRoot}/foo"). Then, it is possible to
-# replace TAP resources already existing by using the same name (e.g. if
-# getName() returns "sync", the /sync resource won't be anymore the default Sync
-# resource of this library but your new resource).
-# 
-# By default, this list is empty ; only the standard TAP resources exist.
-additional_resources = 
-
-######################
-# CUSTOM TAP_FACTORY #
-######################
-
-# [OPTIONAL]
-# Class to use in replacement of the default TAPFactory.
-# 
-# This property must be a class name (given between {...}). It must reference an
-# implementation of TAPFactory. This implementation must have at least one
-# constructor with exactly one parameter of type ServiceConnection.
-# 
-# It is recommended to extend an existing implementation such as:
-# tap.AbstractTAPFactory or tap.config.ConfigurableTAPFactory.
-# 
-# By default, the default TAPFactory (tap.config.ConfigurableTAPFactory) is used
-# and may use all properties related to the backup management, the database
-# access, the TAP_SCHEMA mapping and the ADQL translation.
-tap_factory = 
+################################################################################
+#                        FULL TAP CONFIGURATION FILE                           #
+#                                                                              #
+# TAP Version: 2.3                                                             #
+# Date: 20 March. 2019                                                         #
+# Author: Gregory Mantelet (CDS;ARI)                                           #
+#                                                                              #
+################################################################################ 
+
+###########
+# GENERAL #
+###########
+
+# [OPTIONAL]
+# This property lets set a custom home page.
+# 
+# 4 different kinds of value are accepted:
+#     * nothing (default): the default home page provided by the library (just
+#                          a simple HTML page displaying a list of all available
+#                          TAP resources).
+#     * name or relative path of a file: this method MUST be chosen if the new
+#                                        home page is a JSP file. This file MUST
+#                                        be inside the directory WebContent of
+#                                        your web application.
+#     * a URI starting with file://: in this method the local file pointed by
+#                                    the URI will be merely returned when the
+#                                    home page will be requested.
+#     * a URL: here, a redirection toward this URL will be made at each request
+#              on the home page
+#     * a class name: the class name of an extension of tap.resource.HomePage
+#                     which must replace the default home page resource. This
+#                     class MUST have at least one constructor with exactly one
+#                     parameter not NULL of type tap.resource.TAP.
+home_page = 
+
+# [OPTIONAL]
+# MIME type of the service home page.
+# 
+# This property is used only if the specified "home_page" is a local file path
+# (i.e. if "home_page=file://...").
+# 
+# If no value is provided "text/html" will be set by default.
+# 
+# Default: text/html
+home_page_mime_type = 
+
+############
+# PROVIDER #
+############
+
+# [OPTIONAL]
+# Name of the provider of the TAP Service.
+provider_name = CDS
+
+# [OPTIONAL]
+# Description of the TAP Service.
+service_description = My TAP Service is so amazing! You should use it with your favorite TAP client.
+
+############
+# DATABASE #
+############
+
+# [MANDATORY]
+# Method to use in order to create database connections.
+# 
+# Only two values are supported:
+#     * jndi: database connections will be supplied by a Datasource whose the
+#             JNDI name must be given. This method may propose connection
+#             pooling in function of the datasource configuration.
+#     * jdbc: the library will create itself connections when they will be
+#             needed thanks to the below JDBC parameters. This method does not
+#             propose any connection pooling.
+# 
+# Allowed values: jndi, jdbc.
+database_access = 
+
+# [MANDATORY]
+# The translator to use in order to translate ADQL to a SQL compatible with the
+# used DBMS and its spatial extension.
+# 
+# The TAP library supports only Postgresql (no spatial extension),
+# PostgreSQL+PgSphere, SQLServer (no spatial extension), MySQL (no spatial
+# extension) and H2 (no spatial extension) for the moment. But you can provide
+# your own SQL translator (even if it does not have spatial features), by
+# providing the name of a class (within brackets: {...}) that implements
+# ADQLTranslator (for instance: {apackage.MyADQLTranslator}) and which have at
+# least an empty constructor.
+# 
+# Allowed values: postgres, pgsphere, sqlserver, mysql, h2, a class name
+sql_translator = postgres
+
+# [OPTIONAL]
+# Size of result blocks to fetch from the database when a ADQL query is executed
+# in Synchronous mode.
+# 
+# Rather than fetching a query result in a whole, it may be possible to specify
+# to the database that results may be retrieved by blocks whose the size can be
+# specified with this property. If supported by the DBMS and the JDBC driver,
+# this feature may help sparing memory and avoid too much waiting time from the
+# TAP /sync users (and thus, avoiding some HTTP client timeouts).
+# 
+# A negative or null value means that the default value of the JDBC driver will
+# be used. Generally, it means that the database must wait to have collected all
+# data before sending them to the library.
+# 
+# Default: sync_fetch_size=10000
+sync_fetch_size = 1000
+
+# [OPTIONAL]
+# Size of result blocks to fetch from the database when an ADQL query is
+# executed in Asynchronous mode.
+# 
+# Rather than fetching a query result in a whole, it may be possible to specify
+# to the database that results may be retrieved by blocks whose the size can be
+# specified with this property. If supported by the DBMS and the JDBC driver,
+# this feature may help sparing memory.
+# 
+# A negative or null value means that the default value of the JDBC driver will
+# be used. Generally, it means that the database must wait to have collected all
+# data before sending them to the library.
+# 
+# Default: async_fetch_size=100000
+async_fetch_size = 10000
+
+# [OPTIONAL]
+# If enabled, this option lets automatically try fixing a query whose parsing
+# failed because of a token error. This is particularly useful in the following
+# cases:
+#
+#   - when a column/table identifier/alias has an incorrect syntax
+#     (e.g. `_RAJ2000`, `2mass`)
+#   - if the name of an ADQL function is used as a column/table identifier/alias
+#     (e.g. `distance`, `point`, `min`)
+#   - if the name of a reserved SQL keyword is used as a column/table
+#     identifier/alias
+#     (e.g. `public`, `date`, `year`, `user`)
+# 
+# In all these cases, the name/identifier/alias will be surrounded between
+# double quotes if the option `fix_on_fail` is enabled.
+#
+# This feature is also able to fix some incorrect Unicode characters
+# (e.g. LaTeX alternatives for underscores, spaces and double/single quotes,
+#  copy-pasted from a PDF into a TAP query field).
+#
+# Warning: since this option alters the query provided by the query, it is
+#          possible that, after fix attempt, the query parses and runs but might
+#          generate an output different from what was expected. So, if this
+#          option is enabled, it should made be clear to the user that the TAP
+#          server might alter the query to make it work.
+#
+# Note: when an input query is fixed and run successfully, the fixed ADQL query
+#       is reported in an INFO element named `QUERY_AFTER_AUTO_FIX` inside the
+#       output VOTable.
+#
+# Default: fix_on_fail=false
+fix_on_fail = false
+
+#############################
+# IF DATABASE ACCESS = JNDI #
+#############################
+
+# [MANDATORY]
+# JNDI name of the datasource pointing toward the database to use.
+# It should be defined in the web application (e.g. in the META-INF/context.xml
+# file in tomcat).
+datasource_jndi_name = 
+
+#############################
+# IF DATABASE ACCESS = JDBC #
+#############################
+
+# [MANDATORY]
+# JDBC driver URL pointing toward the database to use.
+# 
+# Note: The username, password or other parameters may be included in it, but
+#       in this case, the corresponding properties should leave empty or not
+#       provided at all.
+jdbc_url =  
+
+# [OPTIONAL]
+# JDBC driver path.
+# 
+# By default, it is guessed in function of the database name provided in the
+# jdbc_url property. It MUST be provided if another DBMS is used or if the
+# JDBC driver path does not match the following ones:
+#     * Oracle    : oracle.jdbc.OracleDriver
+#     * PostgreSQL: org.postgresql.Driver
+#     * MySQL     : com.mysql.jdbc.Driver
+#     * SQLite    : org.sqlite.JDBC
+#     * H2        : org.h2.Driver
+#jdbc_driver = 
+
+# [MANDATORY]
+# [Mandatory if the username is not already provided in jdbc_url]
+#
+# Username used to access to the database.
+db_username = 
+
+# [MANDATORY]
+# [Mandatory if the password is not already provided in jdbc_url]
+#
+# Password used by db_username to access to the database.
+# 
+# Note: No password encryption can be done in this configuration file for the
+#       moment.
+db_password = 
+
+############
+# METADATA #
+############
+
+# [MANDATORY]
+# Metadata fetching method.
+# 
+# The value of this key defines the way the library will get the list of all
+# schemas, tables and columns to publish and all their metadata (e.g. utype,
+# description, type, ...).
+# 
+# In its current state, the library proposes three methods:
+#    1/ Parse a TableSet XML document and load its content into the database
+#       schema TAP_SCHEMA (note: this schema is first erased and rebuilt by the
+#       library).
+#    2/ Get all metadata from the database schema TAP_SCHEMA.
+#    3/ Build yourself the metadata of your service by creating an extension of
+#       tap.metadata.TAPMetadata. This extension must have either an empty
+#       constructor or a constructor with exactly 3 parameters of type
+#       UWSFileManager, TAPFactory and TAPLog ; if both constructor are
+#       provided, only the one with parameters will be used.
+# 
+# For the two first methods, it is also possible to specify an extension of
+# tap.metadata.TAPMetadata which will wrap a default TAPMetadata objects created
+# using the specified methods (i.e. XML tableset or TAP_SCHEMA). In this way, it
+# is possible to get the "default" metadata from an XML file or the database
+# and then add/remove/modify some of them, or to change the output of the
+# 'tables' resource. The extension of tap.metadata.TAPMetadata must have at
+# least one constructor with the following parameters: (TAPMetadata) or
+# (TAPMetadata, UWSFileManager, TAPFactory, TAPLog).
+#  
+# Allowed values: xml, xml {myTAPMetadata}, db, db {myTAPMetadata}
+#                 or a full class name (between {}).
+metadata = 
+
+# [MANDATORY]
+# [Mandatory if the value of "metadata" is "xml".]
+#
+# Local file path to the TableSet XML document.
+#
+# The XML document must implement the schema TableSet defined by VODataService.
+# The file path must be either an absolute local file path or a file path
+# relative to WebContent (i.e. the web application directory in which there are
+# WEB-INF and META-INF).
+metadata_file =   
+
+# [OPTIONAL]
+# [ONLY USED IF metadata = db]
+#
+# Mapping between TAP_SCHEMA ADQL names and their names in the database.
+# 
+# Any property named exactly (case sensitive) like TAP_SCHEMA items will be
+# considered as a mapping between its ADQL name and its DB name.
+#
+# Examples: "TAP_SCHEMA = TAP_SCHEMA2"
+#           or "TAP_SCHEMA.columns.column_name = name"
+#
+# The property value MUST be NOT qualified. Just the item name is required.
+# The value will be used as provided (with the same case).
+#
+# Note:
+#     The column dbName in the database TAP_SCHEMA declaring the standard
+#     TAP_SCHEMA entries (e.g. TAP_SCHEMA.schemas.dbName) is now ignored. Thus,
+#     only the mapping defined here, in the configuration file, is taken into
+#     account.
+# 
+# TAP_SCHEMA = 
+
+#########
+# FILES #
+#########
+
+# [MANDATORY]
+# Type of the file manager.
+# 
+# Accepted values are: local (to manage files on the local system). You can also
+# add another way to manage files by providing the name (within brackets: {...})
+# of a class implementing TAPFileManager and having at least one constructor
+# with only a java.util.Properties parameter.
+# 
+# Allowed values: local, a class name.
+file_manager = local
+
+# [MANDATORY]
+# Local file path of the directory in which all TAP files (logs, errors, job
+# results, backup, ...) must be.
+# 
+# The file path must be either an absolute local directory path or a directory
+# path relative to WebContent (i.e. the web application directory in which there
+# are WEB-INF and META-INF).
+file_root_path = 
+
+# [OPTIONAL]
+# Tells whether a directory should be created for each user.
+# 
+# If yes, the user directory will be named with the user ID. In this directory,
+# there will be error files, job results and it may be the backup file of the
+# user.
+# 
+# Allowed values: true (default), false.
+directory_per_user = true
+
+# [OPTIONAL]
+# Tells whether user directories must be grouped.
+# 
+# If yes, directories are grouped by the first letter found in the user ID.
+# 
+# Allowed values: true (default), false.
+group_user_dir = true
+
+# [OPTIONAL]
+# The default period (in seconds) to keep query results.
+# 
+# The prefix "default" means here that this value is put by default by the TAP
+# Service if the client does not provide a value for it.
+# 
+# The default period MUST be less or equals to the maximum retention period. If
+# this rule is not respected, the default retention period is set immediately to
+# the maximum retention period.
+# 
+# A negative or null value means there is no restriction on the default
+# retention period: job results will be kept forever. Float values are not
+# allowed.
+# 
+# Default: 0 (results kept forever).
+default_retention_period = 0
+
+# [OPTIONAL]
+# The maximum period (in seconds) to keep query results.
+# 
+# The prefix "max" means here that the client can not set a retention period
+# greater than this one.
+# 
+# The maximum period MUST be greater or equals to the default retention period.
+# If this rule is not respected, the default retention period is set immediately
+# to the maximum retention period.
+# 
+# A negative or null value means there is no restriction on the maximum
+# retention period: the job results will be kept forever. Float values are not
+# allowed.
+# 
+# Default: 0 (results kept forever).
+max_retention_period = 0
+
+#############
+# LOG FILES #
+#############
+
+# [OPTIONAL]
+# Logging method to use.
+# 
+# Only two possibilities are already implemented.
+#
+#     * default: default logger provided by the library. Any logged message
+#                will be appended in the file 'service.log' inside the root
+#                directory of this service (cf property 'file_root_path').
+#
+#     * slf4j: wrapper for SLF4J (https://www.slf4j.org). All log messages will
+#              be forwarded to SLF4J. It is up to the implementor to add the
+#              suitable JAR files in the Java class-path. Exactly two JAR files
+#              are expected by SLF4J to work as expected:
+#                  - slf4j-api-{version}.jar (the main API)
+#                  - and the slf4j-{binding}-{version}.jar.
+#              Depending on the chosen SLF4J binding, you may also add another
+#              JAR file (e.g. Log4J, LogBack, ...) in the Java class-path.
+#              A configuration file might also be needed. There, it will be
+#              possible to configure the  the following loggers:
+#                  - "tap.service" (general/root purpose log),
+#                  - "tap.service.UWS" (UWS actions),
+#                  - "tap.service.HTTP" (HTTP requests and responses),
+#                  - "tap.service.JOB" (UWS's jobs actions),
+#                  - "tap.service.THREAD" (job's thread actions),
+#                  - "tap.service.TAP" (TAP actions)
+#                  - and "tap.service.DB" (DB actions).
+#
+#     * {...}: a custom logger. A class name MUST be provided
+#              (between {...}). The specified class must reference
+#              an implementation of tap.log.TAPLog. This implementation
+#              must have at least one constructor with a single parameter of
+#              type uws.service.file.UWSFileManager.
+# 
+# Default: 'default' (i.e. tap.log.DefaultTAPLog)
+logger = 
+
+# [OPTIONAL]
+# Minimum level that a message must have in order to be logged by the default
+# logger.
+#
+# 5 possible values:
+#     * DEBUG: every messages are logged.
+#     * INFO: every messages EXCEPT DEBUG are logged.
+#     * WARNING: every messages EXCEPT DEBUG and INFO are logged.
+#     * ERROR: only ERROR and FATAL messages are logged.
+#     * FATAL: only FATAL messages are logged.
+#
+# Note: this property is ignored if `logger != default`.
+#
+# Default: DEBUG (every messages are logged)
+min_log_level = 
+
+# [OPTIONAL]
+# Frequency of the log file rotation performed by the default logger.
+# That's to say, logs will be written in a new file after this period. This
+# avoid having too big log files. Old log files are renamed so that highlighting
+# its logging period.
+# 
+# The frequency string must respect the following syntax:
+#     'D' hh mm: daily schedule at hh:mm
+#     'W' dd hh mm: weekly schedule at the given day of the week
+#                   (1:sunday, 2:monday, ..., 7:saturday) at hh:mm
+#     'M' dd hh mm: monthly schedule at the given day of the month at hh:mm
+#     'h' mm: hourly schedule at the given minute
+#     'm': scheduled every minute (for completness :-))
+# 
+# Where: hh = integer between 0 and 23,
+#        mm = integer between 0 and 59,
+#        dd (for 'W') = integer between 1 and 7
+#        (1:sunday, 2:monday, ..., 7:saturday),
+#        dd (for 'M') = integer between 1 and 31.
+# 
+# Warning: The frequency type is case sensitive! Then you should particularly
+#          pay attention at the case when using the frequency types 'M'
+#          (monthly) and 'm' (every minute).
+# 
+# Note 1: this property is ignored if the file manager is not any more an
+#         extension of uws.service.file.LocalUWSFileManager.
+#
+# Note 2: this property is ignored if `logger != default`.
+# 
+# Default: D 0 0 (daily at midnight)
+log_rotation = 
+
+##############
+# UWS_BACKUP #
+##############
+
+# [OPTIONAL]
+# Frequency at which the UWS service (that's to say, all its users and jobs)
+# must be backuped.
+# 
+# Allowed values: never (no backup will never be done ; default), user_action
+#                 (each time a user does a writing action, like creating or
+#                 execution a job), a time (must be positive and not null) in
+#                 milliseconds.
+# 
+# The value user_action can be used ONLY IF backup_by_user=true.
+# 
+# Default: never
+backup_frequency = never
+
+# [OPTIONAL]
+# Tells whether the backup must be one file for every user (false), or one file
+# for each user (true). This second option should be chosen if your TAP Service
+# is organizing its files by user directories ; see the property
+# directory_per_user.
+# 
+# This option can be enabled ONLY IF a user identification method is provided ;
+# see property user_identifier.
+# 
+# Default: false
+backup_by_user = false
+
+#####################
+# ASYNCHRONOUS JOBS #
+#####################
+
+# [OPTIONAL]
+# Maximum number of asynchronous jobs that can run simultaneously.
+# 
+# A negative or null value means there is no restriction on the number of
+# running asynchronous jobs.
+# 
+# Default: there is no restriction => max_async_jobs=0.
+max_async_jobs = 0
+
+###################
+# QUERY_EXECUTION #
+###################
+
+# [OPTIONAL]
+# Default time (in milliseconds) for query execution.
+# 
+# The prefix "default" means here that the execution duration will be this one
+# if the client does not set one.
+# 
+# The default duration MUST be less or equals to the maximum execution duration.
+# If this rule is not respected, the default execution duration is set
+# immediately to the maximum execution duration.
+# 
+# A negative or null value means there is no restriction on the default
+# execution duration: the execution could never end. Float values are not
+# allowed.
+# 
+# Default: there is no restriction => default_execution_duration=0.
+default_execution_duration = 0
+
+# [OPTIONAL]
+# Maximum time (in milliseconds) for query execution.
+# 
+# The prefix "max" means here that the client can not set a time greater than
+# this one.
+# 
+# The maximum duration MUST be greater or equals to the default execution
+# duration. If this rule is not respected, the default execution duration is set
+# immediately to the maximum execution duration.
+# 
+# A negative or null value means there is no restriction on the maximum
+# execution duration: the execution could never end. Float values are not
+# allowed.
+# 
+# Default: there is no restriction => max_execution_duration=0.
+max_execution_duration = 0
+
+##########
+# OUTPUT #
+##########
+
+# [OPTIONAL]
+# Comma separated list of output formats for query results.
+# 
+# Allowed values are: votable (or 'vot'), fits, text, csv, tsv, json and html.
+# 
+# The VOTable format may be more detailed with the following syntax:
+# (serialization,version):mime_type:short_mime_type.
+# The MIME type part and the parameters part may be omitted
+# (e.g. votable:application/xml:votable , votable(td,1.3)]).
+# Empty string values are allowed for each values (e.g. votable():: ,
+# votable(td)::votable).
+#
+# The default VOTable format (i.e. serialization and version) is the one defined
+# with the short form `votable`. It is be default set to
+# `vot(binary,1.3)::votable` (see the special value `ALL` below). To change it
+# just define a VOTable format with the short form `votable`. 
+# 
+# It is also possible to define a custom Separated Value format, different from
+# CSV and TSV, thanks to the following syntax:
+# sv(separator):mime_type:short_mime_type. On the contrary to the VOTable
+# syntax, the parameter (i.e. separator) MUST BE provided. The MIME type part
+# may be omitted ; then the MIME type will be set by default to text/plain.
+# 
+# There is finally a last possible value: a class name of a class implementing
+# OutputFormat and having at least one constructor with exactly one parameter of
+# type tap.ServiceConnection.
+#
+# The special value "ALL" will select all formats provided by the library. It is
+# equivalent to the following:
+#  output_formats = vot(binary,1.3)::votable, vot(td,1.3)::votable/td,
+#                   vot(binary,1.3)::votable/b, vot(binary2,1.3)::votable/b2,
+#                   vot(fits,1.3)::votable/fits, fits, csv, tsv, text, html,
+#                   json
+# 
+# Default: ALL
+output_formats = ALL
+
+# [OPTIONAL]
+# Default limit for the result output.
+# 
+# The prefix "default" means here that this value will be set if the client does
+# not provide one.
+# 
+# This limit can be expressed in only one unit: rows.
+# 
+# A negative value means there is no restriction on this limit. Float values are
+# not allowed.
+# 
+# Obviously this limit MUST be less or equal than output_max_limit.
+# 
+# Default: there is no restriction: output_default_limit=-1
+output_default_limit = -1
+
+# [OPTIONAL]
+# Maximum limit for the result output. The prefix "max" means here that the
+# client can not set a limit greater than this one.
+# 
+# This limit can be expressed in only one unit: rows.
+# 
+# A negative value means there is no restriction on this limit. Float values are
+# not allowed.
+# 
+# Obviously this limit MUST be greater or equal than output_default_limit.
+# 
+# Default: there is no restriction => output_max_limit=-1
+output_max_limit = -1
+
+##########
+# UPLOAD #
+##########
+
+# [OPTIONAL]
+# Tells whether the Upload must be enabled.
+# 
+# If enabled, files can be uploaded in the file_root_path, the corresponding
+# tables can be added inside the UPLOAD_SCHEMA of the database, queried and then
+# deleted.
+#
+# NOTE: Before being stored in the directory file_root_path, it is first
+#       uploaded in the temporary directory (defined in the JVM ; generally
+#       `/tmp` on Unix system and `c:\temp` ; it can be changed at start of the
+#       JVM with the property `java.io.tmpdir`). When the upload is complete,
+#       the file is finally moved in file_root_path.
+# 
+# Allowed values: true, false (default).
+upload_enabled = false
+
+# [OPTIONAL]
+# Maximum limit for the number of uploaded records that can be inserted inside
+# the database.
+# 
+# This limit can be expressed with 2 types: rows or bytes. For rows, you just
+# have to suffix the value by a "r" (upper- or lower-case), with nothing (by
+# default, nothing will mean "rows"). For bytes, you have to suffix the numeric
+# value by "b", "kb", "Mb" or "Gb". Here, unit is case sensitive (except for the
+# last character: "b"). No other storage unit is allowed.
+# 
+# A negative value means there is no restriction on this limit. Float values are
+# not allowed.
+#
+# IMPORTANT NOTE: the specified limit will be checked at a different step of
+#                 a query processing in function of its unit.
+#                 If expressed in bytes, the file size will be checked when
+#                 uploading the file on disk. Thus, when the uploading file
+#                 starts to exceed the set limit, it will be no longer uploaded
+#                 and the whole request will be immediately rejected.
+#                 On the contrary, if the limit is expressed in rows, it will
+#                 be tested only when ingesting the whole uploaded file
+#                 (whatever is its size) in the database ; so, after it has been
+#                 uploaded. As soon as, the rows insertion in the database
+#                 exceeds the limit, the query is rejected.
+#                 Consequently, a very huge file could potentially be
+#                 completely uploaded before being rejected if this property is
+#                 expressed in rows. Then, it is very important to set the
+#                 property `upload_max_request_size` limiting the size of a
+#                 whole HTTP request in order to better preserve your machine
+#                 from running out of disk space.
+# 
+# Default: upload_max_db_limit=1000000r (i.e. 1 million rows)
+upload_max_db_limit = 1000000r
+
+
+# [OPTIONAL]
+# Maximum allowed size for a whole HTTP multipart request (i.e. request with
+# uploads).
+# 
+# This limit MUST be expressed in bytes. Thus, you have to suffix the numeric
+# value by "B", "kB", "MB" or "GB". Here, unit is case sensitive. No other
+# storage unit is allowed.
+# 
+# A negative value means there is no restriction on this limit. Float values are
+# not allowed.
+# 
+# Warning: It is highly recommended to set this property in order to prevent
+#          exceeding the disk storage space/quota (especially if
+#          `upload_max_db_limit` is not set or is set in rows). 
+# 
+# Default: upload_max_request_size=250MB
+upload_max_request_size = 250MB
+
+# [OPTIONAL ; DEPRECATED since v2.3]
+# Default limit for the number of uploaded records that can be inserted inside
+# the database.
+# 
+# This property is DEPRECATED. You should use `upload_max_db_limit` instead.
+# If it is set anyway, its value will be used as value for
+# `upload_max_db_limit` ONLY IF this latter is not set.
+# 
+# Default: upload_default_db_limit=-1 (i.e. unlimited)
+upload_default_db_limit = -1
+
+# [OPTIONAL ; DEPRECATED since v2.3]
+# Maximum allowed size for the uploaded file.
+# 
+# This property is DEPRECATED. You should use `upload_max_db_limit` with a value
+# expressed in bytes if you wanted to limit the size of each uploaded file, or
+# `upload_max_request_size` if your goal was to limit the input HTTP request
+# size. If it is set anyway, its value will be used as value for
+# `upload_max_request_size` ONLY IF this latter is not set.
+# 
+# Default: upload_max_file_size=-1 (i.e. unlimited)
+upload_max_file_size = -1
+
+#######################
+# USER IDENTIFICATION #
+#######################
+
+# [OPTIONAL]
+# Class to use in order to identify a user of the TAP service.
+# 
+# The same instance of this class will be used for every request sent to the
+# service.
+# 
+# The value of this property MUST be a class name (with brackets: {...}) of a
+# class implementing the interface uws.service.UserIdentifier. This class MUST
+# have one of its constructors with no parameter.
+# 
+# Default: no identification is performed => all users are then anonymous and
+#          their jobs can be seen by everybody.
+user_identifier = 
+
+######################
+# COORDINATE SYSTEMS #
+######################
+
+# [OPTIONAL]
+# Comma-separated list of all allowed coordinate systems.
+# 
+# Each item of the list be a kind of regular expression respecting the following
+# syntax: Frame RefPos Flavor. In other words, it must be a string of exactly 3
+# parts. Each of this part is a single value, a list of allowed values
+# or a * meaning all values. A list of values must be indicated between
+# parenthesis and values must be separated by a pipe.
+# 
+# Allowed values for Frame are: ICRS, FK4, FK5, J2000, ECLIPTIC, GALACTIC
+#                               and UNKNOWNFRAME.
+# Allowed values for RefPos are: BARYCENTER, GEOCENTER, HELIOCENTER, LSR,
+#                                TOPOCENTER, RELOCATABLE and UNKNOWNREFPOS.
+# Allowed values for Flavor are: CARTESIAN2, CARTESIAN3 and SPHERICAL2.
+# 
+# If the special value NONE is given instead of a list of allowed coordinate
+# systems, no coordinate system will be allowed. And if the list is empty, any
+# coordinate system will be allowed.
+# 
+# By default, any coordinate system is allowed.
+coordinate_systems = 
+
+##############
+# GEOMETRIES #
+##############
+
+# [OPTIONAL]
+# Comma-separated list of all allowed geometries.
+# 
+# Each item of the list must be the name (whatever is the case) of an ADQL
+# geometrical function (e.g. INTERSECTS, COORDSYS, POINT) to allow.
+# If the list is empty (no item), all functions are allowed. And if the special
+# value NONE is given, no ADQL function will be allowed.
+# 
+# Default: all ADQL geometrical functions are allowed.
+geometries = 
+
+#################################
+# USER DEFINED FUNCTIONS (UDFs) #
+#################################
+
+# [OPTIONAL]
+# Comma-separated list of all allowed UDFs (User Defined Functions).
+# 
+# Each item of the list must have the following syntax: [fct_signature],
+# [fct_signature, className] or [fct_signature, className, description].
+# fct_function is the function signature. Its syntax is the same as in
+# TAPRegExt. className is the name of a class extending UserDefinedFunction.
+# An instance of this class will replace any reference of a UDF written in an
+# ADQL function with the associated signature. A class name must be specified if
+# the function to represent has a signature (and more particularly a name)
+# different in ADQL and in SQL. description is the human description of the
+# function to be displayed in the /capabilities of the TAP service. It must be
+# written between double quotes.
+# 
+# Example: udfs = [ivo_healpix_index(hpxOrder integer, ra double, dec double)
+#                  -> bigint, {adql.query.operand.function.healpix.HealpixIndex}
+#                  , "Compute the index of the \"Healpix cell\" containing the
+#                     specified position at the given Healpix order."],
+#                 [trim(txt String) -> String],
+#                 [newFct(x double)-&gt;double, {apackage.MyNewFunction}],
+#                 [random() -> DOUBLE,,"Generate a random number."]
+# 
+# If the list is empty (no item), all unknown functions are forbidden. And if
+# the special value ANY is given, any unknown function is allowed ; consequently
+# the unknown ADQL functions will be translated into SQL as they are in ADQL.
+# 
+# Default: no unknown function is allowed.
+udfs = 
+
+########################
+# ADDITIONAL RESOURCES #
+########################
+
+# [OPTIONAL]
+# URL of the XSLT stylesheet to link with the XML output of /capabilities.
+# 
+# By default, no XSLT stylesheet is defined.
+capabilities_stylesheet = 
+
+# [OPTIONAL]
+# URL of the XSLT stylesheet to link with the XML output of /tables.
+# 
+# By default, no XSLT stylesheet is defined.
+tables_stylesheet = 
+
+# [OPTIONAL]
+# This property lets add an <code>/examples</code> endpoint by specifying an
+# XHTML-RDFa document listing TAP query examples using the syntax specified by
+# TAPNotes 1.0 DALI 1.0.
+# 
+# 3 different kinds of value are accepted:
+#     * nothing (default): no /examples endpoint.
+#     * name or relative path of a file: this method MUST be chosen if the
+#       endpoint content is a JSP file. This file MUST be inside the directory
+#       WebContent of your web application.
+#     * URI starting with file://: in this method the local file pointed by the
+#       URI will be merely returned when the endpoint will be requested.
+#     * a URL: here, a redirection toward this URL will be made at each request
+#       on the endpoint
+# 
+# If you want a custom /examples endpoint (i.e. you do not)
+# want to forward/redirect to a file/URL), you can create a class which
+# implements TAPResource AND VOSIResource. The function getName() must return
+# "examples". Then, just append the classpath to the property
+# "additional_resources" of the TAP configuration file.
+# 
+# By default, the TAP service does not have any <code>/examples</code> endpoint.
+examples = 
+
+# [OPTIONAL]
+# Comma-separated list of additional TAP resources/end-point.
+# 
+# By default, the following standard TAP resources are already existing: /sync,
+# /async, /tables, /capabilities and /availability. With this property, you can
+# add a custom resource to your TAP service (e.g. /adqlValidator, /admin).
+# 
+# Each item of the list MUST be the name of a class implementing
+# tap.resource.TAPResource. This class MUST have at least one constructor with
+# exactly one parameter of type tap.resource.TAP.
+# 
+# The string returned by tap.resource.TAPResource.getName() will be the
+# resource name, following the root TAP service URL (e.g. if getName() returns
+# "foo", then its access URL will "{tapRoot}/foo"). Then, it is possible to
+# replace TAP resources already existing by using the same name (e.g. if
+# getName() returns "sync", the /sync resource won't be anymore the default Sync
+# resource of this library but your new resource).
+# 
+# By default, this list is empty ; only the standard TAP resources exist.
+additional_resources = 
+
+######################
+# CUSTOM TAP_FACTORY #
+######################
+
+# [OPTIONAL]
+# Class to use in replacement of the default TAPFactory.
+# 
+# This property must be a class name (given between {...}). It must reference an
+# implementation of TAPFactory. This implementation must have at least one
+# constructor with exactly one parameter of type ServiceConnection.
+# 
+# It is recommended to extend an existing implementation such as:
+# tap.AbstractTAPFactory or tap.config.ConfigurableTAPFactory.
+# 
+# By default, the default TAPFactory (tap.config.ConfigurableTAPFactory) is used
+# and may use all properties related to the backup management, the database
+# access, the TAP_SCHEMA mapping and the ADQL translation.
+tap_factory = 
diff --git a/src/tap/config/tap_min.properties b/src/tap/config/tap_min.properties
index 26d4d6a244b37fe190afc458773dbe1bf28da59b..08e0f115fec9ea960b274e02ac042ac9c356b369 100644
--- a/src/tap/config/tap_min.properties
+++ b/src/tap/config/tap_min.properties
@@ -1,149 +1,149 @@
-################################################################################
-#                      MINIMUM TAP CONFIGURATION FILE                          #
-#                                                                              #
-# TAP Version: 2.1                                                             #
-# Date: 22 Feb. 2018                                                           #
-# Author: Gregory Mantelet (ARI)                                               #
-#                                                                              #
-################################################################################ 
-
-############
-# DATABASE #
-############
-
-# Method to use in order to create database connections.
-# 
-# Only two values are supported:
-#     * jndi: database connections will be supplied by a Datasource whose the
-#             JNDI name must be given. This method may propose connection
-#             pooling in function of the datasource configuration.
-#     * jdbc: the library will create itself connections when they will be
-#             needed thanks to the below JDBC parameters. This method does not
-#             propose any connection pooling.
-# 
-# Allowed values: jndi, jdbc.
-database_access = 
-
-# The translator to use in order to translate ADQL to a SQL compatible with the
-# used DBMS and its spatial extension.
-# 
-# The TAP library supports only Postgresql (no spatial extension),
-# PostgreSQL+PgSphere, SQLServer (no spatial extension) and MySQL (no spatial
-# extension) for the moment. But you can provide your own SQL translator (even
-# if it does not have spatial features), by providing the name of a class
-# (within brackets: {...}) that implements ADQLTranslator (for instance:
-# {apackage.MyADQLTranslator}) and which have at least an empty constructor.
-# 
-# Allowed values: postgres, pgsphere, sqlserver, mysql, a class name
-sql_translator = postgres
-
-#############################
-# IF DATABASE ACCESS = JNDI #
-#############################
-
-# JNDI name of the datasource pointing toward the database to use.
-# It should be defined in the web application (e.g. in the META-INF/context.xml
-# file in tomcat).
-datasource_jndi_name = 
-
-#############################
-# IF DATABASE ACCESS = JDBC #
-############################# 
-
-# JDBC driver URL pointing toward the database to use.
-# 
-# Note: The username, password or other parameters may be included in it, but
-#       in this case, the corresponding properties should leave empty or not
-#       provided at all.
-jdbc_url = 
-
-# JDBC driver path.
-# 
-# By default, it is guessed in function of the database name provided in the
-# jdbc_url property. It MUST be provided if another DBMS is used or if the
-# JDBC driver path does not match the following ones:
-#     * Oracle    : oracle.jdbc.OracleDriver
-#     * PostgreSQL: org.postgresql.Driver
-#     * MySQL     : com.mysql.jdbc.Driver
-#     * SQLite    : org.sqlite.JDBC
-#     * H2        : org.h2.Driver
-jdbc_driver = 
-
-# [Mandatory if the username is not already provided in jdbc_url]
-#
-# Username used to access to the database.
-db_user = 
-
-# [Mandatory if the password is not already provided in jdbc_url]
-#
-# Password used by db_username to access to the database.
-# 
-# Note: No password encryption can be done in this configuration file for the
-#       moment.
-db_password = 
-
-############
-# METADATA #
-############
-
-# Metadata fetching method.
-# 
-# The value of this key defines the way the library will get the list of all
-# schemas, tables and columns to publish and all their metadata (e.g. utype,
-# description, type, ...).
-# 
-# In its current state, the library proposes three methods:
-#    1/ Parse a TableSet XML document and load its content into the database
-#       schema TAP_SCHEMA (note: this schema is first erased and rebuilt by the
-#       library).
-#    2/ Get all metadata from the database schema TAP_SCHEMA.
-#    3/ Build yourself the metadata of your service by creating an extension of
-#       tap.metadata.TAPMetadata. This extension must have either an empty
-#       constructor or a constructor with exactly 3 parameters of type
-#       UWSFileManager, TAPFactory and TAPLog ; if both constructor are
-#       provided, only the one with parameters will be used.
-# 
-# For the two first methods, it is also possible to specify an extension of
-# tap.metadata.TAPMetadata which will wrap a default TAPMetadata objects created
-# using the specified methods (i.e. XML tableset or TAP_SCHEMA). In this way, it
-# is possible to get the "default" metadata from an XML file or the database
-# and then add/remove/modify some of them, or to change the output of the
-# 'tables' resource. The extension of tap.metadata.TAPMetadata must have at
-# least one constructor with the following parameters: (TAPMetadata) or
-# (TAPMetadata, UWSFileManager, TAPFactory, TAPLog).
-#  
-# Allowed values: xml, xml {myTAPMetadata}, db, db {myTAPMetadata}
-#                 or a full class name (between {}).
-metadata =  
-
-# [Mandatory if the value of "metadata" is "xml".]
-#
-# Local file path to the TableSet XML document.
-#
-# The XML document must implement the schema TableSet defined by VODataService.
-# The file path must be either an absolute local file path or a file path
-# relative to WebContent (i.e. the web application directory in which there are
-# WEB-INF and META-INF).
-metadata_file = 
-
-#########
-# FILES #
-#########
-
-# Type of the file manager.
-# 
-# Accepted values are: local (to manage files on the local system). You can also
-# add another way to manage files by providing the name (within brackets: {...})
-# of a class implementing TAPFileManager and having at least one constructor
-# with only a java.util.Properties parameter.
-# 
-# Allowed values: local, a class name.
-file_manager = local
-
-# Local file path of the directory in which all TAP files (logs, errors, job
-# results, backup, ...) must be.
-# 
-# The file path must be either an absolute local directory path or a directory
-# path relative to WebContent (i.e. the web application directory in which there
-# are WEB-INF and META-INF).
-file_root_path = 
+################################################################################
+#                      MINIMUM TAP CONFIGURATION FILE                          #
+#                                                                              #
+# TAP Version: 2.1                                                             #
+# Date: 22 Feb. 2018                                                           #
+# Author: Gregory Mantelet (ARI)                                               #
+#                                                                              #
+################################################################################ 
+
+############
+# DATABASE #
+############
+
+# Method to use in order to create database connections.
+# 
+# Only two values are supported:
+#     * jndi: database connections will be supplied by a Datasource whose the
+#             JNDI name must be given. This method may propose connection
+#             pooling in function of the datasource configuration.
+#     * jdbc: the library will create itself connections when they will be
+#             needed thanks to the below JDBC parameters. This method does not
+#             propose any connection pooling.
+# 
+# Allowed values: jndi, jdbc.
+database_access = 
+
+# The translator to use in order to translate ADQL to a SQL compatible with the
+# used DBMS and its spatial extension.
+# 
+# The TAP library supports only Postgresql (no spatial extension),
+# PostgreSQL+PgSphere, SQLServer (no spatial extension) and MySQL (no spatial
+# extension) for the moment. But you can provide your own SQL translator (even
+# if it does not have spatial features), by providing the name of a class
+# (within brackets: {...}) that implements ADQLTranslator (for instance:
+# {apackage.MyADQLTranslator}) and which have at least an empty constructor.
+# 
+# Allowed values: postgres, pgsphere, sqlserver, mysql, a class name
+sql_translator = postgres
+
+#############################
+# IF DATABASE ACCESS = JNDI #
+#############################
+
+# JNDI name of the datasource pointing toward the database to use.
+# It should be defined in the web application (e.g. in the META-INF/context.xml
+# file in tomcat).
+datasource_jndi_name = 
+
+#############################
+# IF DATABASE ACCESS = JDBC #
+############################# 
+
+# JDBC driver URL pointing toward the database to use.
+# 
+# Note: The username, password or other parameters may be included in it, but
+#       in this case, the corresponding properties should leave empty or not
+#       provided at all.
+jdbc_url = 
+
+# JDBC driver path.
+# 
+# By default, it is guessed in function of the database name provided in the
+# jdbc_url property. It MUST be provided if another DBMS is used or if the
+# JDBC driver path does not match the following ones:
+#     * Oracle    : oracle.jdbc.OracleDriver
+#     * PostgreSQL: org.postgresql.Driver
+#     * MySQL     : com.mysql.jdbc.Driver
+#     * SQLite    : org.sqlite.JDBC
+#     * H2        : org.h2.Driver
+jdbc_driver = 
+
+# [Mandatory if the username is not already provided in jdbc_url]
+#
+# Username used to access to the database.
+db_user = 
+
+# [Mandatory if the password is not already provided in jdbc_url]
+#
+# Password used by db_username to access to the database.
+# 
+# Note: No password encryption can be done in this configuration file for the
+#       moment.
+db_password = 
+
+############
+# METADATA #
+############
+
+# Metadata fetching method.
+# 
+# The value of this key defines the way the library will get the list of all
+# schemas, tables and columns to publish and all their metadata (e.g. utype,
+# description, type, ...).
+# 
+# In its current state, the library proposes three methods:
+#    1/ Parse a TableSet XML document and load its content into the database
+#       schema TAP_SCHEMA (note: this schema is first erased and rebuilt by the
+#       library).
+#    2/ Get all metadata from the database schema TAP_SCHEMA.
+#    3/ Build yourself the metadata of your service by creating an extension of
+#       tap.metadata.TAPMetadata. This extension must have either an empty
+#       constructor or a constructor with exactly 3 parameters of type
+#       UWSFileManager, TAPFactory and TAPLog ; if both constructor are
+#       provided, only the one with parameters will be used.
+# 
+# For the two first methods, it is also possible to specify an extension of
+# tap.metadata.TAPMetadata which will wrap a default TAPMetadata objects created
+# using the specified methods (i.e. XML tableset or TAP_SCHEMA). In this way, it
+# is possible to get the "default" metadata from an XML file or the database
+# and then add/remove/modify some of them, or to change the output of the
+# 'tables' resource. The extension of tap.metadata.TAPMetadata must have at
+# least one constructor with the following parameters: (TAPMetadata) or
+# (TAPMetadata, UWSFileManager, TAPFactory, TAPLog).
+#  
+# Allowed values: xml, xml {myTAPMetadata}, db, db {myTAPMetadata}
+#                 or a full class name (between {}).
+metadata =  
+
+# [Mandatory if the value of "metadata" is "xml".]
+#
+# Local file path to the TableSet XML document.
+#
+# The XML document must implement the schema TableSet defined by VODataService.
+# The file path must be either an absolute local file path or a file path
+# relative to WebContent (i.e. the web application directory in which there are
+# WEB-INF and META-INF).
+metadata_file = 
+
+#########
+# FILES #
+#########
+
+# Type of the file manager.
+# 
+# Accepted values are: local (to manage files on the local system). You can also
+# add another way to manage files by providing the name (within brackets: {...})
+# of a class implementing TAPFileManager and having at least one constructor
+# with only a java.util.Properties parameter.
+# 
+# Allowed values: local, a class name.
+file_manager = local
+
+# Local file path of the directory in which all TAP files (logs, errors, job
+# results, backup, ...) must be.
+# 
+# The file path must be either an absolute local directory path or a directory
+# path relative to WebContent (i.e. the web application directory in which there
+# are WEB-INF and META-INF).
+file_root_path = 
diff --git a/src/tap/formatter/VOTableFormat.java b/src/tap/formatter/VOTableFormat.java
index c641a6f95ba3ab2263180f65f60f31d324fdf10c..c870007aa91a05124cbf5e091f9f0c3f4daad6c3 100644
--- a/src/tap/formatter/VOTableFormat.java
+++ b/src/tap/formatter/VOTableFormat.java
@@ -415,6 +415,13 @@ public class VOTableFormat implements OutputFormat {
 			out.newLine();
 		}
 
+		// Append the fixed ADQL query, if any:	[OPTIONAL]
+		String fixedQuery = execReport.fixedQuery;
+		if (adqlQuery != null){
+			out.write("<INFO name=\"QUERY_AFTER_AUTO_FIX\"" + VOSerializer.formatAttribute("value", fixedQuery) + "/>");
+			out.newLine();
+		}
+
 		// Insert the definition of all used coordinate systems:
 		HashSet<String> insertedCoosys = new HashSet<String>(10);
 		for(DBColumn col : execReport.resultingColumns){
diff --git a/test/tap/config/TestConfigurableTAPFactory.java b/test/tap/config/TestConfigurableTAPFactory.java
index eeb81002d2a5ef700dfb8b4182b48b348894089f..e015f23664d98fdec65d55a235e9b9496a028eee 100644
--- a/test/tap/config/TestConfigurableTAPFactory.java
+++ b/test/tap/config/TestConfigurableTAPFactory.java
@@ -520,6 +520,11 @@ public class TestConfigurableTAPFactory {
 		public int[] getFetchSize(){
 			return null;
 		}
+
+		@Override
+		public boolean fixOnFailEnabled(){
+			return false;
+		}
 	}
 
 }
diff --git a/test/tap/formatter/ServiceConnection4Test.java b/test/tap/formatter/ServiceConnection4Test.java
index 97f6065c806f8f8f961ffa42c040090c3b8afe27..8ec8487b2ef3a70a97be9ffbd171a445e5276470 100644
--- a/test/tap/formatter/ServiceConnection4Test.java
+++ b/test/tap/formatter/ServiceConnection4Test.java
@@ -153,4 +153,9 @@ public class ServiceConnection4Test implements ServiceConnection {
 		return null;
 	}
 
+	@Override
+	public boolean fixOnFailEnabled(){
+		return false;
+	}
+
 }
\ No newline at end of file
diff --git a/test/tap/parameters/ServiceConnectionOfTest.java b/test/tap/parameters/ServiceConnectionOfTest.java
index 4a82f6bcd08257426a6a8dca371874c4f14b928f..e886b3f86a3f3b1790c8e5d70a63970accb4008f 100644
--- a/test/tap/parameters/ServiceConnectionOfTest.java
+++ b/test/tap/parameters/ServiceConnectionOfTest.java
@@ -174,4 +174,9 @@ public class ServiceConnectionOfTest implements ServiceConnection {
 		return null;
 	}
 
+	@Override
+	public boolean fixOnFailEnabled(){
+		return false;
+	}
+
 }
\ No newline at end of file