C. Translator

From 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:

The library already includes two default implementations which lets to translate ADQL into an SQL adapted to Postgres: 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.

UDF translation
Note that in all implementations provided by the library, User Defined Functions are translated merely by calling their function translate(ADQLTranslator. Anyway, the translator can choose to not use this function and provide its own translation of the UDF.


PostgreSQLTranslator is able to translate any SQL-like part of an ADQL query into SQL. However, the geometrical functions (i.e. POINT, BOX, CIRCLE, CONTAINS, ...) can not be translated for only Postgres...


Indeed, Postgres has no default way to manage geographical information. For that a plugin like PgSphere and Q3C is required. In its current version, the library includes only the translator for PgSphere. Thus, if you want to translate fully (geometrical functions included) an ADQL query, you have to use PgSphereTranslator, because it is the only one to be able to properly translate functions like POINT, BOX, CIRCLE, CONTAINS, ...


Considering the following ADQL parsing:

ADQLParser parser = new ADQLParser();
ADQLQuery query = parser.parse("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:

ADQLTranslator translator = new PostgreSQLTranslator();
System.out.println("SQL (for Postgres alone):\n" + translator.translate(query));
ADQLTranslator translator = new PgSphereTranslator();
System.out.println("SQL (for Postgres + PgSphere):\n" + translator.translate(query));

Here are their respective output:

SQL (for Postgres alone):
FROM data
WHERE CONTAINS(POINT('ICRS', ra, dec), CIRCLE('ICRS', 13, 2, 10)) = 1
SQL (for Postgres + PgSphere):
FROM data
WHERE (spoint(radians(ra),radians(dec)) @ scircle(spoint(radians(13),radians(2)),radians(10))) = '1'