JBoss.orgCommunity Documentation

Chapter 4. Extending The JDBC Translator

4.1. Capabilities Extension
4.2. SQL Translation Extension
4.3. Results Translation Extension
4.4. Adding Function Support
4.4.1. Using FunctionModifiers
4.5. Installing Extensions

The JDBC Translator can be extended to handle new JDBC drivers and database versions. This is one of the most common needs of custom Translator development. This chapter outlines the process by which a user can modify the behavior of the JDBC Translator for a new source, rather than starting from scratch.

To design a JDBC Translator for any RDMS that is not already provided by the Teiid, extend the org.teiid.translator.jdbc.JDBCExecutionFactory class in the "translator-jdbc" module. There are three types of methods that you can override from the base class to define the behavior of the Translator.

Table 4.1. Extensions

Extension

Purpose

Capabilities

Specify the SQL syntax and functions the source supports.

SQL Translation

Customize what SQL syntax is used, how source-specific functions are supported, how procedures are executed.

Results Translation

Customize how results are retrieved from JDBC and translated.


This extension must override the methods that begin with "supports" that describe translator capabilities. For all the available translator capabilities please see this.

The most common example is adding support for a scalar function – this requires both declaring that the translator has the capability to execute the function and often modifying the SQL Translator to translate the function appropriately for the source.

Another common example is turning off unsupported SQL capabilities (such as outer joins or subqueries) for less sophisticated JDBC sources.

The JDBCExcecutionFactory provides several methods to modify the command and the string form of the resulting syntax before it is sent to the JDBC driver, including:

The JDBCExecutionFactory provides several methods to modify the java.sql.Statement and java.sql.ResultSet interactions, including:

See User Defined Functions for adding new functions to Teiid. This example will show you how to declare support for the function and modify how the function is passed to the data source.

Following is a summary of all coding steps in supporting a new scalar function:

  1. Override the capabilities method to declare support for the function (REQUIRED)

  2. Implement a FunctionModifier to change how a function is translated and register it for use (OPTIONAL)

There is a capabilities method getSupportedFunctions() that declares all supported scalar functions.

An example of an extended capabilities class to add support for the “abs” absolute value function:

package my.connector;
            
import java.util.ArrayList;
import java.util.List;

public class ExtendedJDBCExecutionFactory extends JDBCExecutionFactory {
    @Override
    public List getSupportedFunctions() {
        List supportedFunctions = new ArrayList();
        supportedFunctions.addAll(super.getSupportedFunctions());
        supportedFunctions.add("ABS"); 
        return supportedFunctions;
    }
}

In general, it is a good idea to call super.getSupportedFunctions() to ensure that you retain any function support provided by the translator you are extending.

This may be all that is needed to support a Teiid function if the JDBC data source supports the same syntax as Teiid. The built-in SQL translation will translate most functions as: “function(arg1, arg2, …)”.

In some cases you may need to translate the function differently or even insert additional function calls above or below the function being translated. The JDBC translator provides an abstract class FunctionModifier for this purpose.

During the start method a modifier instance can be registered against a given function name via a call to JDBCExecutionFactory.registerFunctionModifier.

The FunctionModifier has a method called translate. Use the translate method to change the way the function is represented.

In addition to building your own FunctionModifiers, there are a number of pre-built generic function modifiers that are provided with the translator.


To register the function modifiers for your supported functions, you must call the ExecutionFactory.registerFunctionModifier(String name, FunctionModifier modifier) method.

public class ExtendedJDBCExecutionFactory extends JDBCExecutionFactory
              
	@Override
	public void start() {
	    super.start();
	    
	    // register functions.
	    registerFunctionModifier("abs", new MyAbsModifier()); 
	    registerFunctionModifier("concat", new AliasModifier(“concat2”)); 
	}
}

Support for the two functions being registered (“abs” and “concat”) must be declared in the capabilities as well. Functions that do not have modifiers registered will be translated as usual.

Once you have developed an extension to the JDBC translator, you must install it into the Teiid Server. The process of packaging or deploying the extended JDBC translators is exactly as any other other translator. Since the RDMS is accessible already through its JDBC driver, there is no need to develop a resource adapter for this source as JBoss AS provides a wrapper JCA connector (DataSource) for any JDBC driver.