Table of Contents

Search

  1. Preface
  2. The Transformation Language
  3. Constants
  4. Operators
  5. Dates
  6. Functions
  7. Creating Custom Functions
  8. Custom Function API Reference
  9. POWERCENTERHELP

Transformation Language Reference

Transformation Language Reference

Step 3. Create an Implementation File

Step 3. Create an Implementation File

The implementation file contains the definitions of the functions you use to create a custom function. Create an implementation file using C. You can use one implementation file for one or more custom functions. You can also use one implementation file to define both the validation and runtime functions of a custom function.
The following example shows the echo.c implementation file for the ECHO custom function:
/*************************************************************************** * ECHO function Procedure File * * This file contains code that creates the ECHO function, which the * Integration Service calls during a workflow. ***************************************************************************/ /* Informatica ECHO function example developed using the Custom Function * API. * Filename: Echo.c * An example of a custom function developed using PowerCenter * * The purpose of the ECHO function is to return the input value to the user. * */ /*************************************************************************** Includes ***************************************************************************/ #include <stdio.h> #include <string.h> #include "sdkexpr/exprsdk.h" #define SAMPLE_EXPR_EXPORTS #include "SampleExprPlugin.hpp" static IUNICHAR ECHO_STR[80]; /*************************************************************************** Functions ***************************************************************************/ /*************************************************************************** Function: INFA_EXPR_GetPluginVersion Description: Defines the version of the plug-in. It must be the same as the Custom Function API version. Returns ISUCCESS if the plug-in version matches the Custom Function API version. Otherwise, returns IFAILURE. Input: sdkVersion - Current version of the Custom Function API. Output: pluginVersion - Set the version of the plug-in. Remarks: Custom Function API checks for compatibility between itself and the plug-in version. ***************************************************************************/ extern "C" SAMPLE_EXPR_SPEC INFA_EXPR_STATUS INFA_EXPR_GetPluginVersion(INFA_VERSION* sdkVersion, INFA_VERSION* pluginVersion) { pluginVersion->m_major = 1; pluginVersion->m_minor = 0; pluginVersion->m_patch = 0; INFA_EXPR_STATUS retStatus; retStatus.status = ISUCCESS; retStatus.errMsg = NULL; return retStatus; } /*************************************************************************** Function: INFA_EXPR_DestroyString Description: Destroys all strings the plug-in returns. For example, it destroys error messages or the return value of other function calls, such as getFunctionDescription. Returns no value. Input: The pointer to the allocated string. Output: N/A Remarks: Frees the memory to avoid issues with multiple heaps. ***************************************************************************/ extern "C" SAMPLE_EXPR_SPEC void INFA_EXPR_DestroyString(IUNICHAR *strToDelete) { delete [] strToDelete; } /*************************************************************************** Function: INFA_EXPR_ValidateGetUserInterface Description: Returns function pointers to the validation functions. Returns ISUCCESS when the plug-in implemented the function. Returns IFAILURE when the plug-in did not implement the function or another error occurred. Input: Namespace and name of function. Output: Functions. The plug-in needs to set various function pointers. Remarks: Check the namespace and function name for validaity. Set the various function pointers appropriately. ***************************************************************************/ extern "C" SAMPLE_EXPR_SPEC INFA_EXPR_STATUS INFA_EXPR_ValidateGetUserInterface(IUNICHAR* ns, IUNICHAR* sFuncName, INFA_EXPR_VALIDATE_METHODS* functions) { INFA_EXPR_STATUS retStatus; retStatus.errMsg = NULL; // check function name is not null if (!sFuncName) { retStatus.status = IFAILURE; return retStatus; } // set the appropriate function pointers functions->validateFunction = validateFunctionEcho; functions->getFunctionDescription = getDescriptionEcho; functions->getFunctionPrototype = getPrototypeEcho; functions->pushdownFunction = pushdownFunctionEcho; retStatus.status = ISUCCESS; return retStatus; } /*************************************************************************** Function: INFA_EXPR_ModuleGetUserInterface Description: Sets the function pointers for module-level interaction. Returns ISUCCESS when functions pointers are set appropriately. Otherwise, returns IFAILURE. Input: N/A Output: Functions. The plug-in needs to set various function pointers. Remarks: Set the module init/deinit function pointers. ***************************************************************************/ extern "C" SAMPLE_EXPR_SPEC INFA_EXPR_STATUS INFA_EXPR_ModuleGetUserInterface(INFA_EXPR_LIB_METHODS* functions) { functions->module_init = moduleInitEcho; functions->module_deinit = moduleDeinitEcho; INFA_EXPR_STATUS retStatus; retStatus.status = ISUCCESS; retStatus.errMsg = NULL; return retStatus; } /*************************************************************************** Function: INFA_EXPR_FunctionGetUserInterface Description: Sets the function pointers for function-level interaction. PowerCenter calls this function for every custom function this library implements. Returns ISUCCESS when The plugin implements this function and sets the function pointers correctly. Otherwise, returns IFAILURE. Input: Namespace and name of function. Output: Functions. The plug-in needs to set function pointers for function init/deinit. Remarks: Set the function init/deinit function pointers. ***************************************************************************/ extern "C" SAMPLE_EXPR_SPEC INFA_EXPR_STATUS INFA_EXPR_FunctionGetUserInterface(IUNICHAR* nameSpaceName, IUNICHAR* functionName, INFA_EXPR_FUNCTION_METHODS* functions) { functions->function_init = functionInitEcho; functions->function_deinit = functionDeinitEcho; INFA_EXPR_STATUS retStatus; retStatus.status = ISUCCESS; retStatus.errMsg = NULL; return retStatus; } /*************************************************************************** Function: INFA_EXPR_FunctionInstanceGetUserInterface Description: Sets the function pointers for function instance-level interaction. PowerCenter calls this function for every custom function this library implements. Returns ISUCCESS when The plugin implements this function and sets the function pointers correctly. Otherwise, returns IFAILURE. Input: Namespace and name of function. Output: Functions. The plug-in needs to set function pointers for instance init/deinit/processrow. Remarks: Set the function instance init/deinit/processrow function pointers. ***************************************************************************/ extern "C" SAMPLE_EXPR_SPEC INFA_EXPR_STATUS INFA_EXPR_FunctionInstanceGetUserInterface(IUNICHAR* nameSpaceName, IUNICHAR* functionName, INFA_EXPR_FUNCTION_INSTANCE_METHODS* functions) { functions->fnInstance_init = functionInstInitEcho; functions->fnInstance_processRow = processRowEcho; functions->fnInstance_deinit = functionInstDeinitEcho; INFA_EXPR_STATUS retStatus; retStatus.status = ISUCCESS; retStatus.errMsg = NULL; return retStatus; } /*************************************************************************** Function: INFA_EXPR_getDescriptionEcho Description: Gets the description of the ECHO function. It calls destroyString to delete the arguments from memory when usage is complete. The return value must be a null-terminated string. Input: Namespace and name of function. Output: Description of the function. Remarks: Returns the description of function. The Custom Functions API calls destroy string to free the allocated memory. ***************************************************************************/ extern "C" SAMPLE_EXPR_SPEC IUNICHAR * getDescriptionEcho(IUNICHAR* ns, IUNICHAR* sFuncName) { static IUNICHAR *uniDesc = NULL; const char *description = "Echoes the input"; if (uniDesc) return uniDesc; int i, len; len = strlen(description); uniDesc = new IUNICHAR[2*len+2]; for (i=0; i<len; i++) { uniDesc[i] = description[i]; } uniDesc[i] = 0; return uniDesc; } /*************************************************************************** Function: INFA_EXPR_getPrototypeEcho Description: Gets the arguments of the ECHO function in the Expression Editor. It calls destroyString to delete the arguments from memory when usage is complete. The return value must be a null-terminated string. The function returns NULL if there is no value for the arguments. Input: Namespace and name of the function. Output: Prototype of the function Remarks: Returns the prototype of function. The Custom Functions API calls destroy string to free the allocated memory. ***************************************************************************/ extern "C" SAMPLE_EXPR_SPEC IUNICHAR * getPrototypeEcho(IUNICHAR* ns, IUNICHAR* sFuncName) { static IUNICHAR *uniProt = NULL; const char *prototype = "Echo(x), where x can be any type, returns x"; if (uniProt) return uniProt; int i, len; len = strlen(prototype); uniProt = new IUNICHAR[2*len+2]; for (i=0; i<len; i++) { uniProt[i] = prototype[i]; } uniProt[i] = 0; return uniProt; } /*************************************************************************** Function: validateFunctionEcho Description: Validates the arguments in the ECHO function. Provides the name, datatype, precision, and scale of the arguments in the ECHO function. Provides the datatype of the return value of the ECHO function. PowerCenter calls this function once for each instance of the ECHO function used in a mapping or workflow. Returns ISUCCESS when function usage is valid as per the syntax. The ECHO function takes exactly one argument of any datatype. The return datatype is the same as the input datatype, because the function echoes the input. Otherwise, returns IFAILURE. Input: Namespace and name of the function, the number of arguments being passed, and the metadata (datatype, scale, precision) of each argument. Output: retValue. Set the metadata for return type. Remarks: Called by the Custom Functions API to validate the usage of the function and the input argument metadata to be passed. The plug-in needs to verify the number of arguments for this function, the expected metadata for each argument, etc. The plug-in can optionally change the expected datatype of the input arguments. The plug-in needs to set the return type metadata. The plugin can specify if the return value of this function is constant, depending on whether or not all input arguments are constant. ***************************************************************************/ extern "C" SAMPLE_EXPR_SPEC INFA_EXPR_STATUS validateFunctionEcho(IUNICHAR* ns, IUNICHAR* sFuncName, IUINT32 numArgs, INFA_EXPR_OPD_METADATA** inputArgList, INFA_EXPR_OPD_METADATA* retValue) { INFA_EXPR_STATUS exprStatus; // Check number of arguments. if (numArgs != 1) { static const char *err = "Echo function takes one argument."; IUNICHAR *errMsg = NULL; unsigned int len = strlen(err); errMsg = new IUNICHAR[2*len+2]; unsigned int i; for (i=0; i<len; i++) { errMsg[i] = err[i]; } errMsg[i] = 0; exprStatus.status = IFAILURE; exprStatus.errMsg = errMsg; return exprStatus; } // This is an echo function. // It returns the input value. retValue->datatype = inputArgList[0]->datatype; retValue->precision = inputArgList[0]->precision; retValue->scale = inputArgList[0]->scale; // If the input value is constant, // the return value is also constant. if (inputArgList[0]->isValueConstant) retValue->isValueConstant = ITRUE; else retValue->isValueConstant = IFALSE; exprStatus.status = ISUCCESS; return exprStatus; } /*************************************************************************** Function: processRowEcho Description: Called when an input row is available to an ECHO function instance. The data for the input arguments of the ECHO function is bound and accessed through fnInstance-inputOPDHandles. Set the data, length, and indicator for the output and return ports in fnInstance->retHandle. PowerCenter calls the function-level initialization function before calling this function. Returns INFA_ROWSUCCESS when the function successfully processes the row of data. Returns INFA_ROWERROR when the function encounters an error for the row of data. The Integration Service increments the internal error count. Only returns this value when the data access mode is row. Returns INFA_FATALERROR when the function encounters a fatal error for the row of data or the block of data. The Integration Service fails the session. Input: Function instance handle, which has the input data. Output: return value Remarks: The plug-in needs to get various input arguments from the function instance handle, perform calculations, and set the return value. ***************************************************************************/ extern "C" SAMPLE_EXPR_SPEC INFA_EXPR_ROWSTATUS processRowEcho(INFA_EXPR_FUNCTION_INSTANCE_HANDLE *fnInstance, IUNICHAR **errMsg) { INFA_EXPR_OPD_RUNTIME_HANDLE* arg1 = fnInstance->inputOPDHandles[0]; INFA_EXPR_OPD_RUNTIME_HANDLE* retHandle = fnInstance->retHandle; // Check if the input argument has a null indicator. // If yes, the return value is also null. if (INFA_EXPR_GetIndicator(arg1) == INFA_EXPR_NULL_DATA) { INFA_EXPR_SetIndicator(retHandle, INFA_EXPR_NULL_DATA); return INFA_EXPR_SUCCESS; } short sval; long lval; int ival; char *strval; IUNICHAR *ustrval; void *rawval; float fval; double dval; INFA_EXPR_DATE *infaDate = NULL; int len; // Depending on the datatype, // get the input argument // and set the same value in the return value. // Also, set the same indicator. switch (arg1->pOPDMetadata->datatype) { case eCTYPE_SHORT: sval = INFA_EXPR_GetShort(arg1); INFA_EXPR_SetShort(retHandle, sval); INFA_EXPR_SetIndicator(retHandle, INFA_EXPR_GetIndicator(arg1)); break; case eCTYPE_LONG: case eCTYPE_LONG64: lval = INFA_EXPR_GetLong(arg1); INFA_EXPR_SetLong(retHandle, lval); INFA_EXPR_SetIndicator(retHandle, INFA_EXPR_GetIndicator(arg1)); break; case eCTYPE_INT32: ival = INFA_EXPR_GetInt(arg1); INFA_EXPR_SetInt(retHandle, ival); INFA_EXPR_SetIndicator(retHandle, INFA_EXPR_GetIndicator(arg1)); break; case eCTYPE_CHAR: strval = INFA_EXPR_GetString(arg1); len = INFA_EXPR_GetLength(arg1); strcpy((char *)retHandle->pUserDefinedPtr, strval); INFA_EXPR_SetString(retHandle, retHandle->pUserDefinedPtr); INFA_EXPR_SetLength(retHandle, INFA_EXPR_GetLength(arg1)); INFA_EXPR_SetIndicator(retHandle, INFA_EXPR_GetIndicator(arg1)); break; case eCTYPE_RAW: rawval = INFA_EXPR_GetRaw(arg1); len = INFA_EXPR_GetLength(arg1); memcpy(retHandle->pUserDefinedPtr, rawval, len); INFA_EXPR_SetRaw(retHandle, retHandle->pUserDefinedPtr); INFA_EXPR_SetLength(retHandle, len); INFA_EXPR_SetIndicator(retHandle, INFA_EXPR_GetIndicator(arg1)); break; case eCTYPE_UNICHAR: ustrval = INFA_EXPR_GetUniString(arg1); len = INFA_EXPR_GetLength(arg1); memcpy(retHandle->pUserDefinedPtr, ustrval, 2*(len+1)); INFA_EXPR_SetUniString(retHandle, retHandle->pUserDefinedPtr); INFA_EXPR_SetLength(retHandle, len); INFA_EXPR_SetIndicator(retHandle, INFA_EXPR_GetIndicator(arg1)); break; case eCTYPE_TIME: infaDate = INFA_EXPR_GetDate(arg1); *((INFA_EXPR_DATE *)retHandle->pUserDefinedPtr) = *infaDate; INFA_EXPR_SetDate(retHandle, retHandle->pUserDefinedPtr); INFA_EXPR_SetIndicator(retHandle, INFA_EXPR_GetIndicator(arg1)); break; case eCTYPE_FLOAT: fval = INFA_EXPR_GetFloat(arg1); INFA_EXPR_SetFloat(retHandle, fval); INFA_EXPR_SetIndicator(retHandle, INFA_EXPR_GetIndicator(arg1)); break; case eCTYPE_DOUBLE: dval = INFA_EXPR_GetDouble(arg1); INFA_EXPR_SetDouble(retHandle, dval); INFA_EXPR_SetIndicator(retHandle, INFA_EXPR_GetIndicator(arg1)); break; default: return INFA_EXPR_ROWERROR; break; } return INFA_EXPR_SUCCESS; } /*************************************************************************** Function: moduleInitEcho Description: Called once for each module to initialize any global data structure in the function. Called before calling any function-level functions. Returns ISUCCESS when module initialization is successful. Otherwise, returns IFAILURE. Input: module handle Output: status Remarks: The plug-in can optionally implement this method for one-time initialization. ***************************************************************************/ extern "C" SAMPLE_EXPR_SPEC INFA_EXPR_STATUS moduleInitEcho(INFA_EXPR_MODULE_HANDLE *modHandle) { INFA_EXPR_STATUS exprStatus; // initialize the ECHO_STR const char *fnName = "Echo"; int len = strlen(fnName); int i; for (i=0;i<len;i++) ECHO_STR[i] = fnName[i]; exprStatus.status = ISUCCESS; return exprStatus; } /*************************************************************************** Function: moduleDeinitEcho Description: Called once for each module to deinitialize any data structure in this function. Called after all function-level interactions are complete. Returns ISUCCESS when module deinitialization is successful. Otherwise, returns IFAILURE. Input: module handle Output: status Remarks: The plug-in can optionally implement this method for one-time deinitialization. ***************************************************************************/ extern "C" SAMPLE_EXPR_SPEC INFA_EXPR_STATUS moduleDeinitEcho(INFA_EXPR_MODULE_HANDLE *modHandle) { INFA_EXPR_STATUS exprStatus; exprStatus.status = ISUCCESS; return exprStatus; } /*************************************************************************** Function: functionInitEcho Description: Called once for each custom function to initialize any structure related to the custom function. Module-level initialization function is called before this function. Returns ISUCCESS when function init is successful. Otherwise, returns IFAILURE. Input: function handle Output: status Remarks: The plug-in can optionally implement this method for one-time function initialization. ***************************************************************************/ extern "C" SAMPLE_EXPR_SPEC INFA_EXPR_STATUS functionInitEcho(INFA_EXPR_FUNCTION_HANDLE *funHandle) { INFA_EXPR_STATUS exprStatus; exprStatus.status = ISUCCESS; return exprStatus; } /*************************************************************************** Function: functionDeinitEcho Description: Called once for each function level to deinitialize any structure related to the ECHO function. Returns ISUCCESS when function deinit is successful. Otherwise, returns IFAILURE. Input: function handle Output: status Remarks: The plug-in can optionally implement this method for one-time function deinitialization. ***************************************************************************/ extern "C" SAMPLE_EXPR_SPEC INFA_EXPR_STATUS functionDeinitEcho(INFA_EXPR_FUNCTION_HANDLE *funHandle) { INFA_EXPR_STATUS exprStatus; exprStatus.status = ISUCCESS; return exprStatus; } /*************************************************************************** Function: functionInstInitEcho Description: Called once for each custom function instance to initialize any structure related to the an instance of the ECHO function. If there are two instances of ECHO in a mapping or workflow, PowerCenter calls this function twice. PowerCenter calls the module-level initialization function before calling this function. Returns ISUCCESS when function instance initialization is successful. Otherwise, returns IFAILURE. Input: function instance handle Output: status Remarks: The plug-in can optionally implement this method for one-time function instance initialization. ***************************************************************************/ extern "C" SAMPLE_EXPR_SPEC INFA_EXPR_STATUS functionInstInitEcho(INFA_EXPR_FUNCTION_INSTANCE_HANDLE *funInstHandle) { INFA_EXPR_STATUS exprStatus; exprStatus.status = ISUCCESS; INFA_EXPR_OPD_RUNTIME_HANDLE *retHandle = funInstHandle->retHandle; // Allocate memory depending on the datatype. if (retHandle->pOPDMetadata->datatype == eCTYPE_CHAR) retHandle->pUserDefinedPtr = new char[retHandle->pOPDMetadata->precision+1]; else if (retHandle->pOPDMetadata->datatype == eCTYPE_UNICHAR) retHandle->pUserDefinedPtr = new IUNICHAR[retHandle->pOPDMetadata->precision+1]; else if (retHandle->pOPDMetadata->datatype == eCTYPE_RAW) retHandle->pUserDefinedPtr = new unsigned char[retHandle->pOPDMetadata->precision]; else if (retHandle->pOPDMetadata->datatype == eCTYPE_TIME) retHandle->pUserDefinedPtr = new INFA_EXPR_DATE(); return exprStatus; } /*************************************************************************** Function: functionInstDeinitEcho Description: Called once for each function level during deinitialization. Can deinitialize any structure related to the ECHO function. Returns ISUCCESS when deinitialization is successful. Otherwise, returns IFAILURE. Input: function instance handle Output: status Remarks: The plug-in can optionally implement this method for one-time function instance deinitialization. ***************************************************************************/ extern "C" SAMPLE_EXPR_SPEC INFA_EXPR_STATUS functionInstDeinitEcho(INFA_EXPR_FUNCTION_INSTANCE_HANDLE *funInstHandle) { INFA_EXPR_STATUS exprStatus; exprStatus.status = ISUCCESS; INFA_EXPR_OPD_RUNTIME_HANDLE *retHandle = funInstHandle->retHandle; if (retHandle->pOPDMetadata->datatype == eCTYPE_CHAR) delete [] (char *)retHandle->pUserDefinedPtr; else if (retHandle->pOPDMetadata->datatype == eCTYPE_UNICHAR) delete [] (IUNICHAR *)retHandle->pUserDefinedPtr; else if (retHandle->pOPDMetadata->datatype == eCTYPE_RAW) delete [] (unsigned char *)retHandle->pUserDefinedPtr; else if (retHandle->pOPDMetadata->datatype == eCTYPE_TIME) delete (INFA_EXPR_DATE *)retHandle->pUserDefinedPtr; return exprStatus; } /*************************************************************************** Function: pushdownFunctionEcho Description: Method to generate SQL code for pushdown optimization. Input: Namespace and name of the function, the number of arguments being passed, and the metadata (datatype, scale, precision) of each argument, database type, Pushdown mode. Output: Generated SQL. Remarks: The plug-in can optionally implement this method to enable pushdown optimization. ***************************************************************************/ //method to generate SQL code for pushdown optimization extern "C" SAMPLE_EXPR_SPEC INFA_EXPR_STATUS pushdownFunctionEcho(IUNICHAR* sNameSpace, IUNICHAR* sFuncName, IUINT32 numArgs, INFA_EXPR_OPD_METADATA** inputArgList, EDatabaseType dbType, EPushdownMode pushdownMode, IUNICHAR** sGenSql) { INFA_EXPR_STATUS retStatus; static const char *sql_str = "{1}"; // Construct the SQL: "{1}" unsigned int len = strlen(sql_str); IUNICHAR *pGenSql = new IUNICHAR[len+1]; unsigned int i; for (i=0; i<len; i++) { pGenSql[i] = sql_str[i]; } pGenSql[len] = 0; // Return the generated SQL *sGenSql = pGenSql; retStatus.status = ISUCCESS; retStatus.errMsg = NULL; return retStatus; }