.ad 8
.bm 8
.fm 4
.bt $Copyright (c) 2000-2005 SAP AG$$Page %$
.tm 12
.hm 6
.hs 3
.tt 1 $SQL$Project Distributed Database System$VPR12$
.tt 2 $$$
.TT 3 $$Fetch Optimization Call Interface$$2001-03-16$
***********************************************************
.nf
 
 .nf
 
 .nf

    ========== licence begin  GPL
    Copyright (c) 2000-2005 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

 
.fo
 
 
.fo
.nf
.sp
MODULE  : Fetch-Optimierung
=========
.sp
Purpose : Fetch Optimization Call Interface
          Ffetch Kommandos werden in mfetch umgesetzt und
          abgearbeitet. (Call-Interface).
.CM *-END-* purpose -------------------------------------
.sp
.cp 3
Define  :
 
        PROCEDURE
              p12baparsen  (VAR sqcca : sqlcatype;
                    VAR gae : sqlgaentry;
                    VAR sqcda     : sqldavrec;
                    VAR cmdfetch : tsp00_Int2;
                    VAR reclen   : tsp00_Int4;
                    VAR parsid   : tpr_parsid);
 
        PROCEDURE
              p12bexecute  (VAR sqcca : sqlcatype;
                    VAR gae : sqlgaentry;
                    VAR sqcda     : sqldavrec;
                    VAR cmdfetch : tsp00_Int2;
                    VAR fa_entry : sqlfaentry;
                    VAR parsid   : tpr_parsid;
                    sqcrowcount   : tsp00_Int4);
 
        PROCEDURE
              p12baexecute  (VAR sqcca : sqlcatype;
                    VAR gae : sqlgaentry;
                    VAR stmparsid  : tpr_parsid);
 
        PROCEDURE
              p12bgetmfetch  (VAR sqcca : sqlcatype;
                    VAR gae : sqlgaentry;
                    VAR sqcda     : sqldavrec;
                    VAR fa_entry : sqlfaentry;
                    sqcrowcount   : tsp00_Int4);
 
.CM *-END-* define --------------------------------------
.sp;.cp 3
Use     :
 
        FROM
              RTE_driver : VEN102;
 
        PROCEDURE
              sqlabort;
 
      ------------------------------ 
 
        FROM
              Precompiler_Runtime_Routinen  : VPR08;
 
        PROCEDURE
              p08runtimeerror (VAR sqlca : sqlcatype;
                    VAR sqlcxa : sqlcxatype;
                    error : tpr_runtime_errors);
 
      ------------------------------ 
 
        FROM
              SQLDB-Auftrags-Schnittstelle : VPR03;
 
        PROCEDURE
              p03find_part  (sqlrap : sqlrapointer;
                    part_kind        : tsp1_part_kind;
                    VAR part_ptr     : tsp1_part_ptr);
 
        PROCEDURE
              p03gselparsid  (sqlrap : sqlrapointer;
                    sqlemp : sqlempointer;
                    VAR parsid : tpr_parsid;
                    VAR SessionID : tpr00_SessionID);
 
      ------------------------------ 
 
        FROM
              C-Type-Checker-Module  : VPR102;
 
        PROCEDURE
              p03dynalloc (VAR desc: tpr_sqlmdesc);
 
        PROCEDURE
              p04trint4(sqlrap : sqlrapointer; szStr : tsp00_Name; cbValue : tsp00_Int4);
&       ifdef TRACE
 
        PROCEDURE
              m90int2 (layer : tsp00_ToolLayer;
                    nam : tsp00_Sname;
                    int : tsp00_Int2);
 
        PROCEDURE
              m90int4 (layer : tsp00_ToolLayer;
                    nam : tsp00_Sname;
                    int : tsp00_Int4);
 
        PROCEDURE
              m90int (layer : tsp00_ToolLayer;
                    nam : tsp00_Sname;
                    int : integer);
 
        PROCEDURE
              m90name (layer : tsp00_ToolLayer;
                    nam : tsp00_Name);
 
        PROCEDURE
              m90identifier (
                    layer : tsp00_ToolLayer;
                    nam   : tsp00_KnlIdentifier);
 
        PROCEDURE
              m90buf1 (layer : tsp00_ToolLayer;
                    VAR buf :  tpr_parsid;
                    pos_anf : integer;
                    pos_end : integer);
&       endif
 
      ------------------------------ 
 
        FROM
              Fetch-Optimierung   : VPR01b;
 
        PROCEDURE
              p01mfentryinit  (VAR sqlca : sqlcatype;
                    VAR index   : integer);
 
        PROCEDURE
              p01bnewmfetch (VAR sqlca : sqlcatype;
                    VAR sqlxa : sqlcxatype;
                    VAR ga : sqlgaentry;
                    VAR fa_entry : sqlfaentry;
                    sqcrowcount   : tsp00_Int4);
 
        PROCEDURE
              p01bsearchnextrec (VAR sqlca : sqlcatype;
                    VAR sqlxa : sqlcxatype;
                    VAR ga : sqlgaentry;
                    kae    : sqlkaentry_ptr;
                    VAR faentry : sqlfaentry;
                    VAR mfindex : tsp00_Int2;
                    VAR cmdfetch : tsp00_Int2;
                    sqcrowcount   : tsp00_Int4);
 
        PROCEDURE
              p01bafterexecute (VAR sqlca : sqlcatype;
                    VAR sqlxa : sqlcxatype;
                    VAR ga : sqlgaentry;
                    kae    : sqlkaentry_ptr;
                    ore : sqlorentry_ptr;
                    VAR parsid: tpr_parsid);
 
      ------------------------------ 
 
        FROM
              Runtime-Stringroutinen   : VPR05;
 
        PROCEDURE
              p05nextsymbol (VAR buf : tsp00_MoveObj;
                    buflen  : tsp00_Int4;
                    pasanf     : tsp00_Int4;
                    VAR sympos : tsp00_Int4;
                    VAR symlen : tsp00_Int4;
                    VAR symb   : tpr_symbol);
 
        FUNCTION
              p05chtoint4 (VAR buf : tsp00_MoveObj;
                    pos : integer;
                    len : integer) : tsp00_Int4;
 
      ------------------------------ 
 
        FROM
              Packet_handling : VSP26;
 
        PROCEDURE
              s26finish_part (packet_ptr : tsp1_packet_ptr;
                    VAR finish_part      : tsp1_part);
 
        PROCEDURE
              s26new_part_init (packet_ptr : tsp1_packet_ptr;
                    VAR segm               : tsp1_segment;
                    VAR new_part_ptr       : tsp1_part_ptr);
 
        PROCEDURE
              s26find_part (VAR segm : tsp1_segment;
                    part_kind        : tsp1_part_kind;
                    VAR part_ptr     : tsp1_part_ptr);
 
      ------------------------------ 
 
        FROM
              GET-Conversions   : VSP40;
 
        PROCEDURE
              s40g4int (VAR buf : tsp00_MoveObj;
                    pos : tsp00_Int4;
                    VAR dest : tsp00_Int4;
                    VAR res : tsp00_NumError);
 
      ------------------------------ 
 
        FROM
              PUT-Conversions   : VSP41;
 
        PROCEDURE
              s41plint ( VAR buf : tsp00_MoveObj;
                    pos : tsp00_Int4;
                    len : integer;
                    frac : integer;
                    source : tsp00_Int4;
                    VAR res : tsp00_NumError);
 
        PROCEDURE
              s41p4int (
                    VAR buf : tsp00_MoveObj;
                    pos     : tsp00_Int4;
                    source  : tsp00_Int4;
                    VAR res : tsp00_NumError);
 
.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :
 
        PROCEDURE
              pr08cSearchFetch;
 
              sqlxatype    sqlcxatype
 
        PROCEDURE
              m90buf;
 
              tsp00_Buf       tsp_packet
 
        PROCEDURE
              m90buf1;
 
              tsp00_Buf       tpr_parsid
 
        PROCEDURE
              p08runtimeerror;
 
              sqlxatype    sqlcxatype
 
        PROCEDURE
              pr08cSearchfetch;
 
              sqlxatype    sqlcxatype
 
        PROCEDURE
              p01bnewmfetch;
 
              sqlxatype    sqlcxatype
 
        PROCEDURE
              p01bafterexecute;
 
              sqlxatype         sqlcxatype
 
        PROCEDURE
              p01bsearchnextrec;
 
              sqlxatype    sqlcxatype
 
.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  :
.sp
.cp 3
Created : 1986-07-07
.sp
.cp 3
.sp
.cp 3
Release :      Date : 2001-03-16
.sp
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Specification:
.sp 2
PROCEDURE  p12bbparsen :
.sp 2
Before_parsing a check is performed to determine whether the
Mfetch mechanism is to be used at all.
sqlfill1,2 (sqlkano,sqlprno is init to :=0)
sqlprno contains the <fetch-spec> (first, next ...).
.br
cmdfetch := cpr_is_true the mechanism is activated.
.sp
.sp 4
PROCEDURE   p12baparsen :
.sp 2
After_parsing, if cmdfetch = cpr_is_true a search is run for a free mfentry
which is reserved for this mfetch, i.e. the parse ID is saved.
.sp 4
PROCEDURE  p12bexecute :
.sp 2
Before_execute, cmdfetch is set to cpr_is_false.
.sp
If it is an Mfetch statement, the next record is fetched
from the saved buffer and cmdfetch := cpr_is_true is set.
If there are no more records available in the buffer
cmdfetch := cpr_is_init is set, i.e. a new mfetch must be issued.
.sp
If no entry is found then
cmdfetch := cpr_is_init is set, i.e. the first mfetch must be issued.
.sp 4
PROCEDURE  p12bgetmfetch :
.sp 2
After_execute is only called if cmdfetch = cpr_is_init is set.
.sp
The associated select parse ID is fetched from the part1
of the request segment.,
If not, the request buffer is saved in the associated
Mfentry and the first record of the buffer is moved to the
output buffer. (p01bnewmfetch).
.sp 4
PROCEDURE  p12baexecute :
.sp
Checks whether a 'close' has been issued for an mfetch
result set and releases the memory in the SQLmf
record.
.sp 2
***********************************************************
.sp 2
 
PROCEDURE  p12bbparsen :
.sp 2
Before_Parsen wird gepr?uft, ob der Mfetch-Mechanismus
?uberhaupt eingesetzt werden soll.
sqlkano und sqlprno werden auf := 0 initialisiert.
In sqlkano wird der Index dieses Kommandos in die sqlmfp^-area abgespeichert.
In sqlprno wird der fetch-spec (next, first, pos ...).
dieses Kommandos abgespeichert.
.br
cmdfetch := cpr_is_true der Mechanismus ist eingeschaltet.
.sp
.sp 4
PROCEDURE   p12baparsen :
.sp 2
Wird bei einem 'fetch' gepr?uft, ob auf der gleichen Ergebnismenge
schon ein ffetch abgesetzt wurde (Error).
ist cmdfetch = cpr_is_true liegt ein ffetch vor.
After_parsen, wenn cmdfetch = cpr_is_true wird ein freies mfentry gesucht
und f?ur dieses mfetch reseviert, d.h. die selparsid wird gerettet.
.sp
Ist noch kein Eintrag in der sqlmfp^-area f?ur die selparsid
so wird es initialisiert und sqlkano belegt.
.sp 4
PROCEDURE  p12bexecute :
.sp 2
Before_execute, cmdfetch wird auf cpr_is_false gesetzt.
.sp
Handelt es sich um ein Massen-select, soe wird falls f?ur die selparsid
schon ein Eintrad in der sqlmfp^-area existiert, ein neuer initialisiert
und sie selectno erh?oht.
.sp
Handelt es sich um ein Mfetch-Statement, wird der n?achste Record
aus dem geretteten Puffer geholt und cmdfetch := cpr_is_true gesetzt.
Ist kein Record mehr im Puffer vorhanden wird cmdfetch := cpr_is_init
gestetzt, d. h. es muss ein neues mfetch abgesetzt werden.
(p01bsearchnextrec)
.sp
Wurde noch kein Puffer geholt, d.h. es ist der erste Zugriff
wird cmdfetch := cpr_is_init gesetzt, der Auftragspuffer belegt
und die Ergebnisse anschliessend geholt.
.sp 4
PROCEDURE  p12bgetmfetch :
.sp 2
After_execute wird nur aufgerufen, wenn cmdfetch = cpr_is_init gesetzt.
.sp
Aus dem Part1 der Auftragssegment wird die zugeh?orige
Select-parsid geholt,
Der Auftragspuffer wird in dem zugeh?origen
Mfentry gerettet und der erste Record der Puffer in den
Ausgabepuffer gebracht. (p01bnewmfetch).
.sp 4
PROCEDURE  p12baexecute :
.sp
Untersucht ob ein 'close'  auf eine mfetch Ergebnismenge
abgesetzt wurde und gibt den Speicher in dem SQLmf-record
frei.
.sp 2
.CM *-END-* specification -------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Description:
.sp 2
.cm  hier input description
.nf
CONST
      mxpr_mfetch        = 18;
      mxpr_mfetchbuffer  = 18;
      mxpr_mfetchrecords = 250;  (* number records per mfetch *)
 
 
TYPE
      (* fetch optimization types  *)
 
      tpr_mfetchentry  = RECORD      (* 52 B *)
        mfInit       : tsp00_Int2;(* cpr_is_true record belegt *)
(**)    mfSelectno   : tsp00_Int2;(* zugeh. select number  *)
        mfBufinit    : tsp00_Int2;(* 0 = kein new alloc,<>0 buf exist*)
        mfBuflen     : tsp00_Int2;(* zugeh. auftrags puffer length*)
        mfRecpos     : tsp00_Int2;(* acctuelle record position im buf*)
        mfReclen     : tsp00_Int2;(* acctuelle record length im buf *)
        mfBufpointer : tpr_ptr_packet; (* pointer eines packets.   *)
        mfSelparsid  : tpr_parsid;  (* select parsid des mfetch     *)
(**)    mfPrevfaspec : tsp00_Int2; (* faspec from command before      *)
(**)    mfLastfaspec : tsp00_Int2; (* faspec cpr_fe_last if it was called *)
(**)    mfRownotfound: tsp00_Int2; (* error : cpr_is_true,                *)
(**)    mfRecposbeg  : tsp00_Int2; (* first record position in buf    *)
(**)    mfMaxselrec  : tsp00_Int4; (* max records in result:sqlerrd(3)*)
(**)    mfLastrecno  : tsp00_Int4; (* last fetch rec no to user    *)
(**)    mfBufbegno   : tsp00_Int4; (* record begin no  in buffer   *)
(**)    mfBufendno   : tsp00_Int4; (* record end no  in buffer     *)
      END;
 
      sqlmfpointer   =  RECORD
(**)       mfselcnt   :  tsp00_Int2;
           mfmfetch   :  tsp00_Int2; (* change next com to mfetch *)
           mfentry    :  array [ 1..mxpr_mfetch ] of tpr_mfetchentry;
      END;
 
      mfetchbuffer = array [ 1..mxpr_mfetchbuffer ] of sql_packet_type;
.sp 2
.CM *-END-* description ---------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.nf
.oc _/1
Structure:
 
.CM *-END-* structure -----------------------------------
.sp 2
**********************************************************
.sp
.cp 10
.nf
.oc _/1
.CM -lll-
Code    :
 
 
(*------------------------------*) 
 
PROCEDURE
      p12baparsen  (VAR sqcca : sqlcatype;
            VAR gae : sqlgaentry;
            VAR sqcda     : sqldavrec;
            VAR cmdfetch : tsp00_Int2;
            VAR reclen   : tsp00_Int4;
            VAR parsid   : tpr_parsid);
 
VAR
      i   : integer;
      found : boolean;
      selparsid  : tpr_parsid;
      kano  : tsp00_Int2;
      prno  : tsp00_Int2;
      part_ptr  : tsp1_part_ptr;
      resname   : tsp00_KnlIdentifier;
      resnamefound : boolean;
      descMaxelem : tsp00_Int4;
      (* after parsen *)
 
BEGIN
WITH sqcca, sqlrap^, sqlcxap^  DO
    (* ADIS 1001416 *)
    IF  sqlcode = 0
    THEN
        BEGIN
&       ifdef TRACE
        m90int2(pc, 'cmdfetch    ', cmdfetch);
        m90int2(pc, 'parsid (11) ',
              ord(parsid [cpr_p_precom_index]));
&       endif
        p12getsqlkano (sqcca, sqcda, kano, prno, reclen);
        found := false;
        (*********   anf 22.3.96 *********)
&       ifdef TRACE
        m90buf1 (pc, parsid, 1, mspr_parsid16);
        m90identifier (pc, sqlresn );
&       endif
        WITH sqlmfp^ DO
            IF  mfdesc.descNelem = 0
            THEN
                BEGIN
                p03dynalloc (mfdesc);
                sqlmfetch := mfdesc.descNelem;
                FOR i := 1 TO mfdesc.descMaxelem DO
                    BEGIN
                    mfentry^[i].mfBufinit := cpr_is_false;
                    mfentry^[i].mfresultname := bsp_knl_identifier;
                    END;
                (*ENDFOR*) 
                i := sqlmfetch;
                p01mfentryinit (sqcca, i);
                END;
            (*ENDIF*) 
        (*ENDWITH*) 
        IF  ((ord (parsid [cpr_p_precom_index]) in
            [csp1_p_mass_select_found,
            csp1_p_reuse_mass_select_found,
            csp1_p_mselect_found,
            csp1_p_reuse_mselect_found,
            csp1_p_select_for_update_found,
            csp1_p_reuse_update_sel_found]))
        THEN
            BEGIN
            resnamefound := FALSE;
            p03find_part (sqlrap, sp1pk_resulttablename, part_ptr);
            IF  part_ptr <> NIL
            THEN
                IF  part_ptr^.sp1p_part_header.sp1p_buf_len > 0
                THEN
                    resnamefound := TRUE;
                (*ENDIF*) 
            (*ENDIF*) 
            resname := sqlresn;
            IF  sqlresn = bsp_knl_identifier
            THEN
                resname[1] := chr (0);
            (*  select command ergname found *)
            (*ENDIF*) 
            i     := 1;
            IF  (resnamefound)
            THEN
                WHILE (i <= sqlmfetch) AND NOT found DO
                    WITH sqlmfp^, mfentry^ [i] DO
                        BEGIN
&                       ifdef TRACE
                        m90int (pc, 'i mf_resname', i);
                        m90int (pc, 'i resname   ', i);
&                       endif
                        IF  (mfresultname = resname)
                        THEN
                            BEGIN
                            found := true;
                            kano := i;
                            p12putsqlkano (sqcca, sqcda, kano, prno);
                            p01mfentryinit (sqcca, i);
                            mfSelparsid := parsid;
                            mfresultname := resname;
&                           ifdef TRACE
                            m90int (pc, 'i =resname  ', i);
                            m90int2(pc, 'mfSelectno  ', mfSelectno);
                            m90buf1 (pc, parsid, 1, mspr_parsid16);
&                           endif
                            END;
                        (*ENDIF*) 
                        i := i + 1;
                        END;
                    (*ENDWITH*) 
                (*ENDWHILE*) 
            (*  select command *)
            (*ENDIF*) 
            i     := 1;
            IF  NOT found
            THEN
                REPEAT
                    WITH sqlmfp^, mfentry^ [i] DO
                        BEGIN
                        IF   mfInit = cpr_is_false
                        THEN
                            BEGIN
                            found := true;
                            kano := i;
                            p12putsqlkano (sqcca, sqcda, kano, prno);
                            p01mfentryinit (sqcca, i);
                            mfSelparsid := parsid;
                            mfresultname := resname;
&                           ifdef TRACE
                            m90int (pc, 'i = mfresn  ', i);
                            m90int2(pc, 'mfSelectno  ', mfSelectno);
                            m90identifier (pc, mfresultname );
                            m90buf1 (pc, parsid, 1, mxpr_parsid16);
&                           endif
                            END;
                        (*ENDIF*) 
                        i := i + 1;
                        END;
                    (*ENDWITH*) 
                UNTIL
                    (i > sqlmfetch) OR (found);
                (*ENDREPEAT*) 
            (*ENDIF*) 
            IF  NOT found
            THEN
                WITH sqlmfp^ DO
                    BEGIN
                    descMaxelem := mfdesc.descMaxelem;
                    p03dynalloc (mfdesc);
                    sqlmfetch := mfdesc.descNelem;
                    FOR i := descMaxelem+1 TO mfdesc.descMaxelem DO
                        mfentry^[i].mfBufinit := cpr_is_false;
                    (*ENDFOR*) 
                    i := sqlmfetch;
                    kano := i;
                    mfentry^[i].mfBufinit := cpr_is_false;
                    p12putsqlkano (sqcca, sqcda, kano, prno);
                    p01mfentryinit (sqcca, i);
                    mfentry^[i].mfSelparsid := parsid;
                    mfentry^[i].mfresultname := resname;
                    END;
                (*ENDWITH*) 
            (*        cmdfetch := cpr_is_false; *)
            (*ENDIF*) 
            END;
        (*********   end 22.3.96 *********)
        (*ENDIF*) 
        IF   parsid [cpr_p_precom_index] = chr (csp1_p_fetch_found)
        THEN
            BEGIN
            (* nicht erlaubt ffetch , fetch aus gleicher resulttable *)
            p03gselparsid (sqlrap, sqlemp, selparsid, gae.gaKnlSessionID);
            IF  (selparsid <> cpr_parsidnull)
            THEN
                BEGIN
&               ifdef TRACE
                m90buf1 (pc, selparsid, 1, mxpr_parsid16);
&               endif
                FOR i := 1 TO sqlmfetch DO
                    WITH sqlmfp^, mfentry^ [i] DO
                        BEGIN
&                       ifdef TRACE
                        m90int2(pc, 'mfFetchget  ', mfFetchget );
                        m90int2(pc, 'mfInit      ', mfInit     );
                        m90buf1 (pc, mfSelparsid, 1, mxpr_parsid16);
&                       endif
                        IF   (mfInit = cpr_is_true)
                            AND  (mfSelparsid = selparsid)
                            AND (mfFetchget <> 0)
                        THEN
                            p08runtimeerror (sqcca, sqlcxap^,
                                  cpr_ffetch_fetch_mix_not_allowed);
                        (*ENDIF*) 
                        END;
                    (*ENDWITH*) 
                (*ENDFOR*) 
                END;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF   cmdfetch = cpr_is_true
        THEN
            BEGIN
            p03gselparsid (sqlrap, sqlemp, selparsid, gae.gaKnlSessionID);
            IF  (selparsid <> cpr_parsidnull)
            THEN
                IF  parsid [cpr_p_precom_index] = chr (csp1_p_mfetch_found)
                THEN
                    IF  ((ord(selparsid [cpr_p_precom_index]) in
                        [csp1_p_select_for_update_found, csp1_p_reuse_update_sel_found])
                        AND (sqldbmode <> cpr_kind_oracle) )
                    THEN
                        p08runtimeerror (sqcca, sqlcxap^,
                              cpr_ffetch_not_allowed);
&                   ifdef TRACE
                    (*ENDIF*) 
                (*ENDIF*) 
            (*ENDIF*) 
            m90buf1 (pc, selparsid, 1, mxpr_parsid16);
&           endif
            i     := 1;
            REPEAT
                WITH sqlmfp^, mfentry^ [i] DO
                    BEGIN
                    IF   (mfInit = cpr_is_true)
                        AND  (mfSelparsid = selparsid)
                    THEN
                        BEGIN
                        found := true;
                        kano := i;
                        p12putsqlkano (sqcca, sqcda, kano, prno);
                        END;
                    (*ENDIF*) 
                    i := i + 1;
                    END;
                (*ENDWITH*) 
            UNTIL
                (i > sqlmfetch) OR (found);
            (*ENDREPEAT*) 
            IF  NOT found
            THEN
                BEGIN
                (*  suche new entry  *)
                i     := 1;
                REPEAT
                    WITH sqlmfp^, mfentry^ [i] DO
                        BEGIN
                        IF   mfInit = cpr_is_false
                        THEN
                            BEGIN
                            found := true;
                            p01mfentryinit (sqcca, i);
                            IF  mfselcnt >= csp_maxint2
                            THEN
                                mfselcnt := 1
                            ELSE
                                mfselcnt := mfselcnt + 1;
                            (*ENDIF*) 
                            mfSelectno  := mfselcnt;
                            mfSelparsid := selparsid;
                            mfMaxselrec := -1;
                            mfPrevfaspec:= cpr_fe_empty;
                            kano := i;
                            p12putsqlkano (sqcca, sqcda, kano, prno);
&                           ifdef TRACE
                            m90int (pc, 'i apars init', i);
                            m90int2(pc, 'mfSelectno  ', mfSelectno);
                            m90int2(pc, 'mfMaxselrec ', mfMaxselrec);
                            m90int2(pc, 'mf_prevfaspe', mfPrevfaspec);
                            m90int (pc, 'sqlkano     ', kano);
                            m90int (pc, 'sqlprno     ', prno);
&                           endif
                            END;
                        (*ENDIF*) 
                        i := i + 1;
                        END;
                    (*ENDWITH*) 
                UNTIL
                    (i > sqlmfetch) OR (found);
                (*ENDREPEAT*) 
                END;
            (*ENDIF*) 
            IF   NOT found
            THEN
                p08runtimeerror (sqcca, sqlcxap^, cpr_select_parsid_missing);
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      p12bexecute (VAR sqcca : sqlcatype;
            VAR gae : sqlgaentry;
            VAR sqcda     : sqldavrec;
            VAR cmdfetch : tsp00_Int2;
            VAR fa_entry : sqlfaentry;
            VAR parsid   : tpr_parsid;
            sqcrowcount   : tsp00_Int4);
 
VAR
      i   : integer;
      ind : integer;
      ffetch_cmd : boolean;
      kano  : tsp00_Int2;
      prno  : tsp00_Int2;
      part_ptr  : tsp1_part_ptr;
      lint      : tsp00_Int4;
      res : tsp00_NumError;
      dummyka : sqlkaentry_ptr;
      (* before execute *)
 
BEGIN
&ifdef TRACE
m90int2(pc, 'cmdfetch 1  ', cmdfetch);
&endif
WITH sqcca, sqlcxap^, sqcda, sqlmfp^, fa_entry, sqlrap^ DO
    BEGIN
    p12getsqlkano (sqcca, sqcda, kano, prno, fareclen);
&   ifdef TRACE
    m90int2(pc, 'kano-vpr12  ', kano    );
    m90int2(pc, 'prno-vpr12  ', prno    );
&   endif
    cmdfetch := cpr_is_false;
    ffetch_cmd := false;
    CASE sqldbmode OF
        cpr_kind_internal :
            BEGIN
            WITH  sqcda.sqldb DO
                BEGIN
&               ifdef TRACE
                m90int2(pc, 'sqlloop adab', sqlloop  );
&               endif
                IF  sqlloop = 0
                THEN
                    ffetch_cmd := true;
                (*ENDIF*) 
                END;
            (*ENDWITH*) 
            END;
        cpr_kind_db2 :
            WITH  sqcda.db2 DO
                BEGIN
                IF  sqlloop = 0
                THEN
                    ffetch_cmd := true;
                (*ENDIF*) 
                END;
            (*ENDWITH*) 
        cpr_kind_oracle, cpr_kind_sapr3 :
            WITH  sqcda.orada DO
                BEGIN
&               ifdef TRACE
                m90int2(pc, 'sqlloop orac', sqlloop  );
&               endif
                IF  sqlloop = 0
                THEN
                    ffetch_cmd := true;
                (*ENDIF*) 
                END;
            (*ENDWITH*) 
        OTHERWISE:
            BEGIN
            WITH  sqcda.sqldb DO
                BEGIN
                IF  sqlloop = 0
                THEN
                    ffetch_cmd := true;
                (*ENDIF*) 
                END;
            (*ENDWITH*) 
            END;
        END;
    (*ENDCASE*) 
    IF  ((ord (parsid [cpr_p_precom_index]) in
        [csp1_p_mass_select_found,
        csp1_p_reuse_mass_select_found,
        csp1_p_mselect_found,
        csp1_p_reuse_mselect_found,
        csp1_p_select_for_update_found,
        csp1_p_reuse_update_sel_found]) )
    THEN
        BEGIN
        (* l?oschen des zugeh?origen fetch eintrags *)
        FOR i := 1 TO sqlmfetch DO
            WITH sqlmfp^.mfentry^ [i] DO
                IF   (mfSelparsid = parsid)
                THEN
                    BEGIN
                    ind   := i;
                    p01mfentryinit (sqcca, ind);
                    IF  mfselcnt >= csp_maxint2
                    THEN
                        mfselcnt := 1
                    ELSE
                        mfselcnt := mfselcnt + 1;
                    (*ENDIF*) 
                    mfSelectno  := mfselcnt;
                    mfSelparsid := parsid;
                    mfMaxselrec := -1;
                    mfPrevfaspec:= cpr_fe_empty;
                    kano := i;
                    p12putsqlkano (sqcca, sqcda, kano, prno);
&                   ifdef TRACE
                    m90int (pc, 'i bexe init ', i);
                    m90int2(pc, 'mfSelectno  ', mfSelectno);
                    m90int2(pc, 'mfMaxselrec ', mfMaxselrec);
                    m90int2(pc, 'mf_prevfaspe', mfPrevfaspec);
                    m90int (pc, 'sqlkano     ', kano);
                    m90int (pc, 'sqlprno     ', prno);
&                   endif
                    END;
                (*ENDIF*) 
            (*ENDWITH*) 
        (*ENDFOR*) 
        END;
    (*ENDIF*) 
    IF   (parsid [cpr_p_precom_index] = chr (csp1_p_fetch_found))
        OR (parsid [cpr_p_precom_index] = chr (csp1_p_mfetch_found))
    THEN (* HBI *)
        IF  (prno = cpr_fe_posv) OR (prno = cpr_fe_relv)
        THEN (* datapart fuer fetch-parameter anlegen *)
            BEGIN
            (* p03find_part (sqlrap, sp1pk_data, part_ptr); *)
            s26find_part (rasegptr^, sp1pk_data, part_ptr);
            IF  part_ptr = NIL
            THEN
                WITH sqlgap^, gae DO
                    BEGIN
                    s26new_part_init (gareqptr, rasegptr^, part_ptr);
                    part_ptr^.sp1p_part_header.sp1p_part_kind
                          :=  sp1pk_data;
                    part_ptr^.sp1p_part_header.sp1p_buf_len
                          :=  mxpr_numb + 1;
                    rasegmpartptr [ord(sp1pk_data)+1] := part_ptr;
                    s26finish_part (gareqptr, part_ptr^);
                    END;
                (*ENDWITH*) 
            (*ENDIF*) 
            WITH  part_ptr^, sp1p_part_header  DO
                BEGIN
                lint := xacfetposc;
                s41p4int (sp1p_buf, 2, lint, res);
                sp1p_buf [1] := csp_defined_byte;
                END;
            (*ENDWITH*) 
            p04trint4( sqlrap, 'FETCH-PARAMETER   ', lint );
            END;
        (*ENDIF*) 
    (*ENDIF*) 
    IF   parsid [cpr_p_precom_index] = chr (csp1_p_mfetch_found)
    THEN
        IF  NOT ffetch_cmd
        THEN
            BEGIN
            (* hole first mfetch, execute *)
            (* p03find_part (sqlrap, sp1pk_resultcount, part_ptr); *)
            s26find_part (rasegptr^, sp1pk_data, part_ptr);
            IF  part_ptr = NIL
            THEN
                WITH sqlgap^, gae DO
                    BEGIN
                    s26new_part_init (gareqptr, rasegptr^, part_ptr);
                    part_ptr^.sp1p_part_header.sp1p_part_kind
                          :=  sp1pk_resultcount;
                    part_ptr^.sp1p_part_header.sp1p_buf_len
                          :=  mxpr_numb + 1;
                    rasegmpartptr [ord(sp1pk_resultcount)+1] := part_ptr;
                    s26finish_part (gareqptr, part_ptr^);
                    END;
                (*ENDWITH*) 
            (*ENDIF*) 
            WITH  part_ptr^, sp1p_part_header  DO
                BEGIN
                lint := sqcda.orada.sqlloop;
                s41p4int (sp1p_buf, 2, lint, res);
                sp1p_buf [1] := csp_defined_byte;
                END;
            (*ENDWITH*) 
            END
        ELSE
            IF  (kano = 0)
            THEN
                p08runtimeerror (sqcca, sqlcxap^, cpr_too_many_fetch_statements)
            ELSE
                WITH sqlmfp^, mfentry^ [kano], fa_entry DO
                    BEGIN
&                   ifdef TRACE
                    m90int2(pc, 'kano mfindex', kano  );
                    m90int2(pc, 'mfInit      ', mfInit);
                    m90int2(pc, 'mfPrevfaspec', mfPrevfaspec );
&                   endif
                    fapos      := 0;
                    IF  (prno = cpr_fe_posc) OR (prno = cpr_fe_relc)
                        OR (prno = cpr_fe_posv) OR (prno = cpr_fe_relv)
                    THEN
                        fapos := xacfetposc;
                    (*ENDIF*) 
                    IF   (mfInit = cpr_is_true)
                        AND  (mfPrevfaspec <> cpr_fe_empty)
                    THEN
                        BEGIN
                        (* init faentry for call-interface *)
                        (* get next record *)
                        faselectno := mfSelectno;
                        famfindex  := kano;
                        faspec     := prno;
                        fafetch    := cpr_is_false;
&                       ifdef TRACE
                        m90int (pc, 'sqlkano     ', kano);
                        m90int (pc, 'sqlprno     ', prno);
                        m90int (pc, 'fapos       ', fapos);
                        m90int4 (pc, 'xacfetposc  ', xacfetposc);
&                       endif
                        dummyka := NIL;
                        p01bsearchnextrec (sqcca, sqlcxap^,
                              gae, dummyka, fa_entry,
                              famfindex, cmdfetch, sqcrowcount );
                        END
                    ELSE
                        BEGIN
                        (* belege fapos bei fetch pos als const oder hostv *)
&                       ifdef TRACE
                        m90int (pc, 'fapos       ', fapos);
&                       endif
                        (* hole first mfetch, execute *)
                        cmdfetch := cpr_is_init;
                        (*p03find_part (sqlrap, sp1pk_resultcount, part_ptr);*)
                        s26find_part (rasegptr^, sp1pk_resultcount, part_ptr);
                        IF  part_ptr <> NIL
                        THEN
                            WITH  part_ptr^, sp1p_part_header  DO
                                BEGIN
                                lint := sqcrowcount;
                                s41p4int (sp1p_buf, 2, lint, res);
                                sp1p_buf [1] := csp_defined_byte;
                                END
                            (*ENDWITH*) 
                        ELSE
                            WITH sqlgap^, gae DO
                                BEGIN
                                s26new_part_init (gareqptr, rasegptr^, part_ptr);
                                part_ptr^.sp1p_part_header.sp1p_part_kind
                                      :=  sp1pk_resultcount;
                                part_ptr^.sp1p_part_header.sp1p_buf_len
                                      := mxpr_numb + 1;
                                rasegmpartptr [ord(sp1pk_resultcount)+1]
                                      := part_ptr;
                                WITH part_ptr^, sp1p_part_header  DO
                                    BEGIN
                                    lint := sqcrowcount;
                                    s41p4int (sp1p_buf, 2, lint, res);
                                    sp1p_buf [1] := csp_defined_byte;
                                    END;
                                (*ENDWITH*) 
                                s26finish_part (gareqptr, part_ptr^);
                                END;
                            (*ENDWITH*) 
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                    END;
                (*ENDWITH*) 
            (*ENDIF*) 
        (*ENDIF*) 
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      p12bgetmfetch (VAR sqcca : sqlcatype;
            VAR gae : sqlgaentry;
            VAR sqcda     : sqldavrec;
            VAR fa_entry : sqlfaentry;
            sqcrowcount   : tsp00_Int4);
 
VAR
      kano  : tsp00_Int2;
      prno  : tsp00_Int2;
      (* after execute with  sqlrequest, sqlreceve *)
 
BEGIN
WITH sqcca, sqlrap^, sqlcxap^, sqcda, fa_entry  DO
    IF   sqlemp^.ereturncode = 0
    THEN
        BEGIN
        p12getsqlkano (sqcca, sqcda, kano, prno, fareclen);
        sqlmfp^.mfentry^[kano].mfRownotfound := cpr_is_false;
        (* init faentry for call-interface *)
        faselectno := sqlmfp^.mfentry^ [kano].mfSelectno;
        famfindex  := kano;
        faspec     := prno;
        fafetch    := cpr_is_false;
        (* fapos wurde in p12bexecute belegt *)
&       ifdef TRACE
        m90int (pc, 'sqlkano     ', kano);
        m90int (pc, 'sqlprno     ', prno);
        m90int (pc, 'fapos       ', fapos);
        m90int (pc, 'fareclen    ', fareclen);
&       endif
        p01bnewmfetch (sqcca, sqlcxap^, gae, fa_entry, sqcrowcount);
        END
&   ifdef SQLODBC
    ELSE (* HBI PTS 1102762 *)
        BEGIN
        p12getsqlkano (sqcca, sqcda, kano, prno, fareclen);
        IF  (sqlemp^.ereturncode = 100) (* ROW NOT FOUND *)
        THEN (* discard the buffer *)
            BEGIN
            sqlmfp^.mfentry^[kano].mfLastrecno := 0;
            sqlmfp^.mfentry^[kano].mfBufbegno  := 0;
            sqlmfp^.mfentry^[kano].mfBufendno  := 0;
            END
        (*ENDIF*) 
        END
    (*ENDIF*) 
(*ENDWITH*) 
&endif (* SQLODBC *)
END;
 
(*------------------------------*) 
 
PROCEDURE
      p12baexecute (VAR sqcca : sqlcatype;
            VAR gae : sqlgaentry;
            VAR stmparsid : tpr_parsid);
 
VAR
      selparsid  : tpr_parsid;
      part_ptr  : tsp1_part_ptr;
      i : integer;
      dummyka : sqlkaentry_ptr;
      dummyore : sqlorentry_ptr;
 
BEGIN
WITH sqcca, sqlrap^, sqlcxap^, sqlemp^  DO
    BEGIN
    IF   (ereturncode = 0)
        OR  (ereturncode = 100)
    THEN
        BEGIN
&       ifdef TRACE
        m90int2(pc, 'parsid (11) ',
              ord(stmparsid [cpr_p_precom_index]));
&       endif
        IF   stmparsid [cpr_p_precom_index] = chr (csp1_p_fetch_found)
        THEN
            BEGIN
            (* nicht erlaubt ffetch , fetch aus gleicher resulttable *)
            p03gselparsid (sqlrap, sqlemp, selparsid, gae.gaKnlSessionID);
            IF  (selparsid <> cpr_parsidnull)
            THEN
&               ifdef TRACE
                m90buf1 (pc, selparsid, 1, 12);
&           endif
            (*ENDIF*) 
            FOR i := 1 TO sqlmfetch DO
                WITH sqlmfp^, mfentry^ [i] DO
                    BEGIN
&                   ifdef TRACE
                    m90int2(pc, 'mfFetchget  ', mfFetchget );
                    m90int2(pc, 'mfInit      ', mfInit     );
                    m90buf1 (pc, mfSelparsid, 1, 12);
&                   endif
                    IF   (mfInit = cpr_is_true)
                        AND  (mfSelparsid = selparsid)
                        AND (mfFetchget <> 0)
                    THEN
                        p08runtimeerror (sqcca, sqlcxap^,
                              cpr_ffetch_fetch_mix_not_allowed);
                    (*ENDIF*) 
                    END;
                (*ENDWITH*) 
            (*ENDFOR*) 
            END;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF   (ereturncode = 0)
        OR  (ereturncode = 100)
    THEN
        BEGIN
        dummyka := NIL;
        dummyore := NIL;
        p01bafterexecute (sqcca, sqcca.sqlcxap^,
              gae, dummyka, dummyore, stmparsid);
        END;
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      p12getsqlkano (VAR sqcca : sqlcatype;
            VAR sqcda     : sqldavrec;
            VAR kano     : tsp00_Int2;
            VAR prno     : tsp00_Int2;
            VAR recleno  : tsp00_Int4);
 
BEGIN
WITH sqcca, sqcda DO
    CASE sqldbmode OF
        cpr_kind_internal :
            BEGIN
            WITH  sqcda.sqldb DO
                BEGIN
                kano := sqlkano;
                prno := sqlprno;
                recleno := sqlrow.oreclen;
                END;
            (*ENDWITH*) 
            END;
        cpr_kind_db2 :
            WITH  sqcda.db2 DO
                BEGIN
                kano := sqlkano;
                prno := sqlprno;
                recleno := sqlrow.oreclen;
                END;
            (*ENDWITH*) 
        cpr_kind_oracle, cpr_kind_sapr3 :
            WITH  sqcda.orada DO
                BEGIN
                kano := sqlkano;
                prno := sqlprno;
                recleno := sqlrow.oreclen;
                END;
            (*ENDWITH*) 
        OTHERWISE:
            BEGIN
            kano := 0;
            prno := 0;
            recleno := 0;
            END;
        END;
    (*ENDCASE*) 
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      p12putsqlkano (VAR sqcca : sqlcatype;
            VAR sqcda     : sqldavrec;
            VAR kano     : tsp00_Int2;
            VAR prno     : tsp00_Int2);
 
BEGIN
WITH sqcca, sqcda DO
    CASE sqldbmode OF
        cpr_kind_internal :
            BEGIN
            WITH  sqcda.sqldb DO
                BEGIN
                sqlkano := kano;
                sqlprno := prno;
                END;
            (*ENDWITH*) 
            END;
        cpr_kind_db2 :
            WITH  sqcda.db2 DO
                BEGIN
                sqlkano := kano;
                sqlprno := prno;
                END;
            (*ENDWITH*) 
        cpr_kind_oracle, cpr_kind_sapr3 :
            WITH  sqcda.orada DO
                BEGIN
                sqlkano := kano;
                sqlprno := prno;
                END;
            (*ENDWITH*) 
        OTHERWISE:
            BEGIN
            END;
        END;
    (*ENDCASE*) 
(*ENDWITH*) 
END;
 
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
.PA 
