*DECK DB$AKY
USETEXT CDCSCTX 
USETEXT RELCMTX 
      PROC DB$AKY;
      BEGIN 
 #
  *   DB$AKY                                     PAGE 1 
  *   M L MOORE                                  DATE 10/15/75
  *   M D SAXE  (REVISION FOR 2.0)               DATE 09/24/76
  DC  PURPOSE 
      PROCESS A RELATION READ WITH RETRIEVAL BY ALTERNATE KEY.  THE 
      RECORD RETURNED (IF ANY) MUST ALSO SATISFY RESTRICT CONDITIONS. 
  
  DC  LANGUAGE
      SYMPL 
  
  DC  ENTRY CONDITIONS
      POINTER FOR RELATION SEARCH TABLE (RSNSTAB) IS SET TO THE ENTRY 
      FOR CURRANK 
      POINTER FOR THE FPT IS SET TO THE RURRENT RANK. 
      RSFCAORD IS SET.
      MFPRETCD = 0
      EOKFLAG = FALSE 
      IN FPT ARRAY, RKW, RKP, KL, KP, KA FIELDS ARE SET. KA POINTS
*       TO THE JOIN BUFFER, WHICH CONTAINS THE KEY. 
        THE FIT EX FIELD MUST POINT TO THE PROC CHECKES.
      MFPRETCD = 0 (RCOKAY) IF A QUALIFIED RECORD IS BEING RETURNED 
               = 1 (RCNULL) IF AN INVALID KEY ERROR OCCURRED
               = 2 (RCIOERR) IF AN I/O, CONVERSION, OR
                     INTERNAL OCCUR OCCURRED
               = 777 (RCNEWRK) IF THE NEXT LOWER RANK MUST BE 
                     PROCESSED, BECAUSE 
                     NO QUALIFIED RECORD CAN BE FOUND AT THIS RANK
      EOKFLAG IS SET TO TRUE IF END-OF-KEY WAS SENSED ON THIS RECORD
  
  DC  CALLING ROUTINE 
      DB$MFP
  
  DC  CALLED ROUTINES 
      CHECKES  - SET MFPRETD IF CRM ERROR 
                 (CALLED THRU FIT EX FIELD )
      DB$JCPR  - COMPARE JOIN DBI VALUE TO ALTERNATE KEY
      DB$MPGT   - READ A RECORD BY KEY
      DB$MPGN   - READ NEXT RECORD
      DB$QTST   - CHECK IF RECORD QUALIFIES VIA DB$QUAL 
      DC$XFER  - MOVE KEY VALUE TO KEYBUF 
  
  DC  DESCRIPTION 
          A FOR LOOP IS INITIATED TO READ RECORDS FROM THE FILE.
        - IF THE RSNFSTRK FLAG INDICATES THAT THIS IS THE FIRST 
      CHILD TO BE RETRIEVED FOR THIS RANK, A CRM GET REQUEST IS 
      ISSUED.  THE KEY FOR THE GET REQUEST IS THE SOURCE DBI VALUE. 
        - OTHERWISE A GETN REQUEST WILL BE ISSUED.
        - MFPRETCD MAY BE SET TO 1 (RCNULL) FOR AN INVALID KEY
      ERROR, OR TO 2 (RCIOERR) FOR OTHER CRM ERRORS.  THIS IS 
      DONE THROUGH THE EX FIELD IN THE FIT, WHICH POINTS TO THE 
      CHECKES PROC. 
        - IF MFPRETCD IS ZERO, THE FOLLOWING PROCESSING IS DONE.
          - IF A DIFFERENT ALTERNATE KEY VALUE WAS RETURNED (POSSIBLE 
            BECAUSE OF CONCURRENCY), MFPRETCD IS SET TO RCNEWRK.
          - EOKFLAG IS SET TO TRUE IF THE FILE POSITION INDICATES 
      THAT THIS IS THE RECORD AT END-OF-KEY.
          - THE QUALTEST PROC IS CALLED TO DETERMINE IF THE 
      RECORD SATISFIES QUALIFICATION CONDITIONS.
          - IF IT DOES NOT, AND EOKFLAG IS TRUE, MFPRETCD IS SET
      TO 777 (RCNEWRK) TO INDICATE THAT A NEW PARENT RECORD MUST
      BE READ AT A LOWER RANK.
          - IF IT DOES NOT, AND EOKFLAG IS FALSE, THE READ LOOP 
      WILL BE CONTINUED.
          - IF IT DOES QUALIFY, THE RECORD WILL BE RETURNED.
        - AN EXIT IS MADE, FIRST CLEARING ALL FIT FIELDS SET BY 
      THIS PROC, IF MFPRETCD IS NON-ZERO, OR IF A QUALIFIED 
      RECORD HAS BEEN RETRIEVED.
 #
                             #
                               CALL TO COMMON DECKS MFPDFDCLS, MFPCMDCLS
                               RELCMDCLS,RMCOMDCLS
                             #
      CONTROL NOLIST; 
*CALL MFPDFDCLS 
*CALL MFPCMDCLS 
*CALL RMCOMDCLS 
      CONTROL LIST; 
  
  
      XREF
        BEGIN 
        ARRAY DB$RA0;;
      PROC DB$MPGT; 
      PROC DB$MPGN; 
        PROC DB$QTST; 
        PROC DB$JCPR; 
        PROC DC$XFER; 
        END 
  
#     LOCAL VARIABLES                                                  #
  
      ITEM I;                # SCRATCH ITEM  #
  
#     ******   BEGINNING OF DB$AKY EXECUTABLE CODE   ******     # 
  
      HILOEQ = 0;            # INITIALIZE FOR FRST TIME THRU #
      FOR I = I DO
        BEGIN                # RECORD READ LOOP   # 
# 
    CHECK IF FIRST TIME FLAG IS SET. IF SO DO A GET BY KEY, ELSE GET THE
    NEXT RECORD.
# 
        IF RSNFSTRK [0] 
          THEN XCALL DB$MPGT; 
        ELSE                   # OTHERWISE, GET NEXT RECORD IN FILE # 
          BEGIN 
          FPFITKA[0] = LOC(KEYREAD);
          XCALL DB$MPGN;
          END 
        IF MFPRETCD EQ 0
          THEN                 # DO OTHER PROCESSING *ONLY* # 
          BEGIN                # IF THERE ARE NO CRM ERRORS # 
          IF NOT RSNFSTRK [0]   # IF GETN WAS DONE, SET UP #
            THEN               # PARAMETERS FOR DB$CMPR CALL #
            BEGIN 
            COMPBWP = JNBUFA + RSNJNPTR [0];
            TGIBBP = 0; 
            TGIFWA = LOC(KEYREAD);
            XCALL DB$JCPR;
            IF HILOEQ NQ 0       # TARGET NOT EQUAL TO JOIN VALUE # 
              AND MFPRETCD EQ 0  # AND NO ERRORS . . .     #
              THEN               # HAVE GONE PAST THIS MAJOR KEY  # 
              BEGIN              # SO RETURN, WITH MFPRETCD = 777 # 
              MFPRETCD = RCNEWRK; 
              RETURN; 
              END 
            END 
          IF FPFITFP[0] EQ FP$EOK  # CHECK FOR END-OF-KEY # 
            THEN EOKFLAG = TRUE;
          XCALL DB$QTST;         #CHECK RECORD QUALIFICATION #
          IF NOT RCQUAL 
            THEN                 #RECORD DOES NOT QUALIFY - - # 
            IF EOKFLAG       # IF AT END-OF-KEY, THEN TELL #
              THEN           # MFP TO READ LOWER RANK  #
              BEGIN          # TURN OFF EOKFLAG TO INDICATE # 
              MFPRETCD = RCNEWRK; 
              EOKFLAG = FALSE;  # NO RECORD FOR NXTLORANK PROC #
              END 
          END 
        IF RCQUAL  OR  MFPRETCD NQ 0
          THEN               # RETURN IF QUALIFIED RECORD, OR ERROR # 
          BEGIN              # OR EOK, OR INVALID KEY            #
          RETURN;                  # TO DB$MFP FROM DB$AKY #
  
          END 
        RSNFSTRK [0] = FALSE;       # CLEAR 1ST TIME THRU FLAG #
        END                  # OF RECORD READ LOOP #
      END                    # END OF DB$AKY #
      TERM
