dfcn and what all goes on when compiling

The Asset Suite application runs with MicroFocus COBOL on non IBM machines. ProCOBOL (Oracle’s COBOL) is in use when a .csm or .ccp program is compiled. The dfcn script in the tools directory runs a custom Ventyx pre compiler that expands certain data type definitions, example: PIC I, and changes and EXEC SQL statements from DB2 style SQL to Oracle SQL (and maybe other stuff that I can’t remember) if Asset Suite is defined to be using the Oracle database. Then the Oracle Pro COBOL compiler will compile the Oracle style SQL and finally the MicroFocus COBOL compiler compiles everything else.

If Asset Suite is using the Oracle database it is possible to write straight Oracle style SQL and use Oracle specific SQL capabilities. The EXEC SQL is marked (I forget exactly how) so that the Ventyx precompiler leaves it alone.

Note that the Ventyx developers use vanilla DB2 style SQL that can be translated to Oracle style SQL. It's the reason why sometimes you'll wonder why the developer didn't use a fancier SQL statement to get the job done.

Cause Ventyx pre compiler to fail

It's possible to cause the Ventyx pre compiler (dfora8tran) to fail by using


EXEC CICS LINK PROGRAM (PGM-NAME)
COMMAREA(DATE-COMMAREA)
END-EXEC


Specific case occured with program containing

EXEC SQL SET :TIME-STAMP-DB2 = CURRENT TIMESTAMP END-EXEC.

Program was compiled in an environment using the Oracle database and the Ventyx pre compiler that changes DB2 SQL to Oracle SQL failed to properly replace the code. After a lengthly debugging process it was found that the EXEC CICS LINK PROGRAM was the culprit even though it was in a different COBOL paragraph.

Do not use Ventyx CURRENT TIMESTAMP precompiler change

Following is relevent for COBOL batch .csm programs used in PassPort / Asset Suite. Could impact any batch program that runs over midnight where the time portion of the time stamp value is being updated. This should be rare.


Example source code:

K000-TIME-STAMP.

 EXEC SQL SET :TIME-STAMP-DB2 = CURRENT TIMESTAMP END-EXEC.
 MOVE TIME-STAMP-DB-CC TO TODAYS-DATE-CC.
 MOVE TIME-STAMP-DB-YY TO TODAYS-DATE-YYMMDD-YY.
 MOVE TIME-STAMP-DB-MM TO TODAYS-DATE-YYMMDD-MM.
 MOVE TIME-STAMP-DB-DD TO TODAYS-DATE-YYMMDD-DD.
 MOVE TIME-STAMP-DB-CC TO CURR-TIMESTAMP-CC.
 MOVE TODAYS-DATE-YYMMDD-YY TO TODAYS-DATE-YY
    CURR-TIMESTAMP-YY.
 MOVE TODAYS-DATE-YYMMDD-MM TO TODAYS-DATE-MM
    CURR-TIMESTAMP-MO.
 MOVE TODAYS-DATE-YYMMDD-DD TO TODAYS-DATE-DD
    CURR-TIMESTAMP-DD.

 ACCEPT CURRENT-TIME-HHMMSSTH FROM TIME.
 MOVE CURRENT-TIME-HHMMSSTH-HH TO CURRENT-TIME-HH
    CURR-TIMESTAMP-HH.
 MOVE CURRENT-TIME-HHMMSSTH-MM TO CURRENT-TIME-MM
    CURR-TIMESTAMP-MM.
 MOVE CURRENT-TIME-HHMMSSTH-SS TO CURRENT-TIME-SS
    CURR-TIMESTAMP-SS.

 MOVE TIME-STAMP-DB-CC TO WS-CENTURY

 MOVE WS-CENTURY TO TODAYS-DATE-CC
    CURR-TIMESTAMP-CC.

 ADD +1 TO CURR-TIMESTAMP-MILLI.
 MOVE CURR-TIMESTAMP-GROUP TO TIME-STAMP-PASS.

K000-EXIT. EXIT.


Example of new source code:


 K000-TIME-STAMP.

*CUST Begin

* EXEC SQL SET :TIME-STAMP-DB2 = CURRENT TIMESTAMP END-EXEC.

* Use Oracle Current_Timestamp from dual.

   EXEC SQL
    SELECT TO_CHAR(CURRENT_TIMESTAMP,'YYYY-MM-DD-HH24.MI.SSXFF')
     INTO :TIME-STAMP-DB2
    FROM DUAL
   END-EXEC.

*CUST end


The result of this is that the Ventyx precompiler will not remove the SQL statement from paragraph K000-TIME-STAMP and have the program rely on a value from paragraph 0100-INITIALIZATION.


Here's a listing of what the Ventyx precompiler would have done:


11622 K000-TIME-STAMP.
11623
11624 MOVE 'K000-TIME-STAMP.' TO ERROR-LINE-3.
11625
11626* EXEC SQL SET :TIME-STAMP-DB2 = CURRENT TIMESTAMP END-EXEC.
11627 MOVE TIME-STAMP-DB TO TIME-STAMP-DB2
11628 MOVE ZERO TO RETURN-CODE


Now the SQL for retrieving time stamp from Oracle will execute each time paragraph K000-TIME-STAMP is executed and return a 26 character time stamp value.


Here's the new listing:


11646 K000-TIME-STAMP.
11647
11648 MOVE 'K000-TIME-STAMP.' TO ERROR-LINE-3.
11649
11650
11651*CUST Begin
11652
11653* EXEC SQL SET :TIME-STAMP-DB2 = CURRENT TIMESTAMP END-EXEC.
11654
11655* Oracle now has a time stamp.
11656
11657* EXEC SQL
11658* SELECT TO_CHAR(CURRENT_TIMESTAMP,
11659* 'YYYY-MM-DD-HH24.MI.SSXFF')
11660* INTO :TIME-STAMP-DB2
11661* FROM DUAL
11662* END-EXEC.
11663 CALL "SQLADR" USING SQ0029 SQL-STMT
11664 MOVE 1 TO SQL-ITERS
11665 MOVE 1879 TO SQL-OFFSET
11666 MOVE 0 TO SQL-OCCURS
11667 MOVE 1 TO SQL-SELERR
11668 CALL "SQLADR" USING
11669 SQLCUD
11670 SQL-CUD
11671 CALL "SQLADR" USING
11672 SQLCA
11673 SQL-SQLEST
11674 MOVE 256 TO SQL-SQLETY
11675 CALL "SQLADR" USING
11676 TIME-STAMP-DB2 IN
11677 DATE-TIME-DB
11678 SQL-SQHSTV(1)
11679 MOVE 26 TO SQL-SQHSTL(1)
11680 MOVE 0 TO SQL-SQHSTS(1)
11681 MOVE 0 TO SQL-SQINDV(1)
11682 MOVE 0 TO SQL-SQINDS(1)
11683 MOVE 0 TO SQL-SQHARM(1)
11684 CALL "SQLADR" USING
11685 SQL-SQHSTV(1)
11686 SQL-SQPHSV

and so on...

Oracle SQL in source code

Example of adding an Oracle HINT to use a specific index. It appears the Ventyx precompiler skips over SQL that it does not recognize.

EXEC SQL DECLARE TIVM10SC1 CURSOR FOR
SELECT
*CUST BEGIN
/*+ INDEX(TIDWOWRK TIIWOWRK_CUSTOM) */
*CUST END
WORK_ORDER_NBR,
...
WO_DESCRIPTION
FROM TIDWOWRK
WHERE (FACILITY BETWEEN
:FACILITY-ORG AND :FACILITY-END)
AND (PLANNER BETWEEN
:PLANNER-ORG AND :PLANNER-END)
AND (WO_STATUS BETWEEN
:WO-STATUS-ORG AND :WO-STATUS-END)
AND (JOB_ACTIVE_IND BETWEEN
:JOB-ACTIVE-IND-ORG AND :JOB-ACTIVE-IND-END)
AND (DISCIPLINE BETWEEN
:DISCIPLINE-ORG AND :DISCIPLINE-END)
AND (WORK_ORDER_NBR BETWEEN
:WORK-ORDER-NBR-LO AND :WORK-ORDER-NBR-HI)
ORDER BY WORK_ORDER_NBR DESC
END-EXEC.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.