package adql.translator;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import adql.db.DBChecker;
import adql.db.DBColumn;
import adql.db.DBTable;
import adql.db.DefaultDBColumn;
import adql.db.DefaultDBTable;
import adql.db.SearchColumnList;
import adql.parser.ADQLParser;
import adql.parser.ParseException;
import adql.parser.SQLServer_ADQLQueryFactory;
import adql.query.ADQLQuery;
import adql.query.from.ADQLJoin;
import adql.query.operand.ADQLColumn;
public class TestSQLServerTranslator {
private List<DBTable> tables = null;
@Before
public void setUp() throws Exception{
tables = new ArrayList<DBTable>(2);
DefaultDBTable t = new DefaultDBTable("aTable");
t.addColumn(new DefaultDBColumn("id", t));
t.addColumn(new DefaultDBColumn("name", t));
t.addColumn(new DefaultDBColumn("aColumn", t));
tables.add(t);
t = new DefaultDBTable("anotherTable");
t.addColumn(new DefaultDBColumn("id", t));
t.addColumn(new DefaultDBColumn("name", t));
t.addColumn(new DefaultDBColumn("anotherColumn", t));
tables.add(t);
}
@Test
public void testNaturalJoin(){
final String adqlquery = "SELECT id, name, aColumn, anotherColumn FROM aTable A NATURAL JOIN anotherTable B;";
try{
ADQLQuery query = (new ADQLParser(new DBChecker(tables), new SQLServer_ADQLQueryFactory())).parseQuery(adqlquery);
SQLServerTranslator translator = new SQLServerTranslator();
// Test the FROM part:
assertEquals("\"aTable\" AS A INNER JOIN \"anotherTable\" AS B ON \"aTable\".\"id\"=\"anotherTable\".\"id\" AND \"aTable\".\"name\"=\"anotherTable\".\"name\"", translator.translate(query.getFrom()));
// Test the SELECT part (in order to ensure the usual common columns (due to NATURAL) are actually translated as columns of the first joined table):
assertEquals("SELECT A.\"id\" AS \"id\" , A.\"name\" AS \"name\" , A.\"aColumn\" AS \"aColumn\" , B.\"anotherColumn\" AS \"anotherColumn\"", translator.translate(query.getSelect()));
}catch(ParseException pe){
pe.printStackTrace();
fail("The given ADQL query is completely correct. No error should have occurred while parsing it. (see the console for more details)");
}catch(TranslationException te){
te.printStackTrace();
fail("No error was expected from this translation. (see the console for more details)");
}
}
@Test
public void testNaturalJoin2(){
final String adqlquery = "SELECT id, name, aColumn, anotherColumn FROM aTable \"A\" NATURAL JOIN anotherTable B;";
try{
ADQLQuery query = (new ADQLParser(new DBChecker(tables), new SQLServer_ADQLQueryFactory())).parseQuery(adqlquery);
SQLServerTranslator translator = new SQLServerTranslator();
ADQLJoin join = (ADQLJoin)query.getFrom();
try{
StringBuffer buf = new StringBuffer();
// Find duplicated items between the two lists and translate them as ON conditions:
DBColumn rightCol;
SearchColumnList leftList = join.getLeftTable().getDBColumns();
SearchColumnList rightList = join.getRightTable().getDBColumns();
for(DBColumn leftCol : leftList){
// search for at most one column with the same name in the RIGHT list
// and throw an exception is there are several matches:
rightCol = ADQLJoin.findAtMostOneColumn(leftCol.getADQLName(), (byte)0, rightList, false);
// if there is one...
if (rightCol != null){
// ...check there is only one column with this name in the LEFT list,
// and throw an exception if it is not the case:
ADQLJoin.findExactlyOneColumn(leftCol.getADQLName(), (byte)0, leftList, true);
// ...append the corresponding join condition:
if (buf.length() > 0)
buf.append(" AND ");
ADQLColumn col = new ADQLColumn(leftCol.getADQLName());
col.setDBLink(leftCol);
// TODO col.setAdqlTable(adqlTable);
buf.append(translator.translate(col));
buf.append("=");
col = new ADQLColumn(rightCol.getADQLName());
col.setDBLink(rightCol);
buf.append(translator.translate(col));
}
}
System.out.println("ON " + buf.toString());
}catch(Exception uje){
System.err.println("Impossible to resolve the NATURAL JOIN between " + join.getLeftTable().toADQL() + " and " + join.getRightTable().toADQL() + "!");
uje.printStackTrace();
}
}catch(ParseException pe){
pe.printStackTrace();
fail("The given ADQL query is completely correct. No error should have occurred while parsing it. (see the console for more details)");
}
}
@Test
public void testJoinWithUSING(){
final String adqlquery = "SELECT B.id, name, aColumn, anotherColumn FROM aTable A JOIN anotherTable B USING(name);";
try{
ADQLQuery query = (new ADQLParser(new DBChecker(tables), new SQLServer_ADQLQueryFactory())).parseQuery(adqlquery);
SQLServerTranslator translator = new SQLServerTranslator();
// Test the FROM part:
assertEquals("\"aTable\" AS A INNER JOIN \"anotherTable\" AS B ON \"aTable\".\"name\"=\"anotherTable\".\"name\"", translator.translate(query.getFrom()));
// Test the SELECT part (in order to ensure the usual common columns (due to USING) are actually translated as columns of the first joined table):
assertEquals("SELECT B.\"id\" AS \"id\" , A.\"name\" AS \"name\" , A.\"aColumn\" AS \"aColumn\" , B.\"anotherColumn\" AS \"anotherColumn\"", translator.translate(query.getSelect()));
}catch(ParseException pe){
pe.printStackTrace();
fail("The given ADQL query is completely correct. No error should have occurred while parsing it. (see the console for more details)");
}catch(TranslationException te){
te.printStackTrace();
fail("No error was expected from this translation. (see the console for more details)");
}
}
}