.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$VBD31$
.tt 2 $$$
.tt 3 $JuergenP$leafhandling$$1999-03-29$
***********************************************************
.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  : leafhandling
=========
.sp
Purpose : operation on leafs containing primary data
.CM *-END-* purpose -------------------------------------
.sp
.cp 3
Define  :
 
        PROCEDURE
              b31add_to_leaf (VAR b : tgg00_Rec;
                    VAR nptr    : tbd_node_ptrs;
                    index       : integer;
                    left        : tsp00_PageNo;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b31append_to_leaf (VAR b : tgg00_Rec;
                    VAR nptr        : tbd_node_ptrs;
                    index           : integer;
                    page_fill_limit : integer;
                    left            : tsp00_PageNo;
                    VAR current     : tbd_current_tree);
 
        PROCEDURE
              b31del_from_leaf (VAR nptr : tbd_node_ptrs;
                    index       : integer;
                    left        : tsp00_PageNo;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b31get_from_leaf (VAR nptr : tbd_node_ptrs;
                    index        : integer;
                    with_kb_lock : boolean;
                    VAR b        : tgg00_Rec;
                    VAR current  : tbd_current_tree);
 
        PROCEDURE
              b31next_search (
                    VAR nptr    : tbd_node_ptrs;
                    VAR index   : integer;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b31nfill_recordbuffer (VAR nptr : tbd_node_ptrs;
                    VAR test_key   : tgg00_Lkey;
                    VAR tree_pos   : tgg00_FilePos;
                    VAR set_result : tgg00_BdSetResultRecord;
                    VAR b          : tsp00_MoveObj;
                    VAR current    : tbd_current_tree);
 
        PROCEDURE
              b31pfill_recordbuffer (VAR nptr : tbd_node_ptrs;
                    VAR test_key   : tgg00_Lkey;
                    VAR tree_pos   : tgg00_FilePos;
                    VAR set_result : tgg00_BdSetResultRecord;
                    VAR b          : tsp00_MoveObj;
                    VAR current    : tbd_current_tree);
 
        PROCEDURE
              b31pointer_list (VAR nptr : tbd_nodeptr);
 
        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
              b31repl_in_leaf (VAR b : tgg00_Rec;
                    VAR nptr    : tbd_node_ptrs;
                    index       : integer;
                    left        : tsp00_PageNo;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b31search_entry (VAR current : tbd_current_tree;
                    VAR rk     : tsp00_Key;
                    KeyLen     : tsp00_Int4;
                    VAR nptr   : tbd_nodeptr;
                    VAR index  : tsp00_Int4;
                    VAR result : tbd_searchresult);
 
        PROCEDURE
              b31sort_entries (VAR nptr : tbd_nodeptr;
                    t : tgg00_TransContextPtr);
 
        PROCEDURE
              b31t_append_to_temp_leaf (VAR b : tgg00_Rec;
                    VAR nptr     : tbd_node_ptrs;
                    VAR tree_pos : tgg00_FilePos;
                    VAR current  : tbd_current_tree);
 
        PROCEDURE
              b31t_prev_temp_search (VAR nptr : tbd_node_ptrs;
                    VAR index   : integer;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b31w_next_search (VAR nptr : tbd_node_ptrs;
                    VAR index   : integer;
                    VAR current : tbd_current_tree);
 
.CM *-END-* define --------------------------------------
.sp;.cp 3
Use     :
 
        FROM
              filesysteminterface_1 : VBD01;
 
        FUNCTION
              b01rec_align (len : tsp00_Int4): tsp00_Int4;
 
      ------------------------------ 
 
        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);
 
        PROCEDURE
              bd06CorruptedTreeHandling (
                    VAR fileId : tgg00_FileId;
                    msgNo      : tsp00_Int4;
                    trError    : tgg00_BasisError);
 
      ------------------------------ 
 
        FROM
              nodehandling : VBD13;
 
        PROCEDURE
              b13free_node (VAR nptr : tbd_node_ptrs;
                    VAR current : tbd_current_tree);
 
        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);
 
        PROCEDURE
              b13w_release_node (VAR nptr : tbd_node_ptrs;
                    VAR current : tbd_current_tree);
 
      ------------------------------ 
 
        FROM
              treehandling : VBD30;
 
        PROCEDURE
              bd30GetSubTree (
                    VAR current : tbd_current_tree;
                    indexPageNo : tsp00_PageNo);
 
        PROCEDURE
              bd30ReleaseSubTree(
                    VAR current : tbd_current_tree);
 
      ------------------------------ 
 
        FROM
              leafoverflow : VBD33;
 
        PROCEDURE
              b33addoverflow (VAR b : tgg00_Rec;
                    VAR nptr    : tbd_node_ptrs;
                    index       : integer;
                    left        : tsp00_PageNo;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b33add_new_leaf (VAR b : tgg00_Rec;
                    VAR nptr    : tbd_node_ptrs;
                    index       : integer;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b33t_add_new_temp_leaf (VAR b : tgg00_Rec;
                    VAR nptr     : tbd_node_ptrs;
                    VAR tree_pos : tgg00_FilePos;
                    VAR current  : tbd_current_tree);
 
      ------------------------------ 
 
        FROM
              b34leafunderflow : VBD34;
 
        PROCEDURE
              b34p_leafunderflow (VAR nptr : tbd_node_ptrs;
                    left        : tsp00_PageNo;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b34t_leafunderflow (VAR nptr : tbd_node_ptrs;
                    left        : tsp00_PageNo;
                    VAR current : tbd_current_tree);
 
      ------------------------------ 
 
        FROM
              entryhandling : VBD35;
 
        PROCEDURE
              b35add_space (VAR nptr : tbd_nodeptr;
                    pos  : tsp00_Int4;
                    plus : tsp00_Int4;
                    t    : tgg00_TransContextPtr);
 
        PROCEDURE
              b35del_space (VAR nptr : tbd_nodeptr;
                    pos   : tsp00_Int4;
                    minus : tsp00_Int4;
                    t     : tgg00_TransContextPtr);
 
        PROCEDURE
              b35get_entrykey (VAR nptr : tbd_nodeptr;
                    index   : integer;
                    VAR sep : tgg00_Lkey;
                    t       : tgg00_TransContextPtr);
 
        PROCEDURE
              b35next_entry (VAR nptr : tbd_nodeptr;
                    VAR index : integer;
                    VAR last  : boolean);
 
      ------------------------------ 
 
        FROM
              indexhandling : VBD50;
 
        PROCEDURE
              bd50FindFirstLevelIndexNode (
                    VAR reckey  : tsp00_Key;
                    keyLen      : tsp00_Int4;
                    VAR nptrs   : tbd_node_ptrs;
                    VAR neighbs : tbd_neighbors;
                    VAR found   : boolean;
                    VAR current : tbd_current_tree);
 
      ------------------------------ 
 
        FROM
              branchnodehandling : VBD51;
 
        PROCEDURE
              b51divert_rightnext (left : tsp00_PageNo;
                    old_right           : tsp00_PageNo;
                    new_right           : tsp00_PageNo;
                    VAR current         : tbd_current_tree);
 
        PROCEDURE
              b51ldivert_leftnext (right : tsp00_PageNo;
                    new_left    : tsp00_PageNo;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              bd51SearchBranch (VAR Current : tbd_current_tree;
                    pSepKey      : tsp00_KeyAddr;
                    KeyLen       : tsp00_Int4;
                    VAR Nptr     : tbd_nodeptr;
                    VAR RecIndex : tsp00_Int4);
 
      ------------------------------ 
 
        FROM
              branchhandling : VBD52;
 
        FUNCTION
              bd52SubtreePno (VAR nptr : tbd_nodeptr;
                    RecIndex : tsp00_Int4) : tsp00_PageNo;
 
      ------------------------------ 
 
        FROM
              indexupdateorders : VBD54;
 
        PROCEDURE
              b54del_index (pSep       : tsp00_KeyAddr;
                    SepLen             : tsp00_Int4;
                    n_level            : tsp00_Int2;
                    VAR indexorderlist : tbd00_OrderList);
 
        PROCEDURE
              b54execute_indexorder (
                    VAR indexorderlist : tbd00_OrderList;
                    VAR current        : tbd_current_tree);
 
      ------------------------------ 
 
        FROM
              Configuration_Parameter : VGG01;
 
        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_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
              SAPDB_PascalOverlappingMove (
                    mod_id      : tsp00_C6;
                    mod_num     : tsp00_Int4;
                    source_upb  : tsp00_Int4;
                    dest_upb    : tsp00_Int4;
                    source      : tsp00_MoveObjPtr;
                    src_pos     : tsp00_Int4;
                    destin      : tsp00_MoveObjPtr;
                    dest_pos    : tsp00_Int4;
                    length      : tsp00_Int4;
                    VAR e       : tgg00_BasisError);
 
        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
              k53bd_share_lock (VAR t : tgg00_TransContext;
                    VAR file_id       : tgg00_FileId;
                    VAR rec_buf       : tgg00_Rec);
 
      ------------------------------ 
 
        FROM
              RTE-Extension-30 : VSP30;
 
        PROCEDURE
              s30cmp (VAR buf1   : tsp00_Key;
                    fieldpos1    : tsp00_Int4;
                    fieldlength1 : tsp00_Int4;
                    VAR buf2     : tbd_node;
                    fieldpos2    : tsp00_Int4;
                    fieldlength2 : tsp00_Int4;
                    VAR l_result : tsp00_LcompResult);
 
        PROCEDURE
              s30cmp1 (VAR buf1  : tsp00_Key;
                    fieldpos1    : tsp00_Int4;
                    fieldlength1 : tsp00_Int4;
                    VAR buf2     : tgg00_RecBody;
                    fieldpos2    : tsp00_Int4;
                    fieldlength2 : tsp00_Int4;
                    VAR l_result : tsp00_LcompResult);
 
.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :
 
        PROCEDURE
              b06dump_bad_page;
 
              tbd_univ_ptr tbd_nodeptr
 
        PROCEDURE
              s30cmp;
 
              tsp00_MoveObj tsp00_Key
              tsp00_MoveObj tbd_node
 
        PROCEDURE
              s30cmp1;
 
              tsp00_MoveObj tsp00_Key
              tsp00_MoveObj tgg00_RecBody
 
.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  :
.sp
.cp 3
Created : 1979-11-13
.sp
.cp 3
.sp
.cp 3
Release :      Date : 1999-03-29
.sp
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Specification:
 
The routines described below operate on the leaves of the
current B* tree (VAR current, see treehandling).  They require that
this tree serve to maintain a primary file (see filesysteminterface)
and that, consequently, record entries are accommodated in the leaves.
.sp
The
.oc _/1;tree_address
of a record entry consists of the page number of the leaf and the
position at which the record entry begins within the leaf.  If more
than one entry begins in a leaf, their positions are sorted in a
list in ascending order by record keys; the entries themselves
can be unordered within the leaf.  Consecutive record entries are
accomodated in neighboring leaves.
.sp
The tree addresses of some of the last record entries to be
referenced are temporarily stored in a short-term memory
(see keymemory) in order to support the sequential processing
of the file.  Whenever the routines described below change the
tree addresses of record entries, they implement the necessary
corrections in the short-term memory themselves.
.sp
The nodes of the current B* tree that are not leaves form the
B* index, which contains a (generally multilevel) index of the
record entries of the tree (see indexhandling).  Changes in the
leaves may result in the need for minor modifications in the
B* index.  If this is the case, the routines concerned compile
suitable orders into a special order list (VAR indexorderlist,
see indexupdateorders) that must be sequentially processed after
the routine has been executed.
.sp 2;.cp 4
b31add_to_leaf(b,nptr,index,left,bd_use_info,
.br
               current,e)
.sp
The record in record buffer b is inserted in the leaf indicated by
the pointer nptr at the position to be determined via 'index'.
If bd_unbuffered is contained in bd_use_info, each page that is
updated is written through to the secondary storage.
.br
Some possible acknowledgements in e:
   - e_ok
   - b_no_more_space
   - b_disk_not_accessible
.sp 2
b31append_to_leaf(b,nptr,index,page_fill_limit,
.br
                left,bd_use_info,current,e)
.sp
The record in record buffer b is inserted after the last record
entry in the leaf indicated by the pointer nptr.  This occurs,
however, only if page_fill_limit will not be exceeded; otherwise,
a new leaf would be appended to the tree.
If bd_unbuffered is contained in bd_use_info, each page that is
changed is written through to the secondary storage.
.br
Some possible acknowledgements in e:
   - e_ok
   - b_no_more_space
   - b_disk_not_accessible
.sp 2
b31repl_in_leaf(b,nptr,index,left,bd_use_info,
.br
                current,e)
.sp
In the leaf indicated by the pointer nptr, the record identified
by 'index' is replaced by the record in record buffer b.
This requires that the two records have the same key.
If bd_unbuffered is contained in bd_use_info, each page that is
changed is written through to the secondary storage.
.br
Some possible acknowledgements in e:
   - e_ok
   - b_no_more_space
   - b_disk_not_accessible
.sp 2
b31del_from_leaf (nptr, index, left, current)
.sp
In the leaf indicated by the pointer nptr, the record identified by
'index' is deleted from the current B* tree.
If bd_unbuffered IN current.curr_tree_id.bd_use each page that is
changed is written through to the secondary storage.
.br
Some possible acknowledgements in current.curr_trans^.trError_gg00:
   - e_ok
.sp 2
b31get_from_leaf (nptr, index, with_kb_lock, b, current)
.sp
The record identified by 'index' is copied from the leaf indicated by
the pointer nptr to the record buffer b.
.br
Some possible acknowledgements in current.curr_trans^.trError_gg00:
   - e_ok
   - e_illegal_entrypos
   - e_invalid_entrypos
.sp 2
b31search_entry(rk,nptr,index,result,current,e)
.sp
This routine searches the leaf indicated by the pointer nptr for
the record entry with the key rk and displays (when e = e_ok)
in 'result' the result of the search as follows:
.sp ;.of 12
thisfound : The entry was found and 'index' is returned.
.br ;.of 12
nextfound : None of the entries in the leaf have this key but
at least one entry has a higher key; the index of the entry
with the higher key is returned.
.br ;.of 12
lastfound : All entries in the leaf have keys smaller than rk;
'index' returns the index of the last of these entries.
.br ;.of 12
nonefound : There are no entries in the leaf.
.sp ;.in
Some possible acknowledgements in e:
   - e_ok
   - b_illegal_entrypos
   - b_invalid_entrypos
   - b_illegal_entrylength
.sp 2
b31prev_search (rk,nptr,index,current,e)
.sp
This routine returns the index of the record entry preceeding
the entry identified by the leaf pointer nptr and by the index
'index'.  If this entry is located in the left neighbor leaf, the
pointer to this leaf is also supplied.  This requires that such a
predecessor exist.
.br
Some possible acknowledgements in e :
  - e_ok
  - b_no_prev_record
  - b_disk_not_accessible
.sp 2
b31next_search (nptr, index, current)
.sp
This routine returns the index of the record entry following the
entry identified by the leaf pointer nptr and by the index
'index'.  If this entry is located on the right neighbor leaf,
the pointer to this leaf is also supplied.  This requires that such
a successor exist.
.br
Some possible acknowledgements in current.curr_trans^.trError_gg00 :
  - e_ok
  - e_no_next_record
.sp 2
b31pfill_recordbuffer(nptr,test_key,tree_pos,set_result,b,
.br
                      current,e)
.sp
This routine returns record buffer b with a maximum of 'cnt'
record entries with keys that are lower than or the same as the
key of the entry identified by the leaf pointer nptr and by
the index 'index'.  If the left edge of the leaf is reached
before the limit condition has been fulfilled, the additional entries
are taken from a possible neighbor leaf on the left.  If the record
buffer is full or the left edge of the leaf has been reached,
b_buffer_limit is sent to e.
.br
Other possible acknowledgements in e:
  - e_ok
  - b_illegal_entrypos
  - b_invalid_entrypos
.sp 2
b31nfill_recordbuffer(nptr,test_key,tree_pos,set_result,b,
.br
                      current,e)
.sp
This routine returns record buffer b with a maximum of 'cnt'
record entries with keys that are higher than or the same as the key
of the entry identified by the leaf pointer nptr and by the index
'index'.  If the right edge of the leaf is reached before the
limit condition has been fulfilled, the additional entries are taken
from a possible neighbor leaf on the right.  If the record buffer is
full or the maximum number of entries 'count' has been reached,
b_buffer_limit is sent to e.
.br
Other possible acknowledgements in e:
  - e_ok
  - b_illegal_entrypos
  - b_invalid_entrypos
  - b_no_next_record
  - b_disk_not_accessible
.sp 2
A leafunderflow handling may be done.
.sp
.br;If bd_unbuffered IN current.curr_tree_id.bd_use each page that is
changed is written through to the secondary storage.
.br;Some possible acknowledgements in current.curr_trans^.trError_gg00:
   - e_ok
.sp 2
b31sort_entries(nptr)
.sp
In this routine, the record entries in the leaf indicated by the
pointer nptr are sorted according to the sequence determined by the
index 'pointer_list'.
.sp 2
b31pointer_list(nptr)
.sp
In this routine, the index 'pointer_list' in the leaf indicated
by the pointer nptr is restructured.  This requires that the
record entries be sorted in ascending order by record keys.
.CM *-END-* specification -------------------------------
.sp2
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Description:
 
Here the leaf_routines are refined insofar as their
effect remains limited to an individual leaf.
.sp
A record is left-justified when it is supplied to or stored in
the record buffer.
.sp ;.cp 5
Record buffer:
.sp
.nf
   +-------------------+---------   ...   ----+
   |     record        |           unused     |
   +-------------------+---------   ...   ----+
.fo
.sp 2;.cp 5
The record itself has the following structure:
.sp
.nf
   +----+----+-----------------+
   | el | kl |    fields       |
   +----+----+-----------------+
.fo
.sp
   el : record length including length field
.br
   kl : record key length excluding length field
.sp 2
When a new record entry is inserted or an old entry is replaced
with a new, longer entry, the case may arise that there is no longer
sufficient space available in the relevant leaf.  At this point,
the record entries of the leaf and of its neighbors are
redistributed to include the new entry (see b33addoverflow).
.sp
Or, on the other hand, the case may arise that when a record entry
is deleted or when an old record entry is replaced by a new,
shorter entry, the leaf is then no longer sufficiently
filled.  As a rule, this is acceptable for the root of a tree
(so that even an empty root can remain!); however, if the leaf
has neighbors, an attempt is made to correct the underflow
by redistributing the record entries (see b34leafunderflow).
.sp
Each leaf has a pointer to its right neighbor, if there is such a
neighbor.  The pointers are also used for leaf reorganization
and release operations.
.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
      b31add_to_leaf (VAR b : tgg00_Rec;
            VAR nptr    : tbd_node_ptrs;
            index       : integer;
            left        : tsp00_PageNo;
            VAR current : tbd_current_tree);
 
VAR
      target     : tsp00_Int2;
      amount     : tsp00_Int4;
      source_pos : tsp00_Int4;
 
BEGIN
WITH nptr, np_ptr^, b, current, curr_tree_id, curr_trans^ DO
    BEGIN
    IF  (nd_bottom + len) > (MAX_BOTTOM_BD00 - ((nd_record_cnt+1)*POINTERSIZE_BD00))
    THEN
        BEGIN
        IF  NOT nd_sorted
        THEN
            b31sort_entries (np_ptr, curr_trans);
        (*ENDIF*) 
        IF  trError_gg00 = e_ok
        THEN
            b33addoverflow (b, nptr, index, left, current)
        (*ENDIF*) 
        END
    ELSE
        BEGIN
        target    := nd_bottom;
        nd_bottom := nd_bottom + b01rec_align (len);
        g10mv ('VBD31 ',   1,    
              sizeof (b), sizeof (np_ptr^),
              @b, 1, @np_ptr^, target, len, trError_gg00);
        (*  pointer list update *)
        IF  nd_record_cnt > 0
        THEN
            BEGIN
            amount := (nd_record_cnt - index) * POINTERSIZE_BD00;
            source_pos := MAX_BOTTOM_BD00 - ((nd_record_cnt)*POINTERSIZE_BD00);
            SAPDB_PascalOverlappingMove ('VBD31 ',   2,    
                  sizeof (np_ptr^), sizeof (np_ptr^),
                  @np_ptr^, source_pos,
                  @np_ptr^, source_pos-POINTERSIZE_BD00, amount, trError_gg00);
            END;
        (*ENDIF*) 
        IF  trError_gg00 = e_move_error
        THEN
            BEGIN
            trError_gg00 := e_data_page_corrupted;
            b06dump_bad_page (trTaskId_gg00, 'd', FILE_EXT_COR_BD00,
                  nd_id, np_ptr, 1)
            END
        ELSE
            BEGIN
            nd_pointer_list [MAX_POINTERINDEX_BD00 - index] := target;
            nd_record_cnt := nd_record_cnt + 1;
            nd_sorted     := false;
            b13w_release_node (nptr, current)
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  trError_gg00 <> e_ok
    THEN
        BEGIN
        IF  np_ptr <> NIL
        THEN
            b13r_release_node (nptr, current, lru_normal);
        (*ENDIF*) 
        IF  ftsConcurrent_egg00 IN fileType_gg00
        THEN
            bd06CorruptedTreeHandling (curr_tree_id,
                  bd31x1TreeUpdateFailed_csp03, trError_gg00);
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b31append_to_leaf (VAR b : tgg00_Rec;
            VAR nptr        : tbd_node_ptrs;
            index           : integer;
            page_fill_limit : integer;
            left            : tsp00_PageNo;
            VAR current     : tbd_current_tree);
 
VAR
      target : tsp00_Int2;
 
BEGIN
WITH nptr, np_ptr^, b, current, curr_tree_id, curr_trans^ DO
    BEGIN
    IF  ((nd_bottom + len) > (MAX_BOTTOM_BD00 - ((nd_record_cnt+1)*POINTERSIZE_BD00)))
        OR ((nd_bottom >= page_fill_limit)
        AND (nd_right = NIL_PAGE_NO_GG00))
    THEN
        IF  nd_right = NIL_PAGE_NO_GG00
        THEN
            b33add_new_leaf (b, nptr, index, current)
        ELSE
            BEGIN
            IF  NOT nd_sorted
            THEN
                b31sort_entries (np_ptr, curr_trans);
            (*ENDIF*) 
            IF  trError_gg00 = e_ok
            THEN
                b33addoverflow (b, nptr, index + 1, left, current)
            (*ENDIF*) 
            END
        (*ENDIF*) 
    ELSE
        BEGIN
        target    := nd_bottom;
        nd_bottom := nd_bottom + b01rec_align (len);
        g10mv ('VBD31 ',   3,    
              sizeof (b), sizeof (np_ptr^),
              @b, 1, @np_ptr^, target, len, trError_gg00);
        IF  trError_gg00 = e_move_error
        THEN
            BEGIN
            trError_gg00 := e_data_page_corrupted;
            b06dump_bad_page (trTaskId_gg00, 'd', FILE_EXT_COR_BD00,
                  nd_id, np_ptr, 1)
            END
        ELSE
            BEGIN
            nd_pointer_list [MAX_POINTERINDEX_BD00 - (index + 1)] := target;
            nd_record_cnt := nd_record_cnt + 1;
            nd_sorted     := false;
            b13w_release_node (nptr, current)
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  trError_gg00 <> e_ok
    THEN
        BEGIN
        IF  np_ptr <> NIL
        THEN
            b13r_release_node (nptr, current, lru_normal);
        (*ENDIF*) 
        IF  ftsConcurrent_egg00 IN fileType_gg00
        THEN
            bd06CorruptedTreeHandling (curr_tree_id,
                  bd31x2TreeUpdateFailed_csp03, trError_gg00);
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b31del_from_leaf (VAR nptr : tbd_node_ptrs;
            index       : integer;
            left        : tsp00_PageNo;
            VAR current : tbd_current_tree);
 
VAR
      pRec        : tgg00_RecPtr;
      i           : integer;
      source_pos  : tsp00_Int4;
      cnt         : integer;
      pos         : integer;
      DelSpaceLen : tsp00_Int4;
      oldsep      : tgg00_Lkey;
 
BEGIN
WITH nptr, np_ptr^, current, curr_tree_id, curr_trans^ DO
    BEGIN
    trError_gg00   := e_ok;
    IF  nd_record_cnt = 1
    THEN
        b35get_entrykey (np_ptr, FIRST_REC_INDEX_BD00, oldsep, curr_trans);
    (*ENDIF*) 
    pos  := nd_pointer_list [MAX_POINTERINDEX_BD00 - index];
    pRec := @nd_body [pos];
    DelSpaceLen := b01rec_align (pRec^.recLen_gg00);
    b35del_space (np_ptr, pos, DelSpaceLen, curr_trans);
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        FOR i := FIRST_REC_INDEX_BD00 TO nd_record_cnt - 1 DO
            IF  nd_pointer_list [MAX_POINTERINDEX_BD00 - i] > pos
            THEN
                nd_pointer_list [MAX_POINTERINDEX_BD00 - i] :=
                      nd_pointer_list [MAX_POINTERINDEX_BD00 - i] - DelSpaceLen;
            (*ENDIF*) 
        (*ENDFOR*) 
        IF  index < nd_record_cnt - 1
        THEN
            BEGIN
            cnt        := POINTERSIZE_BD00 * (nd_record_cnt - 1 - index);
            source_pos := MAX_BOTTOM_BD00 - ((nd_record_cnt)*POINTERSIZE_BD00);
            SAPDB_PascalOverlappingMove ('VBD31 ',   4,    
                  sizeof (np_ptr^), sizeof (np_ptr^),
                  @np_ptr^, source_pos,
                  @np_ptr^, source_pos + POINTERSIZE_BD00, cnt, trError_gg00);
            IF  trError_gg00 = e_move_error
            THEN
                BEGIN
                trError_gg00 := e_data_page_corrupted;
                b06dump_bad_page (trTaskId_gg00, 'd', FILE_EXT_COR_BD00,
                      nd_id, np_ptr, 1)
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        nd_record_cnt := nd_record_cnt - 1;
        IF  (nd_id <> fileRoot_gg00)
            AND (nd_bottom = BODY_BEG_BD00)
        THEN
            BEGIN
            IF  left <> NIL_PAGE_NO_GG00
            THEN
                b51divert_rightnext (left, nd_id, nd_right, current);
            (*ENDIF*) 
            IF  (ftsTemp_egg00 in fileType_gg00) AND
                (nd_right <> NIL_PAGE_NO_GG00) AND
                (trError_gg00 = e_ok)
            THEN
                b51ldivert_leftnext (nd_right, left, current);
            (*ENDIF*) 
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                bd31del_sep (oldsep, nd_level, current);
                IF  trError_gg00 = e_ok
                THEN
                    b13free_node (nptr, current)
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END
        ELSE
            BEGIN
            IF  ((nd_bottom - BODY_BEG_BD00 + ((nd_record_cnt)*POINTERSIZE_BD00))
                < HALF_COVERING_BD00)
                AND (nd_id <> fileRoot_gg00)
                AND (NOT (ftsDynamic_egg00 IN fileType_gg00))
            THEN
                BEGIN
                IF  NOT nd_sorted
                THEN
                    b31sort_entries (np_ptr, curr_trans);
                (*ENDIF*) 
                IF  trError_gg00 = e_ok
                THEN
                    IF  ftsPerm_egg00 in fileType_gg00
                    THEN
                        b34p_leafunderflow (nptr, left, current)
                    ELSE
                        b34t_leafunderflow (nptr, left, current)
                    (*ENDIF*) 
                (*ENDIF*) 
                END
            ELSE
                b13w_release_node (nptr, current)
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  trError_gg00 <> e_ok
    THEN
        BEGIN
        IF  np_ptr <> NIL
        THEN
            b13r_release_node (nptr, current, lru_normal);
        (*ENDIF*) 
        IF  ftsConcurrent_egg00 IN fileType_gg00
        THEN
            bd06CorruptedTreeHandling (curr_tree_id,
                  bd31x3TreeUpdateFailed_csp03, trError_gg00);
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b31get_from_leaf (VAR nptr : tbd_node_ptrs;
            index        : integer;
            with_kb_lock : boolean;
            VAR b        : tgg00_Rec;
            VAR current  : tbd_current_tree);
 
VAR
      source : tsp00_Int4;
      pRec   : tgg00_RecPtr;
 
BEGIN
WITH nptr, np_ptr^, current, curr_trans^ DO
    BEGIN
    source := nd_pointer_list[ MAX_POINTERINDEX_BD00 - index ];
    IF  (source < BODY_BEG_BD00) OR (source > nd_bottom)
    THEN
        BEGIN
        trError_gg00 := e_illegal_entrypos;
        b06dump_bad_page (trTaskId_gg00, 'd', FILE_EXT_COR_BD00, nd_id, np_ptr, 1);
        g01opmsg (sp3p_knldiag, sp3m_error, csp03_b31_1_illegal_entrypos,
              csp3_n_btree, 'Illegal entry pos       ', source);
        b06write_filename_and_root (curr_tree_id)
        END;
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        pRec := @nd_body[source];
        g10mv ('VBD31 ',   5,    
              sizeof (np_ptr^), sizeof (b),
              @np_ptr^, source, @b, 1, pRec^.recLen_gg00, trError_gg00);
        IF  trError_gg00 = e_move_error
        THEN
            BEGIN
            trError_gg00 := e_data_page_corrupted;
            b06dump_bad_page (trTaskId_gg00, 'd', FILE_EXT_COR_BD00, nd_id, np_ptr, 1);
            b06write_filename_and_root (curr_tree_id)
            END
        ELSE
            BEGIN
            IF  with_kb_lock
            THEN
                k53bd_share_lock (curr_trans^, curr_tree_id, b);
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    b13r_release_node (nptr, current, lru_normal);
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b31next_search (
            VAR nptr    : tbd_node_ptrs;
            VAR index   : integer;
            VAR current : tbd_current_tree);
 
VAR
      last          : boolean;
      nextLeafPage  : tsp00_PageNo;
      nextIndexPage : tsp00_PageNo;
 
BEGIN
WITH nptr, current, curr_trans^ DO
    BEGIN
    nextLeafPage := np_ptr^.nd_right;
    b35next_entry (np_ptr, index, last);
    IF  NOT last
    THEN
        trError_gg00 := e_ok
    ELSE
        IF  nextLeafPage = NIL_PAGE_NO_GG00
        THEN
            trError_gg00 := e_no_next_record
        ELSE
            BEGIN
            IF  (ftsPerm_egg00 IN curr_tree_id.fileType_gg00) AND
                (currRightBound_bd00 = np_ptr^.nd_id        ) AND (* subtree boundary reached *)
                (currIndexNptrs_bd00.np_ptr <> NIL          )
            THEN
                nextIndexPage := currIndexNptrs_bd00.np_ptr^.nd_right
            ELSE
                nextIndexPage := NIL_PAGE_NO_GG00;
            (*ENDIF*) 
            b13r_release_node (nptr, current, lru_normal);
            IF  nextIndexPage <> NIL_PAGE_NO_GG00
            THEN
                BEGIN
                bd30ReleaseSubTree (current);
                bd30GetSubTree (current, nextIndexPage)
                END;
            (*ENDIF*) 
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                bd13GetNode (current, nextLeafPage, plmLock_ebd00, nr_for_read, nptr);
                index := FIRST_REC_INDEX_BD00
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b31nfill_recordbuffer (VAR nptr : tbd_node_ptrs;
            VAR test_key   : tgg00_Lkey;
            VAR tree_pos   : tgg00_FilePos;
            VAR set_result : tgg00_BdSetResultRecord;
            VAR b          : tsp00_MoveObj;
            VAR current    : tbd_current_tree);
 
VAR
      l_result : tsp00_LcompResult;
      pRec     : tgg00_RecPtr;
      source   : integer;
      target   : integer;
 
BEGIN
WITH nptr, tree_pos, set_result, current, curr_trans^ DO
    BEGIN
    trError_gg00 := e_ok;
    target       := 1;
    b [1] := chr (0);
    b [2] := chr (0);
    REPEAT
        WITH np_ptr^ DO
            BEGIN
            source := nd_pointer_list[ MAX_POINTERINDEX_BD00 - tpsIndex_gg00 ];
            IF  (source < BODY_BEG_BD00) OR (source > nd_bottom)
            THEN
                BEGIN
                trError_gg00 := e_illegal_entrypos;
                b06dump_bad_page (trTaskId_gg00, 'd', FILE_EXT_COR_BD00,
                      nd_id, np_ptr, 1);
                g01opmsg (sp3p_knldiag, sp3m_error, csp03_b31_3_illegal_entrypos,
                      csp3_n_btree, 'Illegal entry pos       ', source);
                b06write_filename_and_root (curr_tree_id)
                END
            (*ENDIF*) 
            END;
        (*ENDWITH*) 
        IF  trError_gg00 = e_ok
        THEN
            BEGIN
            pRec := @np_ptr^.nd_body[source];
            IF  (target + pRec^.recLen_gg00 - 1) > bd_max_fill_len
            THEN
                trError_gg00 := e_buffer_limit
            ELSE
                BEGIN
                l_result := l_equal;
                IF  bd_key_check_len > 0
                THEN
                    s30cmp (test_key.k, 1, bd_key_check_len, np_ptr^,
                          source + cgg_rec_key_offset, bd_key_check_len,
                          l_result);
                (*ENDIF*) 
                IF  l_result <> l_equal
                THEN
                    BEGIN
                    (* J.P. 19.12.96 Join optimization for inv_only *)
                    IF  target = 1
                    THEN
                        g10mv ('VBD31 ',   6,    
                              sizeof (np_ptr^), bd_max_fill_len,
                              @np_ptr^, source, @b, target, pRec^.recLen_gg00,
                              trError_gg00);
                    (*ENDIF*) 
                    trError_gg00 := e_no_next_record
                    END
                ELSE
                    BEGIN
                    bd_rec_cnt := bd_rec_cnt + 1;
                    g10mv ('VBD31 ',   7,    
                          sizeof (np_ptr^), bd_max_fill_len,
                          @np_ptr^, source, @b, target, pRec^.recLen_gg00,
                          trError_gg00);
                    IF  trError_gg00 = e_move_error
                    THEN
                        BEGIN
                        trError_gg00 := e_data_page_corrupted;
                        b06dump_bad_page (trTaskId_gg00, 'd', FILE_EXT_COR_BD00,
                              np_ptr^.nd_id, np_ptr, 1);
                        b06write_filename_and_root (curr_tree_id)
                        END
                    ELSE
                        BEGIN
                        bd_fill_len := bd_fill_len + pRec^.recLen_gg00;
                        target      := target + pRec^.recLen_gg00;
                        IF  bd_rec_cnt < bd_max_rec_cnt
                        THEN
                            BEGIN
                            IF  tpsIndex_gg00 < np_ptr^.nd_record_cnt - 1
                            THEN
                                tpsIndex_gg00 := tpsIndex_gg00 + 1
                            ELSE
                                BEGIN
                                IF  np_ptr^.nd_right = NIL_PAGE_NO_GG00
                                THEN
                                    BEGIN
                                    (* do not set tpsPno_gg00 to NIL_PAGE_NO !!*)
                                    tpsIndex_gg00 := NIL_RECINDEX_BD00;
                                    END
                                ELSE
                                    BEGIN
                                    tpsPno_gg00 := np_ptr^.nd_right;
                                    b13r_release_node (nptr, current, lru_normal);
                                    bd13GetNode (current, tpsPno_gg00,
                                          plmLock_ebd00, nr_for_read, nptr);
                                    IF  trError_gg00 = e_ok
                                    THEN
                                        tpsIndex_gg00 := FIRST_REC_INDEX_BD00
                                    (*ENDIF*) 
                                    END
                                (*ENDIF*) 
                                END
                            (*ENDIF*) 
                            END
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
    UNTIL
        (tpsIndex_gg00 = NIL_RECINDEX_BD00) OR (bd_rec_cnt = bd_max_rec_cnt) OR (trError_gg00 <> e_ok);
    (*ENDREPEAT*) 
    IF  np_ptr <> NIL
    THEN
        b13r_release_node (nptr, current, lru_normal);
    (*ENDIF*) 
    IF  (trError_gg00 = e_no_next_record) AND (bd_rec_cnt > 0)
    THEN
        trError_gg00 := e_ok;
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        IF  (tpsIndex_gg00 = NIL_RECINDEX_BD00) AND (bd_rec_cnt = 0)
        THEN
            trError_gg00 := e_no_next_record
        (*ENDIF*) 
        END
    ELSE
        IF  (trError_gg00 <> e_no_next_record) AND (trError_gg00 <> e_buffer_limit)
        THEN
            tpsPno_gg00 := NIL_PAGE_NO_GG00
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b31pfill_recordbuffer (VAR nptr : tbd_node_ptrs;
            VAR test_key   : tgg00_Lkey;
            VAR tree_pos   : tgg00_FilePos;
            VAR set_result : tgg00_BdSetResultRecord;
            VAR b          : tsp00_MoveObj;
            VAR current    : tbd_current_tree);
 
VAR
      enough   : boolean;
      l_result : tsp00_LcompResult;
      pRec     : tgg00_RecPtr;
      index    : integer;
      source   : integer;
      target   : integer;
 
BEGIN
WITH nptr, set_result, current, curr_trans^ DO
    BEGIN
    trError_gg00 := e_ok;
    enough       := false;
    target       := 1;
    index        := tree_pos.tpsIndex_gg00;
    REPEAT
        WITH np_ptr^ DO
            BEGIN
            source := nd_pointer_list[ MAX_POINTERINDEX_BD00 - index ];
            IF  (source < BODY_BEG_BD00) OR (source > nd_bottom)
            THEN
                BEGIN
                trError_gg00 := e_illegal_entrypos;
                b06dump_bad_page (trTaskId_gg00, 'd', FILE_EXT_COR_BD00,
                      nd_id, np_ptr, 1);
                g01opmsg (sp3p_knldiag, sp3m_error, csp03_b31_4_illegal_entrypos,
                      csp3_n_btree, 'Illegal entry pos       ', source);
                b06write_filename_and_root (curr_tree_id)
                END;
            (*ENDIF*) 
            IF  trError_gg00 = e_ok
            THEN
                pRec := @nd_body[source];
            (*ENDIF*) 
            END;
        (*ENDWITH*) 
        IF  trError_gg00 = e_ok
        THEN
            IF  (target + pRec^.recLen_gg00 - 1) > bd_max_fill_len
            THEN
                trError_gg00 := e_buffer_limit
            ELSE
                BEGIN
                l_result := l_equal;
                IF  bd_key_check_len > 0
                THEN
                    s30cmp (test_key.k, 1, bd_key_check_len, np_ptr^,
                          source + cgg_rec_key_offset, bd_key_check_len,
                          l_result);
                (*ENDIF*) 
                IF  l_result <> l_equal
                THEN
                    trError_gg00 := e_no_prev_record
                ELSE
                    BEGIN
                    bd_rec_cnt := succ(bd_rec_cnt);
                    g10mv ('VBD31 ',   8,    
                          sizeof (np_ptr^), bd_max_fill_len,
                          @np_ptr^, source, @b, target, pRec^.recLen_gg00, trError_gg00);
                    IF  trError_gg00 = e_move_error
                    THEN
                        BEGIN
                        trError_gg00 := e_data_page_corrupted;
                        b06dump_bad_page (trTaskId_gg00, 'd', FILE_EXT_COR_BD00,
                              np_ptr^.nd_id, np_ptr, 1);
                        b06write_filename_and_root (curr_tree_id)
                        END
                    ELSE
                        BEGIN
                        bd_fill_len := bd_fill_len + pRec^.recLen_gg00;
                        target      := target + pRec^.recLen_gg00;
                        IF  bd_rec_cnt < bd_max_rec_cnt
                        THEN
                            b31t_prev_temp_search (nptr, index, current)
                        ELSE
                            enough := true
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END
            (*ENDIF*) 
        (*ENDIF*) 
    UNTIL
        enough OR (trError_gg00 <> e_ok);
    (*ENDREPEAT*) 
    IF  np_ptr <> NIL
    THEN
        BEGIN
        tree_pos.tpsPno_gg00   := np_ptr^.nd_id;
        tree_pos.tpsIndex_gg00 := index;
        b13r_release_node (nptr, current, lru_normal)
        END;
    (*ENDIF*) 
    IF  (trError_gg00 = e_no_prev_record) AND (bd_rec_cnt > 0)
    THEN
        BEGIN
        trError_gg00 := e_ok;
        IF  bd_rec_cnt <> 1 (* is not used for subsequent b07ctreplace with treePos *)
        THEN
            tree_pos.tpsIndex_gg00 := NIL_RECINDEX_BD00;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  (trError_gg00 <> e_ok) AND (trError_gg00 <> e_no_prev_record) AND
        (trError_gg00 <> e_buffer_limit)
    THEN
        tree_pos.tpsPno_gg00 := NIL_PAGE_NO_GG00
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b31pointer_list (VAR nptr : tbd_nodeptr);
 
VAR
      finish : boolean;
      pRec   : tgg00_RecPtr;
      index  : integer;
      epos   : integer;
 
BEGIN
WITH nptr^ DO
    BEGIN
    IF  BODY_BEG_BD00 < nd_bottom
    THEN
        BEGIN
        index  := FIRST_REC_INDEX_BD00;
        epos   := BODY_BEG_BD00;
        finish := false;
        REPEAT
            nd_pointer_list[ MAX_POINTERINDEX_BD00 - index ] := epos;
            pRec := @nd_body [epos];
            epos := epos + b01rec_align (pRec^.recLen_gg00);
            IF  epos >= nd_bottom
            THEN
                finish := true
            ELSE
                index := index + 1
            (*ENDIF*) 
        UNTIL
            finish;
        (*ENDREPEAT*) 
        nd_record_cnt := index + 1
        END
    ELSE
        nd_record_cnt := 0;
    (*ENDIF*) 
    nd_sorted := true
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
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);
 
VAR
      found      : boolean;
      bindex     : tsp00_Int4;
      br_nptr    : tbd_node_ptrs;
      br_neighbs : tbd_neighbors;
 
BEGIN
WITH current, curr_tree_id, curr_trans^ DO
    BEGIN
    IF  NOT (index = FIRST_REC_INDEX_BD00)
    THEN
        index := index - 1
    ELSE
        IF  nptr.np_ptr^.nd_id = fileRoot_gg00
        THEN
            trError_gg00 := e_no_prev_record
        ELSE
            BEGIN
            prev_leaf        := NIL_PAGE_NO_GG00;
            br_nptr.np_ptr   := NIL;
            br_nptr.np_cbptr := NIL;
            (* *)
            b13r_release_node (nptr, current, lru_normal);
            bd30ReleaseSubTree (current);
            IF  trError_gg00 = e_ok
            THEN
                bd50FindFirstLevelIndexNode (reckey, KeyLen, br_nptr, br_neighbs, found, current);
            (*ENDIF*) 
            IF  (trError_gg00 = e_ok) AND (NOT found)
            THEN
                trError_gg00 := e_no_prev_record;
            (*ENDIF*) 
            IF  trError_gg00 = e_ok
            THEN
                bd51SearchBranch (current, @reckey, KeyLen, br_nptr.np_ptr, bindex);
            (*ENDIF*) 
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                IF  NOT (bindex = FIRST_REC_INDEX_BD00)
                THEN
                    bindex := bindex - 1
                ELSE
                    BEGIN
                    (* *)
                    (* left index node on level 1 is needed *)
                    (* *)
                    IF  br_neighbs.ln = NIL_PAGE_NO_GG00
                    THEN
                        trError_gg00 := e_no_prev_record
                    ELSE
                        BEGIN
                        (* tree level is at least two *)
                        IF  ftsPerm_egg00 IN fileType_gg00
                        THEN
                            BEGIN
                            (* br_nptr is equal to currIndexNptrs_bd00 *)
                            bd30ReleaseSubTree (current);
                            bd30GetSubTree (current, br_neighbs.ln);
                            IF  trError_gg00 = e_ok
                            THEN
                                br_nptr := currIndexNptrs_bd00
                            (*ENDIF*) 
                            END
                        ELSE
                            BEGIN
                            (* for temp trees no currIndexNptrs_bd00 is available *)
                            b13r_release_node (br_nptr, current, lru_normal);
                            bd13GetNode (current, br_neighbs.ln, plmLock_ebd00, nr_for_read, br_nptr)
                            END;
                        (*ENDIF*) 
                        IF  trError_gg00 = e_ok
                        THEN
                            bindex := br_nptr.np_ptr^.nd_record_cnt - 1
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                prev_leaf := bd52SubtreePno (br_nptr.np_ptr, bindex);
                bd13GetNode (current, prev_leaf, plmLock_ebd00, nr_for_read, nptr);
                IF  trError_gg00 = e_ok
                THEN
                    index := nptr.np_ptr^.nd_record_cnt - 1
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  (NOT (ftsPerm_egg00 IN fileType_gg00)) AND (br_nptr.np_ptr <> NIL)
            THEN
                b13r_release_node (br_nptr, current, lru_normal)
            (*ENDIF*) 
            END;
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b31repl_in_leaf (VAR b : tgg00_Rec;
            VAR nptr    : tbd_node_ptrs;
            index       : integer;
            left        : tsp00_PageNo;
            VAR current : tbd_current_tree);
 
VAR
      pRec        : tgg00_RecPtr;
      newlength   : tsp00_Int2;
      target      : tsp00_Int2;
      cnt         : integer;
      i           : integer;
      diff        : integer;
      source_pos  : tsp00_Int4;
      DelSpaceLen : tsp00_Int4;
 
BEGIN
WITH nptr, np_ptr^, current, curr_tree_id, curr_trans^  DO
    BEGIN
    trError_gg00 := e_ok;
    target       := nd_pointer_list [MAX_POINTERINDEX_BD00 - index];
    pRec         := @nd_body [target];
    newlength    := b.len;
    diff := abs(b01rec_align (pRec^.recLen_gg00) - b01rec_align (newlength));
    IF  pRec^.recLen_gg00 = newlength
    THEN
        BEGIN
        g10mv ('VBD31 ',   9,    
              sizeof (b), sizeof (np_ptr^),
              @b, 1, @np_ptr^, target, newlength, trError_gg00);
        IF  trError_gg00 = e_move_error
        THEN
            BEGIN
            trError_gg00 := e_data_page_corrupted;
            b06dump_bad_page (trTaskId_gg00, 'd', FILE_EXT_COR_BD00, nd_id, np_ptr, 1);
            END
        ELSE
            b13w_release_node (nptr, current)
        (*ENDIF*) 
        END
    ELSE
        IF  newlength < pRec^.recLen_gg00
        THEN
            BEGIN
            b35del_space (np_ptr, target, diff, curr_trans);
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                g10mv ('VBD31 ',  10,    
                      sizeof (b), sizeof (np_ptr^),
                      @b, 1, @np_ptr^, target, newlength, trError_gg00);
                IF  trError_gg00 = e_move_error
                THEN
                    BEGIN
                    trError_gg00 := e_data_page_corrupted;
                    b06dump_bad_page (trTaskId_gg00, 'd', FILE_EXT_COR_BD00, nd_id, np_ptr, 1);
                    END
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                FOR i := FIRST_REC_INDEX_BD00 TO nd_record_cnt - 1 DO
                    BEGIN
                    IF  nd_pointer_list [MAX_POINTERINDEX_BD00 - i] > target
                    THEN
                        nd_pointer_list [MAX_POINTERINDEX_BD00 - i] :=
                              nd_pointer_list [MAX_POINTERINDEX_BD00 - i] - diff
                    (*ENDIF*) 
                    END;
                (*ENDFOR*) 
                IF  ((nd_bottom - BODY_BEG_BD00 + ((nd_record_cnt)*POINTERSIZE_BD00))
                    < HALF_COVERING_BD00)
                    AND (nd_id <> fileRoot_gg00)
                    AND (NOT (ftsDynamic_egg00 IN fileType_gg00))
                THEN
                    BEGIN
                    IF  NOT nd_sorted
                    THEN
                        b31sort_entries (np_ptr, curr_trans);
                    (*ENDIF*) 
                    IF  trError_gg00 = e_ok
                    THEN
                        IF  ftsPerm_egg00 in fileType_gg00
                        THEN
                            b34p_leafunderflow (nptr, left, current)
                        ELSE
                            b34t_leafunderflow (nptr, left, current)
                        (*ENDIF*) 
                    (*ENDIF*) 
                    END
                ELSE
                    b13w_release_node (nptr, current)
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END
        ELSE
            (* newlength > oldlength*)
            IF  (nd_bottom + diff) > (MAX_BOTTOM_BD00 - ((nd_record_cnt)*POINTERSIZE_BD00))
            THEN
                BEGIN
                DelSpaceLen := b01rec_align(pRec^.recLen_gg00);
                b35del_space (np_ptr, target, DelSpaceLen, curr_trans);
                IF  trError_gg00 = e_ok
                THEN
                    BEGIN
                    FOR i := FIRST_REC_INDEX_BD00 TO nd_record_cnt - 1 DO
                        BEGIN
                        IF  nd_pointer_list [MAX_POINTERINDEX_BD00 - i] > target
                        THEN
                            nd_pointer_list [MAX_POINTERINDEX_BD00 - i] :=
                                  nd_pointer_list [MAX_POINTERINDEX_BD00 - i] - DelSpaceLen
                        (*ENDIF*) 
                        END;
                    (*ENDFOR*) 
                    IF  index < nd_record_cnt - 1
                    THEN
                        BEGIN
                        cnt        := POINTERSIZE_BD00 * (nd_record_cnt - 1 - index);
                        source_pos := MAX_BOTTOM_BD00 - ((nd_record_cnt)*POINTERSIZE_BD00);
                        SAPDB_PascalOverlappingMove ('VBD31 ',  11,    
                              sizeof (np_ptr^), sizeof (np_ptr^),
                              @np_ptr^, source_pos,
                              @np_ptr^, source_pos+POINTERSIZE_BD00, cnt, trError_gg00);
                        IF  trError_gg00 = e_move_error
                        THEN
                            BEGIN
                            trError_gg00 := e_data_page_corrupted;
                            b06dump_bad_page (trTaskId_gg00, 'd', FILE_EXT_COR_BD00, nd_id, np_ptr, 1);
                            END
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                    nd_record_cnt := nd_record_cnt - 1
                    END;
                (*ENDIF*) 
                IF  NOT nd_sorted
                THEN
                    b31sort_entries (np_ptr, curr_trans);
                (*ENDIF*) 
                IF  trError_gg00 = e_ok
                THEN
                    b33addoverflow (b, nptr, index, left, current)
                (*ENDIF*) 
                END
            ELSE
                BEGIN
                b35add_space (np_ptr, target, diff, curr_trans);
                IF  trError_gg00 = e_ok
                THEN
                    BEGIN
                    g10mv ('VBD31 ',  12,    
                          sizeof (b), sizeof (np_ptr^),
                          @b, 1, @np_ptr^, target, newlength, trError_gg00);
                    IF  trError_gg00 = e_move_error
                    THEN
                        BEGIN
                        trError_gg00 := e_data_page_corrupted;
                        b06dump_bad_page (trTaskId_gg00, 'd', FILE_EXT_COR_BD00, nd_id, np_ptr, 1);
                        END
                    ELSE
                        BEGIN
                        FOR i := FIRST_REC_INDEX_BD00 TO nd_record_cnt - 1 DO
                            BEGIN
                            IF  nd_pointer_list [MAX_POINTERINDEX_BD00 - i] > target
                            THEN
                                nd_pointer_list [MAX_POINTERINDEX_BD00 - i] :=
                                      nd_pointer_list [MAX_POINTERINDEX_BD00 - i] + diff
                            (*ENDIF*) 
                            END;
                        (*ENDFOR*) 
                        b13w_release_node (nptr, current)
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END;
            (*ENDIF*) 
        (*ENDIF*) 
    (*ENDIF*) 
    IF  trError_gg00 <> e_ok
    THEN
        BEGIN
        IF  np_ptr <> NIL
        THEN
            b13r_release_node (nptr, current, lru_normal);
        (*ENDIF*) 
        IF  ftsConcurrent_egg00 IN fileType_gg00
        THEN
            bd06CorruptedTreeHandling (curr_tree_id,
                  bd31x4TreeUpdateFailed_csp03, trError_gg00);
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b31search_entry (VAR current : tbd_current_tree;
            VAR rk     : tsp00_Key;
            KeyLen     : tsp00_Int4;
            VAR nptr   : tbd_nodeptr;
            VAR index  : tsp00_Int4;
            VAR result : tbd_searchresult);
 
VAR
      l_result : tsp00_LcompResult;
      pos      : tsp00_Int4;
      maxindex : tsp00_Int4;
      lwb      : tsp00_Int4;
      upb      : tsp00_Int4;
      lpos     : tsp00_Int4;
      count    : tsp00_Int4;
      pRec     : tgg00_RecPtr;
 
BEGIN
(* Offsets are aligned !*)
WITH current.curr_trans^, nptr^ DO
    BEGIN
    trError_gg00 := e_ok;
    (*  upb <= lwb *)
    upb          := nd_record_cnt - 1;
    lwb          := FIRST_REC_INDEX_BD00;
    maxindex     := upb;
    index        := FIRST_REC_INDEX_BD00;
    result       := nonefound;
    IF  nd_record_cnt <> 0
    THEN
        BEGIN
        REPEAT
            count := upb - lwb + 1;
            IF  count > 2
            THEN
                BEGIN
                lpos := upb - (count DIV 2);
                pos  := nd_pointer_list [ MAX_POINTERINDEX_BD00 - lpos ];
                IF  (pos < BODY_BEG_BD00) OR (pos > nd_bottom)
                THEN
                    trError_gg00 := e_illegal_entrypos;
                (*ENDIF*) 
                IF  trError_gg00 = e_ok
                THEN
                    BEGIN
                    pRec := @nd_body [pos];
                    IF  (pRec^.recLen_gg00 > MAX_RECLEN_GG00 ) OR
                        (pRec^.recLen_gg00 < MIN_RECORD_LEN_BD00)
                    THEN
                        trError_gg00 := e_illegal_entrylength
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                IF  trError_gg00 = e_ok
                THEN
                    BEGIN
                    s30cmp1 (rk, 1, KeyLen, pRec^.recBody_gg00, 1,
                          pRec^.recKeyLen_gg00, l_result);
                    IF  l_result = l_equal
                    THEN
                        BEGIN
                        index := lpos;
                        result := thisfound
                        END
                    ELSE
                        IF  l_result = l_less
                        THEN
                            upb := lpos
                        ELSE
                            lwb := lpos
                        (*ENDIF*) 
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END
            ELSE
                IF  count = 2
                THEN
                    BEGIN
                    lpos := upb;
                    pos  := nd_pointer_list[ MAX_POINTERINDEX_BD00 - lpos ];
                    IF  (pos < BODY_BEG_BD00) OR (pos > nd_bottom)
                    THEN
                        trError_gg00 := e_illegal_entrypos;
                    (*ENDIF*) 
                    IF  trError_gg00 = e_ok
                    THEN
                        BEGIN
                        pRec := @nd_body [pos];
                        IF  (pRec^.recLen_gg00 > MAX_RECLEN_GG00 ) OR
                            (pRec^.recLen_gg00 < MIN_RECORD_LEN_BD00)
                        THEN
                            trError_gg00 := e_illegal_entrylength
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                    IF  trError_gg00 = e_ok
                    THEN
                        BEGIN
                        s30cmp1 (rk, 1, KeyLen, pRec^.recBody_gg00, 1,
                              pRec^.recKeyLen_gg00, l_result);
                        IF  l_result = l_equal
                        THEN
                            BEGIN
                            index  := lpos;
                            result := thisfound
                            END
                        ELSE
                            IF  l_result = l_less
                            THEN
                                upb := lwb
                            ELSE
                                lwb := upb
                            (*ENDIF*) 
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END
                ELSE (*  count = 1 *)
                    BEGIN
                    lpos := upb;
                    pos  := nd_pointer_list[ MAX_POINTERINDEX_BD00 - lpos ];
                    IF  (pos < BODY_BEG_BD00) OR (pos > nd_bottom)
                    THEN
                        trError_gg00 := e_illegal_entrypos;
                    (*ENDIF*) 
                    IF  trError_gg00 = e_ok
                    THEN
                        BEGIN
                        pRec := @nd_body [pos];
                        IF  (pRec^.recLen_gg00 > MAX_RECLEN_GG00 ) OR
                            (pRec^.recLen_gg00 < MIN_RECORD_LEN_BD00)
                        THEN
                            trError_gg00 := e_illegal_entrylength
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                    IF  trError_gg00 = e_ok
                    THEN
                        BEGIN
                        s30cmp1 (rk, 1, KeyLen, pRec^.recBody_gg00, 1,
                              pRec^.recKeyLen_gg00, l_result);
                        IF  l_result = l_equal
                        THEN
                            BEGIN
                            index  := lpos;
                            result := thisfound
                            END
                        ELSE
                            IF  l_result = l_less
                            THEN
                                BEGIN
                                index  := lpos;
                                result := nextfound
                                END
                            ELSE
                                BEGIN
                                IF  lpos = maxindex
                                THEN
                                    BEGIN
                                    index  := lpos;
                                    result := lastfound
                                    END
                                ELSE
                                    BEGIN
                                    index  := lpos + 1;
                                    result := nextfound
                                    END
                                (*ENDIF*) 
                                END
                            (*ENDIF*) 
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
            (*ENDIF*) 
        UNTIL
            (result <> nonefound) OR (trError_gg00 <> e_ok);
        (*ENDREPEAT*) 
        IF  trError_gg00 <> e_ok
        THEN
            BEGIN
            IF  trError_gg00 = e_illegal_entrypos
            THEN
                BEGIN
                b06dump_bad_page (trTaskId_gg00, 'd', FILE_EXT_COR_BD00, nd_id, nptr, 1);
                g01opmsg (sp3p_knldiag, sp3m_error, csp03_b31_5_illegal_entrypos,
                      csp3_n_btree, 'Illegal entry pos       ', pos);
                b06write_filename_and_root (current.curr_tree_id)
                END
            ELSE
                IF  trError_gg00 = e_illegal_entrylength
                THEN
                    BEGIN
                    b06dump_bad_page (trTaskId_gg00, 'd', FILE_EXT_COR_BD00, nd_id, nptr, 1);
                    g01opmsg (sp3p_knldiag, sp3m_error, bd31IllegalEntryLength_csp03,
                          csp3_n_btree, 'Illegal rec len for pos ', pos);
                    b06write_filename_and_root (current.curr_tree_id)
                    END
                (*ENDIF*) 
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b31sort_entries (VAR nptr : tbd_nodeptr;
            t : tgg00_TransContextPtr);
 
VAR
      finish  : boolean;
      pRec    : tgg00_RecPtr;
      index   : integer;
      n_epos  : integer;
      nn_epos : integer;
      nn      : tbd_node;
 
BEGIN
IF  t^.trError_gg00 <> e_data_page_corrupted
THEN
    IF  NOT (nptr^.nd_sorted) AND (BODY_BEG_BD00 < nptr^.nd_bottom)
    THEN
        BEGIN
        nn     := nptr^;
        index  := FIRST_REC_INDEX_BD00;
        n_epos := BODY_BEG_BD00;
        finish := false;
        REPEAT
            nn_epos := nn.nd_pointer_list [MAX_POINTERINDEX_BD00 - index];
            pRec    := @nn.nd_body [nn_epos];
            SAPDB_PascalOverlappingMove ('VBD31 ',  13,    
                  sizeof (nn), sizeof (nptr^),
                  @nn, nn_epos, @nptr^, n_epos, pRec^.recLen_gg00, t^.trError_gg00);
            IF  t^.trError_gg00 = e_move_error
            THEN
                BEGIN
                finish := true;
                t^.trError_gg00 := e_data_page_corrupted;
                b06dump_bad_page (t^.trTaskId_gg00, 'd', FILE_EXT_COR_BD00,
                      nn.nd_id, @nn, 1);
                END;
            (*ENDIF*) 
            nptr^.nd_pointer_list[ MAX_POINTERINDEX_BD00 - index ] := n_epos;
            n_epos := n_epos + b01rec_align (pRec^.recLen_gg00);
            IF  n_epos >= nptr^.nd_bottom
            THEN
                finish := true
            ELSE
                index := index + 1
            (*ENDIF*) 
        UNTIL
            finish;
        (*ENDREPEAT*) 
        nptr^.nd_sorted := true
        END
    (*ENDIF*) 
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b31t_append_to_temp_leaf (VAR b : tgg00_Rec;
            VAR nptr     : tbd_node_ptrs;
            VAR tree_pos : tgg00_FilePos;
            VAR current  : tbd_current_tree);
 
VAR
      target : tsp00_Int2;
 
BEGIN
WITH nptr, np_ptr^, b, tree_pos, current, curr_trans^ DO
    BEGIN
    IF  (nd_bottom + len) > (MAX_BOTTOM_BD00 - ((nd_record_cnt+1)*POINTERSIZE_BD00))
    THEN
        b33t_add_new_temp_leaf (b, nptr, tree_pos, current)
    ELSE
        BEGIN
        tpsIndex_gg00 := tpsIndex_gg00 + 1;
        target    := nd_bottom;
        nd_bottom := nd_bottom + (((len+REC_ALIGN_BD00-1)DIV REC_ALIGN_BD00)*REC_ALIGN_BD00);
        g10mv ('VBD31 ',  14,    
              sizeof (b), sizeof (np_ptr^),
              @b, 1, @np_ptr^, target, len, trError_gg00);
        IF  trError_gg00 = e_move_error
        THEN
            BEGIN
            trError_gg00 := e_data_page_corrupted;
            b06dump_bad_page (trTaskId_gg00, 'd', FILE_EXT_COR_BD00,
                  nd_id, np_ptr, 1);
            b06write_filename_and_root (curr_tree_id)
            END
        ELSE
            BEGIN
            nd_pointer_list [MAX_POINTERINDEX_BD00 - tpsIndex_gg00] := target;
            nd_record_cnt := nd_record_cnt + 1;
            nd_sorted     := true;
            b13w_release_node (nptr, current)
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  (trError_gg00 <> e_ok) AND (np_ptr <> NIL)
    THEN
        b13r_release_node (nptr, current, lru_normal)
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b31t_prev_temp_search (VAR nptr : tbd_node_ptrs;
            VAR index   : integer;
            VAR current : tbd_current_tree);
 
VAR
      prevLeafPage : tsp00_PageNo;
 
BEGIN
WITH nptr, current, curr_trans^ DO
    BEGIN
    prevLeafPage  := np_ptr^.nd_left;
    IF  NOT (index = FIRST_REC_INDEX_BD00)
    THEN
        index := index - 1
    ELSE
        IF  prevLeafPage = NIL_PAGE_NO_GG00
        THEN
            trError_gg00 := e_no_prev_record
        ELSE
            BEGIN
            b13r_release_node (nptr, current, lru_normal);
            bd13GetNode (current, prevLeafPage, plmLock_ebd00, nr_for_read, nptr);
            IF  trError_gg00 = e_ok
            THEN
                index := np_ptr^.nd_record_cnt - 1
            (*ENDIF*) 
            END
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b31w_next_search (VAR nptr : tbd_node_ptrs;
            VAR index   : integer;
            VAR current : tbd_current_tree);
 
VAR
      last : boolean;
      next : tsp00_PageNo;
 
BEGIN
(* only valid for not concurrent, temporary files !!! *)
WITH nptr, current, curr_trans^ DO
    BEGIN
    next := np_ptr^.nd_right;
    b35next_entry (np_ptr, index, last);
    IF  last
    THEN
        IF  next = NIL_PAGE_NO_GG00
        THEN
            trError_gg00 := e_no_next_record
        ELSE
            BEGIN
            b13w_release_node (nptr, current);
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                bd13GetNode (current, next, plmLock_ebd00, nr_for_update, nptr);
                index := FIRST_REC_INDEX_BD00
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
    ELSE
        trError_gg00 := e_ok
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd31del_sep (VAR sep : tgg00_Lkey;
            level          : tsp00_Int2;
            VAR current    : tbd_current_tree);
 
VAR
      indexorderlist : tbd00_OrderList;
 
BEGIN
current.curr_lvl_1_pno        := NIL_PAGE_NO_GG00;
indexorderlist.olstCount_bd00 := 0;
b54del_index (@sep.keyVal_gg00, sep.keyLen_gg00, level, indexorderlist);
b54execute_indexorder (indexorderlist, current);
END;
 
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
.PA 
