.nf
 
 
    ========== licence begin  GPL
    Copyright (c) 2000-2004 SAP AG
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end
 
.fo
*****************************************************
Copyright (c) 2000-2004 SAP AG
SAP Database Technology
 
Release :      Date : 2000-11-07
*****************************************************
modname : VAK74
changed : 2000-11-07
module  : Fetch_Without_Resulttable
 
Author  : ElkeZ
Created : 1985-10-16
*****************************************************
 
Purpose : Provides the procedures in order to get the
          desired result in the case of a FETCH without
          result set.
 
Define  :
 
        PROCEDURE
              a74_search_fetch (
                    VAR acv        : tak_all_command_glob;
                    VAR sparr      : tak_syspointerarr;
                    mtype          : tgg00_MessType2;
                    pos            : tsp00_Int4;
                    VAR resn_rec   : tak_sysbufferaddress;
                    single_fetch   : boolean;
                    mfetch_count   : integer);
 
        PROCEDURE
              a74_copy_twokeys (
                    VAR acv     : tak_all_command_glob;
                    VAR keysbuf : tak_res_keysbuf;
                    VAR source  : tak_two_keyspecs;
                    VAR dest    : tak_two_keyspecs;
                    res_stat    : tak_sresstate);
 
.CM *-END-* define --------------------------------------
***********************************************************
 
Use     :
 
        FROM
              AK_universal_semantic_tools : VAK06;
 
        PROCEDURE
              a06cpy_mblock (
                    VAR acv        : tak_all_command_glob;
                    VAR src_mblock : tgg00_MessBlock;
                    VAR dst_mblock : tgg00_MessBlock;
                    withoutData    : boolean;
                    VAR e          : tgg00_BasisError);
 
        PROCEDURE
              a06init_curr_retpart (VAR acv : tak_all_command_glob);
 
        PROCEDURE
              a06retpart_move (
                    VAR acv     : tak_all_command_glob;
                    moveobj_ptr : tsp00_MoveObjPtr;
                    move_len    : tsp00_Int4);
 
        PROCEDURE
              a06finish_curr_retpart (
                    VAR acv   : tak_all_command_glob;
                    part_kind : tsp1_part_kind;
                    arg_count : tsp00_Int2);
 
        PROCEDURE
              a06rsend_mess_buf (
                    VAR acv     : tak_all_command_glob;
                    VAR mbuf    : tgg00_MessBlock;
                    result_req  : boolean;
                    VAR e       : tgg00_BasisError);
 
      ------------------------------ 
 
        FROM
              AK_error_handling : VAK07;
 
        PROCEDURE
              a07_b_put_error (
                    VAR acv  : tak_all_command_glob;
                    b_err    : tgg00_BasisError;
                    err_code : tsp00_Int4);
 
      ------------------------------ 
 
        FROM
              AK_error_handling : VAK071;
 
        FUNCTION
              a07_return_code (
                    b_err   : tgg00_BasisError;
                    sqlmode : tsp00_SqlMode) : tsp00_Int2;
 
      ------------------------------ 
 
        FROM
              Systeminfo_cache : VAK10;
 
        PROCEDURE
              a10get_sysinfo (
                    VAR acv      : tak_all_command_glob;
                    VAR syskey   : tgg00_SysInfoKey;
                    dstate       : tak_directory_state;
                    VAR syspoint : tak_sysbufferaddress;
                    VAR b_err    : tgg00_BasisError);
 
        PROCEDURE
              a10repl_sysinfo (
                    VAR acv      : tak_all_command_glob;
                    VAR syspoint : tak_sysbufferaddress;
                    VAR b_err    : tgg00_BasisError);
 
      ------------------------------ 
 
        FROM
              Long-Support-Getval: VAK508;
 
        PROCEDURE
              a508_lget_long_columns (
                    VAR acv             : tak_all_command_glob;
                    VAR change_rec      : tak_changerecord;
                    VAR lcol_lock       : boolean;
                    rec_cnt             : integer;
                    rec_len             : integer;
                    startpos            : integer);
 
        FUNCTION
              a508_lcol_found (
                    VAR acv        : tak_all_command_glob;
                    VAR change_rec : tak_changerecord) : boolean;
 
      ------------------------------ 
 
        FROM
              Select_Syntax : VAK60;
 
        PROCEDURE
              a60_change_results (
                    VAR acv        : tak_all_command_glob;
                    VAR data       : tsp00_MoveObj;
                    VAR change_rec : tak_changerecord;
                    startpos       : integer;
                    curr_resreclen : integer);
 
        PROCEDURE
              a60rescount (
                    VAR acv  : tak_all_command_glob;
                    rescount : tsp00_Int4);
 
        PROCEDURE
              a60_put_result (
                    VAR acv    : tak_all_command_glob;
                    VAR mblock : tgg00_MessBlock;
                    spos       : integer);
 
      ------------------------------ 
 
        FROM
              Resulttable: VAK73;
 
        PROCEDURE
              a73_infolen_get (
                    VAR acv        : tak_all_command_glob;
                    no_of_out_cols : integer;
                    VAR output_len : tsp00_Int2);
 
        FUNCTION
              a73_calc_unused_space (
                    VAR acv : tak_all_command_glob) : tsp00_Int4;
 
      ------------------------------ 
 
        FROM
              Single_Select : VKB720;
 
        PROCEDURE
              k720_maxresult_get (
                    VAR data           : tsp00_MoveObj;
                    strat_maxcnt       : tsp00_Int2;
                    VAR maxresult      : tsp00_Int4;
                    VAR b_err          : tgg00_BasisError);
 
      ------------------------------ 
 
        FROM
              Configuration_Parameter : VGG01;
 
        PROCEDURE
              g01mblock_init (
                    VAR source_trans : tgg00_TransContext;
                    mess_type  : tgg00_MessType;
                    mess2_type : tgg00_MessType2;
                    VAR mblock : tgg00_MessBlock);
 
      ------------------------------ 
 
        FROM
              Kernel_move_and_fill : VGG101;
 
        PROCEDURE
              SAPDB_PascalMove  (
                    mod_id          : tsp00_C6;
                    mod_intern_num  : tsp00_Int4;
                    source_upb      : tsp00_Int4;
                    destin_upb      : tsp00_Int4;
                    source          : tsp00_MoveObjPtr;
                    source_pos      : tsp00_Int4;
                    destin          : tsp00_MoveObjPtr;
                    destin_pos      : tsp00_Int4;
                    length          : tsp00_Int4;
                    VAR e           : tgg00_BasisError);
 
        PROCEDURE
              SAPDB_PascalOverlappingMove (
                    mod_id      : tsp00_C6;
                    mod_num     : tsp00_Int4;
                    source_upb  : tsp00_Int4;
                    dest_upb    : tsp00_Int4;
                    source      : tsp00_MoveObjPtr;
                    src_pos     : tsp00_Int4;
                    destin      : tsp00_MoveObjPtr;
                    dest_pos    : tsp00_Int4;
                    length      : tsp00_Int4;
                    VAR e       : tgg00_BasisError);

&       ifdef TRACE
 
      ------------------------------ 
 
        FROM
              Test_Procedures : VTA01;
 
        PROCEDURE
              t01sname (
                    debug : tgg00_Debug;
                    nam   : tsp00_Sname);
 
        PROCEDURE
              t01p2bool (
                    debug : tgg00_Debug;
                    nam_1 : tsp00_Sname;
                    bool1 : boolean;
                    nam_2 : tsp00_Sname;
                    bool2 : boolean);
 
        PROCEDURE
              t01p2int4 (
                    debug : tgg00_Debug;
                    nam_1 : tsp00_Sname;
                    int_1 : tsp00_Int4;
                    nam_2 : tsp00_Sname;
                    int_2 : tsp00_Int4);
 
        PROCEDURE
              t01name (
                    debug : tgg00_Debug;
                    nam   : tsp00_Name);
 
        PROCEDURE
              t01buf (
                    debug    : tgg00_Debug;
                    VAR buf  : tak_res_keysbuf;
                    startpos : integer;
                    endpos   : integer);
 
        PROCEDURE
              t01mess2type (
                    debug         : tgg00_Debug;
                    nam           : tsp00_Sname;
                    mess2_type    : tgg00_MessType2);
 
        PROCEDURE
              t01bool (
                    debug    : tgg00_Debug;
                    nam      : tsp00_Sname;
                    curr_bool: boolean);
 
        PROCEDURE
              t01handling (
                    debug : tgg00_Debug;
                    nam : tsp00_Sname;
                    s   : tgg00_HandlingSet);
 
        PROCEDURE
              t01int4 (
                    debug    : tgg00_Debug;
                    nam      : tsp00_Sname;
                    int      : tsp00_Int4);
 
        PROCEDURE
              t01key (
                    debug   : tgg00_Debug;
                    nam     : tsp00_Sname;
                    VAR k   : tgg00_Lkey);
 
        PROCEDURE
              t01lkey (
                    level : tgg00_Debug;
                    VAR k : tgg00_Lkey);
 
        PROCEDURE
              t01moveobj (
                    debug    : tgg00_Debug;
                    VAR buf  : tsp00_MoveObj;
                    startpos : tsp00_Int4;
                    endpos   : tsp00_Int4);
&       endif
 
.CM *-END-* use -----------------------------------------
***********************************************************
 
Synonym :
 
        PROCEDURE
              t01buf;
 
              tsp00_Buf tak_res_keysbuf
 
.CM *-END-* synonym -------------------------------------
***********************************************************
 
Description:
A74_SEARCH_FETCH
------------------------
 
The system-information record in which the stack entries and data for the
qualification are located is fetched; the record with the information on how
far in the result set fetching has already been performed is used.
Depending on the search direction, preparatory measures are taken: in FIRST
and LAST, entries are made in the key pairs (primary keys and inversion keys)
starting from which the search is to be made (always res_nextkeys or
res_prevkeys).
In DIRECT (specification of POS [  ]), an attempt is made, starting from
known positions (<> -1) in the result set, to find the shortest route to the
desired position. The search can be made starting from res_nextpos or
res_prevpos (different according to preceding MFETCHes) or from the beginning
of the result set. ACT_CNT specifies the number of results to be processed.
USE_RECS specifies that they are to be jumped and not returned to AK (the
search itself is performed in a loop in KB). After this jump, entries must be
made in that key pair in which entries were not already implicitly made in the
course of the jump. After this jump, the position one before the desired
position is reached,
so that, both in FETCH and also in MFETCH, the search can always be
continued with NEXT.
A distinction is made as to whether the user has specified FETCH
(single_fetch) or MFETCH.
In FETCH, a search is made by calling RECORD_FETCH with ACT_CNT = 1 for
precisely only one result record, which is to be delivered in its full length
(with Key and key/keys of the base table(s) required for FOR UPDATE) (ACT_LENG
= RES_RECLEN).
If it was a SELECT with 'FOR UPDATE' (res_length=length of the output
desired by the user < length of a result record (the primary keys of the base
tables are also in there)), the keys are transferred to the extra sysinfo
record for Join View keys or to the normal record, which also contains the
other information required for FETCH. RES_USEUPDK specifies whether it is then
possible to perform a ... CURRENT OF with this result-set name or not.
A60_PUT_RESULT
transfers the result from part1 of the Mess-Buffer to the SQL_PACKET (if
there is still space for it there in addition to the long infos).
If MFETCH was specified, it is not possible for a command with CURRENT
OF to be used.
It is determined how many of the desired results can be accommodated in the
SQL_PACKET together with the info part. As least one result is fetched
and, if necessary, intermediately stored in the Mess-Buffer, so that it can be
fetched with FETCH REST.
In a loop, as many results are fetched as will fit into the SQL_PACKET
or as the user has requested. This is done in that, each time, a maximum of one
buffer is filled with results by calling RECORD_FETCH.
After the first call of RECORD_FETCH (foundrecs = 0), error 100 may
possibly be returned; the search direction is changed from FIRST/LAST to
NEXT/PREV.
S_FETCH specifies whether, in RECORD_FETCH, entries are to be made not only
in RES_NEXTKEYS (in FIRST/NEXT), but also in RES_PREVKEYS (entry with the first
key when first called).
If code conversions are necessary (atcolcount > 0), these are performed for
all results (part2.m_cnt) by the repeated calling of A60_CHANGE_RESULTS.
Since, in MFETCH, not the entire result record, but only its info part
(also excluding any implicitly appended primary keys for FOR UPDATE) is
delivered (the keys for further search are in the structure in part2 of the
Mess-Buffer), the positions given here are different from those in FETCH.
If one of the result records will no longer fit into the request segment
because of the long long infos, it is intermediately stored in part2 of the
Mess-Buffer.
Otherwise, the results are moved directly to the SQL_PACKET. It
applies in this connection that, also for MFETCH PREV/LAST, the result with the
smallest key is at the extreme left in the SQL_PACKET, i.e. the SQL_PACKET
is filled from right to left. This also means that, if fewer than the
desired number of results exist, the filled part of part2 of the
SQL_PACKET has to be pulled up to part1.
The number of results found is, byte-swapped if necessary, entered in the
first two bytes of part2.
.sp 2;RECORD_FETCH
.sp
Depending on the search direction, different key pairs are used for making
entries in the structure in part2 of the Mess-Buffer. There are also
differences as to whether a search is to be made via an inversion (teuseinv in
res_resstate) or not.
.br;It is also specified whether a stop key with a significant value exists.
.sp 2;BUILD_FETCH_MESS_BUF
.sp
The following parameters are passed:
.in +3;.un 3
-  STARTKEYS : Key pair (consists of one inversion-list value and one primary
key) at which the search is to begin
.un 3
-  STOPKEYS : Key pair at which the search is to end
.un 3
-  ONE_STARTKEY : if the search is to be made via an inversion (specified in
MREC.RESST), it may be that the search is not to be started at the first
primary key in the next inversion list, but at the primary-key value identified
by ONE_STARTKEY
.un 3
-  FIRSTKEYS : Key pair in which, if S_FETCH = true, are to be entered the key
values (inversion key and primary key) of the first result found
.un 3
-  MREC : contains information on whether there was a FETCH (single, i.e.
result must be the entire record, not only the Info part), how long a result is
(act_leng), how many results are to be fetched (act_cnt) etc.
.un 3
-  STOP : specifies whether STOPKEYS is to be used or not
.in -3;.br;In this procedure, entries are made in the structure in part2 of
the Mess-Buffer, which has the following appearance:
.nf
           m_use_inv        : boolean;
           m_use_stop       : boolean;
           m_single         : boolean;
           m_use_recs       : boolean;
           m_keylen         : int2;
           m_cnt            : int2;
           m_leng           : int2;
           m_fns1           : filename; (*pos 11*)
           m_fns2           : filename; (*pos 39*)
           m_startkeys      : two_keys; (*pos 67, 325*)
           m_stopkeys       : two_keys; (*pos 583, 841*)
           m_firstkeys      : two_keys; (*pos 1099, 1357*)
           m_start          : lkey;     (*pos 1615*)
.fo
Here, m_use_recs specifies whether the results are required in AK or whether
they are just to be jumped in order to reach the desired position
(specification of POS [  ]).
.br;M_keylen is required in order to identify the start position of the info
part in a result record.
.br;M_fns1 is the file name of the primary file, with m_fns2 being the name of
the secondary file.
.br;After the command has been executed (A06_SEND_MESS_BUF), the transaction
status is reset to its original value, which may have been extended for this
(M)FETCH request to include information for WITH LOCK ...
(state:= state + tmtrans_count.state).
.br;If there is no error, entries are made in the STRATKEYS key pair and, if
applicable, in the FIRSTKEYS key pair.
.br;The values for the positions must be re-determined, so that they can be
used in the next (M)FETCH POS [  ].
.br;Only mm_next (even if (M)FETCH DIRECT/FIRST) specified), mm_last, mm_prev
and mm_same (only in FETCH, not in MFETCH) may appear for the EMTYPE (search is
made with IMTYPE).
.br;If mm_last was specified,
the position of the result is unknown (-1), since the total
number of results is not known. If mm_next/mm_prev was specified,
the position must be
changed by the number of results found. Only when BUILD_FETCH_MESS_BUF is first
called for an MFETCH/FETCH (s_fetch) need an entry be made in the position that
is required for FETCHes with opposite search direction.
.sp 2;A74_COPY_TWOKEYS
.sp
The primary key is transferred in its correct length from the first key pair to
the second key pair; the inversion key is transferred only if the inversion is
used, i.e. if there is also an entry in the key.
.CM *-END-* description ---------------------------------
***********************************************************
.CM -lll-
Code    :
 
 
CONST
      c_stop             = true (* ak74build_fetch_mess_buf *);
 
TYPE
      (* PTS 1111576 E.Z. *)
 
      mfetch_rec = RECORD
            act_cnt       : tsp00_Int4;
            resnamerec    : tak_sysbufferaddress;
            act_leng      : tsp00_Int2;
            resst         : tak_sresstate;
            s_fetch       : boolean;
            imtype        : tgg00_MessType2;
            emtype        : tgg00_MessType2;
            single        : boolean;
            use_recs      : boolean;
      END;
 
 
 
(*------------------------------*) 
 
PROCEDURE
      ak74build_fetch_mess_buf (
            VAR acv          : tak_all_command_glob;
            VAR sparr        : tak_syspointerarr;
            VAR mblock       : tgg00_MessBlock;
            VAR fetch_mblock : tgg00_MessBlock;
            VAR startkeys    : tak_two_keyspecs;
            VAR stopkeys     : tak_two_keyspecs;
            VAR one_startkey : tak_keyspec;
            VAR firstkeys    : tak_two_keyspecs;
            VAR mrec         : mfetch_rec;
            rescnt           : tsp00_Int4;
            direct_retp_move : boolean;
            stop             : boolean);
 
CONST
      c_without_data = true;
 
VAR
      e              : tgg00_BasisError;
      first_free     : integer;
      data_len       : tsp00_Int4;
 
BEGIN
WITH mrec, sparr.px[ 2 ]^.sreskey DO
    BEGIN
    g01mblock_init (acv.a_transinf.tri_trans,
          m_fetch, imtype, fetch_mblock);
    first_free                  := mblock.mb_qual^.mfirst_free;
    mblock.mb_qual^.mfirst_free := 1; (* don't copy stack entries ! *)
    data_len                    := mblock.mb_data_len;
    (* don't copy data in local case *)
    mblock.mb_data_len := 0;
    WITH fetch_mblock DO
        BEGIN
        mb_qual       := acv.a_mblock.mb_qual;
        mb_qual_size  := acv.a_mblock.mb_qual_size;
        mb_strat      := acv.a_mblock.mb_strat;
        mb_strat_size := acv.a_mblock.mb_strat_size;
        mb_valuearr   := acv.a_mblock.mb_valuearr;
        mb_validx_max := acv.a_mblock.mb_validx_max;
        IF  ( direct_retp_move )
        THEN
            BEGIN
            mb_data := @acv.a_curr_retpart^.sp1p_buf[
                  acv.a_curr_retpart^.sp1p_buf_len + 1];
            mb_data_size := acv.a_curr_retpart^.sp1p_buf_size -
                  acv.a_curr_retpart^.sp1p_buf_len
            END
        ELSE
            BEGIN
            mb_data      := acv.a_mb_data_addr;
            mb_data_size := acv.a_mb_data_size;
            END;
        (*ENDIF*) 
        a06cpy_mblock (acv, mblock, fetch_mblock, NOT c_without_data, e);
        mb_st                       := mblock.mb_st;
        mb_st_size                  := mblock.mb_st_size;
        mb_qual^.mst_addr           := mblock.mb_st;
        mb_qual^.mfirst_free        := first_free;
        mblock.mb_qual^.mfirst_free := first_free
        END;
    (*ENDWITH*) 
    (* PTS 1106955 E.Z. *)
    fetch_mblock.mb_qual^.msqlmode := res_pars_sqlmode;
    mblock.mb_data_len := data_len;
    IF  ( e <> e_ok )
    THEN
        a07_b_put_error (acv, e, 1)
    ELSE
        BEGIN
        WITH fetch_mblock, mb_qual^.mf_desc DO
            BEGIN
            mb_type      := m_fetch;
            mb_type2     := imtype;
            (* PTS 1000801 E.Z. *)
            m_rescnt     := rescnt;
            (* h.b. PTS 1001366 *)
            m_rowno      := sparr.px[ 2 ]^.sreskey.res_rowno;
            m_use_stop   := stop;
            m_cnt        := act_cnt;
            m_keylen     := sparr.px[ 2 ]^.sreskey.res_keylen;
            m_leng       := act_leng;
            m_single     := single;
            m_use_recs   := use_recs;
            m_dist_optim := sparr.px[ 2 ]^.sreskey.res_dist_optim;
            m_qual_kind  := sparr.px[ 2 ]^.sreskey.res_qual_kind;
            m_strat_info := sparr.px[ 2 ]^.sreskey.res_strat_info;
            m_searched_pages := sparr.px[2]^.sreskey.res_searched_pages;
            m_use_inv    := (rs_useinv in resst) AND
                  ((imtype <> mm_direct) OR (m_qual_kind = inv_only));
&           ifdef trace
            t01name(ak_sem, 'start -> m_startke');
&           endif
            ak74copy2_twokeys (acv, res_keysbuf, startkeys, m_startkeys, resst);
            IF  ( acv.a_returncode = 0 )
            THEN
                BEGIN
&               ifdef trace
                t01name(ak_sem, 'stop -> m_stopkey ');
&               endif
                ak74copy2_twokeys (acv,
                      res_keysbuf, stopkeys, m_stopkeys, resst)
                END;
            (*ENDIF*) 
            IF  ( acv.a_returncode = 0 )
            THEN
                BEGIN
&               ifdef trace
                t01name(ak_sem, 'one_star-> m_start');
&               endif
                m_start.len := one_startkey.ks_len;
                SAPDB_PascalMove ('VAK74 ',   1,
                      sizeof(res_keysbuf), sizeof(m_start.k),
                      @res_keysbuf, one_startkey.ks_pos, @m_start.k, 1,
                      m_start.len, acv.a_returncode);
                END;
            (*ENDIF*) 
            IF  ( mb_type2 in [ mm_direct, mm_next, mm_first, mm_last_rowno ] ) AND
                ( m_start.len > 0 )
            THEN
                IF  m_start.k[ m_start.len ] < chr(255)
                THEN
                    m_start.k[ m_start.len ] :=
                          chr(succ(ord(m_start.k[ m_start.len ])))
                ELSE
                    BEGIN
                    IF  m_start.len = KEY_MXSP00
                    THEN
                        BEGIN
                        WHILE (m_start.len > 1) AND
                              (m_start.k[ m_start.len ] = chr(255)) DO
                            m_start.len := pred(m_start.len);
                        (*ENDWHILE*) 
                        IF  m_start.k[ m_start.len ] < chr(255)
                        THEN
                            m_start.k[ m_start.len ] :=
                                  chr(succ(ord(m_start.k[ m_start.len ])))
                        ELSE
                            m_start.len := KEY_MXSP00
                        (*ENDIF*) 
                        END
                    ELSE
                        BEGIN
                        m_start.len              := succ(m_start.len);
                        m_start.k[ m_start.len ] := chr(0)
                        END
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
            (*ENDIF*) 
            m_fns1                    := sparr.px[ 2 ]^.sreskey.res_treeids.file_id;
            m_fns1.fileHandling_gg00  := mb_qual^.mtree.fileHandling_gg00;
            m_fns1.fileLeafNodes_gg00 := cgg_nil_leafnodes;
            (* PTS 1111576 E.Z. *)
            IF  hsConsistentLock_egg00 in m_fns1.fileHandling_gg00
            THEN
                m_fns1.fileHandling_gg00 := m_fns1.fileHandling_gg00 +
                      [ hsCollisionTest_egg00 ] - [ hsConsistentLock_egg00 ];
            (*ENDIF*) 
            IF  (hsPermLock_egg00 in m_fns1.fileHandling_gg00) AND
                NOT (hsIntentExcl_egg00 in m_fns1.fileHandling_gg00)
            THEN
                m_fns1.fileHandling_gg00 := m_fns1.fileHandling_gg00 + [ hsWithoutLock_egg00 ];
            (*ENDIF*) 
            m_fns2      := sparr.px[ 2 ]^.sreskey.res_treeids.inv_id;
            m_data := mblock.mb_data;
            mb_qual_len := sizeof (mb_qual^.mf_desc);
            END;
        (*ENDWITH*) 
        END;
    (*ENDIF*) 
    IF  acv.a_returncode = 0
    THEN
        BEGIN
        a06rsend_mess_buf (acv, fetch_mblock, cak_return_req, e);
        (* Do NOT change e to mb_trns^.trError_gg00 *)
&       ifdef TRACE
        t01int4 (ak_sem, 'b_error     ', ord(e));
        t01lkey (ak_sem, fetch_mblock.mb_qual^.mf_desc.m_startkeys.reckey);
        t01moveobj (ak_sem,
              fetch_mblock.mb_data^.mbp_buf, 1, fetch_mblock.mb_data_len);
&       endif
        END;
    (*ENDIF*) 
    IF  acv.a_returncode = 0
    THEN
        WITH fetch_mblock, sparr.px[ 2 ]^.sreskey DO
            BEGIN
            IF  e <> e_ok
            THEN
                IF  (e = e_key_not_found)
                    AND (imtype <> mm_direct)
                THEN
                    mb_trns^.trError_gg00 := e_ok
                ELSE
                    (* PTS 1002020 E.Z. *)
                    IF  (mb_trns^.trError_gg00 = e_no_next_invkey) OR
                        (mb_trns^.trError_gg00 = e_no_next_record) OR
                        (mb_trns^.trError_gg00 = e_no_prev_invkey)
                    THEN
                        mb_trns^.trError_gg00 := e_no_next_record
                    ELSE
                        IF  mb_trns^.trError_gg00 = e_no_prev_record
                        THEN
                            IF  (imtype = mm_prev) AND
                                (* (act_cnt - 1 = mb_qual^.mf_desc.m_cnt) AND *)
                                (* wird ja nicht zurckgeliefert *)
                                (NOT use_recs)
                            THEN
                                BEGIN
                                END
                            ELSE
                                mb_trns^.trError_gg00 := e_no_next_record
                            (*ENDIF*) 
                        ELSE
                            mb_trns^.trError_gg00 := e;
                        (*ENDIF*) 
                    (*ENDIF*) 
                (*ENDIF*) 
            (*ENDIF*) 
            IF  (mb_trns^.trError_gg00 = e_ok) OR
                (mb_trns^.trError_gg00 = e_no_next_record)
            THEN
                WITH sparr.px[ 2 ]^.sreskey DO
                    BEGIN
                    res_searched_pages := mb_qual^.mf_desc.m_searched_pages;
                    IF  ((res_searched_pages >
                        cak68_updstat_minpages) AND
                        (res_searched_pages > res_known_pages
                        * cak68_updstat_factor) AND
                        NOT mrec.resnamerec^.sresname.resimpl_upd_stat
                        (* upd_stat is not written in resname_rec *)
                        )
                    THEN
                        BEGIN
                        mrec.resnamerec^.sresname.resimpl_upd_stat := true;
                        a10repl_sysinfo (acv, mrec.resnamerec, e);
                        (* if there is an error, it doesn't matter *)
                        END;
                    (*ENDIF*) 
                    END;
                (*ENDWITH*) 
            (*ENDIF*) 
            IF  mb_trns^.trError_gg00 = e_ok
            THEN
                BEGIN
                IF  direct_retp_move
                THEN
                    acv.a_curr_retpart^.sp1p_buf_len :=
                          acv.a_curr_retpart^.sp1p_buf_len +
                          fetch_mblock.mb_data_len;
                (*ENDIF*) 
                res_first_fetch := false;
                res_eof         := false;
                (* PTS 1001717 E.Z. *)
&               ifdef trace
                t01name(ak_sem, 'm_start -> startke');
&               endif
                ak74copy1_twokeys (acv, mb_qual^.mf_desc.m_startkeys,
                      res_keysbuf, startkeys, resst,
                      res_startkeys.listkeyspec.ks_pos -
                      res_startkeys.reckeyspec.ks_pos, (* primlen *)
                      res_stopkeys.reckeyspec.ks_pos -
                      res_startkeys.listkeyspec.ks_pos (* invlen *));
                IF  s_fetch
                THEN
                    BEGIN
&                   ifdef trace
                    t01name(ak_sem, 'm_first -> firstke');
&                   endif
                    ak74copy1_twokeys (acv, mb_qual^.mf_desc.m_firstkeys,
                          res_keysbuf, firstkeys, resst,
                          res_startkeys.listkeyspec.ks_pos -
                          res_startkeys.reckeyspec.ks_pos,
                          res_stopkeys.reckeyspec.ks_pos -
                          res_startkeys.listkeyspec.ks_pos);
                    END;
                (*ENDIF*) 
                ;
&               ifdef trace
                t01mess2type( ak_sem, 'emtype      ', mrec.emtype );
&               endif
                CASE emtype OF
                    mm_last :
                        BEGIN
                        res_prevpos := -1;
                        res_nextpos := -1
                        END;
                    mm_next :
                        BEGIN
                        IF  s_fetch
                        THEN
                            IF  res_nextpos <> -1
                            THEN
                                IF  mb_qual^.mf_desc.m_cnt = 0
                                THEN
                                    BEGIN
                                    res_eof     := true;
                                    res_prevpos := res_nextpos
                                    END
                                ELSE
                                    res_prevpos := succ(res_nextpos);
                                (*ENDIF*) 
                            (*ENDIF*) 
                        (*ENDIF*) 
                        IF  res_nextpos <> -1
                        THEN
                            res_nextpos := res_nextpos +
                                  mb_qual^.mf_desc.m_cnt
                        (*ENDIF*) 
                        END;
                    mm_first :
                        (* PTS 1122802 E.Z. *)
                        BEGIN
                        IF  s_fetch
                        THEN
                            IF  mb_qual^.mf_desc.m_cnt = 0
                            THEN
                                res_prevpos := 0
                            ELSE
                                res_prevpos := 1;
                            (*ENDIF*) 
                        (*ENDIF*) 
                        IF  res_nextpos <> -1
                        THEN
                            res_nextpos := res_nextpos +
                                  mb_qual^.mf_desc.m_cnt;
                        (*ENDIF*) 
                        END;
                    mm_prev :
                        BEGIN
                        IF  s_fetch
                        THEN
                            IF  res_prevpos > 0
                            THEN
                                IF  mb_qual^.mf_desc.m_cnt = 0
                                THEN
                                    BEGIN
                                    res_first_fetch := true;
                                    res_nextpos     := res_prevpos
                                    END
                                ELSE
                                    res_nextpos := pred(res_prevpos);
                                (*ENDIF*) 
                            (*ENDIF*) 
                        (*ENDIF*) 
                        IF  res_prevpos > 0
                        THEN
                            res_prevpos := res_prevpos -
                                  mb_qual^.mf_desc.m_cnt
                        (*ENDIF*) 
                        END;
                    OTHERWISE
                        BEGIN
                        END
                    END;
                (*ENDCASE*) 
                (* PTS 1105717 E.Z. *)
                IF  (mb_qual^.mf_desc.m_cnt < act_cnt)
                    AND
                    (act_cnt > 1)
                THEN
                    IF  (imtype = mm_next) OR (imtype = mm_first)
                    THEN
                        BEGIN
                        IF  res_nextpos <> -1
                        THEN
                            res_nextpos := succ(res_nextpos)
                        (*ENDIF*) 
                        END
                    ELSE
                        BEGIN
                        IF  res_prevpos <> -1
                        THEN
                            res_prevpos := pred(res_prevpos)
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                (*ENDIF*) 
                END
            ELSE
                (* mb_trns^.trError_gg00 <> e_ok *)
                IF  mb_trns^.trError_gg00 = e_no_next_record
                THEN
                    BEGIN
                    IF  imtype = mm_next
                    THEN
                        BEGIN
                        res_eof         := true;
                        res_first_fetch := false
                        END
                    ELSE
                        IF  imtype = mm_prev
                        THEN
                            BEGIN
                            res_eof         := false;
                            res_first_fetch := true
                            END
                        (*ENDIF*) 
                    (*ENDIF*) 
                    END
                ELSE
                    (* PTS 1002020 E.Z. *)
                    IF  mb_trns^.trError_gg00 = e_no_prev_record
                    THEN
                        BEGIN
                        res_eof         := false;
                        res_first_fetch := true;
                        res_nextpos := 0;
                        res_prevpos := 0;
                        a74_copy_twokeys (acv, res_keysbuf, res_startkeys,
                              res_prevkeys, res_resstate);
                        mb_trns^.trError_gg00 := e_ok;
                        END
                    ELSE
                        IF  mb_trns^.trError_gg00 = e_old_fileversion
                        THEN
                            a07_b_put_error (acv, e_invalid_mix_dml_ddl, 1)
                        ELSE
                            a07_b_put_error (acv, mb_trns^.trError_gg00, 1)
                        (*ENDIF*) 
                    (*ENDIF*) 
                (*ENDIF*) 
            (*ENDIF*) 
            END;
        (*ENDWITH*) 
&   ifdef trace
    (*ENDIF*) 
    t01p2int4( ak_sem, 'res_nextpos ', res_nextpos,
          'res_prevpos ', res_prevpos );
    t01p2bool( ak_sem, 'res_first_fe', res_first_fetch ,
          'res_eof     ', res_eof );
&   endif
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak74copy1_twokeys (
            VAR acv     : tak_all_command_glob;
            VAR source  : tgg00_TwoKeys;
            VAR keysbuf : tak_res_keysbuf;
            VAR dest    : tak_two_keyspecs;
            res_stat    : tak_sresstate;
            primlen     : integer;
            invlen      : integer);
 
BEGIN
&ifdef TRACE
IF  rs_useinv in res_stat
THEN
    t01key (ak_sem, 'listkey     ', source.listkey);
(*ENDIF*) 
t01key (ak_sem, 'reckey      ', source.reckey);
&endif
(* PTS 1001717 E.Z. *)
IF  source.reckey.len > primlen
THEN
    dest.reckeyspec.ks_len := primlen
ELSE
    dest.reckeyspec.ks_len := source.reckey.len;
(*ENDIF*) 
SAPDB_PascalMove ('VAK74 ',   2,
      sizeof(source.reckey.k), sizeof(keysbuf),
      @source.reckey.k, 1, @keysbuf, dest.reckeyspec.ks_pos,
      dest.reckeyspec.ks_len, acv.a_returncode);
IF  (rs_useinv in res_stat) AND
    (acv.a_returncode = 0)
THEN
    BEGIN
    (* PTS 1001717 E.Z. *)
    IF  source.listkey.len > invlen
    THEN
        dest.listkeyspec.ks_len := invlen
    ELSE
        dest.listkeyspec.ks_len := source.listkey.len;
    (*ENDIF*) 
    SAPDB_PascalMove ('VAK74 ',   3,
          sizeof(source.listkey.k), sizeof(keysbuf),
          @source.listkey.k, 1, @keysbuf, dest.listkeyspec.ks_pos,
          dest.listkeyspec.ks_len, acv.a_returncode)
    END
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak74copy2_twokeys (
            VAR acv     : tak_all_command_glob;
            VAR keysbuf : tak_res_keysbuf;
            VAR source  : tak_two_keyspecs;
            VAR dest    : tgg00_TwoKeys;
            res_stat    : tak_sresstate);
 
BEGIN
dest.reckey.len := source.reckeyspec.ks_len;
SAPDB_PascalMove ('VAK74 ',   4,
      sizeof(keysbuf), sizeof(dest.reckey.k),
      @keysbuf, source.reckeyspec.ks_pos, @dest.reckey.k, 1,
      dest.reckey.len, acv.a_returncode);
IF  (rs_useinv in res_stat) AND
    (acv.a_returncode = 0)
THEN
    BEGIN
    dest.listkey.len := source.listkeyspec.ks_len;
    SAPDB_PascalMove ('VAK74 ',   5,
          sizeof(keysbuf), sizeof(dest.listkey.k),
          @keysbuf, source.listkeyspec.ks_pos, @dest.listkey.k, 1,
          dest.listkey.len, acv.a_returncode)
    END;
(*ENDIF*) 
;
&ifdef TRACE
IF  rs_useinv in res_stat
THEN
    t01key (ak_sem, 'listkey     ', dest.listkey);
(*ENDIF*) 
t01int4 (ak_sem, 'src list pos', source.listkeyspec.ks_pos );
t01int4 (ak_sem, 'src list len', source.listkeyspec.ks_len );
t01key (ak_sem, 'reckey      ', dest.reckey);
t01int4 (ak_sem, 'src key pos ', source.reckeyspec.ks_pos );
t01int4 (ak_sem, 'src key len ', source.reckeyspec.ks_len );
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      ak74record_fetch (
            VAR acv             : tak_all_command_glob;
            VAR sparr           : tak_syspointerarr;
            VAR mblock          : tgg00_MessBlock;
            VAR fetch_mblock    : tgg00_MessBlock;
            VAR mrec            : mfetch_rec;
            direct_retp_move    : boolean);
 
BEGIN
WITH sparr.px[ 2 ]^.sreskey, mrec DO
    BEGIN
    IF  imtype = mm_direct
    THEN
        BEGIN
&       ifdef trace
        t01name(ak_sem, 'r_next -> start   ');
        t01name(ak_sem, 'r_stop -> stop    ');
        t01name(ak_sem, 'r_start -> one_sta');
        t01name(ak_sem, 'r_prev -> firstkey');
&       endif
        ak74build_fetch_mess_buf (acv, sparr, mblock, fetch_mblock,
              res_nextkeys,(* startkeys *)
              res_stopkeys,(* stopkeys*)
              res_startkeys.reckeyspec,(* one_startkey*)
              res_prevkeys,(* firstkeys *)
              mrec, res_nextpos, (* rescnt *)
              direct_retp_move, NOT c_stop);
        END
    ELSE
        IF  NOT (rs_useinv in res_resstate)
        THEN
            CASE imtype OF
                mm_first, mm_next, mm_last_rowno :
                    BEGIN
&                   ifdef trace
                    t01name(ak_sem, 'r_next -> start   ');
                    t01name(ak_sem, 'r_stop -> stop    ');
                    t01name(ak_sem, 'r_start -> one_sta');
                    t01name(ak_sem, 'r_prev -> firstkey');
&                   endif
                    ak74build_fetch_mess_buf (acv,
                          sparr, mblock, fetch_mblock,
                          res_nextkeys, res_stopkeys,
                          res_startkeys.reckeyspec,
                          res_prevkeys, mrec, res_nextpos, direct_retp_move,
                          res_keysbuf[ res_stopkeys.reckeyspec.ks_pos ] <>
                          chr(255));
                    END;
                mm_last, mm_prev :
                    BEGIN
&                   ifdef trace
                    t01name(ak_sem, 'r_prev -> start   ');
                    t01name(ak_sem, 'r_start -> stop   ');
                    t01name(ak_sem, 'r_stop -> one_sta ');
                    t01name(ak_sem, 'r_next -> firstkey');
&                   endif
                    ak74build_fetch_mess_buf (acv,
                          sparr, mblock, fetch_mblock,
                          res_prevkeys, res_startkeys,
                          res_stopkeys.reckeyspec,
                          res_nextkeys, mrec, res_nextpos, direct_retp_move,
                          res_startkeys.reckeyspec.ks_len <> 0);
                    END;
                END
            (*ENDCASE*) 
        ELSE
            CASE imtype OF
                mm_first, mm_next, mm_last_rowno :
                    ak74build_fetch_mess_buf (acv,
                          sparr, mblock, fetch_mblock,
                          res_nextkeys, res_stopkeys,
                          res_startkeys.reckeyspec,
                          res_prevkeys, mrec, res_nextpos, direct_retp_move,
                          ((res_keysbuf[ res_stopkeys.reckeyspec.ks_pos  ] <>
                          chr(255)) OR
                          ( res_keysbuf[ res_stopkeys.listkeyspec.ks_pos ] <>
                          chr(255))));
                mm_last, mm_prev :
                    ak74build_fetch_mess_buf (acv,
                          sparr, mblock, fetch_mblock,
                          res_prevkeys, res_startkeys,
                          res_stopkeys.reckeyspec,
                          res_nextkeys, mrec, res_nextpos, direct_retp_move,
                          ((res_startkeys. reckeyspec.ks_len <> 0) OR
                          ( res_startkeys.listkeyspec.ks_len <> 0)));
                END;
            (*ENDCASE*) 
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      a74_copy_twokeys (
            VAR acv     : tak_all_command_glob;
            VAR keysbuf : tak_res_keysbuf;
            VAR source  : tak_two_keyspecs;
            VAR dest    : tak_two_keyspecs;
            res_stat    : tak_sresstate);
 
BEGIN
dest.reckeyspec.ks_len := source.reckeyspec.ks_len;
SAPDB_PascalMove ('VAK74 ',   6,
      sizeof(keysbuf), sizeof(keysbuf),
      @keysbuf, source.reckeyspec.ks_pos,
      @keysbuf, dest.reckeyspec.ks_pos, dest.reckeyspec.ks_len,
      acv.a_returncode);
IF  (rs_useinv in res_stat)AND
    (acv.a_returncode = 0)
THEN
    BEGIN
    dest.listkeyspec.ks_len := source.listkeyspec.ks_len;
    SAPDB_PascalMove ('VAK74 ',   7,
          sizeof(keysbuf), sizeof(keysbuf),
          @keysbuf, source.listkeyspec.ks_pos,
          @keysbuf, dest.listkeyspec.ks_pos, dest.listkeyspec.ks_len,
          acv.a_returncode)
    END;
&ifdef trace
(*ENDIF*) 
IF  (rs_useinv in res_stat)
THEN
    BEGIN
    t01int4 (ak_sem, 'src list pos', source.listkeyspec.ks_pos );
    t01int4 (ak_sem, 'src list len', source.listkeyspec.ks_len );
    t01sname(ak_sem, 'listkey:    ' );
    t01buf( ak_sem, keysbuf, source.listkeyspec.ks_pos,
          source.listkeyspec.ks_pos + source.listkeyspec.ks_len );
    END;
(*ENDIF*) 
t01int4 (ak_sem, 'src key pos ', source.reckeyspec.ks_pos );
t01int4 (ak_sem, 'src key len ', source.reckeyspec.ks_len );
t01sname(ak_sem, 'reckey:     ' );
t01buf( ak_sem, keysbuf, source.reckeyspec.ks_pos,
      source.reckeyspec.ks_pos + source.reckeyspec.ks_len );
IF  (rs_useinv in res_stat)
THEN
    BEGIN
    t01int4 (ak_sem, 'dst list pos', dest.listkeyspec.ks_pos );
    t01int4 (ak_sem, 'dst list len', dest.listkeyspec.ks_len );
    END;
(*ENDIF*) 
t01int4 (ak_sem, 'dst key pos ', dest.reckeyspec.ks_pos );
t01int4 (ak_sem, 'dst key len ', dest.reckeyspec.ks_len );
&endif
END;
 
(* PTS 1111576 E.Z. *)
(*------------------------------*) 
 
PROCEDURE
      a74_search_fetch (
            VAR acv        : tak_all_command_glob;
            VAR sparr      : tak_syspointerarr;
            mtype          : tgg00_MessType2;
            pos            : tsp00_Int4;
            VAR resn_rec   : tak_sysbufferaddress;
            single_fetch   : boolean;
            mfetch_count   : integer);
 
VAR
      _fill_ret_segm       : boolean;
      _lcol_lock           : boolean;
      _lcol_found          : boolean;
      _direct_retpart_move : boolean;
      _p_messbuf           : tak_sysbufferaddress;
      _b_err               : tgg00_BasisError;
      _e                   : tgg00_BasisError;
      _ic2                 : tsp_int_map_c2;
      _cnt                 : integer;
      _col_no              : integer;
      _foundrecs           : integer;
      _i                   : integer;
      _start_pos           : integer;
      _func_code           : integer;
      _output_offset       : tsp00_Int4;
      _mrec                : mfetch_rec;
      _ke                  : tgg00_SysInfoKey;
      _unused_leng         : tsp00_Int4;
      _fetch_mblock        : tgg00_MessBlock;
      _rowno               : tsp00_Int4;
 
BEGIN
&ifdef trace
t01mess2type(ak_sem, 'mtype       ', mtype);
t01int4 (ak_sem, 'position    ', pos );
t01bool (ak_sem, 'single fetch', single_fetch);
t01int4 (ak_sem, 'mfetch_count', mfetch_count );
t01int4 (ak_sem, 'res_nextpos ', sparr.px[ 2 ]^.sreskey.res_nextpos);
t01int4 (ak_sem, 'res_prevpos ', sparr.px[ 2 ]^.sreskey.res_prevpos);
t01bool (ak_sem, 'res_first_fe', sparr.px[ 2 ]^.sreskey.res_first_fetch);
t01bool (ak_sem, 'res_eof     ', sparr.px[ 2 ]^.sreskey.res_eof);
&endif
_fetch_mblock.mb_trns := @acv.a_transinf.tri_trans;
_direct_retpart_move  := false;
acv.a_long_desc_pos      := 0;
_b_err                := e_ok;
_ke                   := sparr.px[ 2 ]^.syskey;
_ke.sentrytyp         := cak_emessblock;
a10get_sysinfo (acv, _ke, d_release, _p_messbuf, _e);
IF  ( _e <> e_ok )
THEN
    a07_b_put_error (acv, _e, 1)
ELSE
    WITH sparr.px[ 2 ]^.sreskey DO
        IF  ( res_actres = 0 )
        THEN
            a07_b_put_error (acv, e_no_next_record, 1)
        ELSE
            (* there is at least one result record *)
            BEGIN
            k720_maxresult_get( _p_messbuf^.smessblock.mbr_mess_block.
                  mb_data^.mbp_buf, res_rowno, _rowno, _b_err );
            IF  (_rowno > 0) AND (_rowno <> csp_maxint4) AND ( mtype = mm_last )
            THEN
                BEGIN
                mtype := mm_last_rowno;
                pos   := _rowno;
                END;
            (*ENDIF*) 
            _fill_ret_segm := true;
            IF  ( acv.a_ex_kind = only_executing )
            THEN
                WITH sparr.px[ 1 ]^.sparsinfo DO
                    BEGIN
                    IF  ( p_function_code > csp1_min_masscmd_fc )
                    THEN
                        _func_code := p_function_code - csp1_min_masscmd_fc
                    ELSE
                        _func_code := p_function_code;
                    (*ENDIF*) 
                    IF  ( _func_code <> csp1_fetch_relative_fc ) AND
                        (( _func_code < csp1_fetch_first_fc ) OR
                        ( _func_code > csp1_fetch_same_fc ))
                    THEN (* where pos of *)
                        _fill_ret_segm := false;
                    (*ENDIF*) 
                    END;
                (*ENDWITH*) 
            (*ENDIF*) 
            _lcol_lock  := false;
            _lcol_found := false;
            IF  ( res_change.cr_colcount > 0 )
            THEN
                IF  a508_lcol_found (acv, res_change)
                THEN
                    BEGIN
                    _lcol_found := true;
                    (* PTS 1111576 E.Z. *)
                    WITH _p_messbuf^.smessblock.
                         mbr_mess_block.mb_qual^.mtree DO
                        BEGIN
                        IF  (NOT (hsPermLock_egg00 in fileHandling_gg00))
                        THEN
                            BEGIN
                            _lcol_lock     := (fileHandling_gg00 <> fileHandling_gg00
                                  + [ hsTempLock_egg00 ]
                                  - [ hsWithoutLock_egg00 ]);
&                           ifdef trace
                            t01handling (ak_sem, 'lsuphandling',
                                  fileHandling_gg00);
                            t01int4     (ak_sem, 'res_build   ',
                                  ord (res_build));
                            t01int4     (ak_sem, 'lcol_lock   ',
                                  ord (_lcol_lock));
                            t01handling (ak_sem, 'lsuphandling',
                                  fileHandling_gg00);
&                           endif
                            END;
                        (*ENDIF*) 
                        END;
                    (*ENDWITH*) 
                    END;
                (*ENDIF*) 
            (*ENDIF*) 
            _mrec.resst   := res_resstate;
            _mrec.s_fetch := true;
            (* PTS 1111576 E.Z. *)
            _mrec.resnamerec := resn_rec;
            CASE mtype OF
                mm_first :
                    BEGIN
                    res_nextpos := 0;
                    _mrec.emtype := mm_next;
&                   ifdef trace
                    t01name(ak_sem, 'r_start -> r_next ');
&                   endif
                    a74_copy_twokeys (acv, res_keysbuf, res_startkeys,
                          res_nextkeys, res_resstate)
                    END;
                mm_last :
                    BEGIN
&                   ifdef trace
                    t01name(ak_sem, 'r_stop -> r_prev  ');
&                   endif
                    a74_copy_twokeys (acv, res_keysbuf, res_stopkeys,
                          res_prevkeys, res_resstate);
                    END;
                mm_last_rowno,
                mm_direct,
                mm_search :
                    BEGIN
                    IF  mtype = mm_search
                    THEN
                        BEGIN
                        IF  (res_eof         AND (pos >= 0)) OR
                            (res_first_fetch AND (pos <= 0))
                        THEN
                            a07_b_put_error (acv, e_row_not_found, 1)
                        ELSE
                            BEGIN
                            IF  (pos >= 0) AND (res_nextpos <> -1)
                            THEN
                                BEGIN
                                IF  NOT res_first_fetch
                                THEN
                                    pos := res_nextpos + pos;
                                (*ENDIF*) 
                                mtype := mm_direct;
                                END
                            ELSE
                                IF  res_prevpos <> -1
                                THEN
                                    BEGIN
                                    IF  res_eof
                                    THEN
                                        pos := res_prevpos + pos + 1
                                    ELSE
                                        pos := res_prevpos + pos;
                                    (*ENDIF*) 
                                    IF  pos <= 0
                                    THEN
                                        BEGIN
                                        res_first_fetch := true;
                                        res_nextpos := 0;
                                        res_prevpos := 0;
                                        res_eof := false;
                                        a07_b_put_error (acv, e_row_not_found, 1)
                                        END
                                    ELSE
                                        mtype := mm_direct;
                                    (*ENDIF*) 
                                    END;
                                (*ENDIF*) 
                            (*ENDIF*) 
                            ;
&                           ifdef trace
                            t01int4 (ak_sem, 'pos         ', pos);
&                           endif
                            END;
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                    ;
&                   ifdef trace
                    t01mess2type( ak_sem, 'mytpe 2     ', mtype );
&                   endif
                    IF  mtype in [ mm_direct, mm_last_rowno ]
                    THEN
                        BEGIN
                        IF  mtype = mm_last_rowno
                        THEN
                            _mrec.imtype := mtype
                        ELSE
                            _mrec.imtype := mm_next;
                        (*ENDIF*) 
                        IF  res_first_fetch
                        THEN
                            BEGIN
                            res_nextpos := 0;
                            res_prevpos := 0;
&                           ifdef trace
                            t01name(ak_sem, 'r_start -> r_next ');
&                           endif
                            a74_copy_twokeys (acv,
                                  res_keysbuf, res_startkeys,
                                  res_nextkeys, res_resstate);
                            END;
                        (*ENDIF*) 
                        IF  pos = 0
                        THEN
                            BEGIN
                            res_first_fetch := true;
                            res_nextpos := 0;
                            res_prevpos := 0;
                            res_eof := false;
                            a07_b_put_error (acv, e_row_not_found, 1)
                            END
                        ELSE
                            BEGIN
                            IF  pos < 0
                            THEN
                                BEGIN
                                IF  ( _rowno > 0 ) AND ( _rowno <> csp_maxint4)
                                THEN
                                    BEGIN
                                    (* FETCH POS -<int> on ROWNO result set *)
                                    (* fetch from beginning of result set   *)
                                    (* could be cleverer and                *)
                                    (* analyse res_next/prevpos             *)
                                    _mrec.imtype := mm_last_rowno;
                                    _i           := -_rowno;
                                    res_nextpos  := 0;
                                    res_prevpos  := 0;
&                                   ifdef trace
                                    t01name(ak_sem, 'r_start -> r_next ');
&                                   endif
                                    a74_copy_twokeys (acv,
                                          res_keysbuf, res_startkeys,
                                          res_nextkeys, res_resstate);
                                    END
                                ELSE
                                    BEGIN
                                    _mrec.imtype := mm_last;
                                    _i := pos + pos - 1;
&                                   ifdef trace
                                    t01name(ak_sem, 'r_stop -> r_prev  ');
&                                   endif
                                    a74_copy_twokeys (acv, res_keysbuf, res_stopkeys,
                                          res_prevkeys, res_resstate);
                                    END;
                                (*ENDIF*) 
                                END
                            ELSE
                                (* pos > 0 *)
                                BEGIN
                                IF  res_nextpos <> -1
                                THEN
                                    BEGIN
                                    IF  pos > res_nextpos
                                    THEN
                                        _i := res_nextpos + 1
                                    ELSE
                                        IF  res_prevpos <> -1
                                        THEN
                                            BEGIN
                                            IF  pos > res_prevpos
                                            THEN
                                                BEGIN
                                                _i := res_prevpos + 1;
                                                res_nextpos := res_prevpos;
&                                               ifdef trace
                                                t01name(ak_sem, 'r_prev -> r_next  ');
&                                               endif
                                                a74_copy_twokeys (acv,
                                                      res_keysbuf, res_prevkeys,
                                                      res_nextkeys, res_resstate)
                                                END
                                            ELSE
                                                IF  pos - 1 <= res_prevpos - pos + 1
                                                THEN
                                                    BEGIN
                                                    _i := 1;
                                                    res_nextpos := 0;
&                                                   ifdef trace
                                                    t01name(ak_sem, 'r_start -> r_next ');
&                                                   endif
                                                    a74_copy_twokeys (acv,
                                                       res_keysbuf, res_startkeys,
                                                       res_nextkeys, res_resstate)
                                                    END
                                                ELSE
                                                    BEGIN
                                                    _mrec.imtype := mm_prev;
                                                    _i := pos+pos-res_prevpos-1;
                                                    END;
                                                (*ENDIF*) 
                                            (*ENDIF*) 
                                            END
                                        ELSE
                                            (* non valid res_prevpos *)
                                            BEGIN
                                            _i := 1;
                                            res_nextpos := 0;
&                                           ifdef trace
                                            t01name(ak_sem, 'r_start -> r_next ');
&                                           endif
                                            a74_copy_twokeys (acv,
                                                  res_keysbuf, res_startkeys,
                                                  res_nextkeys, res_resstate)
                                            END;
                                        (*ENDIF*) 
                                    (*ENDIF*) 
                                    END
                                ELSE
                                    (* non valid res_nextpos *)
                                    BEGIN
                                    _i := 1;
                                    res_nextpos := 0;
&                                   ifdef trace
                                    t01name(ak_sem, 'r_start -> r_next ');
&                                   endif
                                    a74_copy_twokeys (acv,
                                          res_keysbuf, res_startkeys,
                                          res_nextkeys, res_resstate)
                                    END;
                                (*ENDIF*) 
                                END;
                            (*ENDIF*) 
                            END;
                        (*ENDIF*) 
                        _mrec.act_cnt := pos - _i;
&                       ifdef trace
                        t01mess2type( ak_sem, 'imtype      ', _mrec.imtype );
                        t01int4 (ak_sem, '_i          ', _i);
                        t01int4 (ak_sem, 'act_cnt     ', _mrec.act_cnt);
&                       endif
                        IF  mtype = mm_last_rowno
                        THEN
                            (* for mm_last_rowno jump to the last rowno pos *)
                            _mrec.act_cnt := succ(_mrec.act_cnt);
                        (*ENDIF*) 
                        END
                    ELSE
                        BEGIN
                        (* mm_search *)
                        _i := 0;
                        IF  pos > 0
                        THEN
                            BEGIN
                            _mrec.imtype := mm_next;
                            _mrec.act_cnt := pos - 1
                            END
                        ELSE
                            BEGIN
                            _mrec.imtype := mm_prev;
                            _mrec.act_cnt := -pos + 1
                            END
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                    IF  acv.a_returncode = 0
                    THEN
                        BEGIN
                        IF  _mrec.imtype = mm_last_rowno
                        THEN
                            _mrec.emtype := mm_next
                        ELSE
                            _mrec.emtype := _mrec.imtype;
                        (*ENDIF*) 
                        _fetch_mblock.mb_trns^.trError_gg00 := e_ok;
&                       ifdef TRACE
                        t01int4 (ak_sem, 'res_nextpos ', res_nextpos);
                        t01int4 (ak_sem, 'act_cnt     ', _mrec.act_cnt);
                        t01mess2type( ak_sem, 'emtype      ', _mrec.emtype );
                        t01mess2type( ak_sem, 'imtype      ', _mrec.imtype );
&                       endif
                        _mrec.act_leng  := 0; (* PTS 1115983 *)
                        _mrec.single    := false;
                        _mrec.use_recs  := false;
                        IF  _mrec.act_cnt > 0
                        THEN
                            BEGIN
                            ak74record_fetch (acv, sparr,
                                  _p_messbuf^.smessblock.mbr_mess_block,
                                  _fetch_mblock, _mrec,
                                  _direct_retpart_move);
                            IF  ((_fetch_mblock.mb_trns^.trError_gg00 = e_no_next_record)
                                AND
                                (_mrec.imtype in [mm_next,mm_last_rowno]))
                            THEN
                                BEGIN
                                res_eof         := true;
                                res_first_fetch := false
                                END
                            (*ENDIF*) 
                            END
                        ELSE
                            _fetch_mblock.mb_trns^.trError_gg00 := e_ok;
                        (*ENDIF*) 
                        IF  _mrec.imtype in [ mm_prev, mm_last ]
                        THEN
                            BEGIN
&                           ifdef trace
                            t01name(ak_sem, 'r_prev -> r_next  ');
&                           endif
                            a74_copy_twokeys (acv,
                                  res_keysbuf, res_prevkeys,
                                  res_nextkeys, res_resstate);
                            res_nextpos := res_prevpos
                            END
                        ELSE
                            IF  _mrec.imtype in  [ mm_next, mm_last_rowno ]
                            THEN
                                BEGIN
&                               ifdef trace
                                t01name(ak_sem, 'r_next -> r_prev  ');
&                               endif
                                a74_copy_twokeys (acv,
                                      res_keysbuf, res_nextkeys,
                                      res_prevkeys, res_resstate);
                                res_prevpos := res_nextpos
                                END;
                            (*ENDIF*) 
                        (*ENDIF*) 
                        IF  _fetch_mblock.mb_trns^.trError_gg00 <> e_ok
                        THEN
                            a07_b_put_error (acv,
                                  _fetch_mblock.mb_trns^.trError_gg00, 1);
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END;
                OTHERWISE
                    BEGIN
                    END
                END;
            (*ENDCASE*) 
            ;
            (* common fetch part *)
            IF  acv.a_returncode = 0
            THEN
                BEGIN
                IF  ((mtype = mm_next) AND res_first_fetch)
                THEN
                    (* the first 'fetch next' without previous position *)
                    BEGIN
                    mtype := mm_first;
                    res_nextpos := 0;
                    END
                ELSE
                    IF  ((mtype = mm_prev) AND res_eof)
                    THEN
                        BEGIN
                        mtype := mm_last;
&                       ifdef trace
                        t01name(ak_sem, 'r_stop -> r_prev  ');
&                       endif
                        a74_copy_twokeys (acv,
                              res_keysbuf, res_stopkeys,
                              res_prevkeys, res_resstate);
                        END;
                    (*ENDIF*) 
                (*ENDIF*) 
                _mrec.emtype    := mtype;
                _mrec.use_recs  := true;
                _mrec.single    := single_fetch;
                IF  _fill_ret_segm
                THEN
                    BEGIN
                    IF  ( acv.a_curr_retpart = NIL )
                    THEN
                        a06init_curr_retpart( acv );
                    (*ENDIF*) 
                    a60rescount( acv, 1 );
                    END;
                (*ENDIF*) 
                IF  mtype = mm_same
                THEN
                    BEGIN
                    IF  res_first_fetch OR res_eof
                    THEN
                        a07_b_put_error (acv, e_current_of_needs_fetch, 1);
                    (*ENDIF*) 
                    _mrec.imtype := mm_direct;
                    IF  NOT single_fetch
                    THEN
                        BEGIN
&                       ifdef trace
                        t01name(ak_sem, 'r_prev -> r_next  ');
&                       endif
                        a74_copy_twokeys (acv, res_keysbuf,
                              res_prevkeys, res_nextkeys, res_resstate);
                        res_nextpos := res_prevpos
                        END;
                    (*ENDIF*) 
                    END
                ELSE
                    BEGIN
                    IF  mtype = mm_last_rowno
                    THEN
                        BEGIN
                        _mrec.emtype := mm_last;
                        _mrec.imtype := mm_last;
                        END
                    ELSE
                        IF  mtype in [ mm_direct, mm_search ]
                        THEN
                            IF  res_first_fetch AND NOT (sparr.px[ 2 ]^.sreskey.res_dist_optim
                                IN [ NO_DISTINCT_OPTIM_GG07,AUTO_DISTINCT_OPTIM_GG07 ])
                            THEN
                                BEGIN
                                _mrec.emtype := mm_first;
                                _mrec.imtype := mm_first
                                END
                            ELSE
                                BEGIN
                                _mrec.emtype := mm_next;
                                _mrec.imtype := mm_next;
                                END
                            (*ENDIF*) 
                        ELSE
                            _mrec.imtype := mtype;
                        (*ENDIF*) 
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
&               ifdef trace
                t01bool (ak_sem, 'single fetch', single_fetch);
                t01mess2type( ak_sem, 'imtype      ', _mrec.imtype );
                t01mess2type( ak_sem, 'emtype      ', _mrec.emtype );
                t01p2int4( ak_sem, 'res_nextpos ', res_nextpos,
                      'res_prevpos ', res_prevpos );
                t01p2bool( ak_sem, 'res_first_fe', res_first_fetch ,
                      'res_eof     ', res_eof );
&               endif
                IF  ( single_fetch )
                THEN
                    BEGIN
                    WITH _p_messbuf^.smessblock.mbr_mess_block DO
                        _output_offset :=
                              mb_st^[mb_qual^.mqual_pos].elen_var - 1;
                    (*ENDWITH*) 
                    _direct_retpart_move :=
                          (res_keylen + cgg_rec_key_offset - _output_offset = 0)
                          AND _fill_ret_segm;
&                   ifdef trace
                    t01int4 (ak_sem, 'output_offse', _output_offset);
                    t01bool (ak_sem, 'direct_ret_m', _direct_retpart_move);
&                   endif
                    _foundrecs      := 1;
                    _mrec.act_cnt   := 1;
                    _mrec.act_leng  := res_reclen - _output_offset;
                    IF  _direct_retpart_move
                    THEN
                        a06init_curr_retpart (acv);
                    (*ENDIF*) 
                    IF  ( acv.a_returncode = 0 )
                    THEN
                        ak74record_fetch (acv, sparr,
                              _p_messbuf^.smessblock.mbr_mess_block,
                              _fetch_mblock, _mrec,
                              _direct_retpart_move);
                    (*ENDIF*) 
                    IF  _fetch_mblock.mb_trns^.trError_gg00 <> e_ok
                    THEN
                        a07_b_put_error (acv,
                              _fetch_mblock.mb_trns^.trError_gg00, 1);
                    (*ENDIF*) 
                    IF  acv.a_returncode <> 0
                    THEN
                        res_useupdk := 0
                    ELSE
                        (* now we have positions on the result set *)
                        res_first_fetch := false;
                    (*ENDIF*) 
                    IF  acv.a_returncode = 0
                    THEN
                        BEGIN
                        WITH _fetch_mblock DO
                            BEGIN
                            mb_data_len := res_length - _output_offset;
                            IF  res_for_update
                            THEN
                                BEGIN
                                res_useupdk := res_upd_tabcnt;
                                SAPDB_PascalMove ('VAK74 ',   8,
                                      mb_data_size,
                                      sizeof(res_keysbuf),
                                      @mb_data^.mbp_buf,
                                      res_length - _output_offset + 1,
                                      @res_keysbuf, res_updkey.ks_pos,
                                      res_reclen - res_length,
                                      acv.a_returncode);
                                END;
                            (*ENDIF*) 
                            IF  _fill_ret_segm
                            THEN
                                BEGIN
                                IF  (res_change.cr_colcount > 0) AND
                                    (acv.a_returncode = 0)
                                THEN
                                    a60_change_results (acv, mb_data^.mbp_buf,
                                          res_change,
                                          -_output_offset, res_length);
                                (*ENDIF*) 
                                IF  (NOT _direct_retpart_move) AND
                                    (acv.a_returncode = 0)
                                THEN
                                    a60_put_result (acv, _fetch_mblock,
                                          res_keylen + cgg_rec_key_offset - _output_offset)
                                (*ENDIF*) 
                                END
                            (*ENDIF*) 
                            END;
                        (*ENDWITH*) 
                        END;
                    (*ENDIF*) 
                    END
                ELSE
                    BEGIN  (* there is 'mfetch' command *)
                    a06init_curr_retpart (acv);
                    IF  acv.a_returncode = 0
                    THEN
                        BEGIN
                        _foundrecs := 0;
                        res_useupdk := 0;
                        _i := 0;
                        (* PTS 1116917 E.Z. *)
                        _unused_leng := a73_calc_unused_space (acv);
                        IF  acv.a_init_ex_kind = only_executing
                        THEN
                            (* PTS 1000479 E.Z. *)
                            IF  sparr.px[ 1 ]^.sparsinfo.p_resinfolen < 0
                            THEN
                                BEGIN
                                _col_no := -sparr.px[ 1 ]^.sparsinfo.p_resinfolen;
                                IF  _col_no > res_outcolno
                                THEN
                                    _col_no := res_outcolno;
                                (*ENDIF*) 
                                a73_infolen_get (acv, _col_no, _mrec.act_leng)
                                END
                            ELSE
                                _mrec.act_leng := sparr.px[ 1 ]^.sparsinfo.p_resinfolen
                            (*ENDIF*) 
                        ELSE
                            _mrec.act_leng := res_length - res_keylen - cgg_rec_key_offset;
                        (*ENDIF*) 
                        (* PTS 1106648 E.Z. *)
                        IF  NOT (_mrec.imtype in [ mm_prev, mm_last ])
                        THEN
                            BEGIN
                            _direct_retpart_move := true;
                            _unused_leng := _unused_leng - (res_reclen - res_length);
                            END;
                        (*ENDIF*) 
                        IF  _unused_leng < _mrec.act_leng
                        THEN
                            _cnt := 1
                        ELSE
                            _cnt := _unused_leng DIV _mrec.act_leng;
                        (*ENDIF*) 
                        IF  _cnt > mfetch_count
                        THEN
                            _cnt := mfetch_count;
                        (* PTS 1119953 E.Z. *)
                        (*ENDIF*) 
                        IF  (res_for_update AND
                            (mfetch_count = 1))
                        THEN
                            _mrec.act_leng := _mrec.act_leng + res_reclen - res_length;
                        (*ENDIF*) 
                        IF  ((_mrec.imtype in [ mm_last, mm_prev ])
                            AND (_mrec.act_leng < _unused_leng))
                        THEN
                            acv.a_curr_retpart^.sp1p_buf_len :=
                                  acv.a_curr_retpart^.sp1p_buf_len + _cnt * _mrec.act_leng;
                        (*ENDIF*) 
                        _fetch_mblock.mb_trns^.trError_gg00 := e_ok;
&                       ifdef trace
                        t01int4 (ak_sem, '_cnt        ', _cnt);
&                       endif
                        (* if we do not copy results direct to return part *)
                        (* it can be the case that we need some kb orders  *)
                        (* with small usable space in messblock            *)
                        REPEAT
                            (*  h.b. *)
                            IF  _direct_retpart_move
                            THEN
                                _mrec.act_cnt := _cnt - _foundrecs
                            ELSE
                                BEGIN
                                _mrec.act_cnt :=
                                      (acv.a_mblock.mb_data_size -
                                      _p_messbuf^.smessblock.mbr_mess_block.mb_data_len)
                                      DIV _mrec.act_leng;
                                IF  _mrec.act_cnt > _cnt - _foundrecs
                                THEN
                                    _mrec.act_cnt := _cnt - _foundrecs
                                (*ENDIF*) 
                                END;
                            (*ENDIF*) 
                            ak74record_fetch (acv, sparr,
                                  _p_messbuf^.smessblock.mbr_mess_block,
                                  _fetch_mblock, _mrec,
                                  _direct_retpart_move);
                            IF  _foundrecs = 0
                            THEN
                                (* initializing after first loop *)
                                BEGIN
                                _mrec.s_fetch := false;
                                IF  _fetch_mblock.mb_qual^.mf_desc.m_cnt = 0
                                THEN
                                    a07_b_put_error (acv, e_row_not_found, 1);
                                (*ENDIF*) 
                                IF  (_mrec.imtype in [ mm_first, mm_direct ])
                                THEN
                                    (* now fetch next records *)
                                    _mrec.imtype := mm_next
                                ELSE
                                    IF  _mrec.imtype = mm_last
                                    THEN
                                        (* now fetch previous records *)
                                        _mrec.imtype := mm_prev;
                                    (*ENDIF*) 
                                (*ENDIF*) 
                                END;
                            (*ENDIF*) 
                            IF  ((acv.a_returncode = 0) AND
                                (_fetch_mblock.mb_trns^.trError_gg00 = e_ok))
                            THEN
                                BEGIN
                                IF  (res_for_update AND (_cnt = 1))
                                THEN
                                    BEGIN
                                    res_useupdk := res_upd_tabcnt;
                                    (* PTS 1119953 E.Z. *)
                                    SAPDB_PascalMove ('VAK74 ',   9,
                                          _fetch_mblock.mb_data_size,
                                          sizeof(res_keysbuf),
                                          @_fetch_mblock.mb_data^.mbp_buf,
                                          _mrec.act_leng - res_reclen + res_length + 1,
                                          @res_keysbuf, res_updkey.ks_pos,
                                          res_reclen - res_length,
                                          acv.a_returncode);
                                    END;
                                (*ENDIF*) 
                                IF  (res_change.cr_colcount > 0) AND
                                    (acv.a_returncode = 0)
                                THEN
                                    FOR _i := 1 TO
                                          _fetch_mblock.mb_qual^.mf_desc.m_cnt DO
                                        a60_change_results (acv,
                                              _fetch_mblock.mb_data^.mbp_buf,
                                              res_change,
                                              (_i-1) * _mrec.act_leng-res_keylen-cgg_rec_key_offset,
                                              cgg_rec_key_offset+res_keylen+_mrec.act_leng);
                                    (*ENDFOR*) 
                                (*ENDIF*) 
                                IF  (_mrec.act_leng > _unused_leng) AND
                                    (acv.a_returncode = 0)
                                THEN
                                    (* PTS 1116801 E.Z. *)
                                    a07_b_put_error (acv, e_stack_overflow, 1)
                                ELSE
                                    IF  _mrec.imtype in [ mm_prev, mm_last ]
                                        (* and NOT _direct_retpart_move *)
                                    THEN
                                        (* reverse result order *)
                                        BEGIN
                                        _i := 1;
                                        WHILE (_i <= _fetch_mblock.
                                              mb_qual^.mf_desc.m_cnt) AND
                                              (acv.a_returncode = 0) DO
                                            BEGIN
                                            SAPDB_PascalMove ('VAK74 ',  10,
                                                  _fetch_mblock.mb_data_size,
                                                  acv.a_curr_retpart^.sp1p_buf_size,
                                                  @_fetch_mblock.mb_data^.mbp_buf,
                                                  (_i-1)*_mrec.act_leng+1,
                                                  @acv.a_curr_retpart^.sp1p_buf,
                                                  acv.a_curr_retpart^.sp1p_buf_len
                                                  - (_foundrecs+_i)* _mrec.act_leng+1,
                                                  _mrec.act_leng,
                                                  acv.a_returncode);
                                            _i := succ(_i)
                                            END
                                        (*ENDWHILE*) 
                                        END
                                    ELSE
                                        BEGIN
&                                       ifdef trace
                                        t01int4 (ak_sem, 'MOVE-LEN    ',
                                              _fetch_mblock.mb_qual^.
                                              mf_desc.m_cnt*_mrec.act_leng);
                                        t01moveobj (ak_sem, _fetch_mblock.mb_data^.mbp_buf,
                                              1, _fetch_mblock.mb_qual^.
                                              mf_desc.m_cnt*_mrec.act_leng);
&                                       endif
                                        IF  NOT _direct_retpart_move
                                        THEN
                                            a06retpart_move (acv,
                                                  @_fetch_mblock.mb_data^.mbp_buf,
                                                  _fetch_mblock.mb_qual^.
                                                  mf_desc.m_cnt*_mrec.act_leng);
                                        (*ENDIF*) 
                                        END;
                                    (*ENDIF*) 
                                (*ENDIF*) 
                                _foundrecs := _foundrecs +
                                      _fetch_mblock.mb_qual^.mf_desc.m_cnt;
                                END;
                            (*ENDIF*) 
                        UNTIL
                            ((_foundrecs = _cnt) OR
                            (* no more results from file *)
                            (_mrec.act_cnt > _fetch_mblock.mb_qual^.mf_desc.m_cnt) OR
                            (acv.a_returncode <> 0) OR
                            (_fetch_mblock.mb_trns^.trError_gg00 = e_no_next_record));
                        (*ENDREPEAT*) 
                        IF  acv.a_returncode = 0
                        THEN
                            BEGIN
                            IF  (_fetch_mblock.mb_trns^.trError_gg00 = e_no_next_record)
                                OR
                                (_mrec.act_cnt > _fetch_mblock.mb_qual^.mf_desc.m_cnt)
                            THEN
                                acv.a_curr_retpart^.sp1p_attributes :=
                                      [ sp1pa_last_packet ];
                            (*ENDIF*) 
                            res_first_fetch := false;
                            IF  ((_mrec.imtype in [ mm_last, mm_prev ])
                                AND (acv.a_curr_retpart^.sp1p_buf_len > (_foundrecs * _mrec.act_leng)))
                            THEN
                                SAPDB_PascalOverlappingMove ('VAK74 ',  11,
                                      acv.a_curr_retpart^.sp1p_buf_size,
                                      acv.a_curr_retpart^.sp1p_buf_size,
                                      @acv.a_curr_retpart^.sp1p_buf,
                                      acv.a_curr_retpart^.sp1p_buf_len
                                      - _foundrecs * _mrec.act_leng + 1,
                                      @acv.a_curr_retpart^.sp1p_buf, 1,
                                      _foundrecs * _mrec.act_leng,
                                      acv.a_returncode);
                            (*ENDIF*) 
                            acv.a_curr_retpart^.sp1p_buf_len := _foundrecs * _mrec.act_leng;
                            END;
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                ;
                (* common part for fetch and mfetch *)
&               ifdef TRACE
                t01int4 (ak_sem, 'act_leng    ', _mrec.act_leng);
&               endif
                (* PTS 1105717 E.Z. *)
                IF  _fill_ret_segm AND
                    (acv.a_returncode = 0)
                THEN
                    BEGIN
                    IF  acv.a_long_desc_pos > 0
                    THEN
                        BEGIN
                        _start_pos :=  - (res_keylen + cgg_rec_key_offset);   (* h.b. 1995-05-31 *)
                        IF  _lcol_found
                        THEN
                            (* PTS 1111576 E.Z. *)
                            a508_lget_long_columns (acv, res_change,
                                  _lcol_lock, _foundrecs, _mrec.act_leng, _start_pos)
                                  (* PTS 1111576 E.Z. *)
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                    IF  acv.a_curr_retpart <> NIL
                    THEN
                        IF  (acv.a_curr_retpart^.sp1p_buf_len > 0) OR NOT single_fetch
                        THEN
                            a06finish_curr_retpart (acv, sp1pk_data, _foundrecs);
                        (* PTS 1116801 E.Z. *)
                        (* PTS 1105717 E.Z. *)
                        (*ENDIF*) 
                    (*ENDIF*) 
                    IF  ((_mrec.act_cnt > _fetch_mblock.mb_qual^.mf_desc.m_cnt)
                        AND NOT single_fetch) AND (_mrec.imtype = mm_next)
                    THEN
                        a60rescount (acv, res_nextpos - 1)
                    ELSE
                        a60rescount (acv, res_nextpos)
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END;
        (*ENDIF*) 
    (*ENDWITH*) 
(*ENDIF*) 
END;
 
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
.PA 
