.ad 8
.bm 8
.fm 4
.bt $Copyright by SAP AG, 2002$$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 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
              treehandling : VBD30;
 
        PROCEDURE
              b30search_record (VAR reckey : tsp00_Key;
                    RecKeyLen           : tsp00_Int4;
                    lock_type           : tbd_treelock;
                    node_req            : tbd_node_request;
                    VAR left_estimation : tsp00_Int4;
                    VAR rightestimation : tsp00_Int4;
                    VAR nptr            : tbd_node_ptrs;
                    VAR index           : integer;
                    VAR neighbs         : tbd_neighbors;
                    VAR result          : tbd_searchresult;
                    VAR current         : tbd_current_tree);
 
      ------------------------------ 
 
        FROM
              leafhandling         : VBD31;
 
        PROCEDURE
              b31prev_search (VAR reckey : tsp00_Key;
                    KeyLen        : tsp00_Int4;
                    VAR nptr      : tbd_node_ptrs;
                    VAR index     : integer;
                    VAR prev_leaf : tsp00_PageNo;
                    VAR current   : tbd_current_tree);
 
        PROCEDURE
              b31next_search (release_frame : boolean;
                    VAR nptr    : tbd_node_ptrs;
                    VAR index   : integer;
                    VAR current : tbd_current_tree);
 
      ------------------------------ 
 
        FROM
              indexhandling : VBD50;
 
        PROCEDURE
              b50cross_subtree_boundary (VAR current : tbd_current_tree;
                    source_leaf : tsp00_PageNo;
                    dest_leaf   : tsp00_PageNo);
 
      ------------------------------ 
 
        FROM
              ref_statistic : VBD73;
 
        PROCEDURE
              b73cmd_count (statement_kind : tgg00_RefInfoIndex);
 
      ------------------------------ 
 
        FROM
              concurrency : VBD75;
 
        PROCEDURE
              b75iuread_unlock_index (VAR current : tbd_current_tree;
                    indexnode : tsp00_PageNo);
 
        PROCEDURE
              b75llread_lock_leaf (VAR current : tbd_current_tree;
                    leaf           : tsp00_PageNo;
                    suspend_reason : tsp00_Int2);
 
        PROCEDURE
              b75lulread_unlocklock_leaf (
                    VAR current    : tbd_current_tree;
                    src_leaf       : tsp00_PageNo;
                    src_index      : tsp00_PageNo;
                    dest_leaf      : tsp00_PageNo;
                    dest_index     : tsp00_PageNo;
                    suspend_reason : tsp00_Int2);
 
        PROCEDURE
              b75luread_unlock_leaf (VAR current : tbd_current_tree;
                    leaf : tsp00_PageNo);
 
        FUNCTION
              b75tree_request (pid : tsp00_TaskId;
                    root : tsp00_PageNo) : boolean;
 
      ------------------------------ 
 
        FROM
              Configuration_Parameter : VGG01;
 
        VAR
              g01glob : tgg_kernel_globals;
 
        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    : tsp_int4;
                    msg_label : tsp_c8;
                    msg_text  : tsp_c24;
                    msg_value : tsp_int4);
 
      ------------------------------ 
 
        FROM
              Kernel_move_and_fill : VGG10;
 
        PROCEDURE
              g10fil  (mod_id      : tsp_c6;
                    mod_intern_num : tsp_int4;
                    source_upb     : tsp_int4;
                    VAR source     : tsp_moveobj;
                    source_pos     : tsp_int4;
                    length         : tsp_int4;
                    fill_char      : char;
                    VAR e          : tgg_basis_error);
 
        PROCEDURE
              g10mv   (mod_id      : tsp_c6;
                    mod_intern_num : tsp_int4;
                    source_upb     : tsp_int4;  destin_upb : tsp_int4;
                    VAR source     : tbd_node;  source_pos : tsp_int4;
                    VAR destin     : tsp00_Key; destin_pos : tsp_int4;
                    length         : tsp_int4;
                    VAR e          : tgg_basis_error);
 
        PROCEDURE
              g10mv1  (mod_id      : tsp_c6;
                    mod_intern_num : tsp_int4;
                    source_upb     : tsp_int4;    destin_upb : tsp_int4;
                    VAR source     : tbd_node;    source_pos : tsp_int4;
                    VAR destin     : tsp_moveobj; destin_pos : tsp_int4;
                    length         : tsp_int4;
                    VAR e          : tgg_basis_error);
 
      ------------------------------ 
 
        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         : tgg_select_fields_param;
                    VAR stack_desc  : tgg_stack_desc;
                    VAR n           : tgg00_Rec;
                    VAR unqualified : boolean);
 
      ------------------------------ 
 
        FROM
              RTE-Extension-30 : VSP30;
 
        PROCEDURE
              s30cmp (VAR buf1   : tsp00_Key;
                    fieldpos1    : tsp_int4;
                    fieldlength1 : tsp_int4;
                    VAR buf2     : tsp00_Key;
                    fieldpos2    : tsp_int4;
                    fieldlength2 : tsp_int4;
                    VAR l_result : tsp_lcomp_result);
&       ifdef TRACE
 
      ------------------------------ 
 
        FROM
              Test_Procedures : VTA01;
 
        PROCEDURE
              t01msgcheck (msg      : tsp00_C30;
                    check_condition : boolean;
                    bad_int         : tsp00_Int4);
&       endif
 
.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :
 
        PROCEDURE
              b06dump_bad_page;
 
              tbd_univ_ptr tbd_nodeptr
 
        PROCEDURE
              g10mv;
 
              tsp_moveobj tbd_node
              tsp_moveobj tsp00_Key
 
        PROCEDURE
              g10mv1;
 
              tsp_moveobj tbd_node
 
        PROCEDURE
              s30cmp;
 
              tsp_moveobj tsp00_Key
 
.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  :
.sp
.cp 3
Created : 1983-04-29
.sp
.cp 3
Version : 2002-08-26
.sp
.cp 3
Release :      Date : 1999-06-07
.sp
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Specification:
 
.sp
b36pqual_from_tree, b36nqual_from_tree
.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
      result          : tbd_searchresult;
      l_result        : tsp00_LcompResult;
      el              : tsp00_IntMapC2;
      cur_res_length  : integer;
      pos             : integer;
      last_result_len : integer;
      init_result_len : integer;
      count           : integer;
      index           : integer;
      next            : tsp00_PageNo;
      pRec            : tgg00_RecPtr;
      nptr            : tbd_node_ptrs;
      neighbs         : tbd_neighbors;
      dumm_estimation : tsp00_Int4;
 
BEGIN
WITH current, curr_tree_id, curr_trans^, sel DO
    BEGIN
    unqualified     := false;
    last_result_len := 0;
    init_result_len := sfp_result_length;
    nptr.np_ptr     := NIL;
    nptr.np_cbptr   := NIL;
    b30search_record (RecKey, RecKeyLen, r_lock_leaf, nr_for_read, dumm_estimation,
          dumm_estimation, nptr, index, neighbs, result, current);
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        IF  (sfp_bd_mess2_type = mm_direct)
        THEN
            BEGIN
            IF  result <> thisfound
            THEN
                BEGIN
                trError_gg00 := e_key_not_found;
                IF  sfp_bd_return_knf
                THEN
                    BEGIN
                    IF  result = nextfound
                    THEN
                        BEGIN
                        WITH nptr.np_ptr^ DO
                            BEGIN
                            pos := nd_pointer_list[ MAX_POINTERINDEX_BD00 - index ];
                            IF  (pos < BODY_BEG_BD00) OR (pos >nd_bottom)
                            THEN
                                BEGIN
                                trError_gg00 := e_illegal_entrypos;
                                b06dump_bad_page (trTaskId_gg00, 'd',
                                      FILE_EXT_COR_BD00, nd_id, nptr.np_ptr, 1);
                                g01opmsg (sp3p_knldiag, sp3m_error,
                                      csp03_b36_1_illegal_entrypos, csp3_n_btree,
                                      'Illegal entry pos       ', pos);
                                b06write_filename_and_root (curr_tree_id)
                                END;
                            (*ENDIF*) 
                            IF  trError_gg00 = e_key_not_found
                            THEN
                                BEGIN
                                pRec      := @nd_body [pos];
                                RecKeyLen := pRec^.recKeyLen_gg00;
                                g10mv ('VBD36 ',   1,    
                                      sizeof (nptr.np_ptr^), sizeof (RecKey),
                                      nptr.np_ptr^, pos + cgg_rec_key_offset,
                                      RecKey, 1, RecKeyLen, trError_gg00)
                                END
                            (*ENDIF*) 
                            END
                        (*ENDWITH*) 
                        END
                    ELSE
                        IF  (result = 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
        ELSE
            IF  (result = nonefound) OR ((result = 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
                    BEGIN
&                   ifdef TRACE
                    WITH trRteCommPtr_gg00^ DO
                        IF  (file_root <> NIL_PAGE_NO_GG00) AND
                            (file_root <> fileRoot_gg00)
                        THEN
                            t01msgcheck
                                  ('root mismatch                 ',
                                  file_root = fileRoot_gg00, file_root);
&                       endif
                        (*ENDIF*) 
                    (*ENDWITH*) 
                    trRteCommPtr_gg00^.file_root := fileRoot_gg00
                    END;
                (*ENDIF*) 
            (*ENDIF*) 
        (*ENDIF*) 
        END
    ELSE
        sfp_bd_return_knf := false;
    (*ENDIF*) 
    IF  (trError_gg00 = e_ok) AND
        (((sfp_bd_mess2_type = mm_next ) AND (result <> nextfound)) OR
        ( (sfp_bd_mess2_type = mm_first) AND (result =  lastfound))   )
    THEN
        BEGIN
        b31next_search (RELEASE_FRAME_BD00, nptr, index, current);
        (*might return b_no_next_record*)
        IF  (trError_gg00 = e_ok) AND (index = 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*) 
        count    := 0;
        REPEAT
            unqualified := false;
            WITH nptr.np_ptr^ DO
                BEGIN
                pos := nd_pointer_list[ MAX_POINTERINDEX_BD00 - index ];
                IF  (pos < BODY_BEG_BD00) OR (pos > nd_bottom)
                THEN
                    BEGIN
                    trError_gg00 := e_illegal_entrypos;
                    b06dump_bad_page (trTaskId_gg00, 'd',
                          FILE_EXT_COR_BD00, nd_id, nptr.np_ptr, 1);
                    g01opmsg (sp3p_knldiag, sp3m_error,
                          csp03_b36_2_illegal_entrypos, csp3_n_btree,
                          'Illegal entry pos       ', pos);
                    b06write_filename_and_root (curr_tree_id)
                    END;
                (*ENDIF*) 
                IF  trError_gg00 = e_ok
                THEN
                    BEGIN
                    pRec      := @nd_body [pos];
                    RecKeyLen := pRec^.recKeyLen_gg00;
                    g10mv ('VBD36 ',   2,    
                          sizeof (nptr.np_ptr^), sizeof (RecKey),
                          nptr.np_ptr^, pos + 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, l_result);
                        IF  l_result = l_greater
                        THEN
                            trError_gg00 := e_no_next_record
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END;
            (*ENDWITH*) 
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                pRec := @nptr.np_ptr^.nd_body [pos];
                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
                    BEGIN
                    IF  sfp_bd_mess2_type <> mm_direct
                    THEN
                        trError_gg00 := e_ok
                    ELSE
                        IF  sfp_bd_return_knf
                        THEN
                            IF  index <> nptr.np_ptr^.nd_record_cnt - 1
                            THEN
                                BEGIN
                                WITH nptr.np_ptr^ DO
                                    BEGIN
                                    index := index + 1;
                                    pos   := nd_pointer_list[ MAX_POINTERINDEX_BD00 - index ];
                                    IF  (pos < BODY_BEG_BD00) OR
                                        (pos > nd_bottom)
                                    THEN
                                        sfp_bd_return_knf := false;
                                    (*ENDIF*) 
                                    IF  sfp_bd_return_knf
                                    THEN
                                        BEGIN
                                        pRec      := @nd_body [pos];
                                        RecKeyLen := pRec^.recKeyLen_gg00;
                                        g10mv ('VBD36 ',   3,    
                                              sizeof (nptr.np_ptr^), sizeof (RecKey),
                                              nptr.np_ptr^, pos + cgg_rec_key_offset,
                                              RecKey, 1, RecKeyLen, trError_gg00)
                                        END
                                    (*ENDIF*) 
                                    END
                                (*ENDWITH*) 
                                END
                            ELSE
                                sfp_bd_return_knf := false
                            (*ENDIF*) 
                        (*ENDIF*) 
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  NOT unqualified
            THEN
                BEGIN
                IF  trError_gg00 = e_buffer_limit
                THEN
                    BEGIN
                    IF  cur_res_cnt > 0
                    THEN
                        BEGIN
                        trError_gg00      := e_ok;
                        sfp_m_result_cnt  := cur_res_cnt;
                        sfp_bd_mess2_type := mm_first
                        END
                    (*ENDIF*) 
                    END
                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
                                WITH nptr.np_ptr^ DO
                                    BEGIN
                                    el.mapC2_sp00 [1] := nd_body [pos];
                                    el.mapC2_sp00 [2] := nd_body [pos + 1]
                                    END;
                                (*ENDWITH*) 
                                IF  recbuf_pos + el.mapInt_sp00 - 1 > recbuf_size
                                THEN
                                    trError_gg00 := e_buffer_limit
                                ELSE
                                    BEGIN
                                    g10mv1 ('VBD36 ',   4,    
                                          sizeof (nptr.np_ptr^), recbuf_size,
                                          nptr.np_ptr^, pos,
                                          recbuf_ptr^, recbuf_pos, el.mapInt_sp00,
                                          trError_gg00);
                                    recbuf_pos := recbuf_pos + el.mapInt_sp00;
                                    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
                                    g10fil ('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;
                                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
                            ELSE
                                IF  trError_gg00 = e_buffer_limit
                                THEN
                                    BEGIN
                                    trError_gg00 := e_ok;
                                    sfp_m_result_cnt  := cur_res_cnt;
                                    sfp_bd_mess2_type := mm_first
                                    END
                                (*ENDIF*) 
                            (*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  index <> nptr.np_ptr^.nd_record_cnt - 1
                                        THEN
                                            BEGIN
                                            WITH nptr.np_ptr^ DO
                                                BEGIN
                                                index := index + 1;
                                                pos   := nd_pointer_list[ MAX_POINTERINDEX_BD00 - index ];
                                                IF  (pos < BODY_BEG_BD00) OR
                                                    (pos > nd_bottom)
                                                THEN
                                                    sfp_bd_return_knf := false;
                                                (*ENDIF*) 
                                                IF  sfp_bd_return_knf
                                                THEN
                                                    BEGIN
                                                    pRec      := @nd_body [pos];
                                                    RecKeyLen := pRec^.recKeyLen_gg00;
                                                    g10mv ('VBD36 ',   6,    
                                                       sizeof (nptr.np_ptr^), sizeof (RecKey),
                                                       nptr.np_ptr^, pos + cgg_rec_key_offset,
                                                       RecKey, 1, RecKeyLen, trError_gg00)
                                                    END
                                                (*ENDIF*) 
                                                END
                                            (*ENDWITH*) 
                                            END
                                        ELSE
                                            sfp_bd_return_knf := false;
                                        (*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  index = nptr.np_ptr^.nd_record_cnt - 1
                THEN
                    BEGIN
                    next := nptr.np_ptr^.nd_right;
                    IF  next <> NIL_PAGE_NO_GG00
                    THEN
                        BEGIN
                        count := count + 1;
                        IF  trRteCommPtr_gg00^.to_cancel
                        THEN
                            trError_gg00 := e_cancelled;
                        (*ENDIF*) 
                        IF  (count = MAX_NODE_SCAN_BD00) AND
                            (trError_gg00 = e_ok)
                        THEN
                            BEGIN
                            IF  NOT b75tree_request (trTaskId_gg00, fileRoot_gg00)
                            THEN
                                count := 0
                            ELSE
                                BEGIN
                                unqualified       := true;
                                sfp_bd_mess2_type := mm_next
                                END
                            (*ENDIF*) 
                            END;
                        (*ENDIF*) 
                        IF  (count < MAX_NODE_SCAN_BD00) AND
                            (trError_gg00 = e_ok)
                        THEN
                            BEGIN
                            neighbs.ln := nptr.np_ptr^.nd_id;
                            b13r_release_node (nptr, current, lru_mid);
                            IF  (curr_lockstate = r_lock_leaf)
                            THEN
                                BEGIN
                                IF  (ftsDynamic_egg00 IN fileType_gg00      ) AND
                                    (curr_right_bound = neighbs.ln) AND
                                    g01glob.bd_subtree
                                THEN
                                    BEGIN
                                    b50cross_subtree_boundary (current,
                                          neighbs.ln, next);
                                    IF  trError_gg00 = e_ok
                                    THEN
                                        b75llread_lock_leaf (current, next, 189)
                                    (*ENDIF*) 
                                    END
                                ELSE
                                    b75lulread_unlocklock_leaf (current,
                                          neighbs.ln, curr_lvl_1_locked, next,
                                          curr_lvl_1_locked, 90)
                                (*ENDIF*) 
                                END;
                            (*ENDIF*) 
                            IF  trError_gg00 = e_ok
                            THEN
                                bd13GetNode (current, next,
                                      plmNoLock_ebd00, nr_for_read, nptr);
                            (*ENDIF*) 
                            IF  trError_gg00 = e_ok
                            THEN
                                BEGIN
                                trRteCommPtr_gg00^.file_record_cnt := 1 +
                                      trRteCommPtr_gg00^.file_record_cnt;
                                index := FIRST_REC_INDEX_BD00
                                END
                            ELSE
                                IF  trError_gg00 = e_bd_leaf_unlocked
                                THEN
                                    BEGIN
                                    NodeUnlocked       := next;
                                    sfp_bd_mess2_type  := mm_next
                                    END
                                (*ENDIF*) 
                            (*ENDIF*) 
                            END
                        (*ENDIF*) 
                        END
                    ELSE
                        trError_gg00 := e_no_next_record;
                    (*ENDIF*) 
                    IF  trError_gg00 <> e_ok
                    THEN
                        unqualified := false
                    (*ENDIF*) 
                    END
                ELSE
                    index := index + 1;
                (*ENDIF*) 
                END
            (*ENDIF*) 
        UNTIL
            (count = 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  trError_gg00 = e_ok
    THEN
        b13r_release_node (nptr, current, lru_normal)
    ELSE
        IF  nptr.np_ptr <> NIL
        THEN
            b13r_release_node (nptr, current, lru_mid);
        (*ENDIF*) 
    (*ENDIF*) 
    IF  curr_lockstate = r_lock_leaf
    THEN
        b75luread_unlock_leaf (current, curr_node_locked)
    ELSE
        IF  curr_lockstate = r_lock_index
        THEN
            b75iuread_unlock_index (current, curr_lvl_1_locked)
        (*ENDIF*) 
    (*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
      result          : tbd_searchresult;
      l_result        : tsp00_LcompResult;
      el              : tsp00_IntMapC2;
      cur_res_length  : integer;
      pos             : integer;
      last_result_len : integer;
      init_result_len : integer;
      count           : integer;
      index           : integer;
      dumm_estimation : tsp00_Int4;
      prev_leaf       : 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;
    prev_leaf       := NIL_PAGE_NO_GG00;
    last_result_len := 0;
    init_result_len := sfp_result_length;
    nptr.np_ptr     := NIL;
    nptr.np_cbptr   := NIL;
    b30search_record (RecKey, RecKeyLen, r_lock_leaf, nr_for_read, dumm_estimation,
          dumm_estimation, nptr, index, neighbs, result, current);
    IF  (trError_gg00 = e_ok) AND (result = nonefound)
    THEN
        trError_gg00 := e_no_prev_record;
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        IF  (result = nextfound) OR
            ((sfp_bd_mess2_type = mm_prev) AND
            (result = thisfound))
        THEN
            b31prev_search (RecKey, RecKeyLen, nptr, index, prev_leaf, current);
        (*might return b_no_prev_record*)
        (*ENDIF*) 
        IF  sfp_bd_mess2_type = mm_last
        THEN
            sfp_bd_mess2_type := mm_prev;
        (*ENDIF*) 
        count := 0;
        IF  trError_gg00 = e_ok
        THEN
            REPEAT
                unqualified := false;
                WITH nptr.np_ptr^ DO
                    BEGIN
                    pos := nd_pointer_list[ MAX_POINTERINDEX_BD00 - index ];
                    IF  (pos < BODY_BEG_BD00) OR (pos > nd_bottom)
                    THEN
                        BEGIN
                        trError_gg00 := e_illegal_entrypos;
                        b06dump_bad_page (trTaskId_gg00, 'd',
                              FILE_EXT_COR_BD00, nd_id, nptr.np_ptr, 1);
                        g01opmsg (sp3p_knldiag, sp3m_error,
                              csp03_b36_4_illegal_entrypos, csp3_n_btree,
                              'Illegal entry pos       ', pos);
                        b06write_filename_and_root (curr_tree_id)
                        END;
                    (*ENDIF*) 
                    IF  trError_gg00 = e_ok
                    THEN
                        BEGIN
                        pRec      := @nd_body [pos];
                        RecKeyLen := pRec^.recKeyLen_gg00;
                        g10mv ('VBD36 ',   7,    
                              sizeof (nptr.np_ptr^), sizeof (RecKey),
                              nptr.np_ptr^, pos + 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, l_result);
                            IF  l_result = l_less
                            THEN
                                trError_gg00 := e_no_prev_record
                            (*ENDIF*) 
                            END
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END;
                (*ENDWITH*) 
                IF  trError_gg00 = e_ok
                THEN
                    BEGIN
                    pRec := @nptr.np_ptr^.nd_body [pos];
                    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
                    THEN
                        BEGIN
                        IF  cur_res_cnt > 0
                        THEN
                            BEGIN
                            trError_gg00 := e_ok;
                            sfp_m_result_cnt  := cur_res_cnt;
                            sfp_bd_mess2_type := mm_last
                            END
                        (*ENDIF*) 
                        END
                    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,
                                      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
                                    WITH nptr.np_ptr^ DO
                                        BEGIN
                                        el.mapC2_sp00 [1] := nd_body [pos];
                                        el.mapC2_sp00 [2] := nd_body [pos+1]
                                        END;
                                    (*ENDWITH*) 
                                    IF  recbuf_pos + el.mapInt_sp00 - 1 >
                                        recbuf_size
                                    THEN
                                        trError_gg00 := e_buffer_limit
                                    ELSE
                                        BEGIN
                                        g10mv1 ('VBD36 ',   8,    
                                              sizeof (nptr.np_ptr^),
                                              recbuf_size,
                                              nptr.np_ptr^, pos,
                                              recbuf_ptr^, recbuf_pos,
                                              el.mapInt_sp00, trError_gg00);
                                        recbuf_pos := recbuf_pos + el.mapInt_sp00;
                                        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
                                        g10fil ('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
                                ELSE
                                    IF  trError_gg00 = e_buffer_limit
                                    THEN
                                        BEGIN
                                        trError_gg00 := e_ok;
                                        sfp_m_result_cnt  := cur_res_cnt;
                                        sfp_bd_mess2_type := mm_last
                                        END
                                    (*ENDIF*) 
                                (*ENDIF*) 
                                END
                            ELSE (* PTS 1108174 *)
                                IF  (trError_gg00 = e_lock_collision) AND
                                    (hsIgnoreLock_egg00 in
                                    curr_tree_id.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  index = FIRST_REC_INDEX_BD00
                    THEN
                        BEGIN
                        count := count + 1;
                        IF  trRteCommPtr_gg00^.to_cancel
                        THEN
                            trError_gg00 := e_cancelled;
                        (*ENDIF*) 
                        IF  (count = MAX_NODE_SCAN_BD00) AND
                            (trError_gg00 = e_ok)
                        THEN
                            BEGIN
                            IF  NOT b75tree_request(trTaskId_gg00, fileRoot_gg00)
                            THEN
                                count := 0
                            ELSE
                                BEGIN
                                unqualified       := true;
                                sfp_bd_mess2_type := mm_prev
                                END
                            (*ENDIF*) 
                            END;
                        (*ENDIF*) 
                        IF  (count < MAX_NODE_SCAN_BD00) AND
                            (trError_gg00 = e_ok)
                        THEN
                            BEGIN
                            b31prev_search (RecKey, RecKeyLen, nptr, index,
                                  prev_leaf, current);
                            IF  trError_gg00 = e_bd_leaf_unlocked
                            THEN
                                BEGIN
                                NodeUnlocked      := prev_leaf;
                                sfp_bd_mess2_type := mm_prev
                                END
                            (*ENDIF*) 
                            END;
                        (*ENDIF*) 
                        IF  trError_gg00 <> e_ok
                        THEN
                            unqualified := false
                        (*ENDIF*) 
                        END
                    ELSE
                        index := index - 1;
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
            UNTIL
                (count = 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  trError_gg00 = e_ok
    THEN
        b13r_release_node (nptr, current, lru_normal)
    ELSE
        IF  nptr.np_ptr <> NIL
        THEN
            b13r_release_node (nptr, current, lru_mid);
        (*ENDIF*) 
    (*ENDIF*) 
    IF  curr_lockstate = r_lock_leaf
    THEN
        b75luread_unlock_leaf (current, curr_node_locked)
    ELSE
        IF  curr_lockstate = r_lock_index
        THEN
            b75iuread_unlock_index (current, curr_lvl_1_locked)
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
*-PRETTY-*  statements    :        321
*-PRETTY-*  lines of code :        971        PRETTYX 3.10 
*-PRETTY-*  lines in file :       1361         1997-12-10 
.PA 
