Example
An example of a translation rule for function calls
Description
Let's create a translation rule class that will transform DB2 function calls of foo
to snowflakeFoo
and make some changes in its parameters. The rule will remove the first argument and will make an explicit cast to string in the remaining parameter. Here is an example of the input and output code.
Now, let's take a look at the transformation rule code. As mentioned above, the class definition must have the ExportContract
attribute and inherit from the BaseExtensibleTranslationRule
class. Notice both parameters of the class definition are SqlFuntionExpr
, that means that the rule will take a function call as the input and return a function call as the output.
Next, the IsApplicable
method must make sure that only the desired functions are targeted in this translation rule. This is accomplished by asking for the name of the current function expression and making sure it is equal to foo
.
More complex situations can be verified in the IsApplicable
method, like checking for the amount or type of arguments, or values of internal fields of the AST. All of that can be verified by exploring the exposed types in the SnowConvertExtensibility API.
Now, the replace
method will be called for each one of the instances of the foo
function in the input code. The first argument of the function is removed with line 3. The remaining parameter is casted to string
with line 4 and the name of the function is changed to snowflakeFoo
with line 5.
Highlights
There are a couple of important things to highlight in the Replace
method code.
Immutable AST
As mentioned in the Working with ASTs section, the classes used to represent the ASTs (in this case SqlFunctionExpr
) are immutable. Therefore, each one of the functions in lines 3-5 creates a new instance of the class that is assigned to the result parameter every time.
Emitting code
The concept of Emitting code is also mentioned in Working with ASTs section. When using the SnowConvertExtensibility API, creating new AST nodes or parts of them, cannot be accomplished via the traditional approach of calling the type constructor with the new
keyword. Instead, an instance of an Emitter class must be used to emit new code. For example, each one of the functions called in lines 3-5 end up emitting a new SqlFunctionExpr.
In line 4, the SfEmitter
object (part of the BaseExtensibleTranslationRule
class) is used to produce new Snowflake ASTs. The CastArgument
function takes the index of the parameter and the type to use in the casting, this type must be an instance of the SqlDataType
class. The SfEmitter is used in this case to produce an instance of the SfStringType
which represents an string
in Snowflake.
Get the code
The full code of the example and some other code mentioned in previous sections can be found here.
Last updated