IBMiUnit-test-case-generation

Test case generation using IBMi

🚨 RPGLE Code Generation Mistakes - Comprehensive Documentation

πŸ“‹ Purpose

This document catalogs critical syntax errors and conceptual mistakes made during RPGLE code generation to prevent future compilation failures. Each mistake is documented with the incorrect code generated and the correct compilable alternative.


❌ MISTAKE #1: Data Structure Declaration Errors

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Standalone field declared as data structure
dcl-s errorInfo qualified;

// Wrong: Invalid *LDA declaration
dcl-s systemDataArea char(100) dtaara('*LDA');

βœ… CORRECT COMPILABLE CODE:

// Correct: Use dcl-ds for data structure
dcl-ds errorInfo qualified;
    // fields here
end-ds;

// Correct: Valid *LDA declaration (if needed)
dcl-ds systemDataArea dtaara('*LDA');
    // structure definition
end-ds;

πŸ“– LESSON LEARNED:


❌ MISTAKE #2: Variable Declaration Type Errors

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: %rem variables declared as Packed instead of Int
dcl-s remainder packed(5:0);

// Wrong: Constants declared with packed variable
dcl-c MAX_SIZE packed(3:0) inz(100);

βœ… CORRECT COMPILABLE CODE:

// Correct: Use int for %rem results
dcl-s remainder int(10);

// Correct: Constants use const keyword
dcl-c MAX_SIZE const(100);

πŸ“– LESSON LEARNED:


❌ MISTAKE #3: Invalid BIF Usage

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: %sorta doesn't exist as a BIF
%sorta(numbers);

// Wrong: %equal doesn't work for array comparison
if %equal(array1 : array2);

// Wrong: %occurs BIF doesn't exist
closeBraces = %occurs('}' : jsonData);

// Wrong: %checkr is not a valid BIF
pos = %checkr(' ' : testName);

βœ… CORRECT COMPILABLE CODE:

// Correct: SORTA is an operation code
sorta numbers;

// Correct: Manual array comparison
isEqual = *on;
for i = 1 to 3;
  if array1(i) <> array2(i);
    isEqual = *off;
    leave;
  endif;
endfor;

// Correct: Use %scan for string searching
pos = %scan('}' : jsonData);

// Correct: Use %scan for string operations
pos = %scan(' ' : testName);

πŸ“– LESSON LEARNED:


❌ MISTAKE #4: Multidimensional Array Errors

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Multidimensional array syntax
dcl-s matrix packed(5:2) dim(10) dim(10);
matrix(i:j) = value;

// Wrong: Complex BIF combinations
%sorta(%subarr(numbers : 2 : 3));

βœ… CORRECT COMPILABLE CODE:

// Correct: Single dimension simulating matrix
dcl-s matrix packed(5:2) dim(100);
index = (i - 1) * 10 + j;
matrix(index) = value;

// Correct: Manual subarray operations
for i = 1 to 3;
  temp(i) = numbers(i + 1);
endfor;
sorta temp;
for i = 1 to 3;
  numbers(i + 1) = temp(i);
endfor;

πŸ“– LESSON LEARNED:


❌ MISTAKE #5: Bit Manipulation Errors

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: BITON/BITOFF don't exist in free-format
biton PATTERN_80 bitField;
bitoff PATTERN_01 bitField;

// Wrong: Hardcoded bit manipulation
bitField = %bitand(bitField : x'A4');

βœ… CORRECT COMPILABLE CODE:

// Correct: Use BIFs for bit manipulation
bitField = %bitor(bitField : x'80');      // Set bits
bitField = %bitand(bitField : %bitnot(x'01')); // Clear bits

// Correct: Use %bitnot for proper clearing
bitField = %bitand(bitField : %bitnot(PATTERN_01));

πŸ“– LESSON LEARNED:


❌ MISTAKE #6: Control Flow and Syntax Errors

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Ternary operator not supported
status = (balance > 1000 ? 'GOOD' : 'POOR');
effectiveRate = %parms() >= 2 ? taxRate : defaultRate;

// Wrong: Invalid %subst usage
result = %subst(*blanks : 1 : length);

// Wrong: %varchar as opcode
%varchar(field);

βœ… CORRECT COMPILABLE CODE:

// Correct: Use if/else structure
if balance > 1000;
  status = 'GOOD';
else;
  status = 'POOR';
endif;

if %parms() >= 2;
  effectiveRate = taxRate;
else;
  effectiveRate = defaultRate;
endif;

// Correct: Use *blanks directly
result = *blanks;

// Correct: VARCHAR is handled automatically by IBM i
// No manual conversion needed

πŸ“– LESSON LEARNED:


❌ MISTAKE #7: Memory Management and Pointer Errors

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: %dealloc doesn't exist
%dealloc(ptr);

// Wrong: Invalid assertion syntax
assertNull(%addr(ptr : *data));

βœ… CORRECT COMPILABLE CODE:

// Correct: Use dealloc operation code
dealloc ptr;

// Correct: Proper pointer testing
// (Note: You cannot reliably test pointer deallocation in RPGLE)

πŸ“– LESSON LEARNED:


❌ MISTAKE #8: Display File and Field Length Errors

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Display keyword with > 52 characters
dcl-s longVariable char(100);
// Then using in display file with DDS exceeding 52 chars

βœ… CORRECT COMPILABLE CODE:

// Correct: Limit display fields to 52 characters max
dcl-s displayField char(52);
// Use appropriate field lengths for display files

πŸ“– LESSON LEARNED:


❌ MISTAKE #9: File Operations and Structure Errors

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: IFS operations with multiple errors
// (Specific errors not detailed but code was fundamentally flawed)

// Wrong: Invalid copybook reference
/copy QCPYSRC,HTTPAPI_PR

βœ… CORRECT COMPILABLE CODE:

// Correct: Proper IFS operations require careful syntax
// Need to understand file structure before generating code

// Correct: Valid copybook reference
/copy QCPYSRC,HTTPAPI_PR  // If copybook exists
// Or use appropriate copy member syntax

πŸ“– LESSON LEARNED:


❌ MISTAKE #10: Variable Scope and Declaration Placement

πŸ”΄ INCORRECT CODE GENERATED:

dcl-proc myProcedure;
  // Some executable code
  dcl-s result varchar(32000);  // Wrong: Declaration after code
  
  for i = 1 to 10;
    dcl-s loopVar int(10);      // Wrong: Declaration in loop
  endfor;
end-proc;

βœ… CORRECT COMPILABLE CODE:

dcl-proc myProcedure;
  // Correct: All declarations at beginning
  dcl-s result varchar(32000);
  dcl-s loopVar int(10);
  dcl-s i int(10);
  
  // Executable code follows
  for i = 1 to 10;
    // Use variables declared above
  endfor;
end-proc;

πŸ“– LESSON LEARNED:


❌ MISTAKE #11: Data Structure Template vs Instance Confusion

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Using dcl-s for template-based arrays
dcl-s cache likeds(cacheEntry_t) dim(1000);

// Wrong: Complex BIF in initialization
dcl-s timestamp timestamp inz(%timestamp());

βœ… CORRECT COMPILABLE CODE:

// Correct: Use dcl-ds for template-based structures
dcl-ds cache likeds(cacheEntry_t) dim(100);

// Correct: Separate declaration and assignment
dcl-s timestamp timestamp;
timestamp = %timestamp();

πŸ“– LESSON LEARNED:


❌ MISTAKE #12: Multiple Occurrence Data Structure Errors

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Two-parameter %occur syntax
%occur(MultiOccur : 5);

// Wrong: Qualified access to occurrence fields
MultiOccur.field1 = 'Data';

// Wrong: Mixed declaration syntax
dcl-ds MultiOccur qualified template occurs(10);
dcl-ds testMultiOcc likeds(MultiOccur);

βœ… CORRECT COMPILABLE CODE:

// Correct: Assignment to %occur BIF
%occur(MultiOccur) = 5;

// Correct: Direct field access after setting occurrence
field1 = 'Data';

// Correct: Simple occurs declaration
dcl-ds MultiOccur occurs(10);
    field1 char(10);
    field2 packed(5:0);
end-ds;

πŸ“– LESSON LEARNED:


❌ MISTAKE #13: Test Framework Flow Control

πŸ”΄ INCORRECT CODE GENERATED:

IBMiUnit_setupSuite('Test Suite');
IBMiUnit_addTestCase(%pAddr(Test_Proc1): 'Test_Proc1');
IBMiUnit_teardownSuite();  // Wrong: Executes immediately

dcl-proc Test_Proc1;
    // test code
end-proc;

βœ… CORRECT COMPILABLE CODE:

IBMiUnit_setupSuite('Test Suite');
IBMiUnit_addTestCase(%pAddr(Test_Proc1): 'Test_Proc1');
return;  // Correct: Prevents premature teardown
IBMiUnit_teardownSuite();

dcl-proc Test_Proc1;
    // test code
end-proc;

πŸ“– LESSON LEARNED:


❌ MISTAKE #14: String and Numeric Operation Errors

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: MOD operator usage
result = value mod 10;

// Wrong: String concatenation with +
longString = 'First part' +
             'Second part';

// Wrong: Invalid assertion syntax
assertNotNull(variable);

βœ… CORRECT COMPILABLE CODE:

// Correct: Use %rem() BIF for modulo
result = %rem(value : 10);

// Correct: Keep strings intact or use proper continuation
longString = 'First part Second part';

// Correct: Use %addr() for varchar variables
assertNotNull(%addr(variable));

πŸ“– LESSON LEARNED:


❌ MISTAKE #15: PSDS and System Data Area Errors

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: PSDS without template keyword
dcl-ds PSDS;

// Wrong: Invalid *LDA syntax
dcl-s systemDataArea char(100) dtaara('*LDA');

βœ… CORRECT COMPILABLE CODE:

// Correct: PSDS with template keyword
dcl-ds PSDS template;
    // PSDS fields
end-ds;

// Correct: Proper *LDA declaration
dcl-ds systemDataArea dtaara('*LDA');
    // LDA structure
end-ds;

πŸ“– LESSON LEARNED:


❌ MISTAKE #16: Procedure Interface and Prototype Mismatches

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Mismatched prototype and interface
dcl-pr myProcedure varchar(100);
  inputParam char(50) const;
end-pr;

dcl-proc myProcedure;
  dcl-pi *n char(100);  // Wrong: Different return type
    inputParam varchar(50) const;  // Wrong: Different parameter type
  end-pi;
end-proc;

βœ… CORRECT COMPILABLE CODE:

// Correct: Matching prototype and interface
dcl-pr myProcedure varchar(100);
  inputParam char(50) const;
end-pr;

dcl-proc myProcedure;
  dcl-pi *n varchar(100);
    inputParam char(50) const;
  end-pi;
end-proc;

πŸ“– LESSON LEARNED:


❌ MISTAKE #17: Incorrect Date/Time BIF Usage

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Invalid date format string
currentDate = %char(%date() : '*YMD-');

// Wrong: Invalid %diff parameters
daysDiff = %diff(%date() : startDate);

// Wrong: Invalid timestamp initialization
dcl-s myTimestamp timestamp inz(%timestamp('2024-01-01-12.00.00'));

βœ… CORRECT COMPILABLE CODE:

// Correct: Valid date format
currentDate = %char(%date() : '*YMD');

// Correct: %diff with time unit
daysDiff = %diff(%date() : startDate : *days);

// Correct: Proper timestamp format
dcl-s myTimestamp timestamp;
myTimestamp = %timestamp('2024-01-01-12.00.00.000000');

πŸ“– LESSON LEARNED:


❌ MISTAKE #18: Incorrect %SUBARR and Array BIF Usage

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: %subarr with assignment
%subarr(targetArray : 1 : 5) = %subarr(sourceArray : 1 : 5);

// Wrong: %lookup with wrong parameters
pos = %lookup('VALUE' : myArray : 1 : %elem(myArray));

// Wrong: %tlookup doesn't exist
pos = %tlookup('VALUE' : myArray);

βœ… CORRECT COMPILABLE CODE:

// Correct: Manual array copying
for i = 1 to 5;
  targetArray(i) = sourceArray(i);
endfor;

// Correct: %lookup without range parameters
pos = %lookup('VALUE' : myArray);

// Correct: Use %lookup for table lookup
pos = %lookup('VALUE' : myArray);

πŸ“– LESSON LEARNED:


❌ MISTAKE #19: File I/O Operation Code Confusion

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Using BIF syntax for file operations
%read(myFile);
%write(myFile);
%chain(key : myFile);

// Wrong: Mixed file operation syntax
read myFile %eof();

βœ… CORRECT COMPILABLE CODE:

// Correct: Use operation codes for file I/O
read myFile;
write myFile;
chain key myFile;

// Correct: Check %eof after operation
read myFile;
if %eof(myFile);
  // Handle end of file
endif;

πŸ“– LESSON LEARNED:


❌ MISTAKE #20: Invalid SQL Embedded Syntax

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: SQL variable without colon
exec sql
  select count(*) into recordCount
  from myTable;

// Wrong: Invalid SQL continuation
exec sql select name,
         address
  into :empName, :empAddr
  from employee;

// Wrong: Missing null indicators
exec sql
  select name into :empName
  from employee
  where id = :empId;

βœ… CORRECT COMPILABLE CODE:

// Correct: SQL variable with colon prefix
exec sql
  select count(*) into :recordCount
  from myTable;

// Correct: Proper SQL statement formatting
exec sql
  select name, address
  into :empName, :empAddr
  from employee;

// Correct: Include null indicators
dcl-s empNameInd int(5);
exec sql
  select name into :empName :empNameInd
  from employee
  where id = :empId;

πŸ“– LESSON LEARNED:


❌ MISTAKE #21: Monitor Block and Error Handling Errors

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Missing endmon
monitor;
  riskyOperation();
on-error;
  // Handle error

// Wrong: Invalid error handling syntax
try;
  riskyOperation();
catch;
  // Handle error
endtry;

βœ… CORRECT COMPILABLE CODE:

// Correct: Complete monitor block
monitor;
  riskyOperation();
on-error;
  // Handle error
endmon;

// Correct: RPGLE uses monitor/on-error, not try/catch
monitor;
  riskyOperation();
on-error;
  // Handle error
endmon;

πŸ“– LESSON LEARNED:


❌ MISTAKE #22: Incorrect Global Variable and Copy Member Usage

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Global variable without proper declaration
//copy QCPYSRC,GLOBALS
globalVar = 'Test';  // Used without proper declaration in copy member

// Wrong: Copy member with executable code
/copy MYLIB/QCPYSRC,BADCOPY
// Copy member contains executable statements

βœ… CORRECT COMPILABLE CODE:

// Correct: Proper copy member usage
/copy QCPYSRC,GLOBALS
// Ensure copy member only contains declarations

// Correct: Global variable properly declared in copy member
// Copy member should only contain:
// dcl-s globalVar varchar(100) export;
globalVar = 'Test';

πŸ“– LESSON LEARNED:


❌ MISTAKE #23: Incorrect Use of Named Constants and Figurative Constants

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Named constant with variable syntax
dcl-s MAX_RECORDS const int(10) inz(1000);

// Wrong: Invalid figurative constant usage
field = *null;  // For non-pointer fields
field = *blanks(10);  // Invalid parameter

// Wrong: Incorrect *HIVAL/*LOVAL usage
if date > *hival;  // Invalid comparison

βœ… CORRECT COMPILABLE CODE:

// Correct: Named constant syntax
dcl-c MAX_RECORDS const(1000);

// Correct: Proper figurative constant usage
field = *blanks;  // No parameters needed
ptr = *null;      // Only for pointer fields

// Correct: Proper *HIVAL/*LOVAL usage
if date = *hival;  // Used for initialization/comparison

πŸ“– LESSON LEARNED:


❌ MISTAKE #24: Template and Based Variable Confusion

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Template used as regular variable
dcl-ds myTemplate template;
  field1 char(10);
end-ds;

myTemplate.field1 = 'Test';  // Cannot use template directly

// Wrong: Based variable without pointer
dcl-s basedVar char(100) based;
basedVar = 'Test';  // No pointer specified

βœ… CORRECT COMPILABLE CODE:

// Correct: Template with instance
dcl-ds myTemplate template;
  field1 char(10);
end-ds;

dcl-ds myInstance likeds(myTemplate);
myInstance.field1 = 'Test';

// Correct: Based variable with pointer
dcl-s myPtr pointer;
dcl-s basedVar char(100) based(myPtr);
myPtr = %addr(someVariable);
basedVar = 'Test';

πŸ“– LESSON LEARNED:


❌ MISTAKE #25: Incorrect Loop Control and Iterator Usage

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: FOR loop with string iterator
for name = 'A' to 'Z';
  // Process names
endfor;

// Wrong: Invalid DOW condition
dow %found() and not %eof();  // %found() without context
  // Process records
enddo;

// Wrong: ITER/LEAVE outside loop
if condition;
  iter;  // Not inside a loop
endif;

βœ… CORRECT COMPILABLE CODE:

// Correct: FOR loop with numeric iterator
for i = 1 to 26;
  name = %char(%int('A') + i - 1);
  // Process names
endfor;

// Correct: DOW with proper context
read myFile;
dow not %eof(myFile);
  // Process records
  read myFile;
enddo;

// Correct: ITER/LEAVE inside loop
for i = 1 to 100;
  if condition;
    iter;  // Continue to next iteration
  endif;
  if otherCondition;
    leave;  // Exit loop
  endif;
endfor;

πŸ“– LESSON LEARNED:


🎯 CRITICAL SYNTAX RULES FOR FUTURE REFERENCE

βœ… VARIABLE DECLARATIONS:

// All declarations at beginning of procedure
dcl-proc myProcedure;
  dcl-s variable1 char(10);
  dcl-s variable2 int(10);
  dcl-ds structure1 qualified;
    field1 char(5);
  end-ds;
  
  // Executable code after all declarations
end-proc;

βœ… BIF USAGE PATTERNS:

// Correct BIF usage
result = %scan('text' : string);
result = %rem(number : divisor);
sorta array;  // Operation code, not BIF
%occur(dataStructure) = occurrence;  // Assignment to BIF

βœ… CONTROL FLOW:

// No ternary operator - use if/else
if condition;
  variable = value1;
else;
  variable = value2;
endif;

βœ… MEMORY AND POINTERS:

// Use operation codes for memory management
alloc size ptr;
dealloc ptr;  // Not %dealloc()

🚨 COMPILATION ERROR PREVENTION CHECKLIST

Before generating RPGLE code, verify:


πŸ“š SUCCESS PATTERNS

βœ… DATA STRUCTURE DECLARATIONS:

// Template definition
dcl-ds template_t template;
    field1 char(10);
    field2 packed(5:0);
end-ds;

// Instance with template
dcl-ds instance likeds(template_t);

// Multiple occurrence
dcl-ds occurs_ds occurs(10);
    field1 char(10);
end-ds;

βœ… ERROR HANDLING:

// Always include proper error handling
monitor;
    // Risky operation
on-error;
    // Handle error
endmon;

βœ… STRING OPERATIONS:

// Use appropriate BIFs
pos = %scan(searchString : targetString);
len = %len(%trim(string));
upper = %upper(string);

βœ… PROCEDURE DEFINITIONS:

// Matching prototype and interface
dcl-pr myProcedure varchar(100);
  param1 char(50) const;
  param2 int(10) value;
end-pr;

dcl-proc myProcedure;
  dcl-pi *n varchar(100);
    param1 char(50) const;
    param2 int(10) value;
  end-pi;
  
  // All variable declarations here
  dcl-s result varchar(100);
  
  // Executable code here
  return result;
end-proc;

Additional RPGLE Code Generation Errors - Documentation

❌ MISTAKE #26: Parameter Passing by Reference Validation

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Parameter not valid for reference passing
dcl-pr myProcedure;
  invalidParam char(10) const;  // Cannot pass const by reference
end-pr;

// Call with incompatible parameter
myProcedure(someVariable);

βœ… CORRECT COMPILABLE CODE:

// Correct: Use VALUE for const parameters or remove const for reference
dcl-pr myProcedure;
  validParam char(10) value;  // Pass by value
end-pr;

// Or for reference passing
dcl-pr myProcedure;
  validParam char(10);  // Pass by reference (no const)
end-pr;

πŸ“– LESSON LEARNED:


❌ MISTAKE #27: SQL SET OPTION Usage in Procedures

πŸ”΄ INCORRECT CODE GENERATED:

dcl-proc Test_SQLOption_CloseCursor;
  // Wrong: SET OPTION in procedure
  exec sql set option closqlcsr=*endmod;
  assertNumericEquals(0 : sqlcode);
end-proc;

βœ… CORRECT COMPILABLE CODE:

// Correct: SET OPTION at program level, not in procedures
// Remove the entire test case as SET OPTION is not allowed in procedures
// Handle CLOSQLCSR at compilation level instead

πŸ“– LESSON LEARNED:


❌ MISTAKE #28: SQL Host Structure Array Issues

πŸ”΄ INCORRECT CODE GENERATED:

dcl-proc Test_SQLCursor_FetchMultipleRows;
  dcl-ds fetchArray likeds(myFileTemplate) dim(100);
  exec sql fetch testCursor3 for 100 rows into :fetchArray;
end-proc;

βœ… CORRECT COMPILABLE CODE:

dcl-proc Test_SQLCursor_FetchMultipleRows;
  dcl-ds fetchArray likeds(myFileTemplate) dim(100) template;
  dcl-ds workArray likeds(fetchArray) dim(100);
  dcl-s tempField1 char(10);
  dcl-s tempField2 packed(7:2);
  
  exec sql declare testCursor3 cursor for select field1, field2 from myfile;
  exec sql open testCursor3;
  
  // Fetch one row at a time
  for i = 1 to %elem(workArray);
    exec sql fetch testCursor3 into :tempField1, :tempField2;
    if sqlcode <> 0;
      leave;
    endif;
    workArray(i).field1 = tempField1;
    workArray(i).field2 = tempField2;
  endfor;
  
  exec sql close testCursor3;
end-proc;

πŸ“– LESSON LEARNED:


❌ MISTAKE #29: SQL GET DIAGNOSTICS Syntax

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Invalid GET DIAGNOSTICS syntax
exec sql get diagnostics :sqlState = RETURNED_SQLSTATE;

βœ… CORRECT COMPILABLE CODE:

// Correct: Use built-in SQLSTATE field
sqlState = SQLSTATE;

πŸ“– LESSON LEARNED:


❌ MISTAKE #30: SQL FETCH Syntax Errors

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Invalid FETCH syntax
exec sql fetch testCursor3 for 10 rows into :fetchArray;

βœ… CORRECT COMPILABLE CODE:

// Correct: Proper FETCH syntax
exec sql fetch from testCursor3 for 10 rows into :fetchArray;

πŸ“– LESSON LEARNED:


❌ MISTAKE #31: Invalid %move Operation Code

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: %move doesn't exist as BIF
%move(TEST_DATE : dateds);

βœ… CORRECT COMPILABLE CODE:

// Or use direct assignment
dateds = TEST_DATE;

πŸ“– LESSON LEARNED:


❌ MISTAKE #32: Wrong Assertion Types for Numeric Results

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Using char assertion for numeric result
pos = %scan('text' : string);
assertCharNotEquals('0' : pos);  // %scan returns numeric

βœ… CORRECT COMPILABLE CODE:

// Correct: Use numeric assertion for %scan
pos = %scan('text' : string);
assertNumericNotEquals(0 : pos);  // %scan returns 0 when not found

πŸ“– LESSON LEARNED:


❌ MISTAKE #33: PSDS Template and Qualified Conflict

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: PSDS with template and qualified together
dcl-ds sysds psds qualified template;
  procName char(10) pos(1);
  sysDate char(8) pos(191);
end-ds;

βœ… CORRECT COMPILABLE CODE:

// Correct: PSDS with qualified only
dcl-ds sysds psds qualified;
  procName char(10) pos(1);
  sysDate char(8) pos(191);
end-ds;

// Or template only (separate from PSDS)
dcl-ds psdsTemplate template;
  procName char(10) pos(1);
  sysDate char(8) pos(191);
end-ds;

πŸ“– LESSON LEARNED:


❌ MISTAKE #34: Date Format Keywords in Declarations

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: datfmt keyword in dcl-s
dcl-s eurDate date datfmt(*eur);
dcl-s isoDate date datfmt(*iso);

βœ… CORRECT COMPILABLE CODE:

// Correct: Standard date declarations
dcl-s eurDate date;
dcl-s isoDate date;

// Use format conversion in output
eurDateStr = %char(eurDate : *eur);
isoDateStr = %char(isoDate : *iso);

πŸ“– LESSON LEARNED:


❌ MISTAKE #35: Invalid System Date Initialization

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: *sys not valid in free-format
dcl-s currentDate date inz(*sys);

βœ… CORRECT COMPILABLE CODE:

// Correct: Use %date() BIF
dcl-s currentDate date;
currentDate = %date();

πŸ“– LESSON LEARNED:


❌ MISTAKE #36: Invalid Integer Length Specifications

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Invalid integer lengths
dcl-s testVar int(15);
dcl-s testVar int(7);
dcl-s testVar int(8);

βœ… CORRECT COMPILABLE CODE:

// Correct: Valid integer lengths only
dcl-s testVar int(10);  // 15 -> 10
dcl-s testVar int(10);  // 7 -> 10
dcl-s testVar int(10);  // 8 -> 10

πŸ“– LESSON LEARNED:


❌ MISTAKE #37: Export Keyword in Prototypes

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Export in prototype
dcl-pr square int(10) export;
  pnum int(5) value;
end-pr;

βœ… CORRECT COMPILABLE CODE:

// Correct: Export only in procedure implementation
dcl-pr square int(10);
  pnum int(5) value;
end-pr;

dcl-proc square export;
  dcl-pi *n int(10);
    pnum int(5) value;
  end-pi;
  // procedure body
end-proc;

πŸ“– LESSON LEARNED:


❌ MISTAKE #38: Invalid Unsigned Integer Syntax

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Invalid unsigned integer syntax
dcl-s testVar unsigned int(8);

βœ… CORRECT COMPILABLE CODE:

// Correct: Use standard integer syntax
dcl-s testVar int(10);

πŸ“– LESSON LEARNED:


❌ MISTAKE #40: Data Area Declaration Errors

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Standalone variable for data area
dcl-s testDataArea char(100) dtaara('*LDA');

// Wrong: PSDS with template keyword
dcl-ds testProgramStatus psds qualified template;

βœ… CORRECT COMPILABLE CODE:

// Correct: Data structure for data area
dcl-ds testDataArea dtaara(*lda) qualified;
end-ds;

// Correct: PSDS without template, or template without PSDS
dcl-ds programStatusTemplate qualified template;
  // fields here
end-ds;

πŸ“– LESSON LEARNED:


❌ MISTAKE #41: Incorrect Operation Code Syntax

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Incorrect SCAN and CHECK syntax
scan 'brown' testSearchField testPosition;
check 'aeiou' testSearchField testPosition;

βœ… CORRECT COMPILABLE CODE:

// Correct: Use BIF syntax in free-format
testPosition = %scan('brown' : testSearchField);
testPosition = %check('aeiou' : testSearchField);

πŸ“– LESSON LEARNED:


❌ MISTAKE #42: Multidimensional Array Simulation

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Multidimensional array syntax
dcl-s matrix packed(5:2) dim(MATRIX_SIZE:MATRIX_SIZE);
matrix(i:j) = value;

βœ… CORRECT COMPILABLE CODE:

// Correct: Single dimension with calculated index
dcl-s matrix packed(5:2) dim(100);  // 10x10 = 100 elements
index = (i - 1) * MATRIX_SIZE + j;
matrix(index) = value;

πŸ“– LESSON LEARNED:


❌ MISTAKE #43: Invalid VARCHAR Operation

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: %varchar as operation code
%varchar(field);

βœ… CORRECT COMPILABLE CODE:

// Correct: VARCHAR conversion is automatic
// No manual conversion needed in modern RPG
field = someValue;  // Automatic conversion

πŸ“– LESSON LEARNED:


❌ MISTAKE #44: Multiple Occurrence Issues

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: likeds with occurs not inherited
dcl-ds MultiOccur occurs(10) template;
  field1 char(10);
end-ds;

dcl-ds multiRec likeds(MultiOccur);  // Missing occurs

βœ… CORRECT COMPILABLE CODE:

// Correct: Declare occurs explicitly
dcl-ds MultiOccur occurs(10) template;
  field1 char(10);
end-ds;

dcl-ds multiRec likeds(MultiOccur) occurs(10);

πŸ“– LESSON LEARNED:


❌ MISTAKE #45: Date/Time BIF Initialization Errors

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: BIF in initialization
dcl-s baseDate date inz(%date('2024-01-01'));
dcl-s testTime time inz(%time('12:30:45'));
dcl-s yearStr char(4) inz(%char(%subdt(testDate : *years) : 4));

βœ… CORRECT COMPILABLE CODE:

// Correct: Use date/time literals
dcl-s baseDate date;
dcl-s testTime time;
dcl-s yearStr char(4);

// Initialize in procedure body
baseDate = d'2024-01-01';
testTime = t'12.30.45';  // Use dots, not colons
yearStr = %char(%subdt(testDate : *years));  // No second parameter

πŸ“– LESSON LEARNED:


❌ MISTAKE #46: Invalid Packed Decimal Precision

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Invalid packed decimal precision
dcl-s taxRate packed(3:4) const options(*nopass);

βœ… CORRECT COMPILABLE CODE:

// Correct: Sufficient precision for decimal places
dcl-s taxRate packed(7:4) const options(*nopass);

πŸ“– LESSON LEARNED:


❌ MISTAKE #47: Invalid SORTA with %SUBARR

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Invalid SORTA with %SUBARR combination
%sorta(testSalaries : %subarr(testSalaries : 1 : testEmployeeCount));

βœ… CORRECT COMPILABLE CODE:

// Correct: Use SORTA with %SUBARR properly
sorta %subarr(testSalaries : 1 : testEmployeeCount);

πŸ“– LESSON LEARNED:


❌ MISTAKE #48: Template Name Conflicts

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Template name same as instance name
dcl-ds myTemplate template;
  field1 char(10);
end-ds;

dcl-ds myTemplate likeds(myTemplate);  // Name conflict

βœ… CORRECT COMPILABLE CODE:

// Correct: Different names for template and instance
dcl-ds myTemplate_t template;
  field1 char(10);
end-ds;

dcl-ds myInstance likeds(myTemplate_t);

πŸ“– LESSON LEARNED:


❌ MISTAKE #50: Invalid Parameter Omission

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Invalid parameter omission
myProcedure(param1 : : param3);  // Missing second parameter
myProcedure(param1 : ;);  // Invalid syntax

βœ… CORRECT COMPILABLE CODE:

// Correct: Use *omit for optional parameters
myProcedure(param1 : *omit : param3);

πŸ“– LESSON LEARNED:


❌ MISTAKE #51: Overlay Keyword in Free-Format

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: OVERLAY not supported in **FREE
dcl-proc Test_Overlay_Field1;
  dcl-s masterField char(50);
  dcl-s field1 char(10) overlay(masterField : 1);  // Invalid in **FREE
end-proc;

βœ… CORRECT COMPILABLE CODE:

// Correct: Use data structure for overlay functionality
dcl-ds masterField;
  field1 char(10);
  field2 char(15);
  field3 char(25);
end-ds;

dcl-proc Test_Overlay_Field1;
  masterField = TEST_OVERLAY_DATA;
  assertCharEquals(EXPECTED_FIELD1 : field1);
end-proc;

πŸ“– LESSON LEARNED:


❌ MISTAKE #52: Invalid %occur BIF Syntax

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Invalid %occur syntax
%occur(legacyDS : occurrence) = 1;

βœ… CORRECT COMPILABLE CODE:

// Correct: Proper %occur assignment
%occur(legacyDS) = 1;

πŸ“– LESSON LEARNED:


❌ MISTAKE #53: Based Array Element Size

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Element size too small for operations
dcl-s dynamicArray char(1) dim(32767) based(memoryPtr);

βœ… CORRECT COMPILABLE CODE:

// Correct: Appropriate element size
dcl-s dynamicArray char(10) dim(32767) based(memoryPtr);

πŸ“– LESSON LEARNED:


❌ MISTAKE #54: Cache Array Declaration Type

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: dcl-s for data structure array
dcl-s cache likeds(cacheEntry_t) dim(100);

βœ… CORRECT COMPILABLE CODE:

// Correct: dcl-ds for data structure array
dcl-ds cache likeds(cacheEntry_t) dim(100);

πŸ“– LESSON LEARNED:


❌ MISTAKE #55: Variable Declaration in Loops

πŸ”΄ INCORRECT CODE GENERATED:

// Wrong: Variable declaration inside loop
for i = 1 to count;
  dcl-s len int(10) = %len(%trim(strings(i)));
  if len > 0;
    // logic here
  endif;
endfor;

βœ… CORRECT COMPILABLE CODE:

// Correct: All declarations at procedure level
dcl-s len int(10);

for i = 1 to count;
  len = %len(%trim(strings(i)));
  if len > 0;
    // logic here
  endif;
endfor;

πŸ“– LESSON LEARNED:


🎯 ADDITIONAL CRITICAL SYNTAX RULES

βœ… PARAMETER PASSING:

// Correct parameter specifications
dcl-pr myProc varchar(100);
  param1 char(50) const value;    // const requires value
  param2 char(50);                // reference passing
  param3 char(50) options(*nopass); // optional parameter
end-pr;

βœ… SQL OPERATIONS:

// Correct SQL syntax
exec sql
  select field1, field2
  into :hostVar1, :hostVar2
  from myTable
  where key = :keyValue;

// Use SQLSTATE for error checking
if SQLSTATE <> '00000';
  // Handle SQL error
endif;

βœ… DATE/TIME OPERATIONS:

// Correct date/time handling
dcl-s myDate date;
dcl-s myTime time;

myDate = d'2024-01-01';
myTime = t'12.30.45';

// Correct difference calculation
daysDiff = %diff(endDate : startDate : *days);

βœ… ARRAY OPERATIONS:

// Correct array declarations and operations
dcl-ds myArray likeds(template_t) dim(100);
dcl-s simpleArray char(10) dim(50);

// Correct sorting
sorta simpleArray;
sorta %subarr(simpleArray : 1 : actualElements);

βœ… DATA STRUCTURE DECLARATIONS:

// Template definition
dcl-ds template_t template;
    field1 char(10);
    field2 packed(5:0);
end-ds;

// Instance with template
dcl-ds instance likeds(template_t);

// Multiple occurrence
dcl-ds occurs_ds occurs(10);
    field1 char(10);
end-ds;

βœ… ERROR HANDLING:

// Always include proper error handling
monitor;
    // Risky operation
on-error;
    // Handle error
endmon;

βœ… STRING OPERATIONS:

// Use appropriate BIFs
pos = %scan(searchString : targetString);
len = %len(%trim(string));
upper = %upper(string);

βœ… PROCEDURE DEFINITIONS:

// Matching prototype and interface
dcl-pr myProcedure varchar(100);
  param1 char(50) const;
  param2 int(10) value;
end-pr;

dcl-proc myProcedure;
  dcl-pi *n varchar(100);
    param1 char(50) const;
    param2 int(10) value;
  end-pi;
  
  // All variable declarations here
  dcl-s result varchar(100);
  
  // Executable code here
  return result;
end-proc;

🚨 UPDATED COMPILATION ERROR PREVENTION CHECKLIST

Additional items to verify:

This completes the documentation of the additional errors found during your RPGLE test generation process.

πŸ“ ADDITIONAL SESSION-LEVEL INSIGHTS

Based on the feedback provided, additional common mistakes include:

  1. Field Size Mismatches: Declaring fields with inappropriate sizes for their usage context
  2. Template vs Instance Confusion: Not understanding when to use templates vs direct instances
  3. BIF Parameter Confusion: Using wrong parameter patterns for built-in functions
  4. Legacy vs Modern Syntax: Mixing fixed-format concepts with free-format syntax
  5. Copy Member Dependencies: Generating code that references non-existent copy members
  6. Test Case Structure: Not understanding proper test framework initialization and teardown
  7. Procedure Interface Mismatches: Prototype and interface parameters not matching exactly
  8. Date/Time Operation Errors: Missing required parameters in date/time