MultiLoad Notify Exit Routine issues in 14.00 and 14.10

Tools
Tools covers the tools and utilities you use to work with Teradata and its supporting ecosystem. You'll find information on everything from the Teradata Eclipse plug-in to load/extract tools.
Highlighted
Teradata Employee

MultiLoad Notify Exit Routine issues in 14.00 and 14.10

The Teradata MultiLoad Notify Exit Routine has some issues in the 14.00 and 14.10 releases because of enhancements to the MultiLoad notify events logic. This document discusses the enhancements and issues in detail.

Notify Event Enhancements

MultiLoad Delete Initialize Event Enhancement

In the initial Teradata Multi-System Manager (TMSM)/MultiLoad (MLOAD) integration, no data was passed to the MultiLoad Delete Initialize Event. TMSM requested that the same data sent to the MLOAD Initialize Event be passed to the MultiLoad Delete Initialize Event.

This enhancement was implemented in the 13.10 release. The data passed to the MultiLoad Delete Initialize Event is as follows:

  • Version ID length—4-byte unsigned integer
  • Version ID string—32-byte (maximum) array
  • Utility ID—4-byte unsigned integer
  • Utility name length—4-byte unsigned integer
  • Utility name string—32- byte (maximum) array
  • User name length—4-byte unsigned integer
  • User name string—64- byte (maximum) array
  • Optional string length—4-byte unsigned integer
  • Optional string—80- byte (maximum) array

MultiLoad Phase 1 Begin Event Enhancement

A customer requested that the Database Name be passed to the MultiLoad Phase 1 Begin Event.  When this enhancement was implemented in the 14.00 release, the development team added the Database Name to the beginning of the Phase 1 Begin structure, not the end of it.

See the code snippet below:

struct {
char DBaseName[MAXDBASENAMELEN];
UInt32 TableNameLen;
char TableName[MAXTABLENAMELEN];
UInt32 dummy;
} PhaseIBegin;

This made the Notify Exit facility for MultiLoad 14.00 and 14.10 non-functional against the Notify Exit Routine written in pre-14.00 releases because the field mappings changed. A bug (SA-29733) was opened to have the Database Name placed at the end of the structure.  SA-29733 was also used to back out some Notify source code to support 8-byte activity counts. SA-29733 was implemented in MultiLoad eFixes 14.00.00.009 and 14.10.00.003.

Now the data passed to MultiLoad Phase 1 Begin Event is:

  • Table name length—4-byte unsigned integer
  • Table name—128-byte (maximum) array
  • Table number—4-byte unsigned integer
  • Database name—62-byte (maximum) array

MultiLoad Notify Issues in the 14.10 GCA Release

The following Notify logic issues exist in the 14.10.00.000 release:

  • Usage of both MLNotifyExitParm* and MLNotifyExitParm64 to notify 4 and 8 byte activity count
  • Two functions MLNotify() and MLNotifyEon() to process Notify events
  • Two Notify structure pointers
#ifdef __MVS__
if(info->ModErr = modcall(p,p64))/*DR135262 DR147533*/
#else
if (info->ModErr = theExit(p,p64)) /* DR147533 */
#endif
  • Two MultiLoad samples mlnotf.c and mlnotfeon.c
    • Since no install change was done to include mlnotfeon.c, the MultiLoad Notify feature was broken if the script instrumented either the Extended Object Name (EON) logic or the 8-byte activity count logic.
  • The activity counts are not correct when using either the old sample mlnotf.c or new sample mlnotfeon.c.

JIRA Bug SA-29992 was created to track these bugs. SA-29992 was implemented in the 14.10.00.004 MultiLoad eFix.; NOTE: Some code from other JIRA Issues was backed out to fix the problems. The code changes were implemented in the following areas:

  • Introduced new Notify events:
NMEventInitializeEON  = 30, /* SA-29992 */
NMEventPhaseIBeginEON = 31,/* SA-29992 */
NMEventCheckPoint64 = 32,/* SA-29992 */
NMEventPhaseIIEnd64 = 33, /* SA-29992 */
NMEventErrorTableI64 = 34, /* SA-29992 */
NMEventErrorTableII64 = 35, /* SA-29992 */
NMEventDeleteInitEON = 36, /* SA-29992 */
NMEventDeleteBeginEON = 37, /* SA-29992 */
NMEventDeleteEnd64 = 38 /* SA-29992 */
  • Introduced new structures:

PhaseIEnd64

ImportEnd64

InitializeEON

PhaseIBeginEON

CheckPoint64

PhaseIIEnd64

ErrorTableI64

ErrorTableII64

DeleteInitEON

DeleteBeginEON

DeleteEnd64

  • Added new event handling in mldnotfy.c:

NMEventInitializeEON

NMEventPhaseIBeginEON

NMEventCheckPoint64

NMEventPhaseIIEnd64

NMEventErrorTableI64

NMEventErrorTableII64

NMEventDeleteInitEON

NMEventDeleteBeginEON

NMEventDeleteEnd64

  • In mldcli.c, mldexec.c and mldstmts.c, when EXITEON or EXIT64 is specified, the new events are notified. Otherwise, the old events are notified.
  • Applied SA-29733(Add database name enhancement) to the MLOAD DELETE task.

Sample MultiLoad Notify Exit Routines

For 14.00

/**********************************************************************/
/* */
/* mlnotf.c - Sample Notify Exit for MulitLoad. */
/* */
/* Copyright 1998-2013 by Teradata Corporation. */
/* ALL RIGHTS RESERVED. */
/* TERADATA CONFIDENTIAL AND TRADE SECRET */
/* */
/* Purpose - This is a sample notify exit for MultiLoad. */
/* */
/* Execute - Build Notify on a Unix system */
/* compile and link into shared object */
/* cc -G mlnotf.c -o mlnotf.so */
/* */
/* - Build Notify on a Win32 system */
/* compile and link into dynamic link library */
/* cl /DWIN32 /LD mlnotf.c */
/* */
/**********************************************************************/

#include <stdio.h>
typedef unsigned long UInt32;
typedef enum {
NMEventInitialize = 0,
NMEventFileInmodOpen = 1,
NMEventPhaseIBegin = 2,
NMEventCheckPoint = 3,
NMEventPhaseIEnd = 4,
NMEventPhaseIIBegin = 5,
NMEventPhaseIIEnd = 6,
NMEventErrorTableI = 7,
NMEventErrorTableII = 8,
NMEventDBSRestart = 9,
NMEventCLIError = 10,
NMEventDBSError = 11,
NMEventExit = 12,
NMEventAmpsDown = 21,
NMEventImportBegin = 22,
NMEventImportEnd = 23,
NMEventDeleteInit = 24,
NMEventDeleteBegin = 25,
NMEventDeleteEnd = 26,
NMEventDeleteExit = 27
} NfyMLDEvent;

/**************************************/
/* Structure for User Exit Interface */
/* DR42570 - redesigned and rewritten */
/**************************************/

#define NOTIFYID_FASTLOAD 1
#define NOTIFYID_MULTILOAD 2
#define NOTIFYID_FASTEXPORT 3
#define NOTIFYID_BTEQ 4
#define NOTIFYID_TPUMP 5

#define MAXVERSIONIDLEN 32
#define MAXUTILITYNAMELEN 32
#define MAXUSERNAMELEN 64
#define MAXUSERSTRLEN 80
#define MAXTABLENAMELEN 128
#define MAXFILENAMELEN 256
#define MAXDBASENAMELEN 62 /* Improvement SA-5394 */

typedef struct _MLNotifyExitParm {
UInt32 Event; /* should be NfyMLDEvent values */
union {
struct {
UInt32 VersionLen;
char VersionId[MAXVERSIONIDLEN];
UInt32 UtilityId;
UInt32 UtilityNameLen;
char UtilityName[MAXUTILITYNAMELEN];
UInt32 UserNameLen;
char UserName[MAXUSERNAMELEN];
UInt32 UserStringLen;
char UserString[MAXUSERSTRLEN];
} Initialize;
struct {
UInt32 FileNameLen;
char FileOrInmodName[MAXFILENAMELEN];
UInt32 ImportNo;
} FileInmodOpen ;
struct {
UInt32 TableNameLen;
char TableName[MAXTABLENAMELEN];
UInt32 TableNo;
char DBaseName[MAXDBASENAMELEN];
} PhaseIBegin;
struct {
UInt32 RecordCount;
} CheckPoint;
struct {
UInt32 RecsRead;
UInt32 RecsSkipped;
UInt32 RecsRejected;
UInt32 RecsSent;
} PhaseIEnd ;
struct {
UInt32 dummy;
} PhaseIIBegin;
struct {
UInt32 Inserts;
UInt32 Updates;
UInt32 Deletes;
UInt32 TableNo;
} PhaseIIEnd;
struct {
UInt32 Rows;
UInt32 TableNo;
} ErrorTableI;
struct {
UInt32 Rows;
UInt32 TableNo;
} ErrorTableII ;
struct {
UInt32 dummy;
} DBSRestart;
struct {
UInt32 ErrorCode;
} CLIError;
struct {
UInt32 ErrorCode;
} DBSError;
struct {
UInt32 ReturnCode;
} Exit;
struct {
UInt32 dummy;
} AmpsDown;
struct {
UInt32 ImportNo;
} ImportBegin ;
struct {
UInt32 RecsRead;
UInt32 RecsSkipped;
UInt32 RecsRejected;
UInt32 RecsSent;
UInt32 ImportNo;
} ImportEnd ;
struct {
UInt32 VersionLen;
char VersionId[MAXVERSIONIDLEN];
UInt32 UtilityId;
UInt32 UtilityNameLen;
char UtilityName[MAXUTILITYNAMELEN];
UInt32 UserNameLen;
char UserName[MAXUSERNAMELEN];
UInt32 UserStringLen;
char UserString[MAXUSERSTRLEN];
} DeleteInit;
struct {
UInt32 TableNameLen;
char TableName[MAXTABLENAMELEN];
UInt32 TableNo;
} DeleteBegin;
struct {
UInt32 Deletes;
UInt32 TableNo;
} DeleteEnd;
struct {
UInt32 ReturnCode;
} DeleteExit;
} Vals;
} MLNotifyExitParm;

#ifdef I370
#define MLNfyExit MLNfEx
#endif

extern long MLNfyExit(
#ifdef __STDC__
MLNotifyExitParm *Parms
#endif
);

#ifdef WIN32
__declspec(dllexport) long _dynamn(MLNotifyExitParm *P)
#else
long _dynamn( MLNotifyExitParm *P)
#endif
{
FILE *fp;

if (!(fp = fopen("NFYEXIT.OUT", "a")))
return(1);

switch(P->Event) {
case NMEventInitialize :
fprintf(fp, "exit called @ mload init.\n");
fprintf(fp, "Version: %s\n", P->Vals.Initialize.VersionId);
fprintf(fp, "Utility: %s\n", P->Vals.Initialize.UtilityName);
fprintf(fp, "User: %s\n", P->Vals.Initialize.UserName);
if (P->Vals.Initialize.UserStringLen)
fprintf(fp, "UserString: %s\n", P->Vals.Initialize.UserString);
break;
case NMEventFileInmodOpen:
fprintf(fp, "exit called @ file open: import[%d]: %s\n",
P->Vals.FileInmodOpen.ImportNo,
P->Vals.FileInmodOpen.FileOrInmodName);
break;
case NMEventPhaseIBegin :
fprintf(fp, "exit called @ acquistion start: Database Name : %s.\n",
P->Vals.PhaseIBegin.DBaseName); /* Improvement SA-5394 */
fprintf(fp, "exit called @ acquistion start: tablename[%d] : %s.\n",
P->Vals.PhaseIBegin.TableNo,
P->Vals.PhaseIBegin.TableName);
break;
case NMEventCheckPoint :
fprintf(fp, "exit called @ checkpoint : %d records loaded.\n",
P->Vals.CheckPoint.RecordCount);
break;
case NMEventPhaseIEnd :
fprintf(fp, "exit called @ acquistion end.\n");
fprintf(fp, "Records Read: %d\n", P->Vals.PhaseIEnd.RecsRead);
fprintf(fp, "Records Skipped: %d\n", P->Vals.PhaseIEnd.RecsSkipped);
fprintf(fp, "Records Rejected: %d\n", P->Vals.PhaseIEnd.RecsRejected);
fprintf(fp, "Records Sent: %d\n", P->Vals.PhaseIEnd.RecsSent);
break;
case NMEventPhaseIIBegin :
fprintf(fp, "exit called @ application start\n");
break;
case NMEventPhaseIIEnd :
fprintf(fp, "exit called @ application complete for table %d.\n",
P->Vals.PhaseIIEnd.TableNo);
fprintf(fp, "%d updates, %d inserts, %d deletes\n",
P->Vals.PhaseIIEnd.Updates,
P->Vals.PhaseIIEnd.Inserts,
P->Vals.PhaseIIEnd.Deletes);
break;
case NMEventErrorTableI :
fprintf(fp,
"exit called @ ET Table[%d] Drop : %d records in table.\n",
P->Vals.ErrorTableI.TableNo, P->Vals.ErrorTableI.Rows);
break;
case NMEventErrorTableII :
fprintf(fp,
"exit called @ UV Table[%d] Drop : %d records in table.\n",
P->Vals.ErrorTableII.TableNo, P->Vals.ErrorTableII.Rows);
break;
case NMEventDBSRestart :
fprintf(fp, "exit called @ RDBMS restarted\n");
break;
case NMEventCLIError :
fprintf(fp, "exit called @ CLI error %d\n",
P->Vals.CLIError.ErrorCode);
break;
case NMEventDBSError :
fprintf(fp, "exit called @ DBS error %d\n",
P->Vals.DBSError.ErrorCode);
break;

case NMEventExit :
fprintf(fp, "exit called @ mload notify out of scope: return code %d.\n",
P->Vals.Exit.ReturnCode);
break;
case NMEventAmpsDown :
fprintf(fp, "exit called @ down amps have been detected\n");
break;
case NMEventImportBegin :
fprintf(fp, "exit called @ import %d starting\n",
P->Vals.ImportBegin.ImportNo);
break;
case NMEventImportEnd :
fprintf(fp, "exit called @ import %d ending.\n",
P->Vals.ImportEnd.ImportNo);
fprintf(fp, "Records Read: %d\n", P->Vals.ImportEnd.RecsRead);
fprintf(fp, "Records Skipped: %d\n", P->Vals.ImportEnd.RecsSkipped);
fprintf(fp, "Records Rejected: %d\n", P->Vals.ImportEnd.RecsRejected);
fprintf(fp, "Records Sent: %d\n", P->Vals.ImportEnd.RecsSent);
break;
case NMEventDeleteInit :
fprintf(fp, "exit called @ mload delete init.\n");
fprintf(fp, "Version: %s\n", P->Vals.DeleteInit.VersionId);
fprintf(fp, "Utility: %s\n", P->Vals.DeleteInit.UtilityName);
fprintf(fp, "User: %s\n", P->Vals.DeleteInit.UserName);
if (P->Vals.DeleteInit.UserStringLen)
fprintf(fp, "UserString: %s\n", P->Vals.DeleteInit.UserString);
break;
case NMEventDeleteBegin :
fprintf(fp, "exit called @ delete app start for table[%d]: %s.\n",
P->Vals.DeleteBegin.TableNo, P->Vals.DeleteBegin.TableName);
break;
case NMEventDeleteEnd :
fprintf(fp, "exit called @ delete app done for table[%d]: %d rows.\n",
P->Vals.DeleteEnd.TableNo, P->Vals.DeleteEnd.Deletes);
break;
case NMEventDeleteExit :
fprintf(fp, "exit called @ mload delete notify out of scope: return code %d.\n",
P->Vals.DeleteExit.ReturnCode);
break;
}
fclose(fp);
return(0);
}

For 14.10.00.004

/**********************************************************************/
/* */
/* mlnotf.c - Sample Notify Exit for MulitLoad. */
/* */
/* Copyright 1998-2013 by Teradata Corporation. */
/* ALL RIGHTS RESERVED. */
/* TERADATA CONFIDENTIAL AND TRADE SECRET */
/* */
/* Purpose - This is a sample notify exit for MultiLoad. */
/* */
/* Execute - Build Notify on a Unix system */
/* compile and link into shared object */
/* cc -G mlnotf.c -o mlnotf.so */
/* */
/* - Build Notify on a Win32 system */
/* compile and link into dynamic link library */
/* cl /DWIN32 /LD mlnotf.c */
/* */
/**********************************************************************/
#include <stdio.h>;
typedef unsigned long UInt32;
typedef enum {
NMEventInitialize = 0,
NMEventFileInmodOpen = 1,
NMEventPhaseIBegin = 2,
NMEventCheckPoint = 3,
NMEventPhaseIEnd = 4,
NMEventPhaseIIBegin = 5,
NMEventPhaseIIEnd = 6,
NMEventErrorTableI = 7,
NMEventErrorTableII = 8,
NMEventDBSRestart = 9,
NMEventCLIError = 10,
NMEventDBSError = 11,
NMEventExit = 12,
NMEventAmpsDown = 21,
NMEventImportBegin = 22,
NMEventImportEnd = 23,
NMEventDeleteInit = 24,
NMEventDeleteBegin = 25,
NMEventDeleteEnd = 26,
NMEventDeleteExit = 27,
NMEventPhaseIEnd64 = 28,
NMEventImportEnd64 = 29,
NMEventInitializeEON = 30,
NMEventPhaseIBeginEON = 31,
NMEventCheckPoint64 = 32,
NMEventPhaseIIEnd64 = 33,
NMEventErrorTableI64 = 34,
NMEventErrorTableII64 = 35,
NMEventDeleteInitEON = 36,
NMEventDeleteBeginEON = 37,
NMEventDeleteEnd64 = 38
} NfyMLDEvent;

#define NOTIFYID_FASTLOAD 1
#define NOTIFYID_MULTILOAD 2
#define NOTIFYID_FASTEXPORT 3
#define NOTIFYID_BTEQ 4
#define NOTIFYID_TPUMP 5

#define MAXVERSIONIDLEN 32
#define MAXUTILITYNAMELEN 32
#define MAXUSERNAMELEN 64
#define MAXUSERSTRLEN 80
#define MAXTABLENAMELEN 128
#define MAXFILENAMELEN 256
#define MAXDBASENAMELEN 62
#define MAXUINT64LEN 24
typedef struct _MLNotifyExitParm {
UInt32 Event; /* should be NfyMLDEvent values */
union {
struct {
UInt32 VersionLen;
char VersionId[MAXVERSIONIDLEN];
UInt32 UtilityId;
UInt32 UtilityNameLen;
char UtilityName[MAXUTILITYNAMELEN];
UInt32 UserNameLen;
char UserName[MAXUSERNAMELEN];
UInt32 UserStringLen;
char UserString[MAXUSERSTRLEN];
} Initialize;
struct {
UInt32 FileNameLen;
char FileOrInmodName[MAXFILENAMELEN];
UInt32 ImportNo;
} FileInmodOpen ;
struct {
UInt32 TableNameLen;
char TableName[MAXTABLENAMELEN];
UInt32 TableNo;
char DBaseName[MAXDBASENAMELEN];
} PhaseIBegin;
struct {
UInt32 RecordCount;
} CheckPoint;
struct {
UInt32 RecsRead;
UInt32 RecsSkipped;
UInt32 RecsRejected;
UInt32 RecsSent;
} PhaseIEnd ;
struct {
UInt32 dummy;
} PhaseIIBegin;
struct {
UInt32 Inserts;
UInt32 Updates;
UInt32 Deletes;
UInt32 TableNo;
} PhaseIIEnd;
struct {
UInt32 Rows;
UInt32 TableNo;
} ErrorTableI;
struct {
UInt32 Rows;
UInt32 TableNo;
} ErrorTableII ;
struct {
UInt32 dummy;
} DBSRestart;
struct {
UInt32 ErrorCode;
} CLIError;
struct {
UInt32 ErrorCode;
} DBSError;
struct {
UInt32 ReturnCode;
} Exit;
struct {
UInt32 dummy;
} AmpsDown;
struct {
UInt32 ImportNo;
} ImportBegin ;
struct {
UInt32 RecsRead;
UInt32 RecsSkipped;
UInt32 RecsRejected;
UInt32 RecsSent;
UInt32 ImportNo;
} ImportEnd ;
struct {
UInt32 VersionLen;
char VersionId[MAXVERSIONIDLEN];
UInt32 UtilityId;
UInt32 UtilityNameLen;
char UtilityName[MAXUTILITYNAMELEN];
UInt32 UserNameLen;
char UserName[MAXUSERNAMELEN];
UInt32 UserStringLen;
char UserString[MAXUSERSTRLEN];
} DeleteInit;
struct {
UInt32 TableNameLen;
char TableName[MAXTABLENAMELEN];
UInt32 TableNo;
char DBaseName[MAXDBASENAMELEN];
} DeleteBegin;
struct {
UInt32 Deletes;
UInt32 TableNo;
} DeleteEnd;
struct {
UInt32 ReturnCode;
} DeleteExit;
struct {
char RecsRead[MAXUINT64LEN];
char RecsSkipped[MAXUINT64LEN];
char RecsRejected[MAXUINT64LEN];
char RecsSent[MAXUINT64LEN];
} PhaseIEnd64 ;
struct {
char RecsRead[MAXUINT64LEN];
char RecsSkipped[MAXUINT64LEN];
char RecsRejected[MAXUINT64LEN];
char RecsSent[MAXUINT64LEN];
UInt32 ImportNo;
} ImportEnd64 ;
struct {
UInt32 VersionLen;
char VersionId[MAXVERSIONIDLEN];
UInt32 UtilityId;
UInt32 UtilityNameLen;
char UtilityName[MAXUTILITYNAMELEN];
UInt32 UserNameLen;
char *UserName;
UInt32 UserStringLen;
char *UserString;
} InitializeEON;
struct {
UInt32 TableNameLen;
char *TableName;
UInt32 TableNo;
char *DBaseName;
} PhaseIBeginEON;
struct {
char RecordCount[MAXUINT64LEN];
} CheckPoint64;
struct {
char Inserts[MAXUINT64LEN];
char Updates[MAXUINT64LEN];
char Deletes[MAXUINT64LEN];
UInt32 TableNo;
} PhaseIIEnd64;
struct {
char Rows[MAXUINT64LEN];
UInt32 TableNo;
} ErrorTableI64;
struct {
char Rows[MAXUINT64LEN];
UInt32 TableNo;
} ErrorTableII64 ;
struct {
UInt32 VersionLen;
char VersionId[MAXVERSIONIDLEN];
UInt32 UtilityId;
UInt32 UtilityNameLen;
char UtilityName[MAXUTILITYNAMELEN];
UInt32 UserNameLen;
char *UserName;
UInt32 UserStringLen;
char *UserString;
} DeleteInitEON;
struct {
UInt32 TableNameLen;
char *TableName;
UInt32 TableNo;
char *DBaseName;
} DeleteBeginEON;
struct {
char Deletes[MAXUINT64LEN];
UInt32 TableNo;
} DeleteEnd64;
} Vals;
} MLNotifyExitParm;

#ifdef I370
#define MLNfyExit MLNfEx
#endif

extern long MLNfyExit(
#ifdef __STDC__
MLNotifyExitParm *Parms
#endif
);

#ifdef WIN32
__declspec(dllexport) long _dynamn(MLNotifyExitParm *P)
#else
long _dynamn( MLNotifyExitParm *P)
#endif
{
FILE *fp;

if (!(fp = fopen("NFYEXIT.OUT", "a")))
return(1);

switch(P->Event) {
case NMEventInitialize :
fprintf(fp, "exit called @ mload init.\n");
fprintf(fp, "Version: %s\n", P->Vals.Initialize.VersionId);
fprintf(fp, "Utility: %s\n", P->Vals.Initialize.UtilityName);
fprintf(fp, "User: %s\n", P->Vals.Initialize.UserName);
if (P->Vals.Initialize.UserStringLen)
fprintf(fp, "UserString: %s\n", P->Vals.Initialize.UserString);
break;
case NMEventFileInmodOpen:
fprintf(fp, "exit called @ file open: import[%d]: %s\n",
P->Vals.FileInmodOpen.ImportNo,
P->Vals.FileInmodOpen.FileOrInmodName);
break;
case NMEventPhaseIBegin :
fprintf(fp, "exit called @ acquistion start: Database Name : %s.\n",
P->Vals.PhaseIBegin.DBaseName); /* Improvement SA-5394 */

fprintf(fp, "exit called @ acquistion start: tablename[%d] : %s.\n",
P->Vals.PhaseIBegin.TableNo,
P->Vals.PhaseIBegin.TableName);
break;
case NMEventCheckPoint :
fprintf(fp, "exit called @ checkpoint : %d records loaded.\n",
P->Vals.CheckPoint.RecordCount);
break;
case NMEventPhaseIEnd :
fprintf(fp, "exit called @ acquistion end.\n");
fprintf(fp, "Records Read: %d\n", P->Vals.PhaseIEnd.RecsRead);
fprintf(fp, "Records Skipped: %d\n", P->Vals.PhaseIEnd.RecsSkipped);
fprintf(fp, "Records Rejected: %d\n", P->Vals.PhaseIEnd.RecsRejected);
fprintf(fp, "Records Sent: %d\n", P->Vals.PhaseIEnd.RecsSent);
break;
case NMEventPhaseIIBegin :
fprintf(fp, "exit called @ application start\n");
break;
case NMEventPhaseIIEnd :
fprintf(fp, "exit called @ application complete for table %d.\n",
P->Vals.PhaseIIEnd.TableNo);
fprintf(fp, "%d updates, %d inserts, %d deletes\n",
P->Vals.PhaseIIEnd.Updates,
P->Vals.PhaseIIEnd.Inserts,
P->Vals.PhaseIIEnd.Deletes);
break;
case NMEventErrorTableI :
fprintf(fp,
"exit called @ ET Table[%d] Drop : %d records in table.\n",
P->Vals.ErrorTableI.TableNo, P->Vals.ErrorTableI.Rows);
break;
case NMEventErrorTableII :
fprintf(fp,
"exit called @ UV Table[%d] Drop : %d records in table.\n",
P->Vals.ErrorTableII.TableNo, P->Vals.ErrorTableII.Rows);
break;
case NMEventDBSRestart :
fprintf(fp, "exit called @ RDBMS restarted\n");
break;
case NMEventCLIError :
fprintf(fp, "exit called @ CLI error %d\n",
P->Vals.CLIError.ErrorCode);
break;
case NMEventDBSError :
fprintf(fp, "exit called @ DBS error %d\n",
P->Vals.DBSError.ErrorCode);
break;
case NMEventExit :
fprintf(fp, "exit called @ mload notify out of scope: return code %d.\n",
P->Vals.Exit.ReturnCode);
break;
case NMEventAmpsDown :
fprintf(fp, "exit called @ down amps have been detected\n");
break;
case NMEventImportBegin :
fprintf(fp, "exit called @ import %d starting\n",
P->Vals.ImportBegin.ImportNo);
break;
case NMEventImportEnd :
fprintf(fp, "exit called @ import %d ending.\n",
P->Vals.ImportEnd.ImportNo);
fprintf(fp, "Records Read: %d\n", P->Vals.ImportEnd.RecsRead);
fprintf(fp, "Records Skipped: %d\n", P->Vals.ImportEnd.RecsSkipped);
fprintf(fp, "Records Rejected: %d\n", P->Vals.ImportEnd.RecsRejected);
fprintf(fp, "Records Sent: %d\n", P->Vals.ImportEnd.RecsSent);
break;
case NMEventDeleteInit :
fprintf(fp, "exit called @ mload delete init.\n");
fprintf(fp, "Version: %s\n", P->Vals.DeleteInit.VersionId);
fprintf(fp, "Utility: %s\n", P->Vals.DeleteInit.UtilityName);
fprintf(fp, "User: %s\n", P->Vals.DeleteInit.UserName);
if (P->Vals.DeleteInit.UserStringLen)
fprintf(fp, "UserString: %s\n", P->Vals.DeleteInit.UserString);
break;
case NMEventDeleteBegin :
fprintf(fp, "exit called @ delete app start: Databasename : %s.\n",
P->Vals.DeleteBegin.DBaseName);
fprintf(fp, "exit called @ delete app start for table[%d]: %s.\n",
P->Vals.DeleteBegin.TableNo, P->Vals.DeleteBegin.TableName);
break;
case NMEventDeleteEnd :
fprintf(fp, "exit called @ delete app done for table[%d]: %d rows.\n",
P->Vals.DeleteEnd.TableNo, P->Vals.DeleteEnd.Deletes);
break;
case NMEventDeleteExit :
fprintf(fp, "exit called @ mload delete notify out of scope: return code %d.\n",
P->Vals.DeleteExit.ReturnCode);
break;
case NMEventInitializeEON : /* Nothing */
fprintf(fp, "exit called @ mload init.\n");
fprintf(fp, "Version: %s\n", P->Vals.InitializeEON.VersionId);
fprintf(fp, "Utility: %s\n", P->Vals.InitializeEON.UtilityName);
fprintf(fp, "User: %s\n", P->Vals.InitializeEON.UserName);
if (P->Vals.InitializeEON.UserStringLen)
fprintf(fp, "UserString: %s\n", P->Vals.InitializeEON.UserString);
break;
case NMEventPhaseIBeginEON :
fprintf(fp, "exit called @ acquistion start: Databasename : %s.\n",
P->Vals.PhaseIBeginEON.DBaseName);
fprintf(fp, "exit called @ acquistion start: tablename[%d] : %s.\n",
P->Vals.PhaseIBeginEON.TableNo,
P->Vals.PhaseIBeginEON.TableName);
break;
case NMEventCheckPoint64 :
fprintf(fp, "exit called @ checkpoint : %s records loaded.\n",
P->Vals.CheckPoint64.RecordCount);
break;
case NMEventPhaseIEnd64 :
fprintf(fp, "exit called @ acquistion end.\n");
fprintf(fp, "Records Read: %s\n", P->Vals.PhaseIEnd64.RecsRead);
fprintf(fp, "Records Skipped: %s\n", P->Vals.PhaseIEnd64.RecsSkipped);
fprintf(fp, "Records Rejected: %s\n", P->Vals.PhaseIEnd64.RecsRejected);
fprintf(fp, "Records Sent: %s\n", P->Vals.PhaseIEnd64.RecsSent);
break;
case NMEventPhaseIIEnd64 :
fprintf(fp, "exit called @ application complete for table %d.\n",
P->Vals.PhaseIIEnd64.TableNo);
fprintf(fp, "%s updates, %s inserts, %s deletes\n",
P->Vals.PhaseIIEnd64.Updates,
P->Vals.PhaseIIEnd64.Inserts,
P->Vals.PhaseIIEnd64.Deletes);
break;
case NMEventErrorTableI64 :
fprintf(fp,
"exit called @ ET Table[%d] Drop : %s records in table.\n",
P->Vals.ErrorTableI64.TableNo, P->Vals.ErrorTableI64.Rows);
break;
case NMEventErrorTableII64 :
fprintf(fp,
"exit called @ UV Table[%d] Drop : %s records in table.\n",
P->Vals.ErrorTableII64.TableNo, P->Vals.ErrorTableII64.Rows);
break;
case NMEventImportEnd64 :
fprintf(fp, "exit called @ import %d ending.\n",
P->Vals.ImportEnd64.ImportNo);
fprintf(fp, "Records Read: %s\n", P->Vals.ImportEnd64.RecsRead);
fprintf(fp, "Records Skipped: %s\n", P->Vals.ImportEnd64.RecsSkipped);
fprintf(fp, "Records Rejected: %s\n", P->Vals.ImportEnd64.RecsRejected);
fprintf(fp, "Records Sent: %s\n", P->Vals.ImportEnd64.RecsSent);
break;
case NMEventDeleteInitEON :
fprintf(fp, "exit called @ mload delete init.\n");
fprintf(fp, "Version: %s\n", P->Vals.DeleteInitEON.VersionId);
fprintf(fp, "Utility: %s\n", P->Vals.DeleteInitEON.UtilityName);
fprintf(fp, "User: %s\n", P->Vals.DeleteInitEON.UserName);
if (P->Vals.DeleteInitEON.UserStringLen)
fprintf(fp, "UserString: %s\n", P->Vals.DeleteInitEON.UserString);
break;
case NMEventDeleteBeginEON :
fprintf(fp, "exit called @ delete app start: Databasename : %s.\n",
P->Vals.DeleteBeginEON.DBaseName);
fprintf(fp, "exit called @ delete app start for table[%d]: %s.\n",
P->Vals.DeleteBeginEON.TableNo, P->Vals.DeleteBeginEON.TableName);
break;
case NMEventDeleteEnd64 :
fprintf(fp, "exit called @ delete app done for table[%d]: %s rows.\n",
P->Vals.DeleteEnd64.TableNo, P->Vals.DeleteEnd64.Deletes);
break;
}
fclose(fp);
return(0);
}

1 REPLY
Teradata Employee

Re: MultiLoad Notify Exit Routine issues in 14.00 and 14.10

Thanks for the information.