DataStage generates code for each transformer stage and then compiles this code to produce the executable bits used during a job run. You can not inspect the generated code from the DataStage designer but in this post I will show you how to view it using 3rd party tools.
Let’s say that we have a job with transformer named tr_IncrCol that increases a value of a column:
View the TRX Code
To find out the TRX code (a kind of pseudo code similar to C++) for the transformer issue the following commands in the shell:
cd /opt/IBM/InformationServer/Server/Projects/YourProjectName/
find . -name *YourJobName_YourTransformerName.trx
//// Generated file to implement the V0S0_TransformerCodeDemo_tr_IncrCol transform operator.//// define our input/output link namesinputname 0 in;
outputname 0 out;
initialize { // define our control variablesint8 RowRejected0;
int8 NullSetVar0;
}
mainloop { // initialise the rejected row variableRowRejected0 = 1;
// evaluate columns (no constraints) for link: outout.col1 = (in.col1 + 1);
writerecord 0;
RowRejected0 = 0;
}
finish {}
View the C Code
To view the C code you will need to define the following environment variable APT_TRANSFORM_OPERATOR_DEBUG for your project (by using the DataStage Administrator):
Now use “Force Compile” from the DataStage designer to recompile your job and issue the following command to find the C file:
cd /opt/IBM/InformationServer/Server/Projects/YourProjectName/
find . -name *YourJobName_YourTransformerName.C
The find command returns a file ./RT_BP6.O/V0S0_TransformerCodeDemo_tr_IncrCol.C with the following contents:
// -*-Mode: C++-*-/******************************************************************************** Boiler plate for generated transform operator.** Module: bp.transform.C** Licensed Materials Property of IBM* "Restricted Materials of IBM"* (C) Copyright IBM Corp. 2005, 2012** (c) Copyright 2005 Ascential Software Corporation. All Rights Reserved* This is unpublished proprietary source code of Ascential Software Corporation.* The copyright notice above does not evidence any actual or intended* publication of such source code.*******************************************************************************//*########################################################################### Maintenance log - insert most recent change descriptions at top#### Date RTC# WHO Description.## 03/02/12 97190 lag Added destructor logic#### Date CQ# WHO Description.## 08/25/10 221869 msashiha tweaked stringToNumeric for var. length strings## 10/20/09 180149 eaj Transform code optimizations## 06/18/08 prod93684 msashiha avoid passing STL objects in API methods## 05/07/08 131689 eaj Fix string constant conversion issues related to## 131831 MS 2005 compiler behavior change## 02/15/08 125689 jcallen fix the copyright notice## 06/08/07 112670 dsotkowi Merge from main## 02/02/07 112670 dsotkowi Removed writeOutputRecordChild()## 01/29/07 112670 dsotkowi Move more code from transform.C generation ## into transformbase.C & .h## 01/24/07 112670 dsotkowi Only output writeRecordChild() if has tables.## 01/22/06 112670 dsotkowi Transform refactoring## 01/16/07 97851 dsotkowi If there is a null and no reject dataset abort## if APT_EnvironmentFlag APT_TRANSFORM_ABORT_ON_REJECT_NULL ## is set otherwise if there is no reject dataset drop the record.## 10/06/06 110505 ahirshbe Ported next entry to main/LATEST.## 10/06/06 107791 eaj Correctly cleanup temp lookup fileset## 12/05/06 112590 dsotkowi Fix table -save option.## 09/08/06 104659 dsotkowi Fix friend APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol_issueConversionWarning linkage.## Date Ecase# WHO Description.## 08/10/06 97302 eaj Fix createonly and fileset range lookup handling## 03/07/05 None ahirshbe Make issueConversionWarning a static member function.## 03/06/06 88658 dsotkowi Restore declaration of convStat - ## fails transformop_test_MK_bug7 among others## 02/09/06 85328 vpechori Surrogate keys from DB Sequence.## 08/18/05 69187 xpu Added EOW support.## 06/13/05 66571 eaj Move sharing control from ops to tables## 05/04/05 73547 eaj Handle conversion failures better## 04/29/05 73479 eaj Explicitly force std::llabs on linux## 02/17/05 n/a eaj Updatable functionality## 01/31/05 68170 xpu Redefine max() and min() on Linux.## 07/22/04 30156 eaj Handle a hex value in APT_STRING_PADCHAR## 03/15/04 none eaj Use osh option -string_fields for inserted## field type## 02/28/04 n/a xpu Moved declaration of operator+ out of ## the class.## 01/26/04 linda Adding OS/390 support## 01/21/04 43656 xpu Update output sort keys at run time.## 11/21/03 n/a xpu Inserted spaces for indention.## 09/26/03 39721 xpu Added a newline at the end of the file to## avoid aCC 3.37 future fatal error 690.## 09/04/03 39209 eaj NLS this fix since it came from 6.0## 09/04/03 39209 eaj Added use of APT_STRING_PADCHAR for fixed## length strings.## 05/08/03 9607 xpu Removed setting dataset schemas## 04/09/03 20305 eaj Added handling of + operator for ustring## string mixes## 04/09/03 20130 eaj Add handling of collation sequence option#######################################################################*/#include <apt_components/transformop/transformbasehdrs.h>// user-defined function header file#include <apt_components/transformop/transformbase.h>// Allow for addition of mixed strings and ustringsAPT_DLL_BUILDOP APT_UString operator+ (const APT_UString&, const APT_String& );
APT_DLL_BUILDOP APT_UString operator+ (const APT_String&, const APT_UString&);
class APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol: public APT_TransformBaseOP
{public:APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol();
~APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol();
protected: // pure virtual functions in parentvirtual void processInputRecordChild(int inputDS, int curOutput[], int writtenOutput[]);
virtual void setRejectColumnValue(const APT_UString &errMsg, int rejectDs);
// implement the parent's pure virtual methods virtual APT_Status describeOperatorChild(APT_Schema* inputSchema, APT_Schema* outputSchema); virtual APT_Status doInitialProcessingChild(APT_InputAccessorInterface* inpInt[]); virtual APT_Status initializeWaveChild(); virtual APT_Status doFinalProcessingChild();virtual void processEOWChild(int inputDS);
virtual void serializeChild(APT_Archive& ar, APT_UInt8);
virtual APT_Status setupInputInterfaceAccessorChild(APT_InputAccessorInterface** inCur); virtual APT_Status setupOutputInterfaceAccessorChild(APT_OutputAccessorInterface** outCur);private: // internal macros, required for persistence mechanismAPT_DECLARE_RTTI(APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol);
APT_DECLARE_PERSISTENT(APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol);
// Helper conversion class, should be moved into transformbase class // in future releasestemplate <class T> class stringToNumeric
{ public:static void convert(T& result, const APT_String& source, char* pBuf,
bool* msgPrinted, const APT_String& addlMsg);
static void convert(T& result, const APT_UString& source, UChar* pBuf,
bool* msgPrinted, const APT_String& addlMsg);
static void convert(APT_Decimal& result, const APT_String& source,
bool* msgPrinted, const APT_String& addlMsg);
static void convert(APT_Decimal& result, const APT_UString& source,
bool* msgPrinted, const APT_String& addlMsg);
static void convert64(APT_Int64& result, const APT_String& source, char* pBuf,
bool* msgPrinted, const APT_String& addlMsg);
static void convert64(APT_Int64& result, const APT_UString& source, UChar* pBuf,
bool* msgPrinted, const APT_String& addlMsg);
static void convertU64(APT_UInt64& result, const APT_String& source, char* pBuf,
bool* msgPrinted, const APT_String& addlMsg);
static void convertU64(APT_UInt64& result, const APT_UString& source, UChar* pBuf,
bool* msgPrinted, const APT_String& addlMsg);
private:static void issueWarning(bool* msgPrinted, const APT_String& addlMsg, bool isDecimal = false);
};
// input accessorsAPT_InputAccessorToInt32 input0Int32col1;
// output accessorsAPT_OutputAccessorToInt32 output0Int32col1;
// declare stage (global) variables.APT_Int8 stage0RowRejected0;
APT_Int8 stage0NullSetVar0;
};
APT_IMPLEMENT_RTTI_ONEBASE(APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol, APT_CombinableOperator);
APT_IMPLEMENT_PERSISTENT(APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol);
APT_DEFINE_OSH_NAME(APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol, V0S0_TransformerCodeDemo_tr_IncrCol, ARG_DESC);
APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol::APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol()
{ // initialize base classconst unsigned nOutputs = 1;
const unsigned nInputs = 1;
numinputs_ = nInputs;
numoutputs_ = nOutputs;
numtransfers_ = 1;
numrejects_ = 0;
inTransAdapt_ = new APT_TransferAdapter[nInputs];numRealInputs_ = 1;
numOfConvWithParams_ = 0;
numOfStrDefaultConvs_ = 0;
// initialize stage (global) variables.stage0RowRejected0 = 0;
stage0NullSetVar0 = 0;
}
APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol::~APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol()
{if (inTransAdapt_) { delete [] inTransAdapt_; inTransAdapt_ = 0; }
}
void APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol::serializeChild(APT_Archive& ar, APT_UInt8){ // serialize job parameters}
void APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol::serialize(APT_Archive& ar, APT_UInt8 n){serializeChild(ar,0);
}
// initialize operator before serialization and parallel distribution.APT_Status APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol::describeOperatorChild(APT_Schema* inputSchema, APT_Schema* outputSchema)
{ // set input interface schema. inputSchema[0]=APT_Schema(APT_ConvertFromString_TRX("record\n( col1: int32;\n APT_TRinput0Rec0: *;\n)")); APT_Schema droppedFds;
setupInputInterfaceSchema(inputSchema, droppedFds, 0, 0);
unsigned int input;
// set output interface schema. outputSchema[0]=APT_Schema(APT_ConvertFromString_TRX("record\n( col1: int32;\n APT_TRoutput0Rec0: *;\n)")); int output; // set view/modify adapter. // set transfer adapter. APT_UString* dropped = new APT_UString[1];dropUsedOutputFieldsWithSchema(droppedFds);
inTransAdapt_[0].dropFromVar(APT_UString("APT_TRinput0Rec0"), APT_ConvertFromString_TRX("col1"));
APT_UString* renamedFrom = new APT_UString[1]; APT_UString* renamedTo = new APT_UString[1];setInTransferAdapters(0, dropped, renamedFrom, renamedTo);
delete [] dropped; delete [] renamedFrom; delete [] renamedTo; // declare transfer.declareTransfers();
// set partitioner/sort insertion information.setModifyOutputSortKeys();
// set job parameters return APT_StatusOk;}
// parallel method, invoked in each partition.APT_Status APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol::doInitialProcessingChild(APT_InputAccessorInterface* inpInt[])
{APT_Status status = APT_StatusOk;
// define global variableinitNullMask(1);
// set up input accessor. // set up output accessor.setupOutputInterfaceAccessor();
return status;}
APT_Status APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol::setupInputInterfaceAccessorChild(APT_InputAccessorInterface** inCur)
{APT_STD::map<APT_UString, APT_InputAccessorBase*>* inAcc =
new APT_STD::map<APT_UString, APT_InputAccessorBase*, lessAPTUStr>[numRealInputs_]; inAcc[0].insert(APT_STD::map<APT_UString, APT_InputAccessorBase*, lessAPTUStr>::value_type(APT_ConvertFromString_TRX("col1"), &input0Int32col1));for (unsigned int input=0; input < 1; input++) {
APT_STD::map<APT_UString, APT_InputAccessorBase*, lessAPTUStr>::iterator iter;
for (iter = inAcc[input].begin(); iter != inAcc[input].end(); ++iter)inCur[input]->setupAccessor(iter->first, iter->second);
}
delete [] inAcc; return APT_StatusOk;}
APT_Status APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol::setupOutputInterfaceAccessorChild(APT_OutputAccessorInterface** outCur)
{APT_STD::map<APT_UString, APT_OutputAccessorBase*>* outAcc =
new APT_STD::map<APT_UString, APT_OutputAccessorBase*, lessAPTUStr>[numoutputs_ + numrejects_]; outAcc[0].insert(APT_STD::map<APT_UString, APT_OutputAccessorBase*, lessAPTUStr>::value_type(APT_ConvertFromString_TRX("col1"), &output0Int32col1));for (unsigned int output=0; output < 1; output++) {
APT_STD::map<APT_UString, APT_OutputAccessorBase*, lessAPTUStr>::iterator iter;
for (iter = outAcc[output].begin(); iter != outAcc[output].end(); ++iter)outCur[output]->setupAccessor(iter->first, iter->second);
}
delete [] outAcc; return APT_StatusOk;}
void APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol::processInputRecordChild(int inputDS, int curOutput[], int writtenOutput[])
{APT_Status convStat = APT_StatusOk;
// declare local variables // process records.clearNullMask();
// length of outputs is 1 // length of fields is 1 for output 0stage0RowRejected0=1;
output0Int32col1[0]=input0Int32col1[0]+1;
transferAndPutRecord(0);
stage0RowRejected0=0;
}
// parallel method, invoked in each partition.APT_Status APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol::doFinalProcessingChild()
{ // cleanup tables and caches return APT_StatusOk;}
void APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol::setRejectColumnValue(const APT_UString &errMsg, APT_Int32 rejectDs)
{ // Set the value of the reject column}
void APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol::processEOWChild(int inputDS)
{ // declare local variable // "finish" code segment}
APT_Status APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol::initializeWaveChild()
{APT_Status status = APT_StatusOk;
APT_Status convStat = APT_StatusOk;
// declare local variable // "initialize" code segment return status;}
template <class T>
void APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol::stringToNumeric<T>::convert(T& result, const APT_String& source, char* pBuf,
bool* msgPrinted, const APT_String& addlMsg)
{result = (T)strtod(source, &pBuf);
if (APT_strlen(pBuf) > 0 || APT_strlen(source) == 0) {result = 0;
issueWarning(msgPrinted, addlMsg);
}
}
template <class T>
void APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol::stringToNumeric<T>::convert(T& result, const APT_UString& source, UChar* pBuf,
bool* msgPrinted, const APT_String& addlMsg)
{result = (T)APT_strtod(source, &pBuf);
if (APT_strlen(pBuf) > 0 || APT_strlen(source) == 0) {result = 0;
issueWarning(msgPrinted, addlMsg);
}
}
template <class T>
void APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol::stringToNumeric<T>::convert(APT_Decimal& result, const APT_String& source,
bool* msgPrinted, const APT_String& addlMsg)
{APT_Status checkResult;
result.assignFromString(source, -1, APT_Decimal::eRoundInf, &checkResult);
if (checkResult == APT_StatusFailed) {result = 0;
issueWarning(msgPrinted, addlMsg, true);
}
}
template <class T>
void APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol::stringToNumeric<T>::convert(APT_Decimal& result, const APT_UString& source,
bool* msgPrinted, const APT_String& addlMsg)
{APT_Status checkResult;
result.assignFromString(APT_ConvertToString(source), -1, APT_Decimal::eRoundInf, &checkResult);
if (checkResult == APT_StatusFailed) {result = 0;
issueWarning(msgPrinted, addlMsg, true);
}
}
template <class T>
void APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol::stringToNumeric<T>::convert64(APT_Int64& result, const APT_String& source, char* pBuf,
bool* msgPrinted, const APT_String& addlMsg)
{result = APT_strtol64(source,&pBuf,10);
if (APT_strlen(pBuf) > 0 || APT_strlen(source) == 0)stringToNumeric<APT_Int64>::convert(result, source, pBuf, msgPrinted, addlMsg);
}
template <class T>
void APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol::stringToNumeric<T>::convert64(APT_Int64& result, const APT_UString& source, UChar* pBuf,
bool* msgPrinted, const APT_String& addlMsg)
{result = APT_strtol64(source,&pBuf,10);
if (APT_strlen(pBuf) > 0 || APT_strlen(source) == 0)stringToNumeric<APT_Int64>::convert(result, source, pBuf, msgPrinted, addlMsg);
}
template <class T>
void APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol::stringToNumeric<T>::convertU64(APT_UInt64& result, const APT_String& source, char* pBuf,
bool* msgPrinted, const APT_String& addlMsg)
{result = APT_strtoul64(source, &pBuf, 10);
if (APT_strlen(pBuf) > 0 || APT_strlen(source) == 0)stringToNumeric<APT_UInt64>::convert(result, source, pBuf, msgPrinted, addlMsg);
}
template <class T>
void APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol::stringToNumeric<T>::convertU64(APT_UInt64& result, const APT_UString& source, UChar* pBuf,
bool* msgPrinted, const APT_String& addlMsg)
{result = APT_strtoul64(source, &pBuf, 10);
if (APT_strlen(pBuf) > 0 || APT_strlen(source) == 0)stringToNumeric<APT_UInt64>::convert(result, source, pBuf, msgPrinted, addlMsg);
}
template <class T>
void APT_TransformOperatorImplV0S0_TransformerCodeDemo_tr_IncrCol::stringToNumeric<T>::issueWarning(bool* msgPrinted, const APT_String& addlMsg, bool isDecimal)
{ if (*msgPrinted) return;*msgPrinted = true;
APT_String msg;
static APT_String msgNumeric("Numeric string expected ");
static APT_String msgDecimal("Numeric string expected of the appropriate decimal precision ");
static APT_String msgEnd(". Use default value.");
if (isDecimal)msg = msgDecimal + addlMsg + msgEnd;
elsemsg = msgNumeric + addlMsg + msgEnd;
APT_TOFunctions::get().print_message(msg);
}
No comments:
Post a Comment