Class JDBCTranslator
- All Implemented Interfaces:
ADQLTranslator
- Direct Known Subclasses:
MySQLTranslator
,PostgreSQLTranslator
,SQLServerTranslator
ADQLTranslator
which translates ADQL queries in
SQL queries.
It is already able to translate all SQL standard features, but lets abstract
the translation of all geometrical functions. So, this translator must be
extended as PostgreSQLTranslator
, PgSphereTranslator
,
MySQLTranslator
and SQLServerTranslator
are doing.
Note: Its default implementation of the SQL syntax has been inspired by the PostgreSQL one. However, it should work also with other DBMS, although some translations might be needed (as it is has been done for PostgreSQL about the mathematical functions).
SQL with or without case sensitivity?
In ADQL and in SQL, it is possible to tell the parser to respect the exact
case or not of an identifier (schema, table or column name) by surrounding
it with double quotes. However ADQL identifiers and SQL ones may be
different. In that way, the case sensitivity specified in ADQL on the
different identifiers can not be kept in SQL. That's why this translator
lets specify a general rule on which types of SQL identifier must be double
quoted. This can be done by implementing the abstract function
isCaseSensitive(IdentifierField)
. The functions translating column
and table names will call this function in order to surround the identifiers
by double quotes or not. So, be careful if you want to override the
functions translating columns and tables!
Translation of "SELECT TOP"
The default behavior of this translator is to translate the ADQL "TOP" into
the SQL "LIMIT" at the end of the query. This is ok for some DBMS, but not
all. So, if your DBMS does not know the "LIMIT" keyword, you should override
the function translating the whole query: translate(ADQLQuery)
.
Here is its current implementation:
StringBuffer sql = new StringBuffer(translate(query.getSelect())); sql.append("\nFROM ").append(translate(query.getFrom())); if (!query.getWhere().isEmpty()) sql.append('\n').append(translate(query.getWhere())); if (!query.getGroupBy().isEmpty()) sql.append('\n').append(translate(query.getGroupBy())); if (!query.getHaving().isEmpty()) sql.append('\n').append(translate(query.getHaving())); if (!query.getOrderBy().isEmpty()) sql.append('\n').append(translate(query.getOrderBy())); if (query.getSelect().hasLimit()) sql.append("\nLimit ").append(query.getSelect().getLimit()); return sql.toString();
Translation of ADQL functions
All ADQL functions are by default not translated. Consequently, the SQL
translation is actually the ADQL expression. Generally the ADQL expression
is generic enough. However some mathematical functions may need to be
translated differently. For instance PostgreSQLTranslator
is
translating differently: LOG, LOG10, RAND and TRUNC.
Note: Geometric regions and types have not been managed here. They stay abstract because it is obviously impossible to have a generic translation and conversion ; it totally depends from the database system.
Translation of "FROM" with JOINs
The FROM clause is translated into SQL as written in ADQL. There is no differences except the identifiers that are replaced. The tables' aliases and their case sensitivity are kept like in ADQL.
- Since:
- 1.4
- See Also:
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionappendIdentifier
(StringBuffer str, String id, boolean caseSensitive) Appends the given identifier to the given StringBuffer.final StringBuffer
appendIdentifier
(StringBuffer str, String id, IdentifierField field) Appends the given identifier in the given StringBuffer.abstract DBType
convertTypeFromDB
(int dbmsType, String rawDbmsTypeName, String dbmsTypeName, String[] typeParams) Convert any type provided by a JDBC driver into a type understandable by the ADQL/TAP library.abstract String
convertTypeToDB
(DBType type) Convert any type provided by the ADQL/TAP library into a type understandable by a JDBC driver.getColumnName
(DBColumn column) Get the DB name of the given columnfinal String
Gets the default SQL output for the given ADQL function.protected final String
getDefaultADQLList
(ADQLList<? extends ADQLObject> list) Gets the default SQL output for a list of ADQL objects.protected String
getDefaultADQLList
(ADQLList<? extends ADQLObject> list, boolean withNamePrefix) Gets the default SQL output for a list of ADQL objects.final String
Default translation for the given CAST function.protected String
Gets the default SQL output for a column reference.getQualifiedSchemaName
(DBTable table) Get the qualified DB name of the schema containing the given table.getQualifiedTableName
(DBTable table) Get the qualified DB name of the given table.getTableName
(DBTable table, boolean withSchema) Get the DB name of the given table.abstract boolean
isCaseSensitive
(IdentifierField field) Tell whether the specified identifier MUST be translated so that being interpreted case sensitively or not.translate
(ADQLList<? extends ADQLObject> list) translate
(ADQLObject obj) translate
(ClauseADQL<WithItem> clause) translate
(ClauseConstraints clause) translate
(ClauseSelect clause) translate
(ColumnReference ref) translate
(ADQLConstraint cons) translate
(Comparison comp) translate
(NotConstraint notCons) translate
(FromContent content) translate
(ADQLColumn column) translate
(ADQLOperand op) translate
(Concatenation concat) translate
(ADQLFunction fct) translate
(CastFunction fct) translate
(GeometryFunction.GeometryValue<? extends GeometryFunction> geomValue) translate
(RegionFunction fct) translate
(MathFunction fct) translate
(SQLFunction fct) translate
(LowerFunction fct) translate
(UpperFunction fct) translate
(NegativeOperand negOp) translate
(NumericConstant numConst) translate
(StringConstant strConst) translate
(SelectAllColumns item) translate
(SelectItem item) translate
(SetOperation set) abstract Region
translateGeometryFromDB
(Object jdbcColValue) Parse the given JDBC column value as a geometry object and convert it into aRegion
.abstract Object
translateGeometryToDB
(Region region) Convert the given STC region into a DB column value.
-
Constructor Details
-
JDBCTranslator
public JDBCTranslator()
-
-
Method Details
-
isCaseSensitive
Tell whether the specified identifier MUST be translated so that being interpreted case sensitively or not. By default, an identifier that must be translated with case sensitivity will be surrounded by double quotes. But, if this function returns FALSE, the SQL name will be written just as given in the metadata, without double quotes.
WARNING: An
IdentifierField
object can be a SCHEMA, TABLE, COLUMN and ALIAS. However, in this translator, aliases are translated like in ADQL (so, with the same case sensitivity specification as in ADQL). So, this function will never be used to know the case sensitivity to apply to an alias. It is then useless to write a special behavior for the ALIAS value.- Parameters:
field
- The identifier whose the case sensitive to apply is asked.- Returns:
- true if the specified identifier must be translated case sensitivity, false otherwise (included if ALIAS or NULL).
-
getQualifiedSchemaName
Get the qualified DB name of the schema containing the given table.
Note: This function will, by default, add double quotes if the schema name must be case sensitive in the SQL query. This information is provided by
isCaseSensitive(IdentifierField)
.- Parameters:
table
- A table of the schema whose the qualified DB name is asked.- Returns:
- The qualified (with DB catalog name prefix if any, and with double quotes if needed) DB schema name, or an empty string if there is no schema or no DB name.
-
getQualifiedTableName
Get the qualified DB name of the given table.
Note: This function will, by default, add double quotes if the table name must be case sensitive in the SQL query. This information is provided by
isCaseSensitive(IdentifierField)
.- Parameters:
table
- The table whose the qualified DB name is asked.- Returns:
- The qualified (with DB catalog and schema prefix if any, and with double quotes if needed) DB table name, or an empty string if the given table is NULL or if there is no DB name.
- See Also:
-
getTableName
Get the DB name of the given table. The second parameter lets specify whether the table name must be prefixed by the qualified schema name or not.
Note: This function will, by default, add double quotes if the table name must be case sensitive in the SQL query. This information is provided by
isCaseSensitive(IdentifierField)
.- Parameters:
table
- The table whose the DB name is asked.withSchema
- true if the qualified schema name must prefix the table name, false otherwise.- Returns:
- The DB table name (prefixed by the qualified schema name if asked, and with double quotes if needed), or an empty string if the given table is NULL or if there is no DB name.
- Since:
- 2.0
-
getColumnName
Get the DB name of the given column
Note: This function will, by default, add double quotes if the column name must be case sensitive in the SQL query. This information is provided by
isCaseSensitive(IdentifierField)
.Caution: The given column may be NULL and in this case an empty string will be returned. But if the given column is not NULL, its DB name MUST NOT BE NULL!
- Parameters:
column
- The column whose the DB name is asked.- Returns:
- The DB column name (with double quotes if needed), or an empty string if the given column is NULL.
-
appendIdentifier
Appends the given identifier in the given StringBuffer.
This function just call
appendIdentifier(StringBuffer, String, boolean)
with the same 2 first parameters. The third one is the result of:
.isCaseSensitive(field)
Note: In order to keep a consistent output of the
appendIdentifier(...)
functions, this function can not be overwritten ; it is just a shortcut function.- Parameters:
str
- The string buffer.id
- The identifier to append.field
- The type of identifier (column, table, schema, catalog or alias ?).- Returns:
- The string buffer + identifier.
- See Also:
-
appendIdentifier
Appends the given identifier to the given StringBuffer.- Parameters:
str
- The string buffer.id
- The identifier to append.caseSensitive
- true to format the identifier so that preserving the case sensitivity, false otherwise.- Returns:
- The string buffer + identifier.
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
getDefaultADQLList
protected final String getDefaultADQLList(ADQLList<? extends ADQLObject> list) throws TranslationException Gets the default SQL output for a list of ADQL objects.Implementation note: This function just calls
getDefaultADQLList(ADQLList, boolean)
with the given list in first parameter andtrue
in second one. In other words, this function always prefixes the list items by the list name.- Parameters:
list
- List to format into SQL.- Returns:
- The corresponding SQL.
- Throws:
TranslationException
- If there is an error during the translation.- See Also:
-
getDefaultADQLList
protected String getDefaultADQLList(ADQLList<? extends ADQLObject> list, boolean withNamePrefix) throws TranslationException Gets the default SQL output for a list of ADQL objects.- Parameters:
list
- List to format into SQL.withNamePrefix
- Prefix the list by its name or not. (e.g. 'false' for a Concatenation)- Returns:
- The corresponding SQL.
- Throws:
TranslationException
- If there is an error during the translation.- Since:
- 1.4
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
getDefaultColumnReference
Gets the default SQL output for a column reference.- Parameters:
ref
- The column reference to format into SQL.- Returns:
- The corresponding SQL.
- Throws:
TranslationException
- If there is an error during the translation.
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
getDefaultADQLFunction
Gets the default SQL output for the given ADQL function.- Parameters:
fct
- The ADQL function to format into SQL.- Returns:
- The corresponding SQL.
- Throws:
TranslationException
- If there is an error during the translation.
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
getDefaultCastFunction
Default translation for the given CAST function.It basically writes the same as in ADQL, except for the target datatype which is written, as much as possible, in SQL.
- Parameters:
fct
- The CAST function to translate.- Returns:
- The corresponding translation.
- Throws:
TranslationException
- If any error occurred during translation.
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
- Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
translate
public String translate(GeometryFunction.GeometryValue<? extends GeometryFunction> geomValue) throws TranslationException - Specified by:
translate
in interfaceADQLTranslator
- Throws:
TranslationException
-
convertTypeFromDB
public abstract DBType convertTypeFromDB(int dbmsType, String rawDbmsTypeName, String dbmsTypeName, String[] typeParams) Convert any type provided by a JDBC driver into a type understandable by the ADQL/TAP library.- Parameters:
dbmsType
- Type returned by a JDBC driver. Note: this value is returned by ResultSetMetadata.getColumnType(int) and correspond to a type of java.sql.TypesrawDbmsTypeName
- Full name of the type returned by a JDBC driver. Note: this name is returned by ResultSetMetadata.getColumnTypeName(int) ; this name may contain parametersdbmsTypeName
- Name of type, without the eventual parameters. Note: this name is extracted from rawDbmsTypeName.typeParams
- The eventual type parameters (e.g. char string length). Note: these parameters are extracted from rawDbmsTypeName.- Returns:
- The corresponding ADQL/TAP type or NULL if the specified type is unknown.
-
convertTypeToDB
Convert any type provided by the ADQL/TAP library into a type understandable by a JDBC driver.
Note: The returned DBMS type may contain some parameters between brackets.
- Parameters:
type
- The ADQL/TAP library's type to convert.- Returns:
- The corresponding DBMS type or NULL if the specified type is unknown.
-
translateGeometryFromDB
Parse the given JDBC column value as a geometry object and convert it into a
Region
.Note: Generally the returned object will be used to get its STC-S expression.
Note: If the given column value is NULL, NULL will be returned.
Important note: This function is called ONLY for value of columns flagged as geometries by
convertTypeFromDB(int, String, String, String[])
. So the value should always be of the expected type and format. However, if it turns out that the type is wrong and that the conversion is finally impossible, this function SHOULD throw aParseException
.- Parameters:
jdbcColValue
- A JDBC column value (returned by ResultSet.getObject(int)).- Returns:
- The corresponding
Region
if the given value is a geometry. - Throws:
ParseException
- If the given object is not a geometrical object or can not be transformed into aRegion
object.
-
translateGeometryToDB
Convert the given STC region into a DB column value.
Note: This function is used only by the UPLOAD feature, to import geometries provided as STC-S expression in a VOTable document inside a DB column.
Note: If the given region is NULL, NULL will be returned.
- Parameters:
region
- The region to store in the DB.- Returns:
- The corresponding DB column object.
- Throws:
ParseException
- If the given STC Region can not be converted into a DB object.
-