C. Translator

With the ADQL tree generated by the parser, it is possible to translate an ADQL query into SQL or into another query language...

The interface ADQLTranslator

ADQLTranslator works exactly as ADQLQueryFactory: 1 function per ADQL object. For instance:

For PostgreSQL, the library already includes two default implementations which lets translate ADQL into a suitable SQL query: PostgreSQLTranslator and PgSphereTranslator.

Since there are always slight differences between the SQL of each DataBase Manager System (DBMS), you may have to write an implementation of ADQLTranslator (or an extension of PostgreSQLTranslator) adapted to your DBMS, as it has been done for MySQL ( MySQLTranslator) and MS SQL Server ( SQLServerTranslator) available in the library since version 1.4.

No translation for geometries!

PostgreSQLTranslator, MySQLTranslator and SQLServerTranslator are not able to translate geometrical terms (e.g. POINT, CIRCLE, CONTAINS, ...). You have to extend these translators in order to translate these terms in the way which suits the best your database configuration.

UDF translation
Note that in all implementations provided by the library, User Defined Functions are translated merely by calling their own function UserDefinedFunction.translate(ADQLTranslator). But of course, by overwritting directly the translator function ADQLTranslator.translate(UserDefinedFunction) you can get the same result.

Example

Considering the following ADQL parsing:

ADQLParser parser = new ADQLParser();
ADQLQuery query = parser.parseQuery("SELECT * FROM data WHERE CONTAINS(POINT('ICRS', ra, dec), CIRCLE('ICRS', 13, 2, 10)) = 1");

Below are the differences between the implementation of each translator: left for PostgreSQLTranslator and right for PgSphereTranslator:

PostgreSQLTranslator

The default translator for PostgreSQL does not translate ADQL's geometrical terms. UDFs are translated in SQL exactly as provided in ADQL.

Source code:
ADQLTranslator translator = new PostgreSQLTranslator();
System.out.println("-- SQL (for Postgres alone):\n" + translator.translate(query));
Result:
-- SQL (for Postgres alone):
SELECT 
FROM data
WHERE CONTAINS(POINT('ICRS', ra, dec), CIRCLE('ICRS', 13, 2, 10)) = 1

PgSphereTranslator

Postgres has no default way to manage geographical information. For that a plugin like PgSphere or Q3C is required. In its current version, the library includes only the translator for PgSphere.

Source code:
ADQLTranslator translator = new PgSphereTranslator();
System.out.println("-- SQL (for Postgres + PgSphere):\n" + translator.translate(query));
Result:
-- SQL (for Postgres + PgSphere):
SELECT 
FROM data
WHERE (spoint(radians(ra),radians(dec)) @ scircle(spoint(radians(13),radians(2)),radians(10))) = '1'

MySQLTranslator

Source code:
ADQLTranslator translator = new MySQLTranslator();
System.out.println("-- SQL (for MySQL):\n" + translator.translate(query));
Result:
-- SQL (for MySQL):
SELECT 
FROM data
WHERE CONTAINS(POINT('ICRS', ra, dec), CIRCLE('ICRS', 13, 2, 10)) = 1

SQLServerTranslator

Source code:
ADQLTranslator translator = new SQLServerTranslator();
System.out.println("-- SQL (for SQLServer):\n" + translator.translate(query));
Result:
-- SQL (for SQLServer):
SELECT 
FROM data
WHERE CONTAINS(POINT('ICRS', ra, dec), CIRCLE('ICRS', 13, 2, 10)) = 1