.ad 8
.bm 8
.fm 4
.bt $Copyright (c) 2000-2004 SAP AG$$Page %$
.tm 12
.hm 6
.hs 3
.tt 1 $SQL$Project Distributed Database System$VBD36$
.tt 2 $$$
.tt 3 $JuergenP$qualified_records$$1999-06-07$
***********************************************************
.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
.nf
.sp
Module  : qualified_records
=========
.sp
Purpose : scanning leaves for qualified primary records
.CM *-END-* purpose -------------------------------------
.sp
.cp 3
Define  :
 
        PROCEDURE
              b36nqual_from_tree (VAR RecKey : tsp00_Key;
                    VAR RecKeyLen    : tsp00_Int2;
                    VAR StopKey      : tsp00_Key;
                    StopKeyLen       : tsp00_Int4;
                    recbuf_size      : tsp00_Int4;
                    recbuf_ptr       : tsp00_MoveObjPtr;
                    VAR recbuf_pos   : tsp00_Int4;
                    VAR sel          : tgg00_SelectFieldsParam;
                    VAR stack_desc   : tgg00_StackDesc;
                    VAR current      : tbd_current_tree;
                    VAR cur_res_cnt  : integer;
                    VAR unqualified  : boolean;
                    VAR granted_lock : tgg00_LockReqMode;
                    VAR NodeUnlocked : tsp00_PageNo);
 
        PROCEDURE
              b36pqual_from_tree (VAR RecKey : tsp00_Key;
                    VAR RecKeyLen    : tsp00_Int2;
                    VAR StopKey      : tsp00_Key;
                    StopKeyLen       : tsp00_Int4;
                    recbuf_size      : tsp00_Int4;
                    recbuf_ptr       : tsp00_MoveObjPtr;
                    VAR recbuf_pos   : tsp00_Int4;
                    VAR sel          : tgg00_SelectFieldsParam;
                    VAR stack_desc   : tgg00_StackDesc;
                    VAR current      : tbd_current_tree;
                    VAR cur_res_cnt  : integer;
                    VAR unqualified  : boolean;
                    VAR granted_lock : tgg00_LockReqMode;
                    VAR NodeUnlocked : tsp00_PageNo);
 
.CM *-END-* define --------------------------------------
.sp;.cp 3
Use     :
 
        FROM
              error_text_handling : VBD06;
 
        PROCEDURE
              b06write_filename_and_root (VAR file_id : tgg00_FileId);
 
        PROCEDURE
              b06dump_bad_page (pid : tsp00_TaskId;
                    page_type_flag : char;
                    file_ext       : tsp00_C4;
                    bad_pno        : tsp00_Int4;
                    buf_ptr        : tbd_nodeptr;
                    curr_buf_cnt   : integer);
 
      ------------------------------ 
 
        FROM
              nodehandling : VBD13;
 
        PROCEDURE
              bd13GetNode (VAR Current : tbd_current_tree;
                    Pno          : tsp00_PageNo;
                    PageLockMode : tbd00_PageLockMode;
                    NodeReq      : tbd_node_request;
                    VAR Nptrs    : tbd_node_ptrs);
 
        PROCEDURE
              b13r_release_node (VAR nptr : tbd_node_ptrs;
                    VAR current : tbd_current_tree;
                    lru_info    : tbd_lru_info);
 
      ------------------------------ 
 
        FROM
              systembufferinterface : VBD20;
 
        FUNCTION
              bd20IsPageRequested (
                    cbptr : tbd_nodeptr ) : boolean;
 
      ------------------------------ 
 
        FROM
              treehandling : VBD30;
 
        PROCEDURE
              bd30GetSubTree (
                    VAR current : tbd_current_tree;
                    indexPageNo : tsp00_PageNo);
 
        PROCEDURE
              bd30ReleaseSubTree(
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              bd30SearchRecord(
                    VAR current      : tbd_current_tree;
                    VAR recKey       : tsp00_Key;
                    recKeyLen        : tsp00_Int4;
                    VAR nptr         : tbd_node_ptrs;
                    VAR recIndex     : tsp00_Int4;
                    VAR neighbs      : tbd_neighbors;
                    VAR searchResult : tbd_searchresult);
 
      ------------------------------ 
 
        FROM
              leafhandling         : VBD31;
 
        PROCEDURE
              b31prev_search (VAR reckey : tsp00_Key;
                    KeyLen        : tsp00_Int4;
                    VAR nptr      : tbd_node_ptrs;
                    VAR index     : integer;
                    VAR prevLeafPage  : tsp00_PageNo;
                    VAR current   : tbd_current_tree);
 
        PROCEDURE
              b31next_search (
                    VAR nptr    : tbd_node_ptrs;
                    VAR index   : integer;
                    VAR current : tbd_current_tree);
 
      ------------------------------ 
 
        FROM
              ref_statistic : VBD73;
 
        PROCEDURE
              b73cmd_count (statement_kind : tgg00_RefInfoIndex);
 
      ------------------------------ 
 
        FROM
              Configuration_Parameter : VGG01;
 
        PROCEDURE
              g01key_and_len_assign (VAR source_key : tsp00_Key;
                    source_key_len     : tsp00_Int4;
                    VAR target_key     : tsp00_Key;
                    VAR target_key_len : tsp00_Int2;
                    VAR e              : tgg00_BasisError);
 
        PROCEDURE
              g01opmsg (msg_prio : tsp3_priority;
                    msg_type  : tsp3_msg_type;
                    msg_no    : tsp00_Int4;
                    msg_label : tsp00_C8;
                    msg_text  : tsp00_C24;
                    msg_value : tsp00_Int4);
 
      ------------------------------ 
 
        FROM
              Kernel_move_and_fill : VGG101;
 
        PROCEDURE
              SAPDB_PascalFill (
                    mod_id      : tsp00_C6;
                    mod_num     : tsp00_Int4;
                    obj_upb     : tsp00_Int4;
                    obj         : tsp00_MoveObjPtr;
                    obj_pos     : tsp00_Int4;
                    length      : tsp00_Int4;
                    fillchar    : char;
                    VAR e       : tgg00_BasisError);
 
        PROCEDURE
              SAPDB_PascalMove (
                    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);
 
        PROCEDURE
              g10mv (
                    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);
 
        PROCEDURE
              s10mv (
                    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);
 
      ------------------------------ 
 
        FROM
              KB_transaction : VKB53;
 
        PROCEDURE
              k53row_lock_by_key (VAR t : tgg00_TransContext;
                    VAR FileId      : tgg00_FileId;
                    VAR k           : tsp00_Key;
                    KeyLen          : tsp00_Int4;
                    MessType        : tgg00_MessType;
                    ResultCount     : tsp00_Int4;
                    VAR GrantedMode : tgg00_LockReqMode);
 
      ------------------------------ 
 
        FROM
              KB_get : VKB71;
 
        PROCEDURE
              k71col_select(VAR t   : tgg00_TransContext;
                    VAR sel         : tgg00_SelectFieldsParam;
                    VAR stack_desc  : tgg00_StackDesc;
                    VAR n           : tgg00_Rec;
                    VAR unqualified : boolean);
 
      ------------------------------ 
 
        FROM
              RTE-Extension-30 : VSP30;
 
        PROCEDURE
              s30cmp (VAR buf1   : tsp00_Key;
                    fieldpos1    : tsp00_Int4;
                    fieldlength1 : tsp00_Int4;
                    VAR buf2     : tsp00_Key;
                    fieldpos2    : tsp00_Int4;
                    fieldlength2 : tsp00_Int4;
                    VAR l_result : tsp00_LcompResult);
&       ifdef TRACE
 
      ------------------------------ 
 
        FROM
              Test_Procedures : VTA01;
 
        PROCEDURE
              t01p2int4 (debug : tgg00_Debug;
                    nam_1 : tsp00_Sname;
                    int_1 : tsp00_Int4;
                    nam_2 : tsp00_Sname;
                    int_2 : tsp00_Int4);
 
        PROCEDURE
              t01basis_error (debug : tgg00_Debug;
                    nam   : tsp00_Sname;
                    b_err : tgg00_BasisError);
 
        PROCEDURE
              t01bool (debug : tgg00_Debug;
                    nam      : tsp00_Sname;
                    curr_bool: boolean);
&       endif
 
.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :
 
        PROCEDURE
              b06dump_bad_page;
 
              tbd_univ_ptr tbd_nodeptr
 
        FUNCTION
              bd20IsPageRequested;
 
              tbd02_pDataCBlock tbd_nodeptr
 
        PROCEDURE
              s30cmp;
 
              tsp00_MoveObj tsp00_Key
 
.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  :
.sp
.cp 3
Created : 1983-04-29
.sp
.cp 3
.sp
.cp 3
Release :      Date : 1999-06-07
.sp
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Specification:
 
.sp
.CM *-END-* specification -------------------------------
.sp
.sp 2
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Description:
 
.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
      b36nqual_from_tree (
            VAR RecKey       : tsp00_Key;
            VAR RecKeyLen    : tsp00_Int2;
            VAR StopKey      : tsp00_Key;
            StopKeyLen       : tsp00_Int4;
            recbuf_size      : tsp00_Int4;
            recbuf_ptr       : tsp00_MoveObjPtr;
            VAR recbuf_pos   : tsp00_Int4;
            VAR sel          : tgg00_SelectFieldsParam;
            VAR stack_desc   : tgg00_StackDesc;
            VAR current      : tbd_current_tree;
            VAR cur_res_cnt  : integer;
            VAR unqualified  : boolean;
            VAR granted_lock : tgg00_LockReqMode;
            VAR NodeUnlocked : tsp00_PageNo);
 
VAR
      auxError        : tgg00_BasisError;
      searchResult    : tbd_searchresult;
      compResult      : tsp00_LcompResult;
      cur_res_length  : tsp00_Int4;
      recPos          : tsp00_Int4;
      last_result_len : tsp00_Int4;
      init_result_len : tsp00_Int4;
      scanCount       : tsp00_Int4;
      recIndex        : tsp00_Int4;
      nextLeafPage    : tsp00_PageNo;
      nextIndexPage   : tsp00_PageNo;
      pRec            : tgg00_RecPtr;
      nptr            : tbd_node_ptrs;
      neighbs         : tbd_neighbors;
 
BEGIN
WITH current, curr_tree_id, curr_trans^, sel DO
    BEGIN
    unqualified     := false;
    nextIndexPage   := NIL_PAGE_NO_GG00;
    last_result_len := 0;
    init_result_len := sfp_result_length;
    nptr.np_ptr     := NIL;
    nptr.np_cbptr   := NIL;
    bd30SearchRecord (current, RecKey, RecKeyLen, nptr, recIndex, neighbs, searchResult);
    IF  trError_gg00 <> e_ok
    THEN
        sfp_bd_return_knf := false
    ELSE
        BEGIN
        IF  (sfp_bd_mess2_type <> mm_direct)
        THEN
            BEGIN
            IF  (searchResult = nonefound) OR ((searchResult = lastfound)
                AND (nptr.np_ptr^.nd_right = NIL_PAGE_NO_GG00))
            THEN
                trError_gg00 := e_no_next_record
            ELSE
                IF  NOT (ftsTemp_egg00 in fileType_gg00)
                THEN
                    trRteCommPtr_gg00^.file_root := fileRoot_gg00
                (*ENDIF*) 
            (*ENDIF*) 
            END
        ELSE (* sfp_bd_mess2_type == mm_direct *)
            BEGIN
            IF  searchResult <> thisfound
            THEN
                BEGIN
                trError_gg00 := e_key_not_found;
                IF  sfp_bd_return_knf
                THEN
                    BEGIN
                    IF  searchResult = nextfound
                    THEN
                        BEGIN (* trError_gg00 = e_key_not_found *)
                        trError_gg00 := e_ok;
                        recPos  := nptr.np_ptr^.nd_pointer_list[ MAX_POINTERINDEX_BD00 - recIndex ];
                        IF  bd36_RecordPositionValid (curr_trans^, curr_tree_id, nptr.np_ptr, recPos)
                        THEN
                            BEGIN
                            pRec      := @nptr.np_ptr^.nd_body [recPos];
                            RecKeyLen := pRec^.recKeyLen_gg00;
                            g10mv ('VBD36 ',   1,    
                                  sizeof (nptr.np_ptr^), sizeof (RecKey),
                                  @nptr.np_ptr^, recPos + cgg_rec_key_offset,
                                  @RecKey, 1, RecKeyLen, trError_gg00);
                            IF  trError_gg00 = e_ok
                            THEN
                                trError_gg00 := e_key_not_found
                            (*ENDIF*) 
                            END;
                        (*ENDIF*) 
                        END
                    ELSE
                        IF  (searchResult = lastfound) AND (nptr.np_ptr^.nd_right = NIL_PAGE_NO_GG00)
                        THEN
                            trError_gg00 := e_no_next_record
                        ELSE
                            sfp_bd_return_knf := false
                        (*ENDIF*) 
                    (*ENDIF*) 
                    END
                ELSE
                    sfp_bd_return_knf := false
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  (trError_gg00 = e_ok) AND
        (((sfp_bd_mess2_type = mm_next ) AND (searchResult <> nextfound)) OR
        ( (sfp_bd_mess2_type = mm_first) AND (searchResult =  lastfound)))
    THEN
        BEGIN
        b31next_search (nptr, recIndex, current);
        (*might return b_no_next_record*)
        IF  (trError_gg00 = e_ok) AND (recIndex = FIRST_REC_INDEX_BD00)
        THEN
            trRteCommPtr_gg00^.file_record_cnt :=
                  trRteCommPtr_gg00^.file_record_cnt + 1;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        IF  sfp_bd_mess2_type = mm_first
        THEN
            sfp_bd_mess2_type := mm_next;
        (*ENDIF*) 
        scanCount := 0;
        REPEAT
            unqualified := false;
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                recPos := nptr.np_ptr^.nd_pointer_list[ MAX_POINTERINDEX_BD00 - recIndex ];
                IF  bd36_RecordPositionValid (curr_trans^, curr_tree_id, nptr.np_ptr, recPos)
                THEN
                    BEGIN
                    pRec      := @nptr.np_ptr^.nd_body [recPos];
                    RecKeyLen := pRec^.recKeyLen_gg00;
                    g10mv ('VBD36 ',   2,    
                          sizeof (nptr.np_ptr^), sizeof (RecKey),
                          @nptr.np_ptr^, recPos + cgg_rec_key_offset,
                          @RecKey, 1, RecKeyLen, trError_gg00);
                    IF  sfp_bd_use_stopkey AND (trError_gg00 = e_ok)
                    THEN
                        BEGIN
                        s30cmp (RecKey, 1, RecKeyLen,
                              StopKey, 1, StopKeyLen, compResult);
                        IF  compResult = l_greater
                        THEN
                            trError_gg00 := e_no_next_record
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                pRec := @nptr.np_ptr^.nd_body [recPos];
                k71col_select (curr_trans^, sel, stack_desc, pRec^, unqualified);
&               ifdef TRACE
                t01bool        (bi, 'unqualified ', unqualified);
                t01basis_error (bi, 'b36nq/k71col', trError_gg00);
&               endif
                CASE sfp_bd_mess_type OF
                    m_update:
                        IF  (fileTfn_gg00 = tfnTable_egg00)
                        THEN
                            BEGIN
                            b73cmd_count (iupdates_rows_read);
                            IF  NOT unqualified
                            THEN
                                b73cmd_count (iupdates_rows_upd)
                            (*ENDIF*) 
                            END;
                        (*ENDIF*) 
                    m_delete:
                        IF  (fileTfn_gg00 = tfnTable_egg00)
                        THEN
                            BEGIN
                            b73cmd_count (ideletes_rows_read);
                            IF  NOT unqualified
                            THEN
                                b73cmd_count (ideletes_rows_del)
                            (*ENDIF*) 
                            END;
                        (*ENDIF*) 
                    OTHERWISE:
                        IF  (fileTfn_gg00 = tfnTable_egg00)
                            OR
                            ((fileTfn_gg00 = tfnTemp_egg00) AND
                            (fileTfnTemp_gg00 <= ttfnTempTable_egg00))
                        THEN
                            BEGIN
                            b73cmd_count (iselects_rows_read);
                            IF  NOT unqualified
                            THEN
                                b73cmd_count (iselects_rows_qual)
                            (*ENDIF*) 
                            END
                        (*ENDIF*) 
                    END;
                (*ENDCASE*) 
                IF  unqualified
                THEN
                    BEGIN
                    IF  sfp_bd_mess2_type <> mm_direct
                    THEN
                        trError_gg00 := e_ok
                    ELSE
                        IF  sfp_bd_return_knf
                        THEN
                            IF  recIndex = nptr.np_ptr^.nd_record_cnt - 1
                            THEN
                                sfp_bd_return_knf := false
                            ELSE
                                BEGIN
                                auxError     := trError_gg00;
                                trError_gg00 := e_ok;
                                recIndex     := recIndex + 1;
                                recPos       := nptr.np_ptr^.nd_pointer_list[ MAX_POINTERINDEX_BD00 - recIndex ];
                                IF  bd36_RecordPositionValid (curr_trans^, curr_tree_id, nptr.np_ptr, recPos)
                                THEN
                                    BEGIN
                                    pRec      := @nptr.np_ptr^.nd_body [recPos];
                                    RecKeyLen := pRec^.recKeyLen_gg00;
                                    g10mv ('VBD36 ',   3,    
                                          sizeof (nptr.np_ptr^), sizeof (RecKey),
                                          @nptr.np_ptr^, recPos + cgg_rec_key_offset,
                                          @RecKey, 1, RecKeyLen, trError_gg00);
                                    IF  trError_gg00 = e_ok
                                    THEN
                                        trError_gg00 := auxError
                                    (*ENDIF*) 
                                    END
                                ELSE
                                    sfp_bd_return_knf := false
                                (*ENDIF*) 
                                END
                            (*ENDIF*) 
                        (*ENDIF*) 
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  NOT unqualified
            THEN
                BEGIN
                IF  (trError_gg00 = e_buffer_limit) AND (cur_res_cnt > 0) (* TS 1120770 2003-02-21 *)
                THEN
                    sfp_m_result_cnt := cur_res_cnt
                ELSE
                    IF  trError_gg00 = e_ok
                    THEN
                        BEGIN
                        IF  NOT (ftsTemp_egg00 in curr_tree_id.fileType_gg00)
                        THEN
                            k53row_lock_by_key (curr_trans^, curr_tree_id, RecKey, RecKeyLen,
                                  sfp_bd_mess_type, sfp_act_cntresult, granted_lock);
                        (*ENDIF*) 
                        IF  trError_gg00 = e_ok
                        THEN
                            BEGIN
                            IF  recbuf_ptr <> NIL
                            THEN
                                BEGIN
                                pRec := @nptr.np_ptr^.nd_body [recPos];
                                IF  recbuf_pos + pRec^.recLen_gg00 - 1 > recbuf_size
                                THEN
                                    BEGIN (* TS 1120770 2003-02-21 *)
                                    trError_gg00     := e_buffer_limit;
                                    sfp_m_result_cnt := cur_res_cnt
                                    END
                                ELSE
                                    BEGIN
                                    g10mv ('VBD36 ',   4,    
                                          sizeof (nptr.np_ptr^), recbuf_size,
                                          @nptr.np_ptr^, recPos,
                                          @recbuf_ptr^, recbuf_pos, pRec^.recLen_gg00,
                                          trError_gg00);
                                    recbuf_pos := recbuf_pos + pRec^.recLen_gg00;
                                    IF  sfp_bd_mess_type <> m_fetch
                                    THEN
                                        IF  recbuf_pos MOD 2 = 0
                                        THEN
                                            recbuf_pos := recbuf_pos + 1
                                        (*ENDIF*) 
                                    (*ENDIF*) 
                                    END;
                                (*ENDIF*) 
                                END;
                            (*ENDIF*) 
                            IF  trError_gg00 = e_ok
                            THEN
                                BEGIN
                                cur_res_cnt := cur_res_cnt + 1;
                                IF  (sfp_m_firstkeys_addr <> NIL) AND (cur_res_cnt = 1)
                                THEN
                                    (* save key for scrollable cursor *)
                                    g01key_and_len_assign (RecKey, RecKeyLen,
                                          sfp_m_firstkeys_addr^.reckey.keyVal_gg00,
                                          sfp_m_firstkeys_addr^.reckey.keyLen_gg00,
                                          trError_gg00);
                                (*ENDIF*) 
                                IF  sfp_resrec_maxlen < MAX_INT2_SP00
                                THEN
                                    cur_res_length := sfp_resrec_maxlen
                                ELSE
                                    cur_res_length := sfp_result_length;
                                (*ENDIF*) 
                                IF  sfp_bd_mess_type <> m_fetch
                                THEN
                                    IF  cur_res_length MOD 2 = 1
                                    THEN
                                        cur_res_length := cur_res_length + 1;
&                                   ifdef TRACE
                                    (*ENDIF*) 
                                (*ENDIF*) 
                                IF  cur_res_length - sfp_result_length > 0
                                THEN
                                    SAPDB_PascalFill ('VBD36 ',   5,    
                                          sfp_m_result_size,
                                          @sfp_m_result_addr^,
                                          sfp_result_length + 1,
                                          cur_res_length - sfp_result_length,
                                          chr (0), trError_gg00);
&                               endif
                                (*ENDIF*) 
                                sfp_m_result_len  := sfp_m_result_len + cur_res_length;
                                sfp_m_result_addr := @sfp_m_result_addr^ [cur_res_length + 1];
                                sfp_m_result_size := sfp_m_result_size - cur_res_length;
                                sfp_act_cntresult := sfp_act_cntresult + 1;
&                               ifdef TRACE
                                t01p2int4 (bi, 'm_result_siz', sfp_m_result_size
                                      ,        'act_cntresul', sfp_act_cntresult);
                                t01p2int4 (bi, 'm_result_len', sfp_m_result_len
                                      ,        'cur_res_cnt ', cur_res_cnt);
&                               endif
                                IF  cur_res_cnt < sfp_m_result_cnt
                                THEN
                                    BEGIN
                                    last_result_len   := sfp_result_length;
                                    sfp_result_length := init_result_len
                                    END;
                                (*ENDIF*) 
                                END
                            (*ENDIF*) 
                            END
                        ELSE (* PTS 1108174 *)
                            IF  (trError_gg00 = e_lock_collision) AND
                                (hsIgnoreLock_egg00 IN curr_tree_id.fileHandling_gg00)
                            THEN
                                BEGIN
                                IF  sfp_bd_mess2_type <> mm_direct
                                THEN
                                    trError_gg00 := e_ok
                                ELSE
                                    BEGIN
                                    trError_gg00 := e_key_not_found;
                                    IF  sfp_bd_return_knf
                                    THEN
                                        IF  recIndex = nptr.np_ptr^.nd_record_cnt - 1
                                        THEN
                                            sfp_bd_return_knf := false
                                        ELSE
                                            BEGIN
                                            trError_gg00 := e_ok;
                                            recIndex     := recIndex + 1;
                                            recPos       := nptr.np_ptr^.nd_pointer_list[ MAX_POINTERINDEX_BD00 - recIndex ];
                                            IF  bd36_RecordPositionValid (curr_trans^, curr_tree_id,
                                                nptr.np_ptr, recPos)
                                            THEN
                                                BEGIN
                                                pRec      := @nptr.np_ptr^.nd_body [recPos];
                                                RecKeyLen := pRec^.recKeyLen_gg00;
                                                g10mv ('VBD36 ',   6,    
                                                      sizeof (nptr.np_ptr^), sizeof (RecKey),
                                                      @nptr.np_ptr^, recPos + cgg_rec_key_offset,
                                                      @RecKey, 1, RecKeyLen, trError_gg00);
                                                IF  trError_gg00 = e_ok
                                                THEN
                                                    trError_gg00 := e_key_not_found
                                                (*ENDIF*) 
                                                END
                                            ELSE
                                                sfp_bd_return_knf := false;
                                            (*ENDIF*) 
                                            END
                                        (*ENDIF*) 
                                    (*ENDIF*) 
                                    END;
                                (*ENDIF*) 
                                END;
                            (*ENDIF*) 
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  (trError_gg00 = e_ok) AND (cur_res_cnt < sfp_m_result_cnt)
                AND
                (sfp_bd_mess2_type <> mm_direct)
            THEN
                BEGIN
                IF  recIndex <> nptr.np_ptr^.nd_record_cnt - 1
                THEN
                    recIndex := recIndex + 1
                ELSE
                    BEGIN
                    nextLeafPage := nptr.np_ptr^.nd_right;
                    IF  nextLeafPage = NIL_PAGE_NO_GG00
                    THEN
                        trError_gg00 := e_no_next_record
                    ELSE
                        BEGIN
                        scanCount := succ (scanCount);
                        IF  scanCount = MAX_NODE_SCAN_BD00
                        THEN
                            BEGIN
                            IF  trRteCommPtr_gg00^.to_cancel
                            THEN
                                trError_gg00 := e_cancelled
                            ELSE
                                IF  bd20IsPageRequested (currRootNptrs_bd00.np_cbptr)
                                THEN
                                    trError_gg00 := e_bd_leaf_unlocked
                                ELSE
                                    scanCount := 0
                                (*ENDIF*) 
                            (*ENDIF*) 
                            END;
                        (* *)
                        (*ENDIF*) 
                        IF  trError_gg00 = e_ok
                        THEN
                            BEGIN
                            IF  (ftsPerm_egg00 IN fileType_gg00          ) AND
                                (currRightBound_bd00 = nptr.np_ptr^.nd_id) AND (* subtree boundary reached *)
                                (currIndexNptrs_bd00.np_ptr <> NIL       )
                            THEN
                                nextIndexPage := currIndexNptrs_bd00.np_ptr^.nd_right;
                            (*ENDIF*) 
                            b13r_release_node (nptr, current, lru_mid);
                            IF  nextIndexPage <> NIL_PAGE_NO_GG00
                            THEN
                                BEGIN
                                bd30ReleaseSubTree (current);
                                bd30GetSubTree (current, nextIndexPage);
                                nextIndexPage := NIL_PAGE_NO_GG00
                                END;
                            (*ENDIF*) 
                            IF  trError_gg00 = e_ok
                            THEN
                                bd13GetNode (current, nextLeafPage, plmLock_ebd00, nr_for_read, nptr);
                            (*ENDIF*) 
                            IF  trError_gg00 = e_ok
                            THEN
                                BEGIN
                                trRteCommPtr_gg00^.file_record_cnt := 1 + trRteCommPtr_gg00^.file_record_cnt;
                                recIndex := FIRST_REC_INDEX_BD00
                                END
                            (*ENDIF*) 
                            END
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                    IF  trError_gg00 <> e_ok
                    THEN
                        BEGIN
                        unqualified := false;
                        IF  trError_gg00 = e_bd_leaf_unlocked
                        THEN
                            BEGIN
                            NodeUnlocked       := nextLeafPage;
                            sfp_bd_mess2_type  := mm_next
                            END
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END
            (*ENDIF*) 
        UNTIL
            (scanCount = MAX_NODE_SCAN_BD00) OR
            ((NOT unqualified) AND (cur_res_cnt = sfp_m_result_cnt)) OR
            (trError_gg00 <> e_ok)
        (*ENDREPEAT*) 
        END;
    (*ENDIF*) 
    IF  cur_res_cnt < sfp_m_result_cnt
    THEN
        sfp_result_length := last_result_len;
    (*ENDIF*) 
    IF  nptr.np_ptr <> NIL
    THEN
        b13r_release_node (nptr, current, lru_normal);
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b36pqual_from_tree (
            VAR RecKey       : tsp00_Key;
            VAR RecKeyLen    : tsp00_Int2;
            VAR StopKey      : tsp00_Key;
            StopKeyLen       : tsp00_Int4;
            recbuf_size      : tsp00_Int4;
            recbuf_ptr       : tsp00_MoveObjPtr;
            VAR recbuf_pos   : tsp00_Int4;
            VAR sel          : tgg00_SelectFieldsParam;
            VAR stack_desc   : tgg00_StackDesc;
            VAR current      : tbd_current_tree;
            VAR cur_res_cnt  : integer;
            VAR unqualified  : boolean;
            VAR granted_lock : tgg00_LockReqMode;
            VAR NodeUnlocked : tsp00_PageNo);
 
VAR
      searchResult    : tbd_searchresult;
      compResult      : tsp00_LcompResult;
      cur_res_length  : tsp00_Int4;
      recPos             : tsp00_Int4;
      last_result_len : tsp00_Int4;
      init_result_len : tsp00_Int4;
      scanCount       : tsp00_Int4;
      recIndex        : tsp00_Int4;
      prevLeafPage    : tsp00_PageNo;
      pRec            : tgg00_RecPtr;
      nptr            : tbd_node_ptrs;
      neighbs         : tbd_neighbors;
 
BEGIN
WITH current, curr_tree_id, curr_trans^, sel DO
    BEGIN
    unqualified     := false;
    prevLeafPage    := NIL_PAGE_NO_GG00;
    last_result_len := 0;
    init_result_len := sfp_result_length;
    nptr.np_ptr     := NIL;
    nptr.np_cbptr   := NIL;
    bd30SearchRecord (current, RecKey, RecKeyLen, nptr, recIndex, neighbs, searchResult);
    IF  (trError_gg00 = e_ok) AND (searchResult = nonefound)
    THEN
        trError_gg00 := e_no_prev_record;
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        IF  (searchResult = nextfound) OR
            ((sfp_bd_mess2_type = mm_prev) AND (searchResult = thisfound))
        THEN
            b31prev_search (RecKey, RecKeyLen, nptr, recIndex, prevLeafPage, current);
        (*might return b_no_prev_record*)
        (*ENDIF*) 
        IF  sfp_bd_mess2_type = mm_last
        THEN
            sfp_bd_mess2_type := mm_prev;
        (*ENDIF*) 
        scanCount := 0;
        IF  trError_gg00 = e_ok
        THEN
            REPEAT
                unqualified := false;
                IF  trError_gg00 = e_ok
                THEN
                    BEGIN
                    recPos := nptr.np_ptr^.nd_pointer_list[ MAX_POINTERINDEX_BD00 - recIndex ];
                    IF  bd36_RecordPositionValid (curr_trans^, curr_tree_id, nptr.np_ptr, recPos)
                    THEN
                        BEGIN
                        pRec      := @nptr.np_ptr^.nd_body [recPos];
                        RecKeyLen := pRec^.recKeyLen_gg00;
                        g10mv ('VBD36 ',   7,    
                              sizeof (nptr.np_ptr^), sizeof (RecKey),
                              @nptr.np_ptr^, recPos + cgg_rec_key_offset,
                              @RecKey, 1, RecKeyLen, trError_gg00);
                        IF  sfp_bd_use_stopkey AND (trError_gg00 = e_ok)
                        THEN
                            BEGIN
                            s30cmp (RecKey, 1, RecKeyLen, StopKey, 1, StopKeyLen, compResult);
                            IF  compResult = l_less
                            THEN
                                trError_gg00 := e_no_prev_record
                            (*ENDIF*) 
                            END
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                IF  trError_gg00 = e_ok
                THEN
                    BEGIN
                    pRec := @nptr.np_ptr^.nd_body [recPos];
                    k71col_select (curr_trans^, sel, stack_desc, pRec^, unqualified);
                    CASE sfp_bd_mess_type OF
                        m_update:
                            IF  (fileTfn_gg00 = tfnTable_egg00)
                            THEN
                                BEGIN
                                b73cmd_count (iupdates_rows_read);
                                IF  NOT unqualified
                                THEN
                                    b73cmd_count (iupdates_rows_upd)
                                (*ENDIF*) 
                                END;
                            (*ENDIF*) 
                        m_delete:
                            IF  (fileTfn_gg00 = tfnTable_egg00)
                            THEN
                                BEGIN
                                b73cmd_count (ideletes_rows_read);
                                IF  NOT unqualified
                                THEN
                                    b73cmd_count (ideletes_rows_del)
                                (*ENDIF*) 
                                END;
                            (*ENDIF*) 
                        OTHERWISE:
                            IF  (fileTfn_gg00 = tfnTable_egg00)
                                OR
                                ((fileTfn_gg00 = tfnTemp_egg00) AND
                                (fileTfnTemp_gg00 <= ttfnTempTable_egg00))
                            THEN
                                BEGIN
                                b73cmd_count (iselects_rows_read);
                                IF  NOT unqualified
                                THEN
                                    b73cmd_count (iselects_rows_qual)
                                (*ENDIF*) 
                                END
                            (*ENDIF*) 
                        END;
                    (*ENDCASE*) 
                    IF  unqualified
                    THEN
                        trError_gg00 := e_ok
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                IF  NOT unqualified
                THEN
                    BEGIN
                    IF  (trError_gg00 = e_buffer_limit) AND (cur_res_cnt > 0)
                    THEN
                        sfp_m_result_cnt  := cur_res_cnt
                    ELSE
                        IF  trError_gg00 = e_ok
                        THEN
                            BEGIN
                            IF  NOT (ftsTemp_egg00 IN fileType_gg00)
                            THEN
                                k53row_lock_by_key (curr_trans^, curr_tree_id, RecKey, RecKeyLen,
                                      sel.sfp_bd_mess_type, sel.sfp_act_cntresult, granted_lock);
                            (*ENDIF*) 
                            IF  trError_gg00 = e_ok
                            THEN
                                BEGIN
                                IF  recbuf_ptr <> NIL
                                THEN
                                    BEGIN
                                    IF  recbuf_pos + pRec^.recLen_gg00 - 1 > recbuf_size
                                    THEN
                                        BEGIN
                                        trError_gg00     := e_buffer_limit;
                                        sfp_m_result_cnt := cur_res_cnt;
                                        END
                                    ELSE
                                        BEGIN
                                        g10mv ('VBD36 ',   8,    
                                              sizeof (nptr.np_ptr^), recbuf_size,
                                              @nptr.np_ptr^, recPos,
                                              @recbuf_ptr^, recbuf_pos,
                                              pRec^.recLen_gg00, trError_gg00);
                                        recbuf_pos := recbuf_pos + pRec^.recLen_gg00;
                                        IF  sfp_bd_mess_type <> m_fetch
                                        THEN
                                            IF  recbuf_pos MOD 2 = 0
                                            THEN
                                                recbuf_pos := recbuf_pos + 1
                                            (*ENDIF*) 
                                        (*ENDIF*) 
                                        END
                                    (*ENDIF*) 
                                    END;
                                (*ENDIF*) 
                                IF  trError_gg00 = e_ok
                                THEN
                                    BEGIN
                                    cur_res_cnt := cur_res_cnt + 1;
                                    IF  (sfp_m_firstkeys_addr <> NIL) AND (cur_res_cnt = 1)
                                    THEN
                                        (* save key for scrollable cursor *)
                                        g01key_and_len_assign (RecKey, RecKeyLen,
                                              sfp_m_firstkeys_addr^.reckey.keyVal_gg00,
                                              sfp_m_firstkeys_addr^.reckey.keyLen_gg00,
                                              trError_gg00);
                                    (*ENDIF*) 
                                    IF  sfp_resrec_maxlen < MAX_INT2_SP00
                                    THEN
                                        cur_res_length := sfp_resrec_maxlen
                                    ELSE
                                        cur_res_length := sfp_result_length;
                                    (*ENDIF*) 
                                    IF  sfp_bd_mess_type <> m_fetch
                                    THEN
                                        IF  cur_res_length MOD 2 = 1
                                        THEN
                                            cur_res_length := cur_res_length +1;
&                                       ifdef TRACE
                                        (*ENDIF*) 
                                    (*ENDIF*) 
                                    IF  cur_res_length - sfp_result_length > 0
                                    THEN
                                        SAPDB_PascalFill ('VBD36 ',   9,    
                                              sfp_m_result_size, @sfp_m_result_addr^,
                                              sfp_result_length + 1, cur_res_length - sfp_result_length,
                                              chr (0), trError_gg00);
&                                   endif
                                    (*ENDIF*) 
                                    sfp_m_result_len := sfp_m_result_len +  cur_res_length;
                                    sfp_m_result_addr := @sfp_m_result_addr^[cur_res_length + 1];
                                    sfp_m_result_size := sfp_m_result_size - cur_res_length;
                                    sfp_act_cntresult := sfp_act_cntresult + 1;
                                    IF  cur_res_cnt < sfp_m_result_cnt
                                    THEN
                                        BEGIN
                                        last_result_len   := sfp_result_length;
                                        sfp_result_length := init_result_len
                                        END;
                                    (*ENDIF*) 
                                    END
                                (*ENDIF*) 
                                END
                            ELSE (* PTS 1108174 *)
                                IF  (trError_gg00 = e_lock_collision) AND
                                    (hsIgnoreLock_egg00 IN fileHandling_gg00)
                                THEN
                                    trError_gg00 := e_ok;
                                (*ENDIF*) 
                            (*ENDIF*) 
                            END
                        (*ENDIF*) 
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                IF  (trError_gg00 = e_ok) AND (cur_res_cnt < sfp_m_result_cnt)
                THEN
                    BEGIN
                    IF  recIndex <> FIRST_REC_INDEX_BD00
                    THEN
                        recIndex := recIndex - 1
                    ELSE
                        BEGIN
                        scanCount := succ (scanCount);
                        IF  scanCount = MAX_NODE_SCAN_BD00
                        THEN
                            BEGIN
                            IF  trRteCommPtr_gg00^.to_cancel
                            THEN
                                trError_gg00 := e_cancelled
                            ELSE
                                IF  bd20IsPageRequested (currRootNptrs_bd00.np_cbptr)
                                THEN
                                    trError_gg00 := e_bd_leaf_unlocked
                                ELSE
                                    scanCount := 0
                                (*ENDIF*) 
                            (*ENDIF*) 
                            END;
                        (* *)
                        (*ENDIF*) 
                        IF  trError_gg00 = e_ok
                        THEN
                            b31prev_search (RecKey, RecKeyLen, nptr, recIndex,
                                  prevLeafPage, current);
                        (*ENDIF*) 
                        IF  trError_gg00 <> e_ok
                        THEN
                            BEGIN
                            unqualified := false;
                            IF  trError_gg00 = e_bd_leaf_unlocked
                            THEN
                                BEGIN
                                NodeUnlocked      := prevLeafPage;
                                sfp_bd_mess2_type := mm_prev
                                END
                            (*ENDIF*) 
                            END;
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
            UNTIL
                (scanCount = MAX_NODE_SCAN_BD00) OR
                (trError_gg00 <> e_ok          ) OR
                ((NOT unqualified) AND (cur_res_cnt = sfp_m_result_cnt));
            (*ENDREPEAT*) 
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  cur_res_cnt < sfp_m_result_cnt
    THEN
        sfp_result_length := last_result_len;
    (*ENDIF*) 
    IF  nptr.np_ptr <> NIL
    THEN
        b13r_release_node (nptr, current, lru_normal)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      bd36_RecordPositionValid (
            VAR trans   : tgg00_TransContext;
            VAR fileId  : tgg00_FileId;
            nptr        : tbd_nodeptr;
            recPos      : tsp00_Int4) : boolean;
 
BEGIN
IF  (recPos < BODY_BEG_BD00) OR (recPos > nptr^.nd_bottom)
THEN
    BEGIN
    trans.trError_gg00 := e_data_page_corrupted;
    b06dump_bad_page (trans.trTaskId_gg00, 'd', FILE_EXT_COR_BD00,
          nptr^.nd_id, nptr, 1);
    g01opmsg (sp3p_knldiag, sp3m_error, csp03_b36_1_illegal_entrypos,
          csp3_n_btree, 'Illegal entry pos       ', recPos);
    b06write_filename_and_root (fileId)
    END;
(*ENDIF*) 
bd36_RecordPositionValid := (trans.trError_gg00 = e_ok);
END;
 
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
.PA 
