*DECK DB$MFP
USETEXT RELCMTX 
USETEXT CDCSCTX 
      PROC DB$MFP;
      BEGIN 
 #
  *   DB$MFP     MULTI-FILE PROCESSOR            PAGE 1 
  *   M D SAXE  (REVISION FOR 2.0)               DATE 09/24/76
  *   M L MOORE                                  DATE 10/06/75
  DC  PURPOSE 
      PROCESS ROOT FILE.  FOR OTHER RANKS, CALL APPROPRIATE MODULE
      DEPENDING ON SEARCH STRATEGY. 
  
  DC  LANGUAGE
      SYMPL 
  
  DC  ENTRY CONDITIONS
      JNBUFA / DB$RLCM = FWA OF THE JOIN BUFFER 
      RSNSTAB / DB$RLCM = POINTS TO THE FIRST ENTRY IN THE RSB RELATION 
                          SEARCH TABLE
      CSRLNSER / DB$RLCM = POINTS TO THE FIRST ENTRY IN THE CST RELATION
                           SEARCH TABLE 
      MAXRANK / DB$RLCM = HIGHEST RANK SPECIFIED IN THE RELATION
      EX FIELD  IN THE USER FITS ARE ZEROED FOR ALL RELATION FILES
      DX FIELD  IN THE USER FITS ARE ZEROED FOR ALL RELATION FILES
      RSNCURRK / DB$RLCM = CURRENT RANK TO BE PROCESSED FOR READ ON 
                           RELATION 
      RSB / DB$CDCS = POINTS TO THE CURRENT ENTRY IN THE FIXED PART OF
                      THE RUN-UNIT STATUS BLOCK 
  
  DC  EXIT CONDITIONS 
      MFPRDRNK / DB$RLCM = READ RANK, I.E. RANK AT WHICH RECORD OR NULL 
                            OCCURRENCE BEING RETURNED BY MFP WAS READ 
      MFPRETCD / DB$RLCM = RETURN CODE FOR READ FROM MFP
                             0  (RCOKAY) FOR RECORD OCCURRENCE TO BE
                                         RETURNED SUCCESSFULLY AT 
                                         MFPRDRNK.
                             1  (RCNULL) FOR NULL OCCURRENCE AT 
                                         MFPRDRNK.
                             2  (RCIOERR)  FOR I/O (CRM) ERROR AT 
                                         MFPRDRNK, OR FOR INTERNAL
                                         ERRORS WITHIN DB$MFP.  THE 
                                 SPECIFIC ERROR IS INDICATED BY ERRSTAT 
                                   ERRSTAT = 45 OCTAL IF SEARCH STRAT 
                                             WAS ILLEGAL IN SEARCHTAB 
                                           = 46 OCTAL IF OPERATOR CODE
                                             WAS ILLEGAL IN QUALTAB 
                             3  (RCEOI)  FOR END-OF-INFO ON ROOT FILE,
                                         SEQUENTIAL READ. 
      RSNCURRK / DB$RLCM = CURRENT RANK FOR SUBSEQUENT CALL TO MFP
  
  DC  CALLING ROUTINES
      DB$REL$   RANDOM RELATION READ
      DB$RLS$   SEQUENTIAL RELATION READ
  
  DC  CALLED ROUTINES 
      DB$AKY    SUB-MODULE FOR ALTERNATE KEY RETRIEVAL
      DB$CMPR   COMPARE JOIN DBI VALUE TO OTHER VALUE 
      DB$ERR    ERROR PROCESSOR 
      DB$MKY    SUB-MODULE FOR MAJOR KEY RETRIEVAL
      DB$NKY    SUB-MODULE FOR SEQUENTIAL RETRIEVAL ( NO KEY )
      DB$PKY    SUB-MODULE FOR PRIMARY KEY RETRIEVAL
      DB$QUAL   SUB-MODULE TO PROCESS RECORD QUALIFICATION CRITERIA 
      DB$GET    GET AND LOCK A RECORD 
      DB$GETN   GET AND LOCK NEXT RECORD
      DC$XFER   DATA TRANSFER (MOVE DATA TO JOIN BUFFERS) 
  
  DC  NON-LOCAL VARIABLES 
      ALL VARIABLES REQUIRED BY THE DB$CMPR PROC WILL BE MODIFIED.
  
  DC  DESCRIPTION 
      DB$MFP IS CALLED TO READ A RECORD FROM THE FILE AT THE
      CURRENT RANK, AND TO DETERMINE IF THE RECORD QUALIFIES. 
      EITHER A QUALIFIED RECORD, OR A RETURN CODE INDICATING
      A NULL OCCURRENCE, AN I/O ERROR, OR END-OF-FILE WILL BE 
      RETURNED.  THE CURRENT RANK WILL BE UPDATED IN PREPARATION
      FOR THE NEXT DB$MFP CALL. 
        THE MFP MAIN LOOP PERFORMS SOME INITIALIZATION AND THEN CALLS 
      THE PROC GETFITA TO GET THE FIT ADDRESS FOR THE RANK BEING
      PROCESSED.  THE FIT ERROR EXIT FIELD (EX) IS THEN SET TO POINT
      TO THE PROC CHECKES.  THE END-OF-DATA EXIT IN THE FIT IS SET TO 
      POINT TO THE PROC CHECKEND.  THE MAJOR KEY LENGTH AND RECORD
      LENGTH FIELDS ARE CLEARED IN THE FIT, SO THAT FUTURE CRM
      REQUESTS WILL NOT MISTAKENLY USE A MAJOR KEY, OR PERFORM A
      SEEK RATHER THAN A GET.  ONE OF TWO MAJOR ROUTINES IS 
      THEN CALLED.
          - RDROOT IS CALLED IF THE ROOT FILE RANK IS BEING PROCESSED.
      ALL ROOT FILE PROCESSING WILL BE DONE, INCLUDING CRM GET OR GETN
      REQUESTS AND CALLS TO QUALTEST TO DETERMINE IF THE RECORD WHICH 
      WAS RETRIEVED IS QUALIFIED. 
          - RDRANK IS CALLED FOR OTHER RANKS.  IN THIS PROC A BRANCH IS 
      MADE TO ONE OF THE MFP SUB-MODULES, DEPENDING ON THE SEARCH 
      STRATEGY FOR THE RANK.  ON RETURN FROM THE SUB-MODULE THE EXITOK
      PROC IS CALLED. 
        ON RETURN FROM EITHER RDROOT OR RDRANK, THE VALUE OF MFPRETCD 
      IS USED TO DETERMINE FURTHER PROCESSING.
          - IF MFPRETCD IS NOT 777 (RCNEWRK), A RETURN FROM DB$MFP
      IS MADE.
          - IF MFPRETCD IS 777 (RCNEWRK), A NEW RANK MUST BE PROCESSED. 
      CONTROL IS RETURNED TO THE TOP OF THE MFP MAIN LOOP.
 #
  
                             # CALL TO COMMON DECKS CDCSCOMMN, MFPDFDCLS
                               MFPCMDCLS, RELCMDCLS, RMCOMDCLS, 
                               CSTARDCLS
                             #
      CONTROL NOLIST; 
*CALL MFPDFDCLS 
*CALL MFPCMDCLS 
*CALL RMCOMDCLS 
      CONTROL  LIST;
  
      XDEF
        BEGIN 
        PROC DB$JCPR;        #SET UP PARAMETERS AND CALL DB$CMPR# 
        PROC DB$QTST;        #CALL DB$QUAL IF REQUIRED      # 
      PROC DB$MPGT;          # CALL DB$GET, SAVE AND RESTORE POINTERS#
      PROC DB$MPGN;          #CALL DB$GETN, SAVE AND RESTORE POINTERS#
        END 
  
      XREF
        BEGIN 
        ARRAY DB$RA0;;
            PROC DB$ACR;  # ADD ACCOUNT CHARGES FOR READ REL- DB$MFP   #
        PROC DB$AKY;
        PROC DB$CMPR; 
        PROC DB$ERR;
        PROC DB$FLOP;        # GENERATE FLOW POINT                     #
        PROC DB$LOKD; 
        ARRAY DB$MDCA;;      # DISPLAY TO ASCII COLLATING SEQUENCE #
        ARRAY DB$MDCC;;      # DISPLAY TO COBOL COLLATING SEQUENCE #
        ARRAY DB$MDCU;;      # DISPLAY TO USER COLLATING SEQUENCE # 
        ARRAY DB$MDCX;;      # DISPLAY TO DISPLAY COLLATING SEQUENCE #
        PROC DB$POP;
        FUNC DB$POPF; 
        PROC DB$PUSH; 
        PROC DB$MKY;
        PROC DB$NKY;
        PROC DB$PKY;
        PROC DB$QUAL; 
        PROC DB$GET;
        PROC DB$GETN; 
        PROC DC$XFER; 
        END 
  
#     LOCAL VARIABLES                                                  #
  
      ITEM I;                #SCRATCH VARIABLE# 
  
  
  
#   THE FLOW POINTS GENERATED BY DB$MFP                                #
#                                                                      #
#        ROUTINE   --  FLOW POINT                                      #
#                                                                      #
#        MAIN      --     MFP                                          #
#        DB$JCPR   --     MFP-1                                        #
#        CHKESRT   --     MFP-2                                        #
#        CHECKEND  --     MFP-3                                        #
#        CKECKES   --     MFP-4                                        #
#        EXITOK    --     MFP-5                                        #
#        DB$RDRANK --     MFP-6                                        #
#        DB$RDROOT --     MFP-7                                        #
#        DB$QTST   --     MFP-8                                        #
#        DB$MPGT   --     MFP-9                                        #
#        DB$MPGN   --     MFP-10                                       #
#                                                                      #
  
  
  
#     B E G I N   D B $ M F P   E X E C U T A B L E   C O D E .        #
  
  
      CONTROL IFGR DFFLOP,0;
        DB$FLOP("MFP    "); 
      CONTROL ENDIF;
  
      ERRSTAT = 0;
      CURRANK = RSNCURRK [0]; 
# 
    THE RELATION READ SYMBIONT POINTS THE RSB AND CST SEARCH TABLE BASED
    ARRAYS TO THE FIRST ENTRY IN THE TABLES. THEREFORE THE BASED ARRAYS 
    HAVE TO BE RE-ADJUSTED TO POINT TO THE CURRENT ENTRY TO BE PROCESSED
    THIS IS DONE BY MULTIPLYING THE CURRENT RANK - 1 BY THE ENTRY SIZE
    AND ADDING IT TO THE CST AND RSB POINTER
# 
      P<RSNSTAB> = P<RSNSTAB> + DFRSBSER * (CURRANK - 1); 
      P<CSRLNSER> = P<CSRLNSER> + DFCSTSER * (CURRANK - 1); 
      FOR I = I  DO          # BEGINNING OF READ RANK LOOP IN MFP # 
        BEGIN 
        MFPRETCD = 0;          # INITIALIZE FLAGS, ETC.  #
        EOKFLAG = FALSE;
        MFPRDRNK = CURRANK; 
        RSFCAORD[0] = CSNSAORD[0];
        SETRSARBLK; 
        P<FKL> = RSFFKLLOC[0];
        IF RSARFPT[0] NQ 0
        THEN
          BEGIN 
          P<FPT> = LOC(FKL) + RSARFPT[0]; 
          END 
        FTEX2 = LOC(CHKESRT);      # EX EXIT GOES TO CHKESRT FOR ROOT  #
        FTEX3 = LOC(CHECKES);      #  TO CHECKES FOR OTHER RANKS       #
        FPFTEX[0] = DFFTEX2;
        IF CURRANK NQ 1 
        THEN
          BEGIN 
          FPFTEX[0] = DFFTEX3;
          END 
  
        FTDX2 = LOC(CHECKEND);     # DX EXIT GOES TO CHECKEND          #
        FPFTDX[0] = DFFTDX2;
        FPFITMKL [0] = 0;          # CLEAR MAJOR KEY LGTH IN FPT       #
        FPFITRL [0] = 0;           # CLEAR RECORD LENGTH IN FPT        #
  
#*************************************************************# 
# PROCESS ROOT FILE # 
  
        IF CURRANK EQ 1 
          THEN  CALL RDROOT;
  
#**************************************************************#
# PROCESSING OF RANKS OTHER THAN ROOT FILE                     #
  
        ELSE CALL RDRANK; 
  
# EXIT FROM MFP, RESTORING CURRENT RANK IN RIPTAB, IF MFPRETCD NOT 777# 
# COME HERE AFTER ROOT AND NON-ROOT FILE PROCESSING   # 
  
MFPEND: IF MFPRETCD NQ RCNEWRK
          THEN
          BEGIN 
          RSNCURRK [0] = CURRANK; 
          RETURN; 
  
          END 
        END                  # END OF MFP READ RANK LOOP               #
                             # GO BACK TO BEGINNING OF LOOP IF MFPRETCD#
                             # IS 777 FROM SUB-MODULE PROCESSING       #
  
  
#**********************************************************************#
#                                                                      #
#     I N T E R N A L   P R O C E D U R E   -   D B $ J C P R          #
#                                                                      #
#**********************************************************************#
  
      PROC DB$JCPR; 
      BEGIN 
 #
  *   DB$MFP                                     PAGE 1 
  *   DB$JCPR 
  *   M L MOORE                                  11/24/75 
  *   M D SAXE  (REVISION FOR 2.0)               DATE 09/24/76
  DC  PURPOSE 
      SET UP PARAMETERS TO CALL DB$CMPR TO COMPARE THE JOIN ITEM, 
      DESCRIBED IN THE SEARCH TABLE, WITH ANOTHER VALUE.
  DC  LANGUAGE
      SYMPL 
  DC  ENTRY CONDITIONS
      CST AND RSB SEARCH TABLE POINTERS ARE SET FOR THIS RANK 
      COMPBWP SET TO ADDRESS OF VALUE TO BE COMPARED WITH JOIN ITEM 
      TGIBBP = BEGINNING BIT POSITION FOR TARGET
      TGIFWA = FIRST WORD ADDRESS OF TARGET (ABSOLUTE)
  DC  EXIT CONDITIONS 
      HILOEQ IS SET BY DB$CMPR CALL TO BE - 
        -1 IF VALUE LT JOIN ITEM
         0 IF VALUE EQ JOIN ITEM
         1 IF VALUE GT JOIN ITEM
      HILOEQ IS SET TO 70 IF AN ERROR WAS FOUND BY DB$CMPR -
        IN THIS CASE ERRSTAT CONTAINS AN ERROR CODE, AND
        MFPRETCD = 2 (RCIOERR). 
  DC  CALLING ROUTINES
*     DB$AKY
      DB$MKY
      DB$NKY
      RDROOT
  DC  CALLED ROUTINES 
      DB$CMPR  -  PERFORM COMPARISON
  DC  DESCRIPTION 
      PARAMETERS FOR A CALL TO DB$CMPR ARE SET UP FOR A COMPARISON
      OF THE VALUE POINTED TO BY COMPBWP WITH THE VALUE POINTED TO BY 
      TGIFWA.  PARAMETERS SET UP ARE LENGTH AND CLASS, USING INFORMATION
      FROM THE CURRENT SEARCHTAB ENTRY.  THE CALL TO DB$CMPR IS DONE. 
           THE COLLATING SEQUENCE TABLE IS POINTED ACCORDING TO THE 
      COLLATING SEQUENCE DEFINED FOR THE SOURCE FILE.  THIS IS NOT
      SIGNIFICANT SINCE JOINS ARE DEFINED IN TERMS OF EQUALITY, AND 
      THE COLLATING SEQUENCE IS USED ONLY IF INEQUALITY IS FOUND IN THE 
      COMPARISON. 
 #
  
      COMPBCP = 0;
      LITLENG = ( RSNJNSZ [0] + 9 )  / 10;
      TCLASS = CSNSTYPE[0]; 
  
#     DEFAULT ALL DISPLAY CODE TYPES TO ALPHANUMERIC.                  #
  
      IF TCLASS LQ DCDOUBLE 
        THEN TCLASS = ALPHANUMERIC; 
      TSIZE = RSNJNSZ[0] * 6; 
      IF RSNCOLAT[0] EQ DFCOLASC                 # IF DISPLAY - ASCII#
        THEN P<DCTABLE> = LOC(DB$MDCA);          # DISPLAY TO ASCII # 
        ELSE IF RSNCOLAT[0] EQ DFCOLCOB          # IF DISPLAY - COBOL # 
               THEN P<DCTABLE> = LOC(DB$MDCC);   # DISPLAY TO COBOL # 
               ELSE IF RSNCOLAT[0] EQ DFCOLDIS   # IF DISPLAY-DISPLAY#
                      THEN P<DCTABLE> = LOC(DB$MDCX);      # DISPLAY #
                      ELSE P<DCTABLE> = LOC(DB$MDCU);      # USER # 
  
      CONTROL IFGR DFFLOP,0;
        DB$FLOP("MFP-1  "); 
      CONTROL ENDIF;
  
      XCALL DB$CMPR;                      # PERFORM COMPARISON #
      IF ERRSTAT NQ 0 
        THEN
        BEGIN                # PROCESS ERROR FROM DB$CMPR # 
        HILOEQ = 70;
        MFPRETCD = RCIOERR; 
        END 
      RETURN; 
      END 
  
  
#**********************************************************************#
#                                                                      #
#     I N T E R N A L   P R O C E D U R E   -   C H K E S R T .        #
#                                                                      #
#**********************************************************************#
  
      PROC CHKESRT; 
      BEGIN 
 #
  *   DB$MFP                                     PAGE   1 
  *   CHKESRT 
  *   M L ALLEN                                  DATE 09/18/78
  DC  PURPOSE 
      SET MFPRETCD FOR ROOT RANK CRM ERRORS.
  DC  LANGUAGE
      SYMPL 
  DC  ENTRY CONDITIONS
      CALLED BY CRM THROUGH THE EX FIT FIELD ON ERROR CONDITIONS. 
  DC  EXIT CONDITIONS 
      MFPRETCD = RCIOERR (2)
  DC  DESCRIPTION 
      RESTORE POINTER TO TASKITEMS OF THIS RUN-UNIT.
      MFPRETCD IS UNCONDITIONALLY SET TO INDICATE A CRM ERROR.
 #
  
  
      CONTROL IFGR DFFLOP,0;
        DB$FLOP("MFP-2  "); 
      CONTROL ENDIF;
  
      P<TASKITEMS> = TQMFPBUF[0];  # REPOSITION TASKITEMS FROM THE TQT #
      MFPRETCD[0] = RCIOERR;
      RETURN; 
      END 
  
  
#**********************************************************************#
#                                                                      #
#     I N T E R N A L   P R O C E D U R E   -   C H E C K E N D .      #
#                                                                      #
#**********************************************************************#
  
      PROC CHECKEND;
      BEGIN 
# 
  *   DB$MFP                                     PAGE 1 
 *    CHECKEND
 *    M L MOORE                             04/05/76
  *   M D SAXE  (REVISION FOR 2.0)
 DC   PURPOSE 
      SET MFPRETCD FOR END-OF-DATA CONDITIONS.
 DC   LANGUAGE
      SYMPL 
 DC   ENTRY CONDITIONS
      CALLED BY CRM ON END-OF-DATA CONDITIONS 
 DC   EXIT CONDITIONS 
      MFPRETCD = 777 (RCNEWRK)  FOR ALL BUT THE ROOT RANK 
      MFPRETCD = 3   (RCEOI)    FOR THE ROOT RANK 
 DC   DESCRIPTION 
      RESTORE POINTER TO TASKITEMS OF THIS RUN-UNIT.
      SET MFPRETCD TO 777 TO FORCE READ AT NEXT LOWER RANK WHEN 
      END-OF-DATA IS DETECTED AT THIS RANK.  IF THE RANK BEING
      PROCESSED IS THE ROOT RANK, MFPRETCD IS SET TO 3 TO 
      INDICATE END-OF-INFO ON THE ROOT FILE.
# 
  
  
      CONTROL IFGR DFFLOP,0;
        DB$FLOP("MFP-3  "); 
      CONTROL ENDIF;
  
      P<TASKITEMS> = TQMFPBUF[0];  # REPOSITION TASKITEMS FROM THE TQT #
      MFPRETCD[0] = RCNEWRK;
      IF CURRANK EQ 1 
        THEN MFPRETCD = RCEOI;
      RETURN; 
      END 
  
  
#**********************************************************************#
#                                                                      #
#     I N T E R N A L   P R O C E D U R E   -   C H E C K E S .        #
#                                                                      #
#**********************************************************************#
  
      PROC CHECKES; 
      BEGIN 
 #
  *   DB$MFP                                     PAGE 1 
  *   CHECKES 
  *   M L MOORE                                 10/8/75 
  *   M D SAXE  (REVISION FOR 2.0)               DATE 09/24/76
  DC  PURPOSE 
      CHECK THE FIT ES FIELD FOR INVALID KEY OR OTHER ERROR.
      CALLED BY CRM BECAUSE EX FIELD IN FIT POINTS HERE 
  DC  LANGUAGE
      SYMPL 
  DC  ENTRY CONDITIONS
      POINTER SET TO FITIT BASED ARRAY
  DC  EXIT CONDITIONS 
      MFPRETCD = 1 (RCNULL) IF INVALID KEY
               = 2 (RCIOERR) IF OTHER CRM ERROR STATUS IN ES/FIT
  DC  DESCRIPTION 
      RESTORE POINTER TO TASKITEMS OF THIS RUN-UNIT.
      CHANGE THE MFPRETCD VALUE TO NULL OR IO ERROR, DEPENDING
      ON THE VALUE OF THE ERROR STATUS FIELD IN THE CDCS FIT. 
 #
      ITEM ES;               #UFT ERROR STATUS# 
  
      CONTROL IFGR DFFLOP,0;
        DB$FLOP("MFP-4  "); 
      CONTROL ENDIF;
  
      P<TASKITEMS> = TQMFPBUF[0];  # REPOSITION TASKITEMS FROM THE TQT #
      ES = FPFITES[0];
      IF ES EQ O"445" 
        OR ES EQ O"446" 
        OR ES EQ O"506" 
        OR ES EQ O"442" 
        THEN
        BEGIN 
        MFPRETCD[0] = RCNULL; 
        UFFITES[0] = 0; 
        FPFITES[0] = 0; 
        END 
      ELSE
        BEGIN 
        MFPRETCD[0] = RCIOERR;
        END 
      RETURN; 
      END 
  
  
#**********************************************************************#
#                                                                      #
#     I N T E R N A L   P R O C E D U R E   -   E X I T O K .          #
#                                                                      #
#**********************************************************************#
  
      PROC EXITOK;
      BEGIN 
 #
  *   DB$MFP                                     PAGE 1 
  *   EXITOK
  *   M L MOORE                                  12/03/75 
  *   M D SAXE  (REVISION FOR 2.0)               DATE 09/24/76
  DC  PURPOSE 
      THIS PROC PERFORMS NORMAL EXIT PROCESSING FOR DB$MFP. 
      THE PROCESSING DONE DEPENDS ON THE VALUE OF MFPRETCD. 
  DC  LANGUAGE
      SYMPL 
  DC  ENTRY CONDITIONS
      CST AND RSB SEARCH TABLE POINTERS ARE SET FOR THE CURRENT RANK
      CURRANK = VALUE OF RANK CURRENTLY BEING PROCESSED 
      MAXRANK = VALUE OF LARGEST POSSIBLE RANK FOR THIS RELATION
      EOKFLAG = TRUE IF END-OF-KEY WAS DETECTED DURING PROCESSING 
                OF THIS RANK, OR IF THE RANK JUST READ HAD A
                A SEARCH STRATEGY OF 5 (PRIMARY KEY RETRIEVAL) -
                FALSE OTHERWISE.
      MFPRETCD = 0   (RCOKAY) IF RECORD WAS READ OKAY FOR THIS RANK.
               = 1   (RCNULL) IF NO QUALIFIED RECORD COULD BE FOUND 
               = 777 (RCNEWRK) IF A READ MUST BE PERFORMED FOR A NEW
                              RANK, USUALLY THE NEXT LOWER RANK.
  DC  EXIT CONDITIONS 
      MFPRETCD MAY HAVE THE SAME VALUES AS INDICATED ABOVE FOR ENTRY
              CONDITIONS.  THESE VALUES HAVE THE SAME MEANINGS. 
      CURRANK WILL BE SET TO THE NEXT RANK TO BE PROCESSED. 
      CONTROL BREAK WILL BE SET FOR CURRANK, IF MFPRETCD = RCOKAY 
        AND THE RECORD JUST READ WAS NOT AT THE MAXIMUM RANK. 
  DC  CALLING ROUTINES
      RDRANK
      RDROOT
  DC  CALLED ROUTINES 
      NXTLORANK - GO TO NEXT LOWER RANK 
  DC  DESCRIPTION 
      THE PROCESSING PERFORMED IS ENTIRELY DEPENDENT ON THE VALUE 
      OF MFPRETCD.
       -IF MFPRETCD IS 0 (RCOKAY) A QUALIFIED RECORD WAS READ BY
        THE SUB-MODULE WHICH WAS CALLED BY DB$MFP TO RETRIEVE THE 
        RECORD. 
         -IF THE SUB-MODULE DETECTED END-OF-KEY (EOKFLAG TRUE), THEN
          EITHER THE PROC NXTLORANK IS CALLED, IF THE RANK BEING
          PROCESSED IS THE MAXIMUM RANK, OR THE RECORD-RETURNED AND 
          FIRST-TIME FLAGS FOR THIS RANK ARE SET TO INITIAL VALUES
          SO THAT A FUTURE CALL TO NXTLORANK WILL GO TO THE RANK LOWER
          THAN THIS ONE (IF THIS ONE IS AT END-OF-KEY, IT NEEDS 
          A NEW PARENT).
         -IF END-OF-KEY WAS NOT DETECTED, THE RECORD RETURNED FLAG
          IS SET TO INDICATE THAT A RECORD WAS RETURNED, AND THE
          FIRST TIME FLAG IS SET TO INDICATE THAT THIS IS NOT THE 
          FIRST TIME FOR A CHILD AT THIS RANK.
         -IF THE CURRENT RANK IS NOT THE MAXIMUM RANK, THE CURRANK
          CELL IS INCREMENTED TO GET A NEW CURRENT RANK.
          THE CONTROL BREAK FLAG FOR THIS NEW RANK IS SET, TO 
          INDICATE THAT A PARENT RECORD WAS READ FOR THIS CHILD.
          ****** -SEEK PROCESSING (DESCRIBED BELOW) NOT IMPLEMENTED 
            IF THE SEARCH STRATEGY FOR THE NEW RANK IS FOR ANY TYPE 
            OF KEY RETRIEVAL, A SEEK IS DONE TO POSITION THE FILE 
            AT THIS NEW RANK.  THE KEY VALUE USED FOR THE SEEK IS 
            THE JOIN ITEM VALUE CURRENTLY IN THE CDCS RECORD READ 
            BUFFER (WHICH MAY BE THE USER WORK AREA, IF NO MAPPING).
            IF RETRIEVAL IS ON A MAJOR KEY, THE AREA KEY TABLE
            (ARKEYTBL) IS SEARCHED TO FIND AN ENTRY WHICH HAS THE 
            SAME WORD AND CHARACTER POSITION AS THIS KEY.  THE KEY
            LENGTH FOR THIS ENTRY WILL BE PLUGGED INTO THE KL FIELD 
            IN THE FIT. 
          ****** -END OF SEEK PROCESSING
       -IF THE MFPRETCD VALUE IS 777 (FOR PROCESS A LOWER RANK) 
        THE PROC NXTLORANK IS CALLED TO BUBBLE UP TO THE LOWER
        RANK WHICH SHOULD BE PROCESSED NEXT.
       -IF THE MFPRETCD VALUE IS NULL, THE PROC 
        NXTLORANK IS CALLED TO GO TO THE NEXT LOWER RANK. 
      A RETURN IS THEN MADE.
 #
  
  
      ITEM FLAG B;
  
# PROCESS MFP RETURN CODE OF ZERO (QUALIFIED RECORD READ)  #
  
      CONTROL IFGR DFFLOP,0;
        DB$FLOP("MFP-5  "); 
      CONTROL ENDIF;
  
      IF MFPRETCD EQ RCOKAY  # RECORD READ OK # 
        THEN
        BEGIN 
        IF EOKFLAG           #EOK SENSED FOR THIS RECORD - #
          THEN
          BEGIN 
          IF CURRANK EQ MAXRANK 
            THEN
            BEGIN 
            CALL NXTLORANK;  #DECREMENT RANK IF AT HIGHEST RANK#
            RETURN;          # AND EXIT FROM THIS PROC         #
  
            END 
          ELSE               # IF NOT AT HIGHEST RANK...# 
            BEGIN 
            RSNRETR [0] = FALSE;        # JUST SET FLAGS #
            RSNFSTRK [0] = TRUE;         # TO INITIAL VALUES FOR RANK # 
            END 
          END                #OF EOK PROCESSING # 
        ELSE                 # IF NOT EOK...# 
          BEGIN 
          RSNRETR [0] = TRUE;     #RECORD HAS BEEN RETURNED#
          RSNFSTRK [0] = FALSE;    #NOT 1ST TIME IN ANY MORE# 
          END 
        IF CURRANK NQ MAXRANK 
          THEN
          BEGIN 
          CURRANK = CURRANK + 1;    #INCREMENT CURRENT RANK      #
          P<RSNSTAB> = P<RSNSTAB> + DFRSBSER; 
          P<CSRLNSER> = P<CSRLNSER> + DFCSTSER; 
          RSNBREAK [0] = TRUE;            # SET CONTROL BREAK FOR CHILD#
          END 
        END 
  
# PROCESS MFP RETURN CODE OF 777 (PUT A NEW RANK THRU MFP PROCESSING)  #
  
      IF MFPRETCD EQ RCNEWRK #RETURN CODE 777 SAYS ...# 
        THEN                 #PROCESS NEXT LOWER RANK # 
        BEGIN 
        CALL NXTLORANK; 
        RETURN; 
  
        END 
  
# PROCESS MFP RETURN CODE OF 1 (NULL OCCURRENCE)    # 
  
      IF MFPRETCD EQ RCNULL  #NULL OCCURRENCE RETURN CODE # 
        THEN
        BEGIN 
        CALL NXTLORANK;      # DECREMENT CURRENT RANK ...#
        END 
      RETURN;                # LEAVE EXITOK WITH MFPRETCD SET # 
  
      END 
  
  
#**********************************************************************#
#                                                                      #
#     I N T E R N A L   P R O C E D U R E   -   N X T L O R A N K .    #
#                                                                      #
#**********************************************************************#
  
      PROC NXTLORANK; 
      BEGIN 
 #
  *   DB$MFP                                     PAGE 1 
  *   NXTLORANK 
  *   M L MOORE                                 10/8/75 
  *   M D SAXE  (REVISION FOR 2.0)               DATE 9/24/76 
  DC  PURPOSE 
      TO SET ALL POINTERS AND FLAGS TO THE NEXT LOWER RANK IN 
      THE RELATION SEARCH TABLE 
  DC  LANGUAGE
      SYMPL 
  DC  ENTRY CONDITIONS
      CURRANK = CURRENT RANK PROCESSED
      EOKFLAG = TRUE IF THIS PROC CALLED DURING END-OF-KEY PROCESSING 
                OR PROCESSING OF A PRIMARY KEY RETRIEVAL. 
      CST AND RSB SEARCH TABLE POINTERS ARE SET FOR THE CURRENT RANK
  DC  EXIT CONDITIONS 
      CURRANK WILL BE RESET TO THE NEXT LOWER RANK FOR WHICH THE
        FIRST-TIME FLAG IS NOT TRUE, UNLESS CURRANK WAS 1 ON ENTRY. 
      CST AND RSB SEARCH TABLE POINTERS ARE RESET TO THE CURRENT RANK 
      MFPRETCD = 1 (RCNULL)  IF NO RECORD HAS BEEN RETURNED FOR 
               THE INITIAL CURRENT RANK VALUE.
      CONTROL BREAK FLAG (RSNBREAK IN RSNSTAB) WILL BE SET FOR
                ALL RANKS FROM THE INITIAL CURRANK VALUE TO THE 
                ( FINAL CURRANK VALUE - 1 ).
  DC  DESCRIPTION 
      IN THE SEARCH TABLE FOR THE INITIAL CURRENT RANK -
        RSNRETR SET TO FALSE
        RSNFSTRK SET TO TRUE
      RSNBREAK SET TO TRUE
      FOR ALL RANKS BETWEEN THE INITIAL AND TERMINAL VALUES OF
      CURRANK, RSNBREAK WILL BE SET TO TRUE IF MFPRETCD IS RCNEWRK. 
      THE NEXT RANK TO BE PROCESSED IS THE NEXT LOWEST ONE
      FOR WHICH THE RSNFSTRK FLAG IS FALSE.  THIS FLAG MAY BE 
      SET TO TRUE WHEN END-OF-KEY IS SENSED FOR THE RANK, TO
      INDICATE THAT A NEW PARENT IS REQUIRED FOR THIS RANK. 
 #
  
      IF NOT RSNRETR [0]     # IF NO RECORDS RETURNED FOR THIS #
           AND NOT EOKFLAG   # RANK, UNLESS CALLED DURING EOK, #
        THEN MFPRETCD = RCNULL;   # SET NULL RETURN CODE  # 
      RSNRETR [0] = FALSE;
      RSNFSTRK [0] = TRUE;
      FOR I = I  WHILE CURRANK NQ 1  DO   # LOOP BACKWARDS THRU # 
        BEGIN                             # SEARCHTABS  # 
        IF MFPRETCD EQ RCNEWRK            # IF DOING INTERNAL BUBBLE #
          THEN RSNBREAK [0] = TRUE;       #   SET CONTROL BREAK      #
        CURRANK = CURRANK - 1;
        P<CSRLNSER> = P<CSRLNSER> - DFCSTSER; 
        P<RSNSTAB> = P<RSNSTAB> - DFRSBSER; 
        IF NOT RSNFSTRK [0] 
          THEN RETURN;
  
        END 
      END 
  
  
#**********************************************************************#
#                                                                      #
#     I N T E R N A L   P R O C E D U R E   -   R D R A N K .          #
#                                                                      #
#**********************************************************************#
  
      PROC RDRANK;
      BEGIN 
 #
  *   DB$MFP                                     PAGE 1 
  *   RDRANK
  *   M L MOORE                                 12/03/75
  *   M D SAXE  (REVISION FOR 2.0)               DATE 09/24/76
  DC  PURPOSE 
      PROCESS ALL RANKS OTHER THAN ROOT FILES.
  DC  LANGUAGE
      SYMPL 
  DC  ENTRY CONDITIONS
      CST AND RSB SEARCH TABLE POINTERS ARE SET TO THE CURRENT RANK 
      THE FPT POINTER IS SET TO THE CURRENT RANK
      JNBUFA MUST CONTAIN ADDRESS OF JOIN BUFFER BLOCK
  DC  EXIT CONDITIONS 
      MFPRETCD IS SET BY THE SUB-MODULES PROCESSED
      AND BY THE EXITOK PROCEDURE.
      IF MFPRETCD IS 0 (RCOKAY), A RECORD HAS BEEN READ FOR THE 
          RANK INDICATED BY MFPRDRNK. 
      IF THE SEARCH STRATEGY IN RSNSTAB IS NOT IN THE RANGE 
          0 TO 5, MFPRETCD IS SET TO 2 (RCIOERR), ERRSTAT IS SET
          TO 45 OCTAL, AND NO PROCESSING WILL BE DONE.
  DC  CALLED ROUTINES 
      DB$AKY  - ALTERNATE KEY RETRIEVAL 
      DB$MKY  - MAJOR KEY RETRIEVAL 
      DB$NKY  - NON-KEY OR SEQUENTIAL SORTED KEY RETRIEVAL
      DB$PKY  - PRIMARY KEY RETRIEVAL 
      DB$XFER - MOVE DATA 
      EXITOK  - NORMAL EXIT PROCESSING
  DC  CALLING ROUTINES
      DB$MFP MAIN LOOP
  DC  DESCRIPTION 
           IF THE SEARCH STRATEGY FOR THIS RANK IS NOT IN THE RANGE 
      0 TO 5, AN ERROR RETURN IS MADE (SEE EXIT CONDITIONS, ABOVE). 
           IF THE FIRST-TIME FLAG FOR THIS RANK IS SET, AND THE 
      SEARCH STRATEGY IS FOR SEQUENTIAL OR MAJOR KEY RETRIEVAL, 
      THE SOURCE JOIN DBI VALUE IS MOVED TO THE JOIN BUFFER.
      THIS IS DONE SO THAT THE SOURCE JOIN DBI WILL BE
      AVAILABLE TO CHECK FOR SATISFACTION OF THE JOIN 
      CONDITION DURING THE READS OF ALL RECORDS IN THE FILE 
      AT THIS RANK (SEQUENTIAL RETRIEVAL) OR THE RECORDS READ 
      BY A GETN AFTER THE INITIAL MAJOR KEY RETRIEVAL.
      BECAUSE OF POTENTIAL INTERFERENCE BETWEEN TWO CONCURRENT USERS, 
      THE JOIN BUFFER IS ALSO USED FOR ALTERNATE KEY RETRIEVALS.
      FOR OTHER SEARCH STRATEGIES, THE KEY VALUE IS MOVED TO THE
      KEYREAD BUFFER.  ALL KEY FIELDS IN THE FIT ARE SET FOR KEY
      RETRIEVAL (KA, KP, KL FIELDS).  THE RKW AND RKP FIELDS IN THE 
      FIT ARE SET FOR ALTERNATE KEY RETRIEVAL IF THERE IS MORE THAN 
      ONE ENTRY IN THE AREA KEY TABLE (THIS INDICATES ALTERNATE KEYS).
      THE APPROPRIATE SUB-MODULE FOR THIS RANK IS THEN CALLED 
      (AS DETERMINED BY THE SEARCH STRATEGY FOR THE RANK), AND
      ON RETURN THE PROC EXITOK IS CALLED, TO PROCESS THE 
      RETURN CODE SET BY THE SUB-MODULES.  AN EXIT IS MADE. 
  
 #
  
      SWITCH SEARCHSTRAT  SSSEQ,SSSEQ,SSMAJ,SSMAJ,SSALT,SSPRI;
      ITEM XTARG;            #TARGET LOC FOR DB$XFER CALL # 
  
  
      IF RSNSSTRA [0] LS 0  OR  RSNSSTRA [0] GR 5 
       THEN          #ERROR IF SEARCH STRATEGY OUT OF RANGE # 
       BEGIN
        MFPRETCD = RCIOERR; 
        ERRSTAT = O"45";
        RETURN; 
  
        END 
      IF RSNFSTRK [0]         # IF GET WILL BE DONE . . .#
        THEN                 # MOVE KEY VALUE TO JOIN   # 
        BEGIN                # BUFFER OR KEYREAD BUFFER # 
        IF RSNSSTRA[0] LQ 4 
          THEN XTARG = JNBUFA + RSNJNPTR [0]; 
        ELSE XTARG = LOC (KEYREAD); 
  
        CONTROL IFGR DFFLOP,0;
          DB$FLOP("MFP-6  "); 
        CONTROL ENDIF;
  
        XCALL DC$XFER(RSNSCADD[0],6*RSNSCBCP[0],XTARG,
              0, 6 * RSNJNSZ [0] ); 
        IF RSNSSTRA [0] GR 1
          THEN               # SET ALL FIT FIELDS FOR KEYS #
          BEGIN 
          FPFITKA [0] = XTARG;
          FPFITKL [0] = RSNJNSZ [0];
          P<CSAREBLK> = LOC(CSFIXED) + RSARCSTP[0]; 
          P<CSAKEYTB> = LOC(CSAREBLK) + CSAKEYPT[0];
          IF CSAKEYPT[0] NQ 0 AND CSAKNEXT[0] 
            THEN             # SET RKW, RKP FIELDS IN FIT  #
            BEGIN            # ONLY IF FILE HAS ALTERNATE KEYS #
            FPFITRKP [0] = CSNSTBCP [0];
            FPFITRKW [0] = CSNSTBWP [0];
            END 
          FPFITKP [0] = 0;
          END 
        END 
  
# BRANCH TO SUB-MODULE TO PROCESS SEARCH STRATEGY FOR THIS RANK  #
  
     GOTO  SEARCHSTRAT [ RSNSSTRA [0] ];
  
# SEARCH STRATEGY 0 OR 1, SEQUENTIAL RETRIEVAL                     #
SSSEQ: XCALL DB$NKY;
     GOTO SSRETURN; 
  
# SEARCH STRATEGY 2 OR 3, MAJOR PRIMARY OR ALTERNATE KEY RETRIEVAL  # 
SSMAJ: XCALL DB$MKY;
     GOTO SSRETURN; 
  
# SEARCH STRATEGY 4, ALTERNATE KEY RETRIEVAL                        # 
SSALT: XCALL DB$AKY;
     GOTO SSRETURN; 
  
#SEARCH STRATEGY 5, PRIMARY KEY RETRIEVAL                           # 
SSPRI: XCALL DB$PKY;
  
#  COME HERE ON RETURN FROM ALL SUB-MODULES                         # 
SSRETURN: CALL EXITOK;       # PROCESS RETURN CODES FROM SUB-MODULES# 
      RETURN; 
  
     END                # END OF NON-ROOT-FILE PROCESSING      #
  
  
#**********************************************************************#
#                                                                      #
#     I N T E R N A L   P R O C E D U R E   -   R D R O O T .          #
#                                                                      #
#**********************************************************************#
  
      PROC RDROOT;
      BEGIN 
 #
  *   DB$MFP                                     PAGE 1 
  *   RDROOT
  *   M L MOORE                                  DATE 12/03/75
  *   M D SAXE  (REVISION FOR 2.0)               DATE 09/24/76
  DC  PURPOSE 
      PERFORM PROCESSING OF ROOT FILE.
  DC  LANGUAGE
      SYMPL 
  DC  ENTRY CONDITIONS
      CST AND RSB SEARCH TABLE POINTERS ARE SET TO THE ROOT RANK
  DC  EXIT CONDITIONS 
      MFPRETCD = 0 (RCOKAY)  IF A QUALIFIED RECORD HAS BEEN READ
               = 1 (RCNULL)  IF NULL OCCURRENCE FOR THE ROOT FILE 
               = 2 (RCIOERR)  IF CRM, CONVERSION, OR INTERNAL ERROR 
               = 3 (RCEOI)  IF END-OF-INFORMATION FOUND ON ROOT FILE
  DC  CALLING ROUTINES
      DB$MFP MAIN LOOP
  DC  CALLED ROUTINES 
      DB$JCPR  -  COMPARE FOR JOIN CONDITION
      DB$XFER  -  SAVE KEY VALUE IN KEYREAD BUFFER
      EXITOK   - PROCESS SUB-MODULE RETURN CODE 
*     DB$MPGN  -  READ NEXT RECORD IN FILE
*     DB$MPGT  -  READ RECORD BY KEY
      DB$QTST  -  TEST FOR RECORD QUALIFICATION 
  DC  DESCRIPTION 
      ROOT FILE PROCESSING INVOLVES BOTH SEQUENTIAL AND KEY 
      RETRIEVAL.
           FOR SEQUENTIAL RETRIEVAL, THE NEXT RECORD IN THE ROOT FILE 
      IS READ.
           FOR KEY RETRIEVAL, BOTH ALTERNATE AND PRIMARY
      KEY RETRIEVAL ARE HANDLED BY THE SAME SEARCH STRATEGY.
      CONSEQUENTLY IF A RECORD RETRIEVED BY KEY DOES NOT SATISFY
      THE RECORD QUALIFICATIONS, THE KEY VALUE MUST BE SAVED IN 
      A BUFFER (THE KEYREAD BUFFER) AND THE NEXT RECORD IN THE
      FILE MUST BE READ.  WHEN THE NEXT RECORD HAS BEEN READ, A 
      COMPARISON OF ITS KEY WITH THE KEY VALUE IN KEYREAD MUST
      BE MADE.
       -IF THE KEYS ARE NOT EQUAL, RDROOT RETURNS WITH A NULL 
        OCCURRENCE RETURN CODE. 
       -IF THE KEYS ARE EQUAL, THE RECORD SATISFIES THE JOIN
        CONDITIONS AND, AS ABOVE, A CHECK MUST BE MADE TO SEE 
        IF IT SATISFIES THE QUALIFICATION CONDITIONS. 
           THE LOOP OF READING THE NEXT RECORD AND TESTING IT FOR JOIN
      AND QUALIFICATION CONDITIONS WILL CONTINUE UNTIL- 
       -A RECORD IS FOUND WHICH SATISFIES BOTH SETS OF CONDITIONS 
        IN WHICH CASE (FOR SEQUENTIAL OR KEY RETRIEVAL) RDROOT
        RETURNS WITH MFPRETCD SET TO ZERO (RECORD READ OKAY), 
       -OR A CRM ERROR IS DETECTED (MFPRETCD = 2, RCIOERR - RETURN) 
       -OR AN END-OF-INFORMATION FILE POSITION IS DETECTED ON 
        THE FILE READ BY GOING TO THE DX EXIT, WHERE MFPRETCD WILL
        BE SET TO 3 (RCEOI), FORCING A RETURN FROM RDROOT.
       -IF MFPRETCD IS SET TO INDICATE END-OF-INFORMATION, AND
        NO QUALIFIED RECORD HAS BEEN READ, MFPRETCD IS RESET
        TO 1 (RCNULL) TO INDICATE A NULL RECORD OCCURRENCE. 
          THE FLAGS FOR ALL RANKS IN THE SEARCHTABS (RSNFSTRK AND 
      RSNRETR FLAGS) ARE SET TO INITIAL VALUES IF RETRIEVAL ON THE
      ROOT FILE IS BY KEY.  THIS IS DONE BECAUSE A RANDOM RELATION
      READ INITIALIZES THE ENTIRE RELATION. 
 #
  
      FIRSTTIME = TRUE; 
      IF RSNSSTRA [0] NQ 0
        THEN
        BEGIN              #ALTERNATE OR PRIMARY KEY RETRIEVAL# 
        FOR I = 0  STEP 1  UNTIL MAXRANK - 1  DO
          BEGIN            # INITIALIZE FLAGS FOR ALL RANKS # 
          RSNFSTRK [I] = TRUE;
          RSNRETR [I] = FALSE;
          END 
        DB$MPGT;
        END 
      ELSE                 #SEQUENTIAL RETRIEVAL #
        BEGIN                                                            CD2A050
        FPFITKA[0] = LOC(KEYREAD);
MFPRDSQ:  
        DB$MPGN;
        END                                                              CD2A050
      HILOEQ = 0;            # INITIALIZE FOR LATER TEST  # 
      IF MFPRETCD EQ RCEOI   # IF 2D GET ON FILE (PREVIOUS #
        AND NOT FIRSTTIME    #RECORD NOT QUALIFIED) AND   # 
        THEN MFPRETCD = RCNULL;   # EOI - SET NULL RETURN  #
      IF MFPRETCD EQ 0
        THEN              # IF NOT EOI OR CRM ERROR . . .#
        BEGIN             # CHECK JOIN CONDITION AND QUALIFICATN #
        IF NOT FIRSTTIME     #IF KEY RETRIEVAL AND NOT    # 
          THEN               # FIRST READ, COMPARE KEY FROM # 
          BEGIN              # THIS GET WITH OLD KEY      # 
          COMPBWP = LOC(KEYREAD); 
          TGIBBP = RSNSCBCP [0] * 6;
          TGIFWA = RSNSCADD [0];
          CALL DB$JCPR; 
          IF HILOEQ NQ 0     # IF KEYS NOT EQUAL...#
             AND MFPRETCD EQ 0    # AND NO ERROR #
            THEN             # SET NULL OCCURRENCE RETURN CODE #
            BEGIN 
            MFPRETCD = RCNULL;
            END 
          END 
# CHECK RECORD QUALIFICATION FOR ROOT FILE #
  
        IF HILOEQ EQ 0       # IF COMPARE WAS OKAY, OR #
          THEN             # IF THIS IS FIRST TIME THRU   # 
          BEGIN            # (BECAUSE HILOEQ WAS ZEROED ABOVE )#
          CALL DB$QTST; 
          IF RCQUAL 
            THEN CALL EXITOK; #SET UP NORMAL EXIT IF RECORD QUALIFIES#
          ELSE
            BEGIN                  # IF RECORD IS NOT QUALIFIED . . # 
            IF RSNSSTRA[0] NQ 0 AND FIRSTTIME 
              THEN             # FOR KEY RETRIEVAL, FIRST TRY - # 
              BEGIN            # SAVE ORIGINAL KEY IN KEYREAD BUFF #
              COMPBWP = LOC(KEYREAD); 
  
              CONTROL IFGR DFFLOP,0;
                DB$FLOP("MFP-7  "); 
              CONTROL ENDIF;
  
              XCALL DC$XFER(FPFITKA[0],6*FPFITKP[0], COMPBWP, 
                    0, 6 * FPFITKL [0] ); 
              FIRSTTIME = FALSE; #SET FLAG TO FORCE COMPARE OF KEYS#
              END 
                               # FOR UNQUALIFIED RECORD, GO BACK #
            GOTO MFPRDSQ;      # AND READ NEXT RECORD IN FILE    #
  
            END 
          END 
        END                  # OF -NOT- EOI OR CRM ERROR PROCESSING # 
      RETURN; 
      END                  # OF ROOT FILE PROCESSING #
  
  
#**********************************************************************#
#                                                                      #
#     I N T E R N A L   P R O C E D U R E   -   D B $ Q T S T .        #
#                                                                      #
#**********************************************************************#
  
        PROC DB$QTST; 
      BEGIN 
 #
  *   DB$MFP                                     PAGE 1 
  *   DB$QTST 
  *   M L MOORE                                  10/8/75
  *   M D SAXE  (REVISION FOR 2.0)               DATE 09/24/76
  DC  PURPOSE 
      CALL THE DB$QUAL SUB-MODULE IF THERE IS A QUALIFIER 
*     TABLE ADDRESS IN THE CURRENT RELATION SEARCH TABLE. 
  DC  LANGUAGE
      SYMPL 
  DC  ENTRY CONDITIONS
      CST AND RSB SEARCH TABLE POINTERS ARE SET TO THE CURRENT RANK 
      ALL ENTRY CONDITIONS FOR DB$QUAL MUST BE SATISFIED. 
  DC  EXIT CONDITIONS 
      RCQUAL = TRUE  IF RECORD QUALIFIED, OR IF THERE WAS NO
                     QUALTAB ADDRESS FOR THIS RANK
                     OR IF THERE WERE CONVERSION ERRORS 
             = FALSE IF RECORD DOES NOT QUALIFY 
                     UNQUALIFIED RECORDS ARE UNLOCKED.
      ERRSTAT MAY BE SET IF THERE ARE CONVERSION OR INTERNAL ERRORS.
      MFPRETCD = 2 (RCIOERR) IF THERE ARE CONVERSION OR INTERNAL ERRORS 
  DC  CALLING ROUTINES
      DB$MFP - RDROOT PROC
      DB$AKY
      DB$MKY
      DB$NKY
      DB$PKY
  DC  CALLED ROUTINES 
      DB$LOKD - UNLOCK A RECORD 
      DB$QUAL - TO PROCESS QUALTAB STACK FOR RECORD 
  DC  DESCRIPTION 
      IF QUALIFICATION IS REQUIRED, CALL DB$QUAL PROC.
      IF THIS CALL RESULTS IN A NON-ZERO VALUE FOR ERRSTAT, 
      SET RCQUAL TO TRUE AND MFPRETCD TO 2 (RCIOERR). 
 #
  
  
# 
      CHECK OFFSET POINTER TO THE QUAL ENTRY FOR THE CURRENT RANK. IF 
      POINTER IS ZERO, THERE IS NO QUALIFICATION
# 
  
      CONTROL IFGR DFFLOP,0;
        DB$FLOP("MFP-8  "); 
      CONTROL ENDIF;
  
      IF CSNSQLPT [0] EQ 0
        THEN RCQUAL = TRUE; 
      ELSE  XCALL DB$QUAL;
      IF ERRSTAT NQ 0 
        THEN
        BEGIN 
        RCQUAL = TRUE;
        MFPRETCD = RCIOERR; 
        END 
      IF NOT RCQUAL THEN
        DB$LOKD(FALSE); 
      RETURN; 
      END 
  
  
#**********************************************************************#
#                                                                      #
#     I N T E R N A L   P R O C E D U R E   -   D B $ M P G T          #
#                                                                      #
#**********************************************************************#
  
      PROC DB$MPGT; 
      BEGIN 
 #
  *   DB$MPGT                                    PAGE  1
  *   J E ESLER                                  DATE  3/9/77 
  DC  PURPOSE 
      INTERFACE MFP ROUTINES TO CDCS GET MODULES. REQUIRED PARAMETERS 
      ARE SAVED AND RESTORED, SINCE CRM CALLS ARE INTERRUPTABLE.
  DC  ENTRY CONDITIONS
      RSFCAORD DEFINES THE RSB ORDINAL OF THE RANK TO BE READ.
      THE FPT CONTAINS THE PARAMETERS FOR THE READ TO BE PERFORMED. 
  DC  EXIT CONDITIONS 
      CRM GET HAS BEEN PERFORMED. 
      THE FOLLOWING POINTERS ARE MAINTAINED:  
          RSNSTAB 
          RSBRLNBLK 
          CSRLNSER
          RSAREBLK   (GUARANTEED BY DB$GET) 
  DC  CALLING ROUTINES
      DB$MFP - RDROOT PROC
      DB$AKY
      DB$MKY
      DB$NKY
      DB$PKY
  DC  CALLED ROUTINES 
      DB$GET - GET AND LOCK A RECORD
 #
  
      CONTROL IFGR DFFLOP,0;
        DB$FLOP("MFP-9  "); 
      CONTROL ENDIF;
  
      DB$PUSH(DB$MPGT); 
      DB$PUSH(LOC(CSRLNSER)-LOC(CSFIXED));
      DB$PUSH(LOC(RSBRLNBLK)-LOC(RSB)); 
      DB$PUSH(LOC(RSNSTAB)-LOC(RSB)); 
      P<OFT> = RSAROFIT[0]; 
      RCOFTLOC[0] = LOC(OFT); 
      DB$GET; 
      P<TASKITEMS> = TQMFPBUF[0]; 
      JNBUFA = LOC(RSB) + RSFJNPTR[0];
      P<RSNSTAB> = LOC(RSB) + DB$POPF;
      P<RSBRLNBLK> = LOC(RSB) + DB$POPF;
      P<CSRLNSER> = LOC(CSFIXED) + DB$POPF; 
      DB$POP(DB$MPGT);
      FPFITRL[0] = UFFITRL[0];
      FPFITFP[0] = UFFITFP[0];
      IF ACCNFLAG 
      THEN
        DB$ACR(DFRD2);
      RETURN; 
      END 
  
  
#**********************************************************************#
#                                                                      #
#     I N T E R N A L   P R O C E D U R E   -   D B $ M P G N .        #
#                                                                      #
#**********************************************************************#
  
      PROC DB$MPGN;                                                     000110
      BEGIN                                                             000120
 #                                                                      000130
  *   DB$MPGN                                    PAGE  1                000140
  *   J E ESLER                                  DATE  3/9/77           000150
  DC  PURPOSE                                                           000160
      INTERFACE MFP ROUTINES TO CDCS GET MODULES. REQUIRED PARAMETERS   000170
      ARE SAVED AND RESTORED, SINCE CRM CALLS ARE INTERRUPTABLE.        000180
  DC  ENTRY CONDITIONS                                                  000190
      RSFCAORD DEFINES THE RSB ORDINAL OF THE RANK TO BE READ.
      THE FPT CONTAINS THE PARAMETERS FOR THE READ TO BE PERFORMED. 
  DC  EXIT CONDITIONS                                                   000210
      CRM GETN HAS BEEN PERFORMED.                                      000220
      THE FOLLOWING POINTERS ARE MAINTAINED:                            000230
          RSNSTAB                                                       000250
          RSBRLNBLK                                                     000260
          CSRLNSER                                                      000270
          RSAREBLK   (GUARANTEED BY DB$GETN)                            000280
  DC  CALLING ROUTINES
      DB$MFP - RDROOT PROC
      DB$AKY
      DB$MKY
      DB$NKY
      DB$PKY
  DC  CALLED ROUTINES 
      DB$GETN - GET AND LOCK NEXT RECORD                                000300
 #                                                                      000310
  
      CONTROL IFGR DFFLOP,0;
        DB$FLOP("MFP-10 "); 
      CONTROL ENDIF;
  
      DB$PUSH(DB$MPGN); 
      DB$PUSH(LOC(CSRLNSER)-LOC(CSFIXED));
      DB$PUSH(LOC(RSBRLNBLK)-LOC(RSB)); 
      DB$PUSH(LOC(RSNSTAB)-LOC(RSB)); 
      P<OFT> = RSAROFIT[0]; 
      RCOFTLOC[0] = LOC(OFT); 
      DB$GETN;
      P<TASKITEMS> = TQMFPBUF[0]; 
      JNBUFA = LOC(RSB) + RSFJNPTR[0];
      P<RSNSTAB> = LOC(RSB) + DB$POPF;
      P<RSBRLNBLK> = LOC(RSB) + DB$POPF;
      P<CSRLNSER> = LOC(CSFIXED) + DB$POPF; 
      DB$POP(DB$MPGN);
      FPFITRL[0] = UFFITRL[0];
      FPFITFP[0] = UFFITFP[0];
      IF ACCNFLAG 
      THEN
        DB$ACR(DFRD1);
      RETURN;                                                           000410
      END                                                               000420
  
      END                    #OF DB$MFP#
      TERM
