diff --git a/src/tap/data/ResultSetTableIterator.java b/src/tap/data/ResultSetTableIterator.java
index 9325771b0b8485072ed052938c0554a7b2f72f94..ae2fd1d41b02b9ca2bc8a8b28683d5d893026ae0 100644
--- a/src/tap/data/ResultSetTableIterator.java
+++ b/src/tap/data/ResultSetTableIterator.java
@@ -24,10 +24,14 @@ import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
 import java.util.NoSuchElementException;
 
+import tap.db.JDBCTAPFactory;
+import tap.metadata.TAPColumn;
+import tap.metadata.TAPType;
+
 /**
  * <p>{@link TableIterator} which lets iterate over a SQL {@link ResultSet}.</p>
  * 
- * <p>{@link #getColType()} will return the type declared in the {@link ResultSetMetaData} object.</p>
+ * <p>{@link #getColType()} will return a TAP type base on the one declared in the {@link ResultSetMetaData} object.</p>
  * 
  * @author Gr&eacute;gory Mantelet (ARI) - gmantele@ari.uni-heidelberg.de
  * @version 2.0 (06/2014)
@@ -40,8 +44,8 @@ public class ResultSetTableIterator implements TableIterator {
 
 	/** Number of columns to read. */
 	private final int nbColumns;
-	/** Type of all columns. */
-	private final String[] colTypes;
+	/** Metadata of all columns identified before the iteration. */
+	private final TAPColumn[] colMeta;
 
 	/** Indicate whether the row iteration has already started. */
 	private boolean iterationStarted = false;
@@ -82,14 +86,21 @@ public class ResultSetTableIterator implements TableIterator {
 			// count columns:
 			nbColumns = metadata.getColumnCount();
 			// determine their type:
-			colTypes = new String[nbColumns];
-			for(int i = 1; i <= nbColumns; i++)
-				colTypes[i - 1] = metadata.getColumnTypeName(i);
+			colMeta = new TAPColumn[nbColumns];
+			for(int i = 1; i <= nbColumns; i++){
+				TAPType datatype = JDBCTAPFactory.toTAPType(metadata.getColumnTypeName(i));
+				colMeta[i - 1] = new TAPColumn(metadata.getColumnLabel(i), datatype);
+			}
 		}catch(SQLException se){
 			throw new DataReadException("Can not get the column types of the given ResultSet!", se);
 		}
 	}
 
+	@Override
+	public TAPColumn[] getMetadata(){
+		return colMeta;
+	}
+
 	@Override
 	public boolean nextRow() throws DataReadException{
 		try{
@@ -144,7 +155,7 @@ public class ResultSetTableIterator implements TableIterator {
 	}
 
 	@Override
-	public String getColType() throws IllegalStateException, DataReadException{
+	public TAPType getColType() throws IllegalStateException, DataReadException{
 		// Basically check the read state (for rows iteration):
 		checkReadState();
 
@@ -155,7 +166,7 @@ public class ResultSetTableIterator implements TableIterator {
 			throw new IllegalStateException("All columns have already been read!");
 
 		// Return the column type:
-		return colTypes[colIndex - 1];
+		return colMeta[colIndex - 1].getDatatype();
 	}
 
 }
diff --git a/src/tap/data/TableIterator.java b/src/tap/data/TableIterator.java
index 5e6234ee389c758ae3bfdb21d552206d7c6fccd2..3051b3a52bc990b8ce253ba765b2a690df0324b6 100644
--- a/src/tap/data/TableIterator.java
+++ b/src/tap/data/TableIterator.java
@@ -21,6 +21,9 @@ package tap.data;
 
 import java.util.NoSuchElementException;
 
+import tap.metadata.TAPColumn;
+import tap.metadata.TAPType;
+
 /**
  * <p>Let's iterate on each row and then on each column over a table dataset.</p>
  * 
@@ -48,6 +51,23 @@ import java.util.NoSuchElementException;
  * @since 2.0
  */
 public interface TableIterator {
+	/**
+	 * <p>Get all the metadata column that have been successfully extracted at the creation of this iterator.</p>
+	 * 
+	 * <p><b>Important:</b> This function should be callable at any moment from the creation of the iterator until the end of the table dataset has been reached.</p>
+	 * 
+	 * <p><i>Note: This function MAY BE NOT IMPLEMENTED or the metadata can not be fetched. In this case, NULL will be returned.</i></p>
+	 * 
+	 * <p><i><b>Warning:</b> If the metadata part of the original document is corrupted (i.e. false number of columns),
+	 * the column type information should be fetched thanks to {@link #getColType()} while iterating over rows and columns.</i></p>
+	 * 
+	 * @return	An array of {@link TAPColumn} objects (each for a column of any row),
+	 *          or NULL if this function is not implemented OR if it was not possible to get these metadata.
+	 * 
+	 * @see #getColType()
+	 */
+	public TAPColumn[] getMetadata();
+
 	/**
 	 * <p>Go to the next row if there is one.</p>
 	 * 
@@ -88,13 +108,19 @@ public interface TableIterator {
 	/**
 	 * <p>Get the type of the current column value.</p>
 	 * 
-	 * <p><i>Note: "Current column value" means here "the value last returned by {@link #nextCol()}".</i></p>
+	 * <p><i>Note 1: "Current column value" means here "the value last returned by {@link #nextCol()}".</i></p>
+	 * 
+	 * <p><i>Note 2: This function MAY BE NOT IMPLEMENTED or the type information can not be fetched. If this is the case, NULL will be returned.</i></p>
+	 * 
+	 * <p><i><b>Warning:</b> In some cases, the metadata part of the original document does not match with the data
+	 * it should have represented. In such case, the types returned here and by {@link #getMetadata()} would be different.
+	 * <b>In case of such mismatch, the type returned by {@link #getColType()} should be considered as more correct/accurate.</b></i></p>
 	 * 
 	 * @return	Type of the current column value,
 	 *          or NULL if this information is not available or if this function is not implemented. 
 	 * 
 	 * @throws IllegalStateException	If {@link #nextCol()} has not yet been called.
-	 * @throws DataReadException	If an error occurs while reading the table dataset.
+	 * @throws DataReadException		If an error occurs while reading the table dataset.
 	 */
-	public String getColType() throws IllegalStateException, DataReadException;
+	public TAPType getColType() throws IllegalStateException, DataReadException;
 }
diff --git a/src/tap/data/VOTableIterator.java b/src/tap/data/VOTableIterator.java
new file mode 100644
index 0000000000000000000000000000000000000000..00349c24714987c12681a093967334cae95d1a18
--- /dev/null
+++ b/src/tap/data/VOTableIterator.java
@@ -0,0 +1,467 @@
+package tap.data;
+
+/*
+ * 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 2014 - Astronomisches Rechen Institut (ARI)
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import tap.metadata.TAPColumn;
+import tap.metadata.TAPType;
+import tap.metadata.VotType;
+import tap.metadata.VotType.VotDatatype;
+import cds.savot.model.DataBinaryReader;
+import cds.savot.model.FieldSet;
+import cds.savot.model.SavotBinary;
+import cds.savot.model.SavotField;
+import cds.savot.model.SavotResource;
+import cds.savot.model.SavotTD;
+import cds.savot.model.SavotTR;
+import cds.savot.model.SavotTableData;
+import cds.savot.pull.SavotPullEngine;
+import cds.savot.pull.SavotPullParser;
+
+/**
+ * <p>{@link TableIterator} which lets iterate over a VOTable input stream using Savot ({@link SavotPullParser} more exactly).</p>
+ * 
+ * <p>{@link #getColType()} will return TAP type based on the type declared in the VOTable metadata part.</p>
+ * 
+ * @author Gr&eacute;gory Mantelet (ARI) - gmantele@ari.uni-heidelberg.de
+ * @version 2.0 (06/2014)
+ * @since 2.0
+ */
+public class VOTableIterator implements TableIterator {
+
+	/** Metadata of all columns identified before the iteration. */
+	private final TAPColumn[] colMeta;
+	/** Inner TableIterator. It lets iterate over a binary or a table data set in a transparent way. */
+	private final TableIterator it;
+
+	/**
+	 * Build a TableIterator able to read rows and columns inside the given VOTable input stream.
+	 * 
+	 * @param input	Input stream over a VOTable document.
+	 * 
+	 * @throws NullPointerException	If NULL is given in parameter.
+	 * @throws DataReadException	If the given VOTable can not be parsed.
+	 */
+	public VOTableIterator(final InputStream input) throws DataReadException{
+		// An input stream MUST BE provided:
+		if (input == null)
+			throw new NullPointerException("Missing VOTable document input stream over which to iterate!");
+
+		try{
+			// Start parsing the VOTable:
+			SavotPullParser parser = new SavotPullParser(input, SavotPullEngine.SEQUENTIAL, null);
+
+			// Get the first resource:
+			SavotResource resource = parser.getNextResource();
+			if (resource == null)
+				throw new DataReadException("Incorrect VOTable format: missing resource node!");
+
+			// Extract the metadata about all fields:
+			FieldSet fields = resource.getFieldSet(0);
+			colMeta = extractColMeta(fields);
+
+			// Build the iterator over the data:
+			SavotBinary binary = resource.getData(0).getBinary();
+			if (binary != null)
+				it = new BinaryVOTableIterator(binary, fields, colMeta);
+			else
+				it = new DataVOTableIterator(resource.getData(0).getTableData(), colMeta);
+		}catch(Exception ex){
+			throw new DataReadException("Unable to parse/read the given VOTable input stream!", ex);
+		}
+	}
+
+	/**
+	 * Extract an array of {@link TAPColumn} objects. Each corresponds to one of the fields given in parameter,
+	 * and so corresponds to the metadata of a column. 
+	 * 
+	 * @param fields	List of metadata fields provided in a VOTable.
+	 * 
+	 * @return			The corresponding list of {@link TAPColumn} objects.
+	 */
+	private static final TAPColumn[] extractColMeta(final FieldSet fields){
+		// Count the number columns and initialize the array:
+		TAPColumn[] columns = new TAPColumn[fields.getItemCount()];
+
+		// Add all columns meta:
+		for(int i = 0; i < fields.getItemCount(); i++){
+			// get the field:
+			SavotField field = (SavotField)fields.getItemAt(i);
+
+			// Resolve the field type:
+			TAPType type = resolveVotType(field.getDataType(), field.getArraySize(), field.getXtype()).toTAPType();
+
+			// build the TAPColumn object:
+			TAPColumn col = new TAPColumn(field.getName(), type, field.getDescription(), field.getUnit(), field.getUcd(), field.getUtype());
+			col.setPrincipal(false);
+			col.setIndexed(false);
+			col.setStd(false);
+
+			// append it to the array:
+			columns[i] = col;
+		}
+
+		return columns;
+	}
+
+	/**
+	 * Resolve a VOTable field type by using the datatype, arraysize and xtype strings as specified in a VOTable document.
+	 * 
+	 * @param datatype		Attribute value of VOTable corresponding to the datatype.
+	 * @param arraysize		Attribute value of VOTable corresponding to the arraysize.
+	 * @param xtype			Attribute value of VOTable corresponding to the xtype.
+	 * 
+	 * @return	The resolved VOTable field type, or a CHAR(*) type if the specified type can not be resolved.
+	 */
+	private static VotType resolveVotType(final String datatype, final String arraysize, final String xtype){
+		// If no datatype is specified, return immediately a CHAR(*) type:
+		if (datatype == null || datatype.trim().length() == 0)
+			return new VotType(VotDatatype.CHAR, VotType.NO_SIZE, true);
+
+		// 1. IDENTIFY THE DATATYPE:
+
+		// Identify the specified datatype:
+		VotDatatype votdatatype;
+		try{
+			votdatatype = VotDatatype.valueOf(datatype.toUpperCase());
+		}catch(IllegalArgumentException iae){
+			// if it can't be identified, return immediately a CHAR(*) type:
+			return new VotType(VotDatatype.CHAR, VotType.NO_SIZE, true);
+		}
+
+		// 2. DETERMINE ITS ARRAYSIZE:
+
+		int votarraysize = VotType.NO_SIZE;
+		boolean votunlimitedSize = false;
+
+		// If no arraysize is specified, let's set it to 1 (for an elementary value):
+		if (arraysize == null || arraysize.trim().isEmpty())
+			votarraysize = 1;
+
+		// Otherwise, get it:
+		else{
+			String str = arraysize.trim();
+
+			// Determine whether an "unlimited size" character is specified:
+			votunlimitedSize = str.endsWith("*");
+
+			// If one is specified, remove it from the arraysize string:
+			if (votunlimitedSize)
+				str = str.substring(0, str.length() - 1);
+
+			// If a size is really specified (more characters than "*"), get the arraysize value:
+			if (str.length() > 0){
+				try{
+					votarraysize = Integer.parseInt(str);
+				}catch(NumberFormatException nfe){}
+			}
+		}
+
+		// And finally build the VOTable type:
+		return new VotType(votdatatype, votarraysize, votunlimitedSize, xtype);
+	}
+
+	/**
+	 * <p>Check the row iteration state. That's to say whether:</p>
+	 * <ul>
+	 * 	<li>the row iteration has started = the first row has been read = a first call of {@link #nextRow()} has been done</li>
+	 * 	<li>AND the row iteration is not finished = the last row has been read.</li>
+	 * </ul>
+	 * @throws IllegalStateException
+	 */
+	private static void checkReadState(final boolean iterationStarted, final boolean endReached) throws IllegalStateException{
+		if (!iterationStarted)
+			throw new IllegalStateException("No row has yet been read!");
+		else if (endReached)
+			throw new IllegalStateException("End of ResultSet already reached!");
+	}
+
+	@Override
+	public TAPColumn[] getMetadata(){
+		return colMeta;
+	}
+
+	@Override
+	public boolean nextRow() throws DataReadException{
+		return it.nextRow();
+	}
+
+	@Override
+	public boolean hasNextCol() throws IllegalStateException, DataReadException{
+		return it.hasNextCol();
+	}
+
+	@Override
+	public Object nextCol() throws NoSuchElementException, IllegalStateException, DataReadException{
+		return it.nextCol();
+	}
+
+	@Override
+	public TAPType getColType() throws IllegalStateException, DataReadException{
+		return it.getColType();
+	}
+
+	/**
+	 * <p>{@link TableIterator} which lets iterate over a VOTable binary data part.</p>
+	 * 
+	 * <p>This {@link TableIterator} is only usable by {@link VOTableIterator}.</p>
+	 * 
+	 * @author Gr&eacute;gory Mantelet (ARI) - gmantele@ari.uni-heidelberg.de
+	 * @version 2.0 (Jun 27, 2014)
+	 * @since 2.0
+	 */
+	private static class BinaryVOTableIterator implements TableIterator {
+
+		/** Binary data reader which lets read rows and columns, and thus iterate over them. */
+		private final DataBinaryReader reader;
+		/** Metadata of all columns identified before the iteration. <i>(In this TableIterator, they are completely provided by {@link VOTableIterator}).</i> */
+		private final TAPColumn[] colMeta;
+
+		/** The last read row. Each item is a column value. */
+		private Object[] row;
+
+		/** Indicate whether the row iteration has already started. */
+		private boolean iterationStarted = false;
+		/** Indicate whether the last row has already been reached. */
+		private boolean endReached = false;
+		/** Index of the last read column (=0 just after {@link #nextRow()} and before {@link #nextCol()}). */
+		private int colIndex;
+
+		/**
+		 * Build a TableIterator on the given binary data part of a VOTable whose fields are also described in parameter.
+		 * 
+		 * @param binary		Binary data part of a VOTable document.
+		 * @param fields		Description of all the fields that should be read.
+		 * @param columnsMeta	Metadata information extracted from the VOTable metadata part.
+		 * 
+		 * @throws DataReadException	If there is an error while starting reading the given binary data.
+		 */
+		public BinaryVOTableIterator(final SavotBinary binary, final FieldSet fields, final TAPColumn[] columnsMeta) throws DataReadException{
+			try{
+				reader = new DataBinaryReader(binary.getStream(), fields, false);
+				colMeta = columnsMeta;
+			}catch(IOException ioe){
+				throw new DataReadException("Can not open a stream to decode the binary VOTable data!", ioe);
+			}
+		}
+
+		@Override
+		public TAPColumn[] getMetadata(){
+			return null;
+		}
+
+		@Override
+		public boolean nextRow() throws DataReadException{
+			try{
+				// Go to the next row:
+				boolean rowFetched = reader.next();
+				// prepare the iteration over its columns:
+				if (rowFetched){
+					row = reader.getRow();
+					colIndex = -1;
+					iterationStarted = true;
+				}else{
+					row = null;
+					colIndex = -1;
+					endReached = true;
+				}
+				return rowFetched;
+			}catch(IOException e){
+				throw new DataReadException("Unable to read a VOTable row!", e);
+			}
+		}
+
+		@Override
+		public boolean hasNextCol() throws IllegalStateException, DataReadException{
+			// Check the read state:
+			checkReadState(iterationStarted, endReached);
+
+			// Determine whether the last column has been reached or not:
+			return (colIndex + 1 < row.length);
+		}
+
+		@Override
+		public Object nextCol() throws NoSuchElementException, IllegalStateException, DataReadException{
+			// Check the read state and ensure there is still at least one column to read:
+			if (!hasNextCol())
+				throw new NoSuchElementException("No more column to read!");
+
+			// Get the column value:
+			return row[++colIndex];
+		}
+
+		@Override
+		public TAPType getColType() throws IllegalStateException, DataReadException{
+			// Basically check the read state (for rows iteration):
+			checkReadState(iterationStarted, endReached);
+
+			// Check deeper the read state (for columns iteration):
+			if (colIndex < 0)
+				throw new IllegalStateException("No column has yet been read!");
+			else if (colIndex >= colMeta.length)
+				return null;
+
+			// Get the column value:
+			return colMeta[colIndex].getDatatype();
+		}
+
+	}
+
+	/**
+	 * <p>{@link TableIterator} which lets iterate over a VOTable table data part.</p>
+	 * 
+	 * <p>This {@link TableIterator} is only usable by {@link VOTableIterator}.</p>
+	 * 
+	 * @author Gr&eacute;gory Mantelet (ARI) - gmantele@ari.uni-heidelberg.de
+	 * @version 2.0 (Jun 27, 2014)
+	 * @since 2.0
+	 */
+	private static class DataVOTableIterator implements TableIterator {
+
+		/** Iterator over the rows contained in the VOTable data part. */
+		private final Iterator<Object> data;
+		/** Metadata of all columns identified before the iteration. <i>(In this TableIterator, they are completely provided by {@link VOTableIterator}).</i> */
+		private final TAPColumn[] colMeta;
+
+		/** Iterator over the columns contained in the last read row. */
+		private Iterator<Object> colsIt;
+
+		/** Indicate whether the row iteration has already started. */
+		private boolean iterationStarted = false;
+		/** Indicate whether the last row has already been reached. */
+		private boolean endReached = false;
+		/** Index of the last read column (=0 just after {@link #nextRow()} and before {@link #nextCol()}). */
+		private int colIndex;
+
+		/**
+		 * Build a TableIterator on the given table data part of a VOTable.
+		 * 
+		 * @param dataset		Table data part of a VOTable document.
+		 * @param columnsMeta	Metadata information extracted from the VOTable metadata part.
+		 */
+		public DataVOTableIterator(final SavotTableData dataset, final TAPColumn[] columnsMeta){
+			Collection<Object> trset = dataset.getTRs().getItems();
+			if (trset == null){
+				data = new NullIterator();
+				colMeta = columnsMeta;
+				iterationStarted = true;
+				endReached = true;
+			}else{
+				data = trset.iterator();
+				colMeta = columnsMeta;
+			}
+		}
+
+		@Override
+		public TAPColumn[] getMetadata(){
+			return null;
+		}
+
+		@Override
+		public boolean nextRow() throws DataReadException{
+			if (data.hasNext()){
+				// Go to the next row:
+				SavotTR row = (SavotTR)data.next();
+
+				// Prepare the iteration over its columns:
+				Collection<Object> tdset = row.getTDSet().getItems();
+				if (tdset == null)
+					colsIt = new NullIterator();
+				else
+					colsIt = tdset.iterator();
+
+				colIndex = -1;
+				iterationStarted = true;
+
+				return true;
+			}else{
+				// No more row to read => end of VOTable reached:
+				endReached = true;
+				return false;
+			}
+		}
+
+		@Override
+		public boolean hasNextCol() throws IllegalStateException, DataReadException{
+			// Check the read state:
+			checkReadState(iterationStarted, endReached);
+
+			// Determine whether the last column has been reached or not:
+			return colsIt.hasNext();
+		}
+
+		@Override
+		public Object nextCol() throws NoSuchElementException, IllegalStateException, DataReadException{
+			// Check the read state and ensure there is still at least one column to read:
+			if (!hasNextCol())
+				throw new NoSuchElementException("No more column to read!");
+
+			// Get the column value:
+			Object value = ((SavotTD)colsIt.next()).getContent();
+			colIndex++;
+			return value;
+		}
+
+		@Override
+		public TAPType getColType() throws IllegalStateException, DataReadException{
+			// Basically check the read state (for rows iteration):
+			checkReadState(iterationStarted, endReached);
+
+			// Check deeper the read state (for columns iteration):
+			if (colIndex < 0)
+				throw new IllegalStateException("No column has yet been read!");
+			else if (colIndex >= colMeta.length)
+				return null;
+
+			// Get the column value:
+			return colMeta[colIndex].getDatatype();
+		}
+
+	}
+
+	/**
+	 * Iterator over nothing.
+	 * 
+	 * @author Gr&eacute;gory Mantelet (ARI) - gmantele@ari.uni-heidelberg.de
+	 * @version 2.0 (06/2014)
+	 * @version 2.0
+	 */
+	private final static class NullIterator implements Iterator<Object> {
+		@Override
+		public boolean hasNext(){
+			return false;
+		}
+
+		@Override
+		public Object next(){
+			return null;
+		}
+
+		@Override
+		public void remove(){}
+
+	}
+
+}
diff --git a/src/tap/db/JDBCTAPFactory.java b/src/tap/db/JDBCTAPFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..8ef12bf4e06f907dafe374040ab08742ec1079ca
--- /dev/null
+++ b/src/tap/db/JDBCTAPFactory.java
@@ -0,0 +1,228 @@
+package tap.db;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import tap.metadata.TAPType;
+import tap.metadata.TAPType.TAPDatatype;
+
+public class JDBCTAPFactory {
+
+	public static enum DBMS{
+		POSTGRES;
+	}
+
+	public static interface DbmsTypeConverter< T, C > {
+		public C convert(final T typeToConvert);
+	}
+
+	public static Map<String,TAPDatatype> mapTypeAliases;
+	public static Map<String,DbmsTypeConverter<String,TAPType>> mapDbmsToTap;
+	public static Map<DBMS,Map<TAPDatatype,DbmsTypeConverter<TAPType,String>>> mapTapToDbms;
+
+	static{
+		/* DECLARE DBMS TYPE ALIASES */
+		mapTypeAliases = new HashMap<String,TAPType.TAPDatatype>();
+		mapTypeAliases.put("int8", TAPDatatype.BIGINT);
+		mapTypeAliases.put("bigserial", TAPDatatype.BIGINT);
+		mapTypeAliases.put("bit", TAPDatatype.VARCHAR);
+		mapTypeAliases.put("bit varying", TAPDatatype.VARCHAR);
+		mapTypeAliases.put("varbit", TAPDatatype.VARCHAR);
+		mapTypeAliases.put("boolean", TAPDatatype.SMALLINT);
+		mapTypeAliases.put("bytea", TAPDatatype.VARBINARY);
+		mapTypeAliases.put("character varying", TAPDatatype.VARCHAR);
+		mapTypeAliases.put("character", TAPDatatype.CHAR);
+		mapTypeAliases.put("double precision", TAPDatatype.DOUBLE);
+		mapTypeAliases.put("float8", TAPDatatype.DOUBLE);
+		mapTypeAliases.put("integer", TAPDatatype.INTEGER);
+		mapTypeAliases.put("int4", TAPDatatype.INTEGER);
+		mapTypeAliases.put("float4", TAPDatatype.REAL);
+		mapTypeAliases.put("int2", TAPDatatype.SMALLINT);
+		mapTypeAliases.put("serial", TAPDatatype.INTEGER);
+		mapTypeAliases.put("serial4", TAPDatatype.INTEGER);
+		mapTypeAliases.put("text", TAPDatatype.VARCHAR);
+
+		/* DECLARE SPECIAL DBMS->TAP CONVERSIONS */
+		mapDbmsToTap = new HashMap<String,JDBCTAPFactory.DbmsTypeConverter<String,TAPType>>();
+		mapDbmsToTap.put("numeric", new DbmsTypeConverter<String,TAPType>(){
+			@Override
+			public TAPType convert(String typeToConvert){
+				return new TAPType(TAPDatatype.DOUBLE);
+			}
+		});
+		mapDbmsToTap.put("decimal", new DbmsTypeConverter<String,TAPType>(){
+			@Override
+			public TAPType convert(String typeToConvert){
+				return new TAPType(TAPDatatype.DOUBLE);
+			}
+		});
+
+		/* DECLARE SPECIAL TAP->DBMS CONVERSIONS */
+		mapTapToDbms = new HashMap<DBMS,Map<TAPDatatype,DbmsTypeConverter<TAPType,String>>>();
+		// POSTGRES
+		HashMap<TAPDatatype,DbmsTypeConverter<TAPType,String>> postgresConverters = new HashMap<TAPDatatype,JDBCTAPFactory.DbmsTypeConverter<TAPType,String>>();
+		postgresConverters.put(TAPDatatype.DOUBLE, new DbmsTypeConverter<TAPType,String>(){
+			@Override
+			public String convert(TAPType typeToConvert){
+				return "double precision";
+			}
+		});
+		DbmsTypeConverter<TAPType,String> binaryConverter = new DbmsTypeConverter<TAPType,String>(){
+			@Override
+			public String convert(TAPType typeToConvert){
+				return "bytea";
+			}
+		};
+		postgresConverters.put(TAPDatatype.VARBINARY, binaryConverter);
+		postgresConverters.put(TAPDatatype.BINARY, binaryConverter);
+		postgresConverters.put(TAPDatatype.BLOB, binaryConverter);
+		postgresConverters.put(TAPDatatype.CLOB, binaryConverter);
+		mapTapToDbms.put(DBMS.POSTGRES, postgresConverters);
+	}
+
+	public JDBCTAPFactory(){
+		// TODO Auto-generated constructor stub
+	}
+
+	/**
+	 * <p>Convert the given TAP column type into a column type compatible with the specified DBMS.</p>
+	 * 
+	 * <p><i>Note 1: if no {@link TAPType} is provided, the returned DBMS type will correspond to a
+	 * VARCHAR.</i></p>
+	 * 
+	 * <p><i>Note 2: if no DBMS is specified or if the conversion has failed, the given TAP type will be
+	 * just "stringified" (by calling {@link TAPType#toString()})</i></p>
+	 * 
+	 * @param tapType	A TAP column type.
+	 * @param dbms		DBMS target in which the given TAP column type must be converted.
+	 * 
+	 * @return	The corresponding DBMS column type.
+	 */
+	public static String toDbmsType(TAPType tapType, final DBMS dbms){
+		// If no TAP type is specified, consider it by default as a VARCHAR type:
+		if (tapType == null)
+			tapType = new TAPType(TAPDatatype.VARCHAR);
+
+		// By default, just "stringify" the given TAP type:
+		String dbmsType = tapType.toString();
+
+		// If some converters are defined for the specified DBMS...
+		if (dbms != null && mapTapToDbms.containsKey(dbms)){
+			Map<TAPDatatype,DbmsTypeConverter<TAPType,String>> dbmsMap = mapTapToDbms.get(dbms);
+			// ...and if a converter exists for the given TAP datatype...
+			DbmsTypeConverter<TAPType,String> converter = dbmsMap.get(tapType.type);
+			if (converter != null){
+				// ...convert the given TAP type:
+				String conversion = converter.convert(tapType);
+				// ...and set the DBMS conversion if NOT NULL:
+				if (conversion != null)
+					dbmsType = conversion;
+			}
+		}
+
+		return dbmsType;
+	}
+
+	/**
+	 * <p>Convert the given DBMS column type into a compatible TAP datatype.</p>
+	 * 
+	 * <p><i>Note: If no DBMS type is specified or if the DBMS type can not be identified,
+	 * it will be converted as a VARCHAR.</i></p>
+	 * 
+	 * @param dbmsType	DBMS column datatype.
+	 * 
+	 * @return	The corresponding TAP column datatype.
+	 */
+	public static TAPType toTAPType(final String dbmsType){
+		// If no type is provided return VARCHAR:
+		if (dbmsType == null || dbmsType.trim().length() == 0)
+			return new TAPType(TAPDatatype.VARCHAR);
+
+		// Extract the type prefix and lower-case it:
+		int paramIndex = dbmsType.indexOf('(');
+		String dbmsTypePrefix = (paramIndex <= 0) ? dbmsType : dbmsType.substring(0, paramIndex);
+		dbmsTypePrefix = dbmsTypePrefix.toLowerCase();
+
+		// Use this type prefix as key to determine if it's a DBMS type alias and get its corresponding TAP datatype:
+		TAPDatatype datatype = mapTypeAliases.get(dbmsTypePrefix);
+
+		// If it's an alias, build the corresponding TAP type:
+		if (datatype != null)
+			return new TAPType(datatype, getLengthParam(dbmsType, paramIndex));
+
+		// If it's not an alias, use the type prefix as key to get a corresponding converter:
+		DbmsTypeConverter<String,TAPType> converter = mapDbmsToTap.get(dbmsTypePrefix);
+
+		// Try the type conversion using this converter:
+		TAPType taptype = null;
+		if (converter != null)
+			taptype = converter.convert(dbmsType);
+
+		/* 
+		 * If no converter was found OR if the type conversion has failed,
+		 * consider the given type as equivalent to a declared TAP type.
+		 * 
+		 * /!\ But if no equivalent exists, the given type will be ignore and
+		 *     VARCHAR will be returned!
+		 */
+		if (taptype == null){
+			try{
+
+				// Try to find an equivalent TAPType:
+				datatype = TAPDatatype.valueOf(dbmsTypePrefix.toUpperCase());
+
+				// If there is one return directly the TAPType:
+				taptype = new TAPType(datatype, getLengthParam(dbmsType, paramIndex));
+
+			}catch(IllegalArgumentException iae){
+				// If none exists, return VARCHAR:
+				taptype = new TAPType(TAPDatatype.VARCHAR, TAPType.NO_LENGTH);
+			}
+		}
+
+		return taptype;
+	}
+
+	/**
+	 * <p>Extract the 'length' parameter of a DBMS type string.</p>
+	 * 
+	 * <p>
+	 * 	If the given type string does not contain any parameter
+	 * 	OR if the first parameter can not be casted into an integer,
+	 * 	{@link TAPType#NO_LENGTH} will be returned.
+	 * </p>
+	 * 
+	 * @param dbmsType		DBMS type string (containing the datatype and the 'length' parameter).
+	 * @param paramIndex	Index of the open bracket.
+	 * 
+	 * @return	The 'length' parameter value if found, {@link TAPType#NO_LENGTH} otherwise.
+	 */
+	private static int getLengthParam(final String dbmsType, final int paramIndex){
+		// If no parameter has been previously detected, no length parameter:
+		if (paramIndex <= 0)
+			return TAPType.NO_LENGTH;
+
+		// If there is one and that at least ONE parameter is provided....
+		else{
+			int lengthParam = TAPType.NO_LENGTH;
+			String paramsStr = dbmsType.substring(paramIndex + 1);
+
+			// ...extract the 'length' parameter:
+			/* note: we suppose here that no other parameter is possible ;
+			 *       but if there are, they are ignored and we try to consider the first parameter
+			 *       as the length */
+			int paramEndIndex = paramsStr.indexOf(',');
+			if (paramEndIndex <= 0)
+				paramEndIndex = paramsStr.indexOf(')');
+
+			// ...cast it into an integer:
+			try{
+				lengthParam = Integer.parseInt(paramsStr.substring(0, paramEndIndex));
+			}catch(Exception ex){}
+
+			// ...and finally return it:
+			return lengthParam;
+		}
+	}
+
+}
diff --git a/test/tap/data/ResultSetTableIteratorTest.java b/test/tap/data/ResultSetTableIteratorTest.java
index cd0e7f9d6da32e816791ff9d24dc0b761de1dcbc..99d7057f72c81b8a73ea603e67dc6c91a21df274 100644
--- a/test/tap/data/ResultSetTableIteratorTest.java
+++ b/test/tap/data/ResultSetTableIteratorTest.java
@@ -43,6 +43,8 @@ public class ResultSetTableIteratorTest {
 			ResultSet rs = DBTools.select(conn, "SELECT id, ra, deg, gmag FROM gums LIMIT 10;");
 
 			TableIterator it = new ResultSetTableIterator(rs);
+			// TEST there is column metadata before starting the iteration:
+			assertTrue(it.getMetadata() != null);
 			final int expectedNbLines = 10, expectedNbColumns = 4;
 			int countLines = 0, countColumns = 0;
 			while(it.nextRow()){
@@ -75,6 +77,8 @@ public class ResultSetTableIteratorTest {
 			ResultSet rs = DBTools.select(conn, "SELECT * FROM gums WHERE id = 'foo';");
 
 			TableIterator it = new ResultSetTableIterator(rs);
+			// TEST there is column metadata before starting the iteration:
+			assertTrue(it.getMetadata() != null);
 			int countLines = 0;
 			// count lines:
 			while(it.nextRow())
diff --git a/test/tap/data/VOTableIteratorTest.java b/test/tap/data/VOTableIteratorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..cc78ad3838948da681dcaf282124c8df7aab1fe3
--- /dev/null
+++ b/test/tap/data/VOTableIteratorTest.java
@@ -0,0 +1,172 @@
+package tap.data;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.junit.Test;
+
+public class VOTableIteratorTest {
+
+	public final static String directory = "/home/gmantele/workspace/tap/test/tap/data/";
+
+	public final static File dataVOTable = new File(directory + "testdata.vot");
+	public final static File binaryVOTable = new File(directory + "testdata_binary.vot");
+
+	public final static File emptyVOTable = new File(directory + "emptyset.vot");
+	public final static File emptyBinaryVOTable = new File(directory + "emptyset_binary.vot");
+
+	@Test
+	public void testWithNULL(){
+		try{
+			new VOTableIterator(null);
+			fail("The constructor should have failed, because: the given VOTable is NULL.");
+		}catch(Exception ex){
+			assertEquals(ex.getClass().getName(), "java.lang.NullPointerException");
+		}
+	}
+
+	@Test
+	public void testWithData(){
+		InputStream input = null;
+		try{
+			input = new BufferedInputStream(new FileInputStream(dataVOTable));
+			TableIterator it = new VOTableIterator(input);
+			// TEST there is column metadata before starting the iteration:
+			assertTrue(it.getMetadata() != null);
+			final int expectedNbLines = 100, expectedNbColumns = 4;
+			int countLines = 0, countColumns = 0;
+			while(it.nextRow()){
+				// count lines:
+				countLines++;
+				// reset columns count:
+				countColumns = 0;
+				while(it.hasNextCol()){
+					it.nextCol();
+					// count columns
+					countColumns++;
+					// TEST the column type is set (not null):
+					assertTrue(it.getColType() != null);
+				}
+				// TEST that all columns have been read:
+				assertEquals(expectedNbColumns, countColumns);
+			}
+			// TEST that all lines have been read: 
+			assertEquals(expectedNbLines, countLines);
+
+		}catch(Exception ex){
+			ex.printStackTrace(System.err);
+			fail("An exception occurs while reading a correct VOTable (containing some valid rows).");
+		}finally{
+			try{
+				if (input != null)
+					input.close();
+			}catch(IOException e){
+				e.printStackTrace();
+			}
+		}
+	}
+
+	@Test
+	public void testWithBinary(){
+		InputStream input = null;
+		try{
+			input = new BufferedInputStream(new FileInputStream(binaryVOTable));
+			TableIterator it = new VOTableIterator(input);
+			// TEST there is column metadata before starting the iteration:
+			assertTrue(it.getMetadata() != null);
+			final int expectedNbLines = 100, expectedNbColumns = 4;
+			int countLines = 0, countColumns = 0;
+			while(it.nextRow()){
+				// count lines:
+				countLines++;
+				// reset columns count:
+				countColumns = 0;
+				while(it.hasNextCol()){
+					it.nextCol();
+					// count columns
+					countColumns++;
+					// TEST the column type is set (not null):
+					assertTrue(it.getColType() != null);
+				}
+				// TEST that all columns have been read:
+				assertEquals(expectedNbColumns, countColumns);
+			}
+			// TEST that all lines have been read: 
+			assertEquals(expectedNbLines, countLines);
+
+		}catch(Exception ex){
+			ex.printStackTrace(System.err);
+			fail("An exception occurs while reading a correct VOTable (containing some valid rows).");
+		}finally{
+			try{
+				if (input != null)
+					input.close();
+			}catch(IOException e){
+				e.printStackTrace();
+			}
+		}
+	}
+
+	@Test
+	public void testWithEmptySet(){
+		InputStream input = null;
+		try{
+			input = new BufferedInputStream(new FileInputStream(emptyVOTable));
+			TableIterator it = new VOTableIterator(input);
+			// TEST there is column metadata before starting the iteration:
+			assertTrue(it.getMetadata() != null);
+			int countLines = 0;
+			// count lines:
+			while(it.nextRow())
+				countLines++;
+			// TEST that no line has been read: 
+			assertEquals(countLines, 0);
+
+		}catch(Exception ex){
+			ex.printStackTrace(System.err);
+			fail("An exception occurs while reading a correct VOTable (even if empty).");
+		}finally{
+			try{
+				if (input != null)
+					input.close();
+			}catch(IOException e){
+				e.printStackTrace();
+			}
+		}
+	}
+
+	@Test
+	public void testWithEmptyBinarySet(){
+		InputStream input = null;
+		try{
+			input = new BufferedInputStream(new FileInputStream(emptyBinaryVOTable));
+			TableIterator it = new VOTableIterator(input);
+			// TEST there is column metadata before starting the iteration:
+			assertTrue(it.getMetadata() != null);
+			int countLines = 0;
+			// count lines:
+			while(it.nextRow())
+				countLines++;
+			// TEST that no line has been read: 
+			assertEquals(countLines, 0);
+
+		}catch(Exception ex){
+			ex.printStackTrace(System.err);
+			fail("An exception occurs while reading a correct binary VOTable (even if empty).");
+		}finally{
+			try{
+				if (input != null)
+					input.close();
+			}catch(IOException e){
+				e.printStackTrace();
+			}
+		}
+	}
+}
diff --git a/test/tap/data/emptyset.vot b/test/tap/data/emptyset.vot
new file mode 100644
index 0000000000000000000000000000000000000000..fe9b28f07d38b03eb805da25fe3f0b04fe100048
--- /dev/null
+++ b/test/tap/data/emptyset.vot
@@ -0,0 +1,123 @@
+<?xml version='1.0'?>
+<VOTABLE version="1.2"
+ xmlns="http://www.ivoa.net/xml/VOTable/v1.2">
+<!--
+ !  VOTable written by STIL version 3.0-5+ (uk.ac.starlink.votable.VOTableWriter)
+ !  at 2014-06-27T15:46:42
+ !-->
+<RESOURCE>
+<TABLE name="sn" nrows="1">
+<PARAM arraysize="19" datatype="char" name="source" value="2012arXiv1202.0132R"/>
+<PARAM arraysize="9" datatype="char" name="CoordFlavor" utype="stc:AstroCoordSystem.SpaceFrame.CoordFlavor" value="SPHERICAL"/>
+<PARAM arraysize="1" datatype="char" name="coord_naxes" utype="stc:AstroCoordSystem.SpaceFrame.CoordFlavor.coord_naxes" value="3"/>
+<PARAM arraysize="4" datatype="char" name="CoordRefFrame" utype="stc:AstroCoordSystem.SpaceFrame.CoordRefFrame" value="ICRS"/>
+<PARAM arraysize="6" datatype="char" name="Epoch" utype="stc:AstroCoords.Position3D.Epoch" value="2010.0"/>
+<PARAM arraysize="1" datatype="char" name="yearDef" utype="stc:AstroCoords.Position3D.Epoch.yearDef" value="J"/>
+<PARAM arraysize="41" datatype="char" name="URI" utype="stc:DataModel.URI" value="http://www.ivoa.net/xml/STC/stc-v1.30.xsd"/>
+<PARAM arraysize="31" datatype="char" name="server" value="http://dc.zah.uni-heidelberg.de"/>
+<PARAM arraysize="69" datatype="char" name="query" value="SELECT * FROM gums.sn WHERE sourceid = 5227706337957249025 LIMIT 2000"/>
+<PARAM arraysize="36" datatype="char" name="src_res" value="Contains traces from resource gums/q">
+<DESCRIPTION>GUMS-10 is the 10th version of the Gaia Universe Model Snapshot, a
+simulation of the expected contents of the Gaia cataloge run at the
+MareNostrum supercomputer. The models used and the characteristics of
+GUMS-10 are described in: A.C. Robin et al, "Gaia Universe Model
+Snapshot. A statistical analysis of the expected contents of the Gaia
+catalogue", Astronomy &amp; Astrophysics (2012), in press. For more
+details see also http://gaia.am.ub.es/GUMS-10/</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="34" datatype="char" name="src_table" value="Contains traces from table gums.sn">
+<DESCRIPTION>Supernovae in the GUMS-10 simulated GAIA result set.</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="54" datatype="char" name="copyright" value="Content from gums/q has rights note (see INFO content)">
+<DESCRIPTION>If you use this data, please acknowledge that GUMS was created using
+the MareNostrum supercomputer.</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="2" datatype="char" name="QUERY_STATUS" value="OK">
+<DESCRIPTION>Query successful</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="11" datatype="char" name="Service short name" value="GAVO DC TAP">
+<DESCRIPTION>Short name for TAP service</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="28" datatype="char" name="Service title" value="GAVO Data Center TAP service">
+<DESCRIPTION>TAP service title</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="36" datatype="char" name="Identifier" value="ivo://org.gavo.dc/__system__/tap/run">
+<DESCRIPTION>Unique resource registry identifier</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="16" datatype="char" name="Service publisher" value="The GAVO DC team">
+<DESCRIPTION>Publisher for TAP service</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="55" datatype="char" name="Service reference URL" value="http://dc.zah.uni-heidelberg.de/__system__/tap/run/info">
+<DESCRIPTION>Descriptive URL for search resource</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="50" datatype="char" name="Contact person" value="GAVO Data Center Team &lt;gavo@ari.uni-heidelberg.de&gt;">
+<DESCRIPTION>Individual to contact about this service</DESCRIPTION>
+</PARAM>
+<FIELD ID="v" datatype="float" name="v" unit="mag">
+<DESCRIPTION>Intrinsic apparent V magnitude</DESCRIPTION>
+</FIELD>
+<FIELD ID="colorvminusi" datatype="float" name="colorvminusi" ucd="phot.color;em.opt.V;em.opt.I" unit="mag">
+<DESCRIPTION>Intrinsic V-I color.</DESCRIPTION>
+</FIELD>
+<FIELD ID="meanabsolutev" datatype="float" name="meanabsolutev" ucd="phot.mag;em.opt.V" unit="mag">
+<DESCRIPTION>Mean absolute V magnitude.</DESCRIPTION>
+</FIELD>
+<FIELD ID="redshift" datatype="float" name="redshift" ucd="src.redshift">
+<DESCRIPTION>Object redshift.</DESCRIPTION>
+</FIELD>
+<FIELD ID="alpha" datatype="double" name="alpha" ucd="pos.eq.ra;meta.main" unit="deg">
+<DESCRIPTION>Right ascention of the barycenter at J2010 reference epoch in the ICRS frame</DESCRIPTION>
+</FIELD>
+<FIELD ID="delta" datatype="double" name="delta" ucd="pos.eq.dec;meta.main" unit="deg">
+<DESCRIPTION>Declination of the barycenter at J2010 reference epoch in the ICRS frame</DESCRIPTION>
+</FIELD>
+<FIELD ID="distance" datatype="float" name="distance" ucd="pos.distance;pos.heliocentric" unit="pc">
+<DESCRIPTION>Distance from the barycenter of the Solar System to the barycenter of the source at J2010 reference epoch</DESCRIPTION>
+</FIELD>
+<FIELD ID="mualpha" datatype="float" name="mualpha" ucd="pos.pm;pos.eq.ra" unit="mas/a">
+<DESCRIPTION>Proper motion along right ascention at J2010 reference epoch</DESCRIPTION>
+</FIELD>
+<FIELD ID="mudelta" datatype="float" name="mudelta" ucd="pos.pm;pos.eq.dec" unit="mas/a">
+<DESCRIPTION>Proper motion along declination at J2010 reference epoch</DESCRIPTION>
+</FIELD>
+<FIELD ID="radialvelocity" datatype="float" name="radialvelocity" ucd="spect.dopplerVeloc;pos.heliocentric" unit="km/s">
+<DESCRIPTION>Radial Velocity at J2010 reference epoch</DESCRIPTION>
+</FIELD>
+<FIELD ID="ag" datatype="float" name="ag" ucd="phys.absorption;em.opt" unit="mag">
+<DESCRIPTION>Interstellar absorption in the G band assuming the extinction law of 1989ApJ...345..245C.</DESCRIPTION>
+</FIELD>
+<FIELD ID="av" datatype="float" name="av" ucd="phys.absorption;em.opt.V" unit="mag">
+<DESCRIPTION>Interstellar absorption in the V-band assuming the extinction law of 1989ApJ...345..245C.</DESCRIPTION>
+</FIELD>
+<FIELD ID="rv" datatype="float" name="rv" ucd="arith.diff;phys.absorption;em.opt.B;em.opt.V" unit="mag">
+<DESCRIPTION>Extinction parameter according to 2003A&amp;A...409..205D.</DESCRIPTION>
+</FIELD>
+<FIELD ID="magg" datatype="float" name="magg" ucd="phot.mag;em.opt.V" unit="mag">
+<DESCRIPTION>GAIA G band apparent magnitude at reference epoch. The GAIA G-band has a wide bandpass between 350 and 150 nm. This is close to Johnson V for V-I between -0.4 and 1.4.</DESCRIPTION>
+</FIELD>
+<FIELD ID="maggbp" datatype="float" name="maggbp" ucd="phot.mag;em.opt.B" unit="mag">
+<DESCRIPTION>GAIA G_BP band apparent magnitude at reference epoch. The GAIA G_BP band has a bandpass between 350 and 770 nm.</DESCRIPTION>
+</FIELD>
+<FIELD ID="maggrp" datatype="float" name="maggrp" ucd="phot.mag;em.opt.R" unit="mag">
+<DESCRIPTION>GAIA G_RP band apparent magnitude at reference epoch. The GAIA G_RP band has a bandpass between 650 and 1050 nm.</DESCRIPTION>
+</FIELD>
+<FIELD ID="maggrvs" datatype="float" name="maggrvs" ucd="phot.mag;em.opt;em.opt.R" unit="mag">
+<DESCRIPTION>GAIA G_RVS band apparent magnitude at reference epoch. The GAIA G_RVS band has a narrow bandpass between 850 and 880 nm.</DESCRIPTION>
+</FIELD>
+<FIELD ID="type" arraysize="*" datatype="char" name="type">
+<DESCRIPTION>Supernova type (one of Ia, Ib/c, II-L, II-P)</DESCRIPTION>
+</FIELD>
+<FIELD ID="sourceid" datatype="long" name="sourceid" ucd="meta.id;meta.main">
+<DESCRIPTION>GUMS source identifier</DESCRIPTION>
+<VALUES null='-9223372036854775808'/>
+</FIELD>
+<FIELD ID="sourceextendedid" arraysize="*" datatype="char" name="sourceextendedid" ucd="meta.id">
+<DESCRIPTION>GUMS extended source identifier</DESCRIPTION>
+</FIELD>
+<DATA>
+<TABLEDATA>
+</TABLEDATA>
+</DATA>
+</TABLE>
+</RESOURCE>
+</VOTABLE>
diff --git a/test/tap/data/emptyset_binary.vot b/test/tap/data/emptyset_binary.vot
new file mode 100644
index 0000000000000000000000000000000000000000..e123464d597c1fccbaf981edcad57d4553fc5491
--- /dev/null
+++ b/test/tap/data/emptyset_binary.vot
@@ -0,0 +1,125 @@
+<?xml version='1.0'?>
+<VOTABLE version="1.2"
+ xmlns="http://www.ivoa.net/xml/VOTable/v1.2">
+<!--
+ !  VOTable written by STIL version 3.0-5+ (uk.ac.starlink.votable.VOTableWriter)
+ !  at 2014-06-27T15:47:08
+ !-->
+<RESOURCE>
+<TABLE name="sn" nrows="1">
+<PARAM arraysize="19" datatype="char" name="source" value="2012arXiv1202.0132R"/>
+<PARAM arraysize="9" datatype="char" name="CoordFlavor" utype="stc:AstroCoordSystem.SpaceFrame.CoordFlavor" value="SPHERICAL"/>
+<PARAM arraysize="1" datatype="char" name="coord_naxes" utype="stc:AstroCoordSystem.SpaceFrame.CoordFlavor.coord_naxes" value="3"/>
+<PARAM arraysize="4" datatype="char" name="CoordRefFrame" utype="stc:AstroCoordSystem.SpaceFrame.CoordRefFrame" value="ICRS"/>
+<PARAM arraysize="6" datatype="char" name="Epoch" utype="stc:AstroCoords.Position3D.Epoch" value="2010.0"/>
+<PARAM arraysize="1" datatype="char" name="yearDef" utype="stc:AstroCoords.Position3D.Epoch.yearDef" value="J"/>
+<PARAM arraysize="41" datatype="char" name="URI" utype="stc:DataModel.URI" value="http://www.ivoa.net/xml/STC/stc-v1.30.xsd"/>
+<PARAM arraysize="31" datatype="char" name="server" value="http://dc.zah.uni-heidelberg.de"/>
+<PARAM arraysize="69" datatype="char" name="query" value="SELECT * FROM gums.sn WHERE sourceid = 5227706337957249025 LIMIT 2000"/>
+<PARAM arraysize="36" datatype="char" name="src_res" value="Contains traces from resource gums/q">
+<DESCRIPTION>GUMS-10 is the 10th version of the Gaia Universe Model Snapshot, a
+simulation of the expected contents of the Gaia cataloge run at the
+MareNostrum supercomputer. The models used and the characteristics of
+GUMS-10 are described in: A.C. Robin et al, "Gaia Universe Model
+Snapshot. A statistical analysis of the expected contents of the Gaia
+catalogue", Astronomy &amp; Astrophysics (2012), in press. For more
+details see also http://gaia.am.ub.es/GUMS-10/</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="34" datatype="char" name="src_table" value="Contains traces from table gums.sn">
+<DESCRIPTION>Supernovae in the GUMS-10 simulated GAIA result set.</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="54" datatype="char" name="copyright" value="Content from gums/q has rights note (see INFO content)">
+<DESCRIPTION>If you use this data, please acknowledge that GUMS was created using
+the MareNostrum supercomputer.</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="2" datatype="char" name="QUERY_STATUS" value="OK">
+<DESCRIPTION>Query successful</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="11" datatype="char" name="Service short name" value="GAVO DC TAP">
+<DESCRIPTION>Short name for TAP service</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="28" datatype="char" name="Service title" value="GAVO Data Center TAP service">
+<DESCRIPTION>TAP service title</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="36" datatype="char" name="Identifier" value="ivo://org.gavo.dc/__system__/tap/run">
+<DESCRIPTION>Unique resource registry identifier</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="16" datatype="char" name="Service publisher" value="The GAVO DC team">
+<DESCRIPTION>Publisher for TAP service</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="55" datatype="char" name="Service reference URL" value="http://dc.zah.uni-heidelberg.de/__system__/tap/run/info">
+<DESCRIPTION>Descriptive URL for search resource</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="50" datatype="char" name="Contact person" value="GAVO Data Center Team &lt;gavo@ari.uni-heidelberg.de&gt;">
+<DESCRIPTION>Individual to contact about this service</DESCRIPTION>
+</PARAM>
+<FIELD ID="v" datatype="float" name="v" unit="mag">
+<DESCRIPTION>Intrinsic apparent V magnitude</DESCRIPTION>
+</FIELD>
+<FIELD ID="colorvminusi" datatype="float" name="colorvminusi" ucd="phot.color;em.opt.V;em.opt.I" unit="mag">
+<DESCRIPTION>Intrinsic V-I color.</DESCRIPTION>
+</FIELD>
+<FIELD ID="meanabsolutev" datatype="float" name="meanabsolutev" ucd="phot.mag;em.opt.V" unit="mag">
+<DESCRIPTION>Mean absolute V magnitude.</DESCRIPTION>
+</FIELD>
+<FIELD ID="redshift" datatype="float" name="redshift" ucd="src.redshift">
+<DESCRIPTION>Object redshift.</DESCRIPTION>
+</FIELD>
+<FIELD ID="alpha" datatype="double" name="alpha" ucd="pos.eq.ra;meta.main" unit="deg">
+<DESCRIPTION>Right ascention of the barycenter at J2010 reference epoch in the ICRS frame</DESCRIPTION>
+</FIELD>
+<FIELD ID="delta" datatype="double" name="delta" ucd="pos.eq.dec;meta.main" unit="deg">
+<DESCRIPTION>Declination of the barycenter at J2010 reference epoch in the ICRS frame</DESCRIPTION>
+</FIELD>
+<FIELD ID="distance" datatype="float" name="distance" ucd="pos.distance;pos.heliocentric" unit="pc">
+<DESCRIPTION>Distance from the barycenter of the Solar System to the barycenter of the source at J2010 reference epoch</DESCRIPTION>
+</FIELD>
+<FIELD ID="mualpha" datatype="float" name="mualpha" ucd="pos.pm;pos.eq.ra" unit="mas/a">
+<DESCRIPTION>Proper motion along right ascention at J2010 reference epoch</DESCRIPTION>
+</FIELD>
+<FIELD ID="mudelta" datatype="float" name="mudelta" ucd="pos.pm;pos.eq.dec" unit="mas/a">
+<DESCRIPTION>Proper motion along declination at J2010 reference epoch</DESCRIPTION>
+</FIELD>
+<FIELD ID="radialvelocity" datatype="float" name="radialvelocity" ucd="spect.dopplerVeloc;pos.heliocentric" unit="km/s">
+<DESCRIPTION>Radial Velocity at J2010 reference epoch</DESCRIPTION>
+</FIELD>
+<FIELD ID="ag" datatype="float" name="ag" ucd="phys.absorption;em.opt" unit="mag">
+<DESCRIPTION>Interstellar absorption in the G band assuming the extinction law of 1989ApJ...345..245C.</DESCRIPTION>
+</FIELD>
+<FIELD ID="av" datatype="float" name="av" ucd="phys.absorption;em.opt.V" unit="mag">
+<DESCRIPTION>Interstellar absorption in the V-band assuming the extinction law of 1989ApJ...345..245C.</DESCRIPTION>
+</FIELD>
+<FIELD ID="rv" datatype="float" name="rv" ucd="arith.diff;phys.absorption;em.opt.B;em.opt.V" unit="mag">
+<DESCRIPTION>Extinction parameter according to 2003A&amp;A...409..205D.</DESCRIPTION>
+</FIELD>
+<FIELD ID="magg" datatype="float" name="magg" ucd="phot.mag;em.opt.V" unit="mag">
+<DESCRIPTION>GAIA G band apparent magnitude at reference epoch. The GAIA G-band has a wide bandpass between 350 and 150 nm. This is close to Johnson V for V-I between -0.4 and 1.4.</DESCRIPTION>
+</FIELD>
+<FIELD ID="maggbp" datatype="float" name="maggbp" ucd="phot.mag;em.opt.B" unit="mag">
+<DESCRIPTION>GAIA G_BP band apparent magnitude at reference epoch. The GAIA G_BP band has a bandpass between 350 and 770 nm.</DESCRIPTION>
+</FIELD>
+<FIELD ID="maggrp" datatype="float" name="maggrp" ucd="phot.mag;em.opt.R" unit="mag">
+<DESCRIPTION>GAIA G_RP band apparent magnitude at reference epoch. The GAIA G_RP band has a bandpass between 650 and 1050 nm.</DESCRIPTION>
+</FIELD>
+<FIELD ID="maggrvs" datatype="float" name="maggrvs" ucd="phot.mag;em.opt;em.opt.R" unit="mag">
+<DESCRIPTION>GAIA G_RVS band apparent magnitude at reference epoch. The GAIA G_RVS band has a narrow bandpass between 850 and 880 nm.</DESCRIPTION>
+</FIELD>
+<FIELD ID="type" arraysize="*" datatype="char" name="type">
+<DESCRIPTION>Supernova type (one of Ia, Ib/c, II-L, II-P)</DESCRIPTION>
+</FIELD>
+<FIELD ID="sourceid" datatype="long" name="sourceid" ucd="meta.id;meta.main">
+<DESCRIPTION>GUMS source identifier</DESCRIPTION>
+<VALUES null='-9223372036854775808'/>
+</FIELD>
+<FIELD ID="sourceextendedid" arraysize="*" datatype="char" name="sourceextendedid" ucd="meta.id">
+<DESCRIPTION>GUMS extended source identifier</DESCRIPTION>
+</FIELD>
+<DATA>
+<BINARY>
+<STREAM encoding='base64'>
+</STREAM>
+</BINARY>
+</DATA>
+</TABLE>
+</RESOURCE>
+</VOTABLE>
diff --git a/test/tap/data/testdata.vot b/test/tap/data/testdata.vot
new file mode 100644
index 0000000000000000000000000000000000000000..bfec957f865ae0e186109adc3edafb4163f34872
--- /dev/null
+++ b/test/tap/data/testdata.vot
@@ -0,0 +1,676 @@
+<?xml version='1.0'?>
+<VOTABLE version="1.2"
+ xmlns="http://www.ivoa.net/xml/VOTable/v1.2">
+<!--
+ !  VOTable written by STIL version 3.0-5+ (uk.ac.starlink.votable.VOTableWriter)
+ !  at 2014-06-27T15:28:34
+ !-->
+<RESOURCE>
+<TABLE name="sn" nrows="100">
+<PARAM arraysize="19" datatype="char" name="source" value="2012arXiv1202.0132R"/>
+<PARAM arraysize="9" datatype="char" name="CoordFlavor" utype="stc:AstroCoordSystem.SpaceFrame.CoordFlavor" value="SPHERICAL"/>
+<PARAM arraysize="1" datatype="char" name="coord_naxes" utype="stc:AstroCoordSystem.SpaceFrame.CoordFlavor.coord_naxes" value="3"/>
+<PARAM arraysize="4" datatype="char" name="CoordRefFrame" utype="stc:AstroCoordSystem.SpaceFrame.CoordRefFrame" value="ICRS"/>
+<PARAM arraysize="6" datatype="char" name="Epoch" utype="stc:AstroCoords.Position3D.Epoch" value="2010.0"/>
+<PARAM arraysize="1" datatype="char" name="yearDef" utype="stc:AstroCoords.Position3D.Epoch.yearDef" value="J"/>
+<PARAM arraysize="41" datatype="char" name="URI" utype="stc:DataModel.URI" value="http://www.ivoa.net/xml/STC/stc-v1.30.xsd"/>
+<PARAM arraysize="31" datatype="char" name="server" value="http://dc.zah.uni-heidelberg.de"/>
+<PARAM arraysize="58" datatype="char" name="query" value="SELECT sourceid, alpha, delta, magg FROM gums.sn LIMIT 100"/>
+<PARAM arraysize="36" datatype="char" name="src_res" value="Contains traces from resource gums/q">
+<DESCRIPTION>GUMS-10 is the 10th version of the Gaia Universe Model Snapshot, a
+simulation of the expected contents of the Gaia cataloge run at the
+MareNostrum supercomputer. The models used and the characteristics of
+GUMS-10 are described in: A.C. Robin et al, "Gaia Universe Model
+Snapshot. A statistical analysis of the expected contents of the Gaia
+catalogue", Astronomy &amp; Astrophysics (2012), in press. For more
+details see also http://gaia.am.ub.es/GUMS-10/</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="34" datatype="char" name="src_table" value="Contains traces from table gums.sn">
+<DESCRIPTION>Supernovae in the GUMS-10 simulated GAIA result set.</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="54" datatype="char" name="copyright" value="Content from gums/q has rights note (see INFO content)">
+<DESCRIPTION>If you use this data, please acknowledge that GUMS was created using
+the MareNostrum supercomputer.</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="2" datatype="char" name="QUERY_STATUS" value="OK">
+<DESCRIPTION>Query successful</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="8" datatype="char" name="QUERY_STATUS" value="OVERFLOW"/>
+<PARAM arraysize="11" datatype="char" name="Service short name" value="GAVO DC TAP">
+<DESCRIPTION>Short name for TAP service</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="28" datatype="char" name="Service title" value="GAVO Data Center TAP service">
+<DESCRIPTION>TAP service title</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="36" datatype="char" name="Identifier" value="ivo://org.gavo.dc/__system__/tap/run">
+<DESCRIPTION>Unique resource registry identifier</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="16" datatype="char" name="Service publisher" value="The GAVO DC team">
+<DESCRIPTION>Publisher for TAP service</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="55" datatype="char" name="Service reference URL" value="http://dc.zah.uni-heidelberg.de/__system__/tap/run/info">
+<DESCRIPTION>Descriptive URL for search resource</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="50" datatype="char" name="Contact person" value="GAVO Data Center Team &lt;gavo@ari.uni-heidelberg.de&gt;">
+<DESCRIPTION>Individual to contact about this service</DESCRIPTION>
+</PARAM>
+<FIELD ID="sourceid" datatype="long" name="sourceid" ucd="meta.id;meta.main">
+<DESCRIPTION>GUMS source identifier</DESCRIPTION>
+<VALUES null='-9223372036854775808'/>
+</FIELD>
+<FIELD ID="alpha" datatype="double" name="alpha" ucd="pos.eq.ra;meta.main" unit="deg">
+<DESCRIPTION>Right ascention of the barycenter at J2010 reference epoch in the ICRS frame</DESCRIPTION>
+</FIELD>
+<FIELD ID="delta" datatype="double" name="delta" ucd="pos.eq.dec;meta.main" unit="deg">
+<DESCRIPTION>Declination of the barycenter at J2010 reference epoch in the ICRS frame</DESCRIPTION>
+</FIELD>
+<FIELD ID="magg" datatype="float" name="magg" ucd="phot.mag;em.opt.V" unit="mag">
+<DESCRIPTION>GAIA G band apparent magnitude at reference epoch. The GAIA G-band has a wide bandpass between 350 and 150 nm. This is close to Johnson V for V-I between -0.4 and 1.4.</DESCRIPTION>
+</FIELD>
+<DATA>
+<TABLEDATA>
+  <TR>
+    <TD>5227706337957249025</TD>
+    <TD>315.196288862219</TD>
+    <TD>35.8348069501976</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228535898005569537</TD>
+    <TD>316.147921016408</TD>
+    <TD>36.6446327038496</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228619830256467969</TD>
+    <TD>318.330750006546</TD>
+    <TD>37.1427090694981</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228490199553540097</TD>
+    <TD>317.277486660807</TD>
+    <TD>37.0393622283472</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228526638056079361</TD>
+    <TD>315.539651502155</TD>
+    <TD>36.8330799223032</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228191235470000129</TD>
+    <TD>314.547544336433</TD>
+    <TD>37.0316381891978</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228254186805657601</TD>
+    <TD>313.515158379912</TD>
+    <TD>37.4594494511725</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228511485411459073</TD>
+    <TD>315.14630133005</TD>
+    <TD>37.30463920468</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228510390194798593</TD>
+    <TD>315.138724413456</TD>
+    <TD>37.3939357419666</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228207019474812929</TD>
+    <TD>315.105090571779</TD>
+    <TD>37.7967663884429</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228645273642729473</TD>
+    <TD>316.445593967068</TD>
+    <TD>37.7724610890285</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228210176275775489</TD>
+    <TD>314.202309571622</TD>
+    <TD>37.7622018074421</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228340180640858113</TD>
+    <TD>313.926940760892</TD>
+    <TD>38.1681256686532</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228338668812369921</TD>
+    <TD>313.90078126178</TD>
+    <TD>38.3468303111387</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228678658423521281</TD>
+    <TD>318.638315340027</TD>
+    <TD>37.4599061823721</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228643048849670145</TD>
+    <TD>319.842618598044</TD>
+    <TD>37.9120544280358</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228662732684787713</TD>
+    <TD>317.822382752931</TD>
+    <TD>37.730199142655</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228557072194338817</TD>
+    <TD>320.851132165837</TD>
+    <TD>38.0701678757365</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228059294074667009</TD>
+    <TD>322.683603029896</TD>
+    <TD>38.732846513021</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5227925888095485953</TD>
+    <TD>320.553882864028</TD>
+    <TD>38.6789639187946</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5227935367088308225</TD>
+    <TD>320.101290659979</TD>
+    <TD>39.0461898040604</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5227934688483475457</TD>
+    <TD>320.567657954422</TD>
+    <TD>39.2569187331424</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228419671895572481</TD>
+    <TD>316.501197124071</TD>
+    <TD>38.3542948966148</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228404837078532097</TD>
+    <TD>317.530403840919</TD>
+    <TD>39.5711378023383</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228457149780197377</TD>
+    <TD>319.129957970345</TD>
+    <TD>38.8903631574443</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228411159270391809</TD>
+    <TD>318.350167533456</TD>
+    <TD>39.3739776364656</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228411343953985537</TD>
+    <TD>318.482291321702</TD>
+    <TD>39.4682813466895</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5224886425639452673</TD>
+    <TD>319.915330168399</TD>
+    <TD>40.5474606685377</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5226038743890132993</TD>
+    <TD>310.809142713647</TD>
+    <TD>37.2981603041502</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5225901627059208193</TD>
+    <TD>310.195297620624</TD>
+    <TD>38.1682983805255</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228389010124046337</TD>
+    <TD>314.311278360606</TD>
+    <TD>39.1132344243341</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228357485064093697</TD>
+    <TD>313.765487694087</TD>
+    <TD>39.2010205946055</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228357416344616961</TD>
+    <TD>313.948253770717</TD>
+    <TD>39.2341334918952</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228138918473367553</TD>
+    <TD>311.600215055814</TD>
+    <TD>38.7829579962378</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5225905883371798529</TD>
+    <TD>309.209065483013</TD>
+    <TD>38.3922939934094</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5225922745413402625</TD>
+    <TD>308.273187634308</TD>
+    <TD>38.623472717439</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228170748475998209</TD>
+    <TD>311.504809355259</TD>
+    <TD>39.2736949239031</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228128756580745217</TD>
+    <TD>310.060117657241</TD>
+    <TD>39.6150923667196</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228125286247170049</TD>
+    <TD>310.391975607677</TD>
+    <TD>39.8567447863678</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5224523603982155777</TD>
+    <TD>310.152548466881</TD>
+    <TD>40.5933397790503</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228287051895406593</TD>
+    <TD>315.254195083038</TD>
+    <TD>40.0540124515679</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228273862050840577</TD>
+    <TD>316.999352337993</TD>
+    <TD>40.027560397733</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5225021858843197441</TD>
+    <TD>318.644478458537</TD>
+    <TD>40.6779438099924</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5225035018622992385</TD>
+    <TD>317.991463519871</TD>
+    <TD>40.9677441144194</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5225072127140429825</TD>
+    <TD>316.867441178056</TD>
+    <TD>41.9057772663151</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5225072367658598401</TD>
+    <TD>317.075907997518</TD>
+    <TD>41.9597478851952</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5224716538208059393</TD>
+    <TD>313.033381590424</TD>
+    <TD>41.0862110982932</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5224690454871670785</TD>
+    <TD>311.948458977198</TD>
+    <TD>41.2530675452654</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5225070142865539073</TD>
+    <TD>317.083554655278</TD>
+    <TD>42.1259327238697</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5224684089730138113</TD>
+    <TD>314.089161892257</TD>
+    <TD>41.9708284872533</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5224636059110866945</TD>
+    <TD>314.400321502975</TD>
+    <TD>42.3087726851734</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5224644606095785985</TD>
+    <TD>313.645709386859</TD>
+    <TD>42.4971549481861</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5225193335412490241</TD>
+    <TD>315.244056852409</TD>
+    <TD>42.906387451096</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228101612387434497</TD>
+    <TD>323.946749631999</TD>
+    <TD>38.9774811407551</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228088950823845889</TD>
+    <TD>322.965760533976</TD>
+    <TD>39.4816358229734</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228086506987454465</TD>
+    <TD>322.524642165751</TD>
+    <TD>39.3913412985295</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228082809020612609</TD>
+    <TD>323.086525996038</TD>
+    <TD>39.9569058778203</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5228085098238181377</TD>
+    <TD>323.378976745126</TD>
+    <TD>39.9909965671913</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5227900238550794241</TD>
+    <TD>325.947644795287</TD>
+    <TD>39.8622684927386</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5224755742669537281</TD>
+    <TD>327.292078064864</TD>
+    <TD>40.473580488463</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5224801402466861057</TD>
+    <TD>326.41569461502</TD>
+    <TD>41.1675012881196</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5224907135971753985</TD>
+    <TD>321.814585593307</TD>
+    <TD>40.5017107987482</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5224912689364467713</TD>
+    <TD>322.474668103376</TD>
+    <TD>40.7876461525313</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5224941637444042753</TD>
+    <TD>320.738328210729</TD>
+    <TD>40.5629925694948</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5224940666781433857</TD>
+    <TD>320.250893992984</TD>
+    <TD>41.1634130035394</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5224927141929418753</TD>
+    <TD>321.863542181784</TD>
+    <TD>41.5729254211298</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5224986902104375297</TD>
+    <TD>325.246238155948</TD>
+    <TD>42.1565777812423</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5225019698474647553</TD>
+    <TD>323.396785057197</TD>
+    <TD>41.5880307398769</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5224955600382722049</TD>
+    <TD>322.517800858037</TD>
+    <TD>41.8237610271847</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5224831699166167041</TD>
+    <TD>323.118494600869</TD>
+    <TD>42.3750358062487</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5224858555596668929</TD>
+    <TD>324.918116160156</TD>
+    <TD>42.3752514943318</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5224856356573413377</TD>
+    <TD>324.4784816304</TD>
+    <TD>42.46964115857</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5260489398125854721</TD>
+    <TD>328.501192472745</TD>
+    <TD>40.7150346615374</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5264154912194822145</TD>
+    <TD>328.849577108117</TD>
+    <TD>41.0695787815177</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5260548449631207425</TD>
+    <TD>328.800988064444</TD>
+    <TD>42.0664845440737</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5224757619570245633</TD>
+    <TD>326.101379574238</TD>
+    <TD>41.806210370532</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5224756915195609089</TD>
+    <TD>326.471956864544</TD>
+    <TD>42.0126282312272</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5260532828835151873</TD>
+    <TD>327.435294140766</TD>
+    <TD>42.3992262672942</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5260531072193527809</TD>
+    <TD>327.198909516082</TD>
+    <TD>42.7478419636105</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5260542758799540225</TD>
+    <TD>327.887606567932</TD>
+    <TD>42.6236566188535</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5260660973479395329</TD>
+    <TD>326.073858008429</TD>
+    <TD>43.3546455828375</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5260725440938508289</TD>
+    <TD>326.558221138756</TD>
+    <TD>43.4106167711329</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5264186024937914369</TD>
+    <TD>329.486489620386</TD>
+    <TD>42.6516399387462</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5260511212264751105</TD>
+    <TD>328.31979095659</TD>
+    <TD>43.1663725965885</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5264374758685802497</TD>
+    <TD>329.515222942698</TD>
+    <TD>43.9904808369981</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5264303453638754305</TD>
+    <TD>329.435473863596</TD>
+    <TD>44.0758732707729</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5260592159513378817</TD>
+    <TD>329.128518386386</TD>
+    <TD>44.2614704113209</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5225085673467281409</TD>
+    <TD>319.120731512924</TD>
+    <TD>41.5540952888462</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5224915403783798785</TD>
+    <TD>320.791989793507</TD>
+    <TD>42.2286522853318</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5225266367036391425</TD>
+    <TD>320.762347236735</TD>
+    <TD>42.4649033314846</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5224960535300145153</TD>
+    <TD>322.54003062151</TD>
+    <TD>42.2407563101143</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5224862219203772417</TD>
+    <TD>323.333101161478</TD>
+    <TD>42.5494790946244</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5224835594701504513</TD>
+    <TD>322.065062640506</TD>
+    <TD>43.1338723489886</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5225263253185101825</TD>
+    <TD>316.390889854207</TD>
+    <TD>42.7484218698054</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5225213848176295937</TD>
+    <TD>316.472765214816</TD>
+    <TD>43.499451176508</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5225112469768241153</TD>
+    <TD>319.657659923454</TD>
+    <TD>43.4408787249805</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5225153065799122945</TD>
+    <TD>320.387669861088</TD>
+    <TD>43.8725637888719</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5225098042973093889</TD>
+    <TD>321.970847371195</TD>
+    <TD>44.2731477586804</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5224328779970641921</TD>
+    <TD>321.402786393259</TD>
+    <TD>44.5459368319667</TD>
+    <TD>0.0</TD>
+  </TR>
+  <TR>
+    <TD>5224353149615079425</TD>
+    <TD>318.918788589935</TD>
+    <TD>44.3809159912124</TD>
+    <TD>0.0</TD>
+  </TR>
+</TABLEDATA>
+</DATA>
+</TABLE>
+</RESOURCE>
+</VOTABLE>
diff --git a/test/tap/data/testdata_binary.vot b/test/tap/data/testdata_binary.vot
new file mode 100644
index 0000000000000000000000000000000000000000..829a5b88f3bfbf8b803d35405779860be2e4d303
--- /dev/null
+++ b/test/tap/data/testdata_binary.vot
@@ -0,0 +1,137 @@
+<?xml version='1.0'?>
+<VOTABLE version="1.2"
+ xmlns="http://www.ivoa.net/xml/VOTable/v1.2">
+<!--
+ !  VOTable written by STIL version 3.0-5+ (uk.ac.starlink.votable.VOTableWriter)
+ !  at 2014-06-27T15:28:54
+ !-->
+<RESOURCE>
+<TABLE name="sn" nrows="100">
+<PARAM arraysize="19" datatype="char" name="source" value="2012arXiv1202.0132R"/>
+<PARAM arraysize="9" datatype="char" name="CoordFlavor" utype="stc:AstroCoordSystem.SpaceFrame.CoordFlavor" value="SPHERICAL"/>
+<PARAM arraysize="1" datatype="char" name="coord_naxes" utype="stc:AstroCoordSystem.SpaceFrame.CoordFlavor.coord_naxes" value="3"/>
+<PARAM arraysize="4" datatype="char" name="CoordRefFrame" utype="stc:AstroCoordSystem.SpaceFrame.CoordRefFrame" value="ICRS"/>
+<PARAM arraysize="6" datatype="char" name="Epoch" utype="stc:AstroCoords.Position3D.Epoch" value="2010.0"/>
+<PARAM arraysize="1" datatype="char" name="yearDef" utype="stc:AstroCoords.Position3D.Epoch.yearDef" value="J"/>
+<PARAM arraysize="41" datatype="char" name="URI" utype="stc:DataModel.URI" value="http://www.ivoa.net/xml/STC/stc-v1.30.xsd"/>
+<PARAM arraysize="31" datatype="char" name="server" value="http://dc.zah.uni-heidelberg.de"/>
+<PARAM arraysize="58" datatype="char" name="query" value="SELECT sourceid, alpha, delta, magg FROM gums.sn LIMIT 100"/>
+<PARAM arraysize="36" datatype="char" name="src_res" value="Contains traces from resource gums/q">
+<DESCRIPTION>GUMS-10 is the 10th version of the Gaia Universe Model Snapshot, a
+simulation of the expected contents of the Gaia cataloge run at the
+MareNostrum supercomputer. The models used and the characteristics of
+GUMS-10 are described in: A.C. Robin et al, "Gaia Universe Model
+Snapshot. A statistical analysis of the expected contents of the Gaia
+catalogue", Astronomy &amp; Astrophysics (2012), in press. For more
+details see also http://gaia.am.ub.es/GUMS-10/</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="34" datatype="char" name="src_table" value="Contains traces from table gums.sn">
+<DESCRIPTION>Supernovae in the GUMS-10 simulated GAIA result set.</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="54" datatype="char" name="copyright" value="Content from gums/q has rights note (see INFO content)">
+<DESCRIPTION>If you use this data, please acknowledge that GUMS was created using
+the MareNostrum supercomputer.</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="2" datatype="char" name="QUERY_STATUS" value="OK">
+<DESCRIPTION>Query successful</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="8" datatype="char" name="QUERY_STATUS" value="OVERFLOW"/>
+<PARAM arraysize="11" datatype="char" name="Service short name" value="GAVO DC TAP">
+<DESCRIPTION>Short name for TAP service</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="28" datatype="char" name="Service title" value="GAVO Data Center TAP service">
+<DESCRIPTION>TAP service title</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="36" datatype="char" name="Identifier" value="ivo://org.gavo.dc/__system__/tap/run">
+<DESCRIPTION>Unique resource registry identifier</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="16" datatype="char" name="Service publisher" value="The GAVO DC team">
+<DESCRIPTION>Publisher for TAP service</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="55" datatype="char" name="Service reference URL" value="http://dc.zah.uni-heidelberg.de/__system__/tap/run/info">
+<DESCRIPTION>Descriptive URL for search resource</DESCRIPTION>
+</PARAM>
+<PARAM arraysize="50" datatype="char" name="Contact person" value="GAVO Data Center Team &lt;gavo@ari.uni-heidelberg.de&gt;">
+<DESCRIPTION>Individual to contact about this service</DESCRIPTION>
+</PARAM>
+<FIELD ID="sourceid" datatype="long" name="sourceid" ucd="meta.id;meta.main">
+<DESCRIPTION>GUMS source identifier</DESCRIPTION>
+<VALUES null='-9223372036854775808'/>
+</FIELD>
+<FIELD ID="alpha" datatype="double" name="alpha" ucd="pos.eq.ra;meta.main" unit="deg">
+<DESCRIPTION>Right ascention of the barycenter at J2010 reference epoch in the ICRS frame</DESCRIPTION>
+</FIELD>
+<FIELD ID="delta" datatype="double" name="delta" ucd="pos.eq.dec;meta.main" unit="deg">
+<DESCRIPTION>Declination of the barycenter at J2010 reference epoch in the ICRS frame</DESCRIPTION>
+</FIELD>
+<FIELD ID="magg" datatype="float" name="magg" ucd="phot.mag;em.opt.V" unit="mag">
+<DESCRIPTION>GAIA G band apparent magnitude at reference epoch. The GAIA G-band has a wide bandpass between 350 and 150 nm. This is close to Johnson V for V-I between -0.4 and 1.4.</DESCRIPTION>
+</FIELD>
+<DATA>
+<BINARY>
+<STREAM encoding='base64'>
+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
+W6obV0BGMMHa7mPtAAAAAA==
+</STREAM>
+</BINARY>
+</DATA>
+</TABLE>
+</RESOURCE>
+</VOTABLE>