.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
*****************************************************
Copyright by SAP AG, 2000
SAP Database Technology
 
Release :      Date : 2000-10-31
*****************************************************
modname : VKB721
changed : 2000-10-31
module  : Single_Select_Part2
 
Author  : ElkeZ
Created : 1987-09-22
*****************************************************
 
Purpose : Search in one table using the strategy
          information build in AK
 
Define  :
 
        PROCEDURE
              k721add_into_result (
                    VAR t                : tgg00_TransContext;
                    VAR selrec           : tkb7_select_param;
                    VAR next_mblock      : tgg_mess_block_ptr);
 
        PROCEDURE
              k721call_later_output (
                    VAR m       : tgg_mess_block;
                    VAR res_buf : tsp_buf;
                    h_keylen    : integer);
 
        PROCEDURE
              k721do_avg (
                    VAR m        : tgg_mess_block;
                    VAR selrec   : tkb7_select_param;
                    later_output : boolean;
                    h_keylen     : integer);
 
        PROCEDURE
              k721do_rowno (
                    VAR m      : tgg_mess_block;
                    VAR selrec : tkb7_select_param);
 
        PROCEDURE
              k721eval_pagecount (VAR m : tgg_mess_block);
 
        PROCEDURE
              k721null_result (
                    VAR m         : tgg_mess_block;
                    VAR selrec    : tkb7_select_param;
                    VAR sel       : tgg_select_fields_param;
                    act_cntresult : tsp_int4;
                    later_output  : boolean;
                    h_keylen      : integer);
 
        PROCEDURE
              k721catalog_add_into_result (
                    VAR m           : tgg_mess_block;
                    VAR sel         : tgg_select_fields_param;
                    VAR selrec_ctxt : tsp_buf;
                    VAR getrec      : tkb7_get_param;
                    VAR result_rec  : tgg_rec_buf;
                    VAR one_res_rec : tgg_rec_buf;
                    VAR res_cnt     : tsp_int4);
 
        PROCEDURE
              k721read_subquery (VAR m : tgg_mess_block);
 
        PROCEDURE
              k721strat_distribution (
                    VAR m                : tgg_mess_block;
                    VAR getrec           : tkb7_get_param;
                    VAR selrec           : tkb7_select_param;
                    VAR selfields        : tgg_select_fields_param;
                    VAR gg_strategy      : tgg07_StrategyInfo;
                    VAR finding_possible : boolean);
 
        PROCEDURE
              k721inv_gets (
                    VAR m            : tgg_mess_block;
                    VAR ftrees       : tgg_two_tree_ids;
                    VAR startkeys    : tgg_two_keys;
                    VAR stopkeys     : tgg_two_keys;
                    VAR act_key      : tgg_lkey;
                    istop            : tgg_bd_inv_set;
                    mtype            : tgg_message2_type;
                    VAR getrec       : tkb7_get_param;
                    VAR selrec       : tkb7_select_param;
                    VAR selfields    : tgg_select_fields_param;
                    VAR oj_info      : tkb7_oj_info_type);
 
        PROCEDURE
              k721function_add (
                    VAR m      : tgg_mess_block;
                    VAR selrec : tkb7_select_param;
                    aggr       : boolean);
 
        FUNCTION
              k721out_entry (
                    st_addr     : tgg_stack_list_ptr;
                    start_entry : integer) : integer;
 
.CM *-END-* define --------------------------------------
***********************************************************
 
Use     :
 
        FROM
              Scanner : VAK01;
 
        VAR
              a01diag_monitor_on : boolean;
 
      ------------------------------ 
 
        FROM
              KB_stringcol_copy_trunc_expand :  vkb43;
 
        PROCEDURE
              k43_ins_copy_column (
                    VAR mtrans            : tgg00_TransContextPtr;
                    VAR mheader           : tgg00_MessBufHeader;
                    VAR src_tree          : tgg00_FileId;
                    VAR dst_tree          : tgg00_FileId;
                    VAR src_tab_id        : tgg00_Surrogate;
                    VAR src_surr          : tgg00_Surrogate;
                    VAR dst_surr          : tgg00_Surrogate;
                    dst_has_shrt_col_file : boolean;
                    VAR shrt_col_rec_ptr  : tgg00_RecPtr;
                    use_shrt_col_rec      : boolean);
 
      ------------------------------ 
 
        FROM
              KB_trans_state : VKB50;
 
        PROCEDURE
              k50hash (
                    VAR buf    : tsp00_Buf;
                    pos        : tsp00_Int4;
                    len        : tsp00_Int4;
                    VAR resbuf : tsp00_Buf;
                    respos     : integer);
 
      ------------------------------ 
 
        FROM
              KB_transaction : VKB53;
 
        PROCEDURE
              k53wait (
                    VAR t     : tgg00_TransContext;
                    MessType  : tgg00_MessType;
                    MessType2 : tgg00_MessType2);
 
      ------------------------------ 
 
        FROM
              KB_ins_del_upd : VKB61;
 
        PROCEDURE
              k61del_select (
                    VAR m          : tgg00_MessBlock;
                    VAR old_k      : tgg00_Lkey;
                    VAR old_rec    : tgg00_Rec;
                    granted_lock   : tgg00_LockReqMode);
 
        PROCEDURE
              k61ins_select (
                    VAR m       : tgg00_MessBlock;
                    VAR new_rec : tgg00_Rec;
                    is_nokey    : boolean;
                    upd_dupl    : boolean;
                    rec_count   : tsp00_Int4);
 
      ------------------------------ 
 
        FROM
              KB_inv_link_trigger_handling : VKB62;
 
        PROCEDURE
              k62late_unique_check (VAR m : tgg00_MessBlock);
 
      ------------------------------ 
 
        FROM
              KB_update : VKB63;
 
        PROCEDURE
              k63upd_select (
                    VAR m               : tgg00_MessBlock;
                    VAR rec_key         : tgg00_Lkey;
                    VAR old_rec         : tgg00_Rec;
                    sel_addr            : tgg00_SelectParamPtr;
                    result_ptr          : tsp00_MoveObjPtr;
                    result_len          : tsp00_Int4;
                    VAR new_rec         : tsp_buf;
                    VAR key_upd_file_id : tgg00_FileId;
                    granted_lock        : tgg00_LockReqMode);
 
      ------------------------------ 
 
        FROM
              KB_get : VKB71;
 
        PROCEDURE
              k71sel_qualification_test (
                    VAR m          : tgg_mess_block;
                    VAR sel        : tgg_select_fields_param;
                    check_new_rec  : boolean;
                    VAR rec        : tgg_rec_buf);
 
        PROCEDURE
              k71inv_col_select (
                    VAR t           : tgg00_TransContext;
                    VAR sel         : tgg_select_fields_param;
                    VAR stack_desc  : tgg_stack_desc;
                    sec_key         : tsp00_KeyAddr;
                    sec_key_len     : tsp_int2;
                    prim_key        : tsp00_KeyAddr;
                    prim_key_len    : tsp_int2;
                    VAR unqualified : boolean);
 
      ------------------------------ 
 
        FROM
              Single_Select : VKB73;
 
        PROCEDURE
              k73_index_range (
                    VAR m                : tgg_mess_block;
                    VAR getrec           : tkb7_get_param;
                    VAR selrec           : tkb7_select_param;
                    VAR sel              : tgg_select_fields_param;
                    VAR strat            : tgg07_StrategyInfo;
                    VAR finding_possible : boolean);
 
        PROCEDURE
              k73in_multindex (
                    VAR m      : tgg_mess_block;
                    VAR getrec : tkb7_get_param;
                    VAR selrec : tkb7_select_param;
                    VAR sel    : tgg_select_fields_param;
                    VAR strat  : tgg07_StrategyInfo);
 
        PROCEDURE
              k73sub_multindex (
                    VAR m                : tgg_mess_block;
                    VAR getrec           : tkb7_get_param;
                    VAR selrec           : tkb7_select_param;
                    VAR sel              : tgg_select_fields_param;
                    VAR strat            : tgg07_StrategyInfo);
 
        PROCEDURE
              k73select_invrec (
                    VAR m                   : tgg_mess_block;
                    VAR ftrees              : tgg_two_tree_ids;
                    VAR keypair             : tgg_two_keys;
                    VAR stop_keypair        : tgg_two_keys;
                    VAR startkey            : tgg_lkey;
                    stop                    : tgg_bd_inv_set;
                    VAR b                   : tgg_rec_buf;
                    VAR sel                 : tgg_select_fields_param;
                    VAR result_buf          : tsp_buf;
                    new_inv_not_found_error : tgg_basis_error);
 
        PROCEDURE
              k73prim_key_build (
                    VAR selrec        : tkb7_select_param;
                    VAR prim_startkey : tgg_lkey;
                    VAR prim_stopkey  : tgg_lkey;
                    VAR istop         : tgg_bd_inv_set;
                    VAR e             : tgg_basis_error);
 
      ------------------------------ 
 
        FROM
              KB_Join_Select : VKB74;
 
        PROCEDURE
              k74join_with_left_result (
                    VAR m           : tgg_mess_block;
                    VAR getrec      : tkb7_get_param;
                    VAR sel         : tgg_select_fields_param;
                    VAR selrec      : tkb7_select_param;
                    VAR listkey     : tgg_lkey;
                    return_next_key : boolean);
&       ifdef trace
 
      ------------------------------ 
 
        FROM
              RTE_kernel : VEN101;
 
        PROCEDURE
              vdebug_break (debug_break_pos : tsp_int4);
&       endif
 
      ------------------------------ 
 
        FROM
              filesysteminterface_1 : VBD01;
 
        VAR
              b01fullkey    : tsp00_Key;
 
        PROCEDURE
              b01tcreate_file (
                    VAR t           : tgg00_TransContext;
                    VAR act_tree_id : tgg00_FileId);
 
        PROCEDURE
              b01destroy_file (
                    VAR t           : tgg00_TransContext;
                    VAR act_tree_id : tgg00_FileId);
 
        PROCEDURE
              bd01CalculateRecordsAndLeaves(
                    VAR Trans           : tgg00_TransContext;
                    VAR FileId          : tgg00_FileId;
                    VAR NumberOfLeaves  : tsp00_Int4;
                    VAR NumberOfRecords : tsp00_Int4 );
 
      ------------------------------ 
 
        FROM
              filesysteminterface_2 : VBD02;
 
        PROCEDURE
              b02calculate_page_count (
                    VAR t            : tgg00_TransContext;
                    VAR file_id      : tgg00_FileId;
                    VAR startkey     : tgg00_Lkey;
                    VAR stopkey      : tgg00_Lkey;
                    VAR page_count   : tsp00_Int4);
 
        PROCEDURE
              b02eval_page_count (
                    VAR t            : tgg00_TransContext;
                    VAR file_id      : tgg00_FileId;
                    VAR startkey     : tgg00_Lkey;
                    VAR stopkey      : tgg00_Lkey;
                    count_records    : boolean;
                    VAR page_count   : tsp00_Int4;
                    VAR min_page_cnt : tsp00_Int4;
                    VAR record_cnt   : tsp00_Int4);
 
        PROCEDURE
              b02kb_select_rec (
                    VAR t             : tgg00_TransContext;
                    VAR file_id       : tgg00_FileId;
                    VAR RecKey        : tsp00_Key;
                    VAR RecKeyLen     : tsp00_Int2;
                    VAR StopKey       : tsp00_Key;
                    StopKeyLen        : tsp00_Int4;
                    recbuf_size       : tsp00_Int4;
                    recbuf_ptr        : tsp00_MoveObjPtr;
                    ignore_vwait      : boolean;
                    VAR sel           : tgg00_SelectFieldsParam;
                    VAR stack_desc    : tgg00_StackDesc;
                    VAR unqualified   : boolean;
                    VAR granted_lock  : tgg00_LockReqMode);
 
        PROCEDURE
              b02next_record (
                    VAR t       : tgg00_TransContext;
                    VAR file_id : tgg00_FileId;
                    VAR rk      : tgg00_Lkey;
                    inclusive   : boolean;
                    VAR b       : tgg00_Rec);
 
      ------------------------------ 
 
        FROM
              filesysteminterface_3 : VBD03;
 
        PROCEDURE
              b03calculate_page_count (
                    VAR t            : tgg00_TransContext;
                    VAR file_id      : tgg00_FileId;
                    VAR startkey     : tgg00_Lkey;
                    VAR stopkey      : tgg00_Lkey;
                    count_records    : boolean;
                    VAR page_count   : tsp00_Int4;
                    VAR min_page_cnt : tsp00_Int4;
                    VAR record_cnt   : tsp00_Int4);
 
        PROCEDURE
              b03get_inv (
                    VAR t              : tgg00_TransContext;
                    VAR act_tree_id    : tgg00_FileId;
                    VAR lk             : tgg00_Lkey;
                    VAR rk             : tgg00_Lkey;
                    VAR stop_rk        : tgg00_Lkey;
                    VAR CurrentPrimKey : tgg00_Lkey;
                    VAR bd_inv_info    : tgg00_BdInvSet;
                    count_only         : boolean;
                    wanted_lock        : tgg00_LockReqMode;
                    VAR b              : tgg00_KeylistBuf;
                    VAR primkeycnt     : tsp00_Int4;
                    VAR ll             : tsp00_Int4);
 
        PROCEDURE
              b03select_invrec (
                    VAR t            : tgg00_TransContext;
                    VAR file_ids     : tgg00_TwoFileIds;
                    VAR keypair      : tgg00_TwoKeys;
                    VAR stop_keypair : tgg00_TwoKeys;
                    VAR start_key    : tgg00_Lkey;
                    VAR invrange_set : tgg00_BdInvSet;
                    recbuf_size      : tsp00_Int4;
                    recbuf_ptr       : tsp00_MoveObjPtr;
                    VAR sel          : tgg00_SelectFieldsParam;
                    VAR stack_desc   : tgg00_StackDesc;
                    VAR granted_lock : tgg00_LockReqMode;
                    count_usage      : boolean);
 
      ------------------------------ 
 
        FROM
              filesysteminterface_7 : VBD07;
 
        PROCEDURE
              b07cadd_record (
                    VAR t           : tgg00_TransContext;
                    VAR act_tree_id : tgg00_FileId;
                    VAR b           : tsp_buf);
 
        PROCEDURE
              b07cappend_record (
                    VAR t        : tgg00_TransContext;
                    VAR file_id  : tgg00_FileId;
                    VAR tree_pos : tgg00_FilePos;
                    VAR b        : tsp_buf);
 
        PROCEDURE
              b07cnext_record (
                    VAR t           : tgg00_TransContext;
                    VAR act_tree_id : tgg00_FileId;
                    VAR rk          : tgg00_Lkey;
                    VAR set_result  : tgg00_BdSetResultRecord;
                    VAR tree_pos    : tgg00_FilePos;
                    VAR b           : tsp_buf);
 
        PROCEDURE
              b07cget_record (
                    VAR t           : tgg00_TransContext;
                    VAR act_tree_id : tgg00_FileId;
                    VAR rk          : tgg00_Lkey;
                    VAR b           : tsp_buf);
 
        PROCEDURE
              b07crepl_record (
                    VAR t           : tgg00_TransContext;
                    VAR act_tree_id : tgg00_FileId;
                    VAR b           : tsp_buf);
 
      ------------------------------ 
 
        FROM
              task_temp_data_cache : VBD21;
 
        PROCEDURE
              b21mp_root_put (
                    temp_cache_ptr : tgg00_TempDataCachePtr;
                    root : tsp00_PageNo);
 
      ------------------------------ 
 
        FROM
              ref_statistic : VBD73;
 
        PROCEDURE
              b73cmd_count (statement_kind : tgg00_RefInfoIndex);
 
        PROCEDURE
              b73cmds_count (
                    statement_kind : tgg00_RefInfoIndex;
                    count : tsp00_Int4);
 
      ------------------------------ 
 
        FROM
              Configuration_Parameter : VGG01;
 
        VAR
              g01code : tgg_code_globals;
              g01glob : tgg_kernel_globals;
 
      ------------------------------ 
 
        FROM
              Select_Help_Procedures : VGG04;
 
        FUNCTION
              g04inv_tfn (tfn : tgg00_Tfn) : boolean;
 
        PROCEDURE
              g04limitprimkeys (
                    VAR m           : tgg_mess_block;
                    VAR startkeyarr : tgg07_ColPosArr;
                    VAR start_key   : tgg_lkey;
                    VAR stopkeyarr  : tgg07_ColPosArr;
                    VAR stop_key    : tgg_lkey;
                    VAR use_stopkey : boolean;
                    in_stack        : tsp_int2;
                    in_cnt          : tsp_int2);
 
        PROCEDURE
              g04onevalue (
                    VAR m     : tgg_mess_block;
                    valpos     : tsp_int2;
                    last_field : boolean;
                    descending : boolean;
                    maxlen     : tsp_int2;
                    VAR key    : tgg_lkey);
 
        PROCEDURE
              g04subqvalue (
                    VAR subq_buf : tgg_rec_buf;
                    last_field   : boolean;
                    descending   : boolean;
                    maxlen       : tsp_int2;
                    VAR key      : tgg_lkey;
                    VAR e        : tgg_basis_error);
 
        PROCEDURE
              g04aggr_func (
                    VAR m          : tgg_mess_block;
                    VAR read_first : boolean;
                    VAR read_last  : boolean;
                    VAR optim      : boolean);
 
        PROCEDURE
              g04read_subquery (
                    VAR mblock      : tgg_mess_block;
                    VAR result      : tgg_rec_buf;
                    VAR subqtree_id : tgg00_FileId;
                    VAR m_key       : tgg_lkey;
                    VAR aux_error   : tgg_basis_error;
                    VAR ok          : boolean);
 
        PROCEDURE
              gg04subq_limitkey (
                    VAR mblock      : tgg_mess_block;
                    VAR subq_buf    : tgg_rec_buf;
                    VAR keyarr      : tgg07_ColPosArr;
                    VAR one_key     : tgg_lkey;
                    VAR use_stopkey : boolean);
 
      ------------------------------ 
 
        FROM
              RTE-Extension-10 : VSP10;
 
        PROCEDURE
              s10fil2 (
                    size     : tsp_int4;
                    VAR m    : tsp_moveobj;
                    pos      : tsp_int4;
                    len      : tsp_int4;
                    fillchar : char);
 
      ------------------------------ 
 
        FROM
              Kernel_move_and_fill : VGG10;
 
        PROCEDURE
              g10fil  (
                    mod_id         : tsp_c6;
                    mod_intern_num : tsp_int4;
                    source_upb     : tsp_int4;
                    VAR source     : tsp_key;
                    source_pos     : tsp_int4;
                    length         : tsp_int4;
                    fill_char      : char;
                    VAR e          : tgg_basis_error);
 
        PROCEDURE
              g10fil1 (
                    mod_id         : tsp_c6;
                    mod_intern_num : tsp_int4;
                    source_upb     : tsp_int4;
                    VAR source     : tsp_buf;
                    source_pos     : tsp_int4;
                    length         : tsp_int4;
                    fill_char      : char;
                    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     : tsp_buf;  source_pos : tsp_int4;
                    VAR destin     : tsp_key;  destin_pos : tsp_int4;
                    length         : tsp_int4;
                    VAR e          : tgg_basis_error);
 
        PROCEDURE
              g10mv2  (
                    mod_id         : tsp_c6;
                    mod_intern_num : tsp_int4;
                    source_upb     : tsp_int4;   destin_upb : tsp_int4;
                    VAR source     : tsp_resnum; source_pos : tsp_int4;
                    VAR destin     : tsp_buf;    destin_pos : tsp_int4;
                    length         : tsp_int4;
                    VAR e          : tgg_basis_error);
 
        PROCEDURE
              g10mv3  (
                    mod_id         : tsp_c6;
                    mod_intern_num : tsp_int4;
                    source_upb     : tsp_int4;          destin_upb : tsp_int4;
                    VAR source     : tsp_buf;           source_pos : tsp_int4;
                    VAR destin     : tkb7_select_param; destin_pos : tsp_int4;
                    length         : tsp_int4;
                    VAR e          : tgg_basis_error);
 
        PROCEDURE
              g10mv4  (
                    mod_id         : tsp_c6;
                    mod_intern_num : tsp_int4;
                    source_upb     : tsp_int4;     destin_upb : tsp_int4;
                    VAR source     : tgg_mess_info_buf; s_pos : tsp_int4;
                    VAR destin     : tsp_key;      destin_pos : tsp_int4;
                    length         : tsp_int4;
                    VAR e          : tgg_basis_error);
 
        PROCEDURE
              g10mv5  (
                    mod_id         : tsp_c6;
                    mod_intern_num : tsp_int4;
                    source_upb     : tsp_int4;     destin_upb : tsp_int4;
                    VAR source     : tsp_key;      source_pos : tsp_int4;
                    VAR destin     : tgg_mess_info_buf; d_pos : tsp_int4;
                    length         : tsp_int4;
                    VAR e          : tgg_basis_error);
 
        PROCEDURE
              g10mv6  (
                    mod_id         : tsp_c6;
                    mod_intern_num : tsp_int4;
                    source_upb     : tsp_int4; destin_upb : tsp_int4;
                    VAR source     : tsp_buf;  source_pos : tsp_int4;
                    VAR destin     : tsp_buf;  destin_pos : tsp_int4;
                    length         : tsp_int4;
                    VAR e          : tgg_basis_error);
 
        PROCEDURE
              g10mv7  (
                    mod_id         : tsp_c6;
                    mod_intern_num : tsp_int4;
                    source_upb     : tsp_int4; destin_upb : tsp_int4;
                    VAR source     : tsp_key;  source_pos : tsp_int4;
                    VAR destin     : tsp_key;  destin_pos : tsp_int4;
                    length         : tsp_int4;
                    VAR e          : tgg_basis_error);
 
        PROCEDURE
              g10mv8  (
                    mod_id         : tsp_c6;
                    mod_intern_num : tsp_int4;
                    source_upb     : tsp_int4;          destin_upb : tsp_int4;
                    VAR source     : tkb7_select_param; source_pos : tsp_int4;
                    VAR destin     : tsp_buf;           destin_pos : tsp_int4;
                    length         : tsp_int4;
                    VAR e          : tgg_basis_error);
 
        PROCEDURE
              g10mv9  (
                    mod_id         : tsp_c6;
                    mod_intern_num : tsp_int4;
                    source_upb     : tsp_int4;    destin_upb : tsp_int4;
                    VAR source     : tsp_moveobj; source_pos : tsp_int4;
                    VAR destin     : tgg00_FileId; destin_pos : tsp_int4;
                    length         : tsp_int4;
                    VAR e          : tgg_basis_error);
 
        PROCEDURE
              g10mv10 (
                    mod_id         : tsp_c6;
                    mod_intern_num : tsp_int4;
                    source_upb     : tsp_int4;       destin_upb : tsp_int4;
                    VAR source     : tgg_surrogate;  source_pos : tsp_int4;
                    VAR destin     : tsp00_Buf;      destin_pos : tsp_int4;
                    length         : tsp_int4;
                    VAR e          : tgg_basis_error);
 
        PROCEDURE
              g10mv11 (
                    mod_id         : tsp_c6;
                    mod_intern_num : tsp_int4;
                    source_upb     : tsp_int4; destin_upb : tsp_int4;
                    VAR source     : tsp_buf;  source_pos : tsp_int4;
                    VAR destin     : tsp_int4; destin_pos : tsp_int4;
                    length         : tsp_int4;
                    VAR e          : tgg_basis_error);
 
        PROCEDURE
              g10mv12 (
                    mod_id         : tsp_c6;
                    mod_intern_num : tsp_int4;
                    source_upb     : tsp_int4; destin_upb : tsp_int4;
                    VAR source     : tsp_key;  source_pos : tsp_int4;
                    VAR destin     : tsp_buf;  destin_pos : tsp_int4;
                    length         : tsp_int4;
                    VAR e          : tgg_basis_error);
 
        PROCEDURE
              g10mv13 (
                    mod_id         : tsp_c6;
                    mod_intern_num : tsp_int4;
                    source_upb     : tsp_int4;    destin_upb : tsp_int4;
                    VAR source     : tsp_moveobj; source_pos : tsp_int4;
                    VAR destin     : tsp_key;     destin_pos : tsp_int4;
                    length         : tsp_int4;
                    VAR e          : tgg_basis_error);
 
        PROCEDURE
              g10mv14 (
                    mod_id         : tsp_c6;
                    mod_intern_num : tsp_int4;
                    source_upb     : tsp_int4; destin_upb : tsp_int4;
                    VAR source     : tsp_buf;  source_pos : tsp_int4;
                    VAR destin     : tsp_key;  destin_pos : tsp_int4;
                    length         : tsp_int4;
                    VAR e          : tgg_basis_error);
 
        PROCEDURE
              g10mv15 (
                    mod_id         : tsp_c6;
                    mod_intern_num : tsp_int4;
                    source_upb     : tsp_int4;    destin_upb : tsp_int4;
                    VAR source     : tsp_buf;     source_pos : tsp_int4;
                    VAR destin     : tsp_moveobj; destin_pos : tsp_int4;
                    length         : tsp_int4;
                    VAR e          : tgg_basis_error);
 
        PROCEDURE
              g10mv16  (
                    mod_id         : tsp_c6;
                    mod_intern_num : tsp_int4;
                    source_upb     : tsp_int4;   destin_upb : tsp_int4;
                    VAR source     : tsp00_Buf;  source_pos : tsp_int4;
                    VAR destin     : tsp00_Buf;  destin_pos : tsp_int4;
                    length         : tsp_int4;
                    VAR e          : tgg_basis_error);
 
        PROCEDURE
              g10mv17 (
                    mod_id         : tsp_c6;
                    mod_intern_num : tsp_int4;
                    source_upb     : tsp_int4;        destin_upb : tsp_int4;
                    VAR source     : tsp00_Buf;       source_pos : tsp_int4;
                    VAR destin     : tgg00_Surrogate; destin_pos : tsp_int4;
                    length         : tsp_int4;
                    VAR e          : tgg_basis_error);
 
        PROCEDURE
              g10mvb  (
                    mod_id         : tsp_c6;
                    mod_intern_num : tsp_int4;
                    source_upb     : tsp_int4; destin_upb : tsp_int4;
                    VAR source     : tsp_buf;  source_pos : tsp_int4;
                    VAR destin     : tsp_buf;  destin_pos : tsp_int4;
                    length         : tsp_int4;
                    VAR e          : tgg_basis_error);
 
      ------------------------------ 
 
        FROM
              RTE-Extension-20 : VSP20;
 
        PROCEDURE
              s20ch4sw (
                    val        : tsp_int4;
                    sourceswap : tsp_swap_kind;
                    VAR dest   : tgg_mess_info_buf;
                    di         : tsp_int4;
                    destswap   : tsp_swap_kind);
 
        FUNCTION
              s20or4sw (
                    VAR source     : tsp_buf;
                    si             : tsp_int4;
                    sourceswap     : tsp_swap_kind;
                    destswap       : tsp_swap_kind) : tsp_int4;
 
      ------------------------------ 
 
        FROM
              RTE-Extension-30 : VSP30;
 
        PROCEDURE
              s30cmp (
                    VAR buf1     : tsp_buf;
                    fieldpos1    : tsp_int4;
                    fieldlength1 : tsp_int4;
                    VAR buf2     : tsp_buf;
                    fieldpos2    : tsp_int4;
                    fieldlength2 : tsp_int4;
                    VAR l_result : tsp_lcomp_result);
 
      ------------------------------ 
 
        FROM
              GET-Conversions : VSP40;
 
        PROCEDURE
              s40g4int (
                    VAR buf     : tsp_buf;
                    pos         : tsp_int4;
                    VAR dest    : tsp_int4;
                    VAR res     : tsp_num_error);
 
      ------------------------------ 
 
        FROM
              PUT-Conversions : VSP41;
 
        PROCEDURE
              s41plint (
                    VAR buf     : tsp_buf;
                    pos         : tsp_int4;
                    len         : integer;
                    frac        : integer;
                    source      : tsp_int4;
                    VAR res     : tsp_num_error);
 
        PROCEDURE
              s41p4int (
                    VAR buf     : tsp_buf;
                    pos         : tsp_int4;
                    source      : tsp_int4;
                    VAR res     : tsp_num_error);
 
      ------------------------------ 
 
        FROM
              Number-Arithmetic : VSP51;
 
        PROCEDURE
              s51add (
                    VAR left       : tsp_buf;
                    lpos           : tsp_int4;
                    llen           : integer;
                    VAR right      : tsp_buf;
                    rpos           : tsp_int4;
                    rlen           : integer;
                    VAR result     : tsp_buf;
                    respos         : tsp_int4;
                    reslen         : integer;
                    resfrac        : integer;
                    VAR resbytelen : integer;
                    VAR ret        : tsp_num_error);
 
        PROCEDURE
              s51sub (
                    VAR left       : tsp_buf;
                    lpos           : tsp_int4;
                    llen           : integer;
                    VAR right      : tsp_buf;
                    rpos           : tsp_int4;
                    rlen           : integer;
                    VAR result     : tsp_buf;
                    respos         : tsp_int4;
                    reslen         : integer;
                    resfrac        : integer;
                    VAR resbytelen : integer;
                    VAR ret        : tsp_num_error);
 
        PROCEDURE
              s51mul (
                    VAR left       : tsp_buf;
                    lpos           : tsp_int4;
                    llen           : integer;
                    VAR right      : tsp_buf;
                    rpos           : tsp_int4;
                    rlen           : integer;
                    VAR result     : tsp_buf;
                    respos         : tsp_int4;
                    reslen         : integer;
                    resfrac        : integer;
                    VAR resbytelen : integer;
                    VAR ret        : tsp_num_error);
 
        PROCEDURE
              s51div (
                    VAR left       : tsp_buf;
                    lpos           : tsp_int4;
                    llen           : integer;
                    VAR right      : tgg_rec_buf;
                    rpos           : tsp_int4;
                    rlen           : integer;
                    VAR result     : tgg_rec_buf;
                    respos         : tsp_int4;
                    reslen         : integer;
                    resfrac        : integer;
                    VAR resbytelen : integer;
                    VAR ret        : tsp_num_error);
 
      ------------------------------ 
 
        FROM
              Exponential-Functions: VSP52;
 
        PROCEDURE
              s52sqrt (
                    VAR source     : tsp_buf;
                    spos           : tsp_int4;
                    slen           : integer;
                    VAR result     : tsp_buf;
                    respos         : tsp_int4;
                    reslen         : integer;
                    resfrac        : integer;
                    VAR ret        : tsp_num_error);
&       ifdef TRACE
 
      ------------------------------ 
 
        FROM
              Test_Procedures : VTA01;
 
        PROCEDURE
              t01int4 (
                    debug    : tgg00_Debug;
                    nam      : tsp00_Sname;
                    int      : tsp00_Int4);
 
        PROCEDURE
              t01buf  (
                    level     : tgg00_Debug;
                    VAR buf   : tsp00_Buf;
                    pos_start : integer;
                    pos_end   : integer);
 
        PROCEDURE
              t01name (
                    debug : tgg00_Debug;
                    nam  : tsp00_Name);
 
        PROCEDURE
              t01messblock (
                    debug         : tgg00_Debug;
                    nam           : tsp00_Sname;
                    VAR m         : tgg00_MessBlock);
 
        PROCEDURE
              t01stackentry (
                    debug          : tgg00_Debug;
                    VAR st         : tgg00_StackEntry;
                    entry_index    : integer);
&       endif
 
      ------------------------------ 
 
        FROM
              Unionhandling: VKB722;
 
        PROCEDURE
              k722_add_union_record (
                    VAR t        : tgg00_TransContext;
                    VAR selrec   : tkb7_select_param);
 
      ------------------------------ 
 
        FROM
              KB_Fetch: VKB75;
 
        PROCEDURE
              k75pre_fetch (
                    VAR t        : tgg00_TransContext;
                    VAR tree_id  : tgg00_FileId;
                    VAR key      : tgg_lkey);
 
.CM *-END-* use -----------------------------------------
***********************************************************
 
Synonym :
 
        PROCEDURE
              b03get_inv;
 
              tgg_keylist_buf tsp_buf
 
        PROCEDURE
              b07cadd_record;
 
              tgg00_Rec tsp_buf
 
        PROCEDURE
              b07cappend_record;
 
              tgg00_Rec tsp_buf
 
        PROCEDURE
              b07cget_record;
 
              tgg00_Rec tsp_buf
 
        PROCEDURE
              b07crepl_record;
 
              tgg00_Rec tsp_buf
 
        PROCEDURE
              b07cnext_record;
 
              tsp00_MoveObj tsp_buf
 
        PROCEDURE
              g10fil;
 
              tsp_moveobj tsp_key
 
        PROCEDURE
              g10fil1;
 
              tsp_moveobj tsp_buf
 
        PROCEDURE
              g10mv1;
 
              tsp_moveobj tsp_buf
              tsp_moveobj tsp_key
 
        PROCEDURE
              g10mv2;
 
              tsp_moveobj tsp_resnum
              tsp_moveobj tsp_buf
 
        PROCEDURE
              g10mv3;
 
              tsp_moveobj tsp_buf
              tsp_moveobj tkb7_select_param
 
        PROCEDURE
              g10mv4;
 
              tsp_moveobj tgg_mess_info_buf
              tsp_moveobj tsp_key
 
        PROCEDURE
              g10mv5;
 
              tsp_moveobj tgg_mess_info_buf
              tsp_moveobj tsp_key
 
        PROCEDURE
              g10mv6;
 
              tsp_moveobj tsp_buf
 
        PROCEDURE
              g10mv7;
 
              tsp_moveobj tsp_key
 
        PROCEDURE
              g10mv8;
 
              tsp_moveobj tkb7_select_param
              tsp_moveobj tsp_buf
 
        PROCEDURE
              g10mv9;
 
              tsp_moveobj tgg00_FileId
 
        PROCEDURE
              g10mv10;
 
              tsp_moveobj tgg_surrogate
              tsp_moveobj tsp00_Buf
 
        PROCEDURE
              g10mv11;
 
              tsp_moveobj tsp_buf
              tsp_moveobj tsp_int4
 
        PROCEDURE
              g10mv12;
 
              tsp_moveobj tsp_key
              tsp_moveobj tsp_buf
 
        PROCEDURE
              g10mv13;
 
              tsp_moveobj tsp_key
 
        PROCEDURE
              g10mv14;
 
              tsp_moveobj tsp_buf
              tsp_moveobj tsp_key
 
        PROCEDURE
              g10mv15;
 
              tsp_moveobj tsp_buf
 
        PROCEDURE
              g10mv16;
 
              tsp_moveobj tsp00_Buf
 
        PROCEDURE
              g10mv17;
 
              tsp_moveobj tsp00_Buf
              tsp_moveobj tgg00_Surrogate
 
        PROCEDURE
              g10mvb;
 
              tsp_page tsp_buf
 
        PROCEDURE
              k63upd_select;
 
              tgg00_Rec  tsp_buf
 
        PROCEDURE
              s20ch4sw;
 
              tsp_moveobj tgg_mess_info_buf
 
        FUNCTION
              s20or4sw;
 
              tsp_moveobj tsp_buf
 
        PROCEDURE
              s30cmp;
 
              tsp_moveobj tsp_buf
 
        PROCEDURE
              s40g4int;
 
              tsp_moveobj tsp_buf
 
        PROCEDURE
              s41plint;
 
              tsp_moveobj tsp_buf
 
        PROCEDURE
              s41p4int;
 
              tsp_moveobj tsp_buf
 
        PROCEDURE
              s51add;
 
              tsp_moveobj tsp_buf
 
        PROCEDURE
              s51sub;
 
              tsp_moveobj tsp_buf
 
        PROCEDURE
              s51mul;
 
              tsp_moveobj tsp_buf
 
        PROCEDURE
              s51div;
 
              tsp_moveobj tsp_buf
              tsp_moveobj tgg_rec_buf
 
        PROCEDURE
              s52sqrt;
 
              tsp_moveobj tsp_buf
 
.CM *-END-* synonym -------------------------------------
***********************************************************
 
Specification:
 
KB721SEARCH_THROUGH_ONE_INVLIST
------------------------------------
 
All records whose primary key is contained in a particular inversion
list are checked during this procedure to find out whether they meet
all specified qualifications and are further processed if appropriate.
 
K721DO_ROWNO
------------------------------------
 
If the rowno is supposed to appear in the output, due to 'distinct'
or 'order-by' data that might be present it is not
possible to immediately enter the rowno into the result record
when the result table is built while following the correct sequence.
The procedure catches up and the rowno is assigned in the output a
maximum of 32 times.
 
.CM *-END-* specification -------------------------------
***********************************************************
 
Description:
 
K721DO_AVG
------------------------------------
 
During the processing of single result records, only
the values needed for building the average (summed up)
and the number of results can be determined.
In this procedure the average values are formed out of these two
values when all records have been found.
All records that contain the totalled values are accessed in a
repeat loop.  Due to the group formation, there can be more than one of
these records.  If there is a maximum of one (no group formation,
keyl = 4), the summation record is present already in the buffer to which
otherwise
the records are being transferred from the file one after the other.
However, this record is not located in the file.
In a 'while' loop, all function stack entries are branched in.
A run-through of the stack entries is facilitated by the fact
that the last qualification stack entry and all the function stack
entries indicate how many stack entries there have been since the
previous function stack entry.
For AVG and SUM, there is a risk of an internal overflow, indicated
by the exponent 255 and the mantissa h'99 99 ..'.  A value that
has overflowed in this manner is now transferred to the NULL value.  The
NULL value cannot be entered immediately during the summation because it
would be overwritten by the value to be added during the next addition.
The average is formed from the sum (located at epos) and the
quantity of values located 11 bytes before the sum.  For the two values,
11 bytes are always available for the maximum numerical representation.
If a record has been updated (AVG formed or overflow handled),
it is replaced in the file or newly inserted.
 
K721DO_ROWNO
------------------------------------
 
After the result records have been sorted, rownos that are supposed
to appear in the output are entered here.
The positions in the result record at which the rowno value is to
be located are determined in the 1st 'while' loop and entered in
'rowarr'.  In the case of simple non-join-select, the position is
normally found in the stack entry (epos).
For join-selects, the epos gives the position for the single-table
intermediate result from which it (position onfrom) must be placed
in the total-join-result (position onto (position in buf.info) + 4).
The rowno value must therefore be written to the position onto+4.  If
several fields were combined in n_pos (onfrom < epos, onfrom+length > epos),
'onto' must still be altered by the distance from 'epos' to 'onfrom'.
 
In the repeat loop, all result records are retrieved.  The rowno
value, which is always processed as fixed(10,0) (greater values do
not fit in countresult : int4), is transferred to the first of the
desired positions and copied from there to the other positions.
The record in the file is replaced and the key of this record is
identified in hkey so that a further search can start from this key.
 
K721NULL_RESULT
------------------------------------
 
If the output list contains SET functions but no result record has
been generated because no record fulfilled the qualifications, a
Null record is generated.  This record contains the NULL value for all
fields except 'count' outputs, which are filled with 0 (represented
numerically by h'00 80 00 00 ..').  'Count' outputs are always 11 bytes
long.
 
KB721IN_KEYRECORD
------------------------------------
 
The strategy 'keyin' signifies an '=' or 'IN' condition on the
only key field.  'Cntin' indicates the number of IN values;
for '=', cntin is 1.  Cntin value stack entries are located right to
stpos (stack-entry position of the key-field stack entry).  A stack
entry can become st_dummy via G04_IN_BETWEEN_CHANGE.
The values are transferred one after another to startkey and further
processed by SELECT_GETS.
 
IN_INVLIST
------------------------------------
 
The strategy 'fieldin' signifies an '=' or IN condition on a singly
inverted field.
The inversion file name is formed that contains the userid and the
table name as does the primary file name but that has a different
identifier as its 1st byte and has as its 2nd byte the external column
number of the inverted field (located in ecol_tab[ 1 ] of the field
stack entry).
Cntin indicates the number of IN values; for '=', cntin is 1.
Cntin value stack entries are located right to stpos (stack entry
position of the field stack entries).  A stack entry can become
st_dummy via G04_IN_BETWEEN_CHANGE.
A special situation arises when '=' conditions have been entered
by the user as LIKE.  The value then appears three times in a
row in part2 (twice with a st_dummy stack entry and once with a value
stack entry).  This means that the first dummy stack entry can also be
used as a position indicator in part2.
The values are transferred one after another to invkey.  For indexes
that are set up in descending order, the value must be reversed.  This
means that the NULL values are always transformed to h'00', length 1;
all other values must be represented in the maximum length for this
field (specified in ecol_tab[ 2 ] of the field stack entry) so
that a correct sorting can be achieved.
The current field length (elen_var) can be greater than the
maximum possible length since the parameter is requested as float(18)
at 'numberfield = :param'.
For indexes that are set up in ascending order, NULL values are
used with the length 1 and values with variable fields are used with
their true length or with their maximum length (ecol_tab[ 2 ]).
Via KB721SEARCH_THROUGH_ONE_INVLIST, the associated inversion
list is processed completely.
 
MULTINV
------------------------------------
 
The strategy 'multindex' signifies '=' conditions or range conditions
('>','>=','<','<=', BETW, LIKE) on all or on the first x fields of a
named, multi-field index.  Named, single-field indexes are handled
as unnamed.
Via G04_MINDEX-KEY, the two secondary keys that define the
multiple 'range' (invkey, stopkey) are formed from the individual
field values.
Mi_equal = true indicates that 'equality' conditions have been
specified for all fields contained in the named index, i.e. only one
inversion list is to be processed via
KB721SEARCH_THROUGH_ONE_INVLIST.
Mi_equal = false indicates that only the first x fields of the
named index with the number index_no show a range or '=' condition.
This means that several inversion lists that all have the same
beginning must be processed.
In the loop, starting from the current inversion-list value
(the first time, it is only the initial segment), the next inversion
list is found, compared with the stopkey ('stopkey')
and, if appropriate, completely processed via
KB721SEARCH_THROUGH_ONE_INVLIST.
 
INTERSECTINV
------------------------------------
 
The strategy 'intinv' signifies '=' conditions on more than one
singly inverted field.
The intersection of the associated inversion lists is formed in
K73_SINTER_SECTE, i.e. a new inversion list is formed in the
temporary file invfn which contains only primary keys
that were contained in all the inversion lists viewed, i.e. whose
records already fulfilled all the '=' conditions.
This new inversion list is processed with
KB721SEARCH_THROUGH_ONE_INVLIST and the temporary file is deleted.
VIEWKEY_SEARCH
 
The strategy j_viewkey signifies that the qualification should be
tested for the primary key specified in part2 of the mess_buffer.
The key is transferred to act_key and further processed via
SELECT_GETS.
 
KB721SEARCH_THROUGH_ONE_INVLIST
------------------------------------
 
When the procedure is initiated, the inversion file name in invfn,
the list key in invkey, startkey and stopkey (primary key limits)
are assigned by G04_LIMITKEY.
Beginning with startkey (incl. startkey) a list of primary keys
that is contained in the inversion list is requested.  This list
is located in invkeybuf in the following form:
 
 
 ||  1         len        ||
 ||-----------------------||
 || len |   primary key   ||
 ||-----------------------||
 ||                       ||
 
 
One after another, the primary keys are transferred to act_key and the
records are further processed via SELECT_GETS.
If there are additional primary keys (error = b_buffer_limit),
starting from act_key (excl. this value) the next series of primary
keys is requested and processed.  b03get_inv ensures that no
primary key > stopkey is supplied if primary_stop is set.
SEQ_SEARCH
 
The basetable must be searched sequentially; primary key
limits (startkey and stopkey) must be taken into account.
Searching and processing occur via SELECT_GETS.
 
KB721SELECT_GETS
------------------------------------
 
In SELECT-GETS, depending on the mtype (= mm_direct, if calling
from IN_KEYRECORD or KB721SEARCH_THROUGH_ONE_INVLIST; otherwise,
mm_first or mm_next), either the record identified by act_key is
found and processed directly or the next record (inclusive or
exclusive) with relation to act_key is found and processed.
Sel is the parameter that is passed on, up to the qualification
test.  Result_length describes the total length of the result
accumulated up until that time.  Since, unlike select, no fixed
output positions can be specified for insert-select, (variable length
fields and keys) and, therefore, the next field is appended to the
current record, the length must be set to 4 (2 bytes total length,
2 bytes key length) or to 4 + length of the syskey, which cannot
be ascertained by select.
Act_cntresult is required for rowno conditions.  The value
'countresult' sent back to the user is not yet updated since even
a record that has been found is not always included in the result,
depending on 'distinct' and the like.
For insert-select, the file version of the table to be searched
must be used.
The search, the qualification test and any locking of the record
that may be necessary occur in K71ALL_GET; for set updates
and set deletes, a write-lock is requested immediately.
If a lock request cannot be granted immediately (another process
has a contending lock, kb_wait_for_lock_release), it waits in K53WAIT
for the lock release or for the request timeout
value to elapse.
If everything is ok, the same record (act_key not updated) is again
searched and tested since it could have been deleted or updated in
the meantime.
During the direct search, errors such as e_key_not_found and
kb_qual/view_violation can occur and must not be allowed to cause
the entire search to be cancelled, i.e. they must be destroyed.
If a result record is found (e_ok) and there are more than one
strategy (intern_dist), an attempt is made to insert
the primary key in the help file.  If this fails (b_duplicate_key),
a result record was already formed from the same primary record and,
for this reason, it must not be inserted in the result file
(put_into = false).
Whereas it was unimportant for the search as a whole whether
processing was done for a set select, set update or set delete or an
insert-select, a different procedure must, of course, be followed when
a result record is used further.
For set updates and set deletes, the number of records processed
increases and the actual updating is executed by K61UPD_SELECT and
K61DEL_SELECT.
For insert-selects, the result record is completed
(total length of the record = len, keylen only if the length of the
user-specific key was not already assigned when the
record was built (is_nokey)).
The file version used is that of the file in which the insertion is
to be made and the insertion is executed via K61INS_SELECT.
Since the implicit locking of the key in the new file (totally
unrelated to the read lock on the primary record in the basetable)
can again lead to a wait state (kb_wait_for_lock_release),
the same procedure is applied as for the search.
For the next search, the file version of the search file is again
used (and overwritten by the other version only in the case of an error
since the other version is required for rollbacks in the insert file).
The number of records processed (countresult) is incremented only
if there were no problems; otherwise an error causes it to terminate if
the error message b_duplicate_key was not overridden by IGNORE DUPLICATES.
For set selects, the key length and total length (unlike
insert-select, fixed from very the beginning) are entered and, depending
on the degree of difficulty, inserted in the result file via
FUNCTION_ADD or K72_ADD_INTO_RESULT.
 
K72_ADD_INTO_RESULT
------------------------------------
 
The finished result record is located in selrec.result and should be
incorporated in the file result_fn/result_tr.
The incremented result counter is set at the end of the result key
(due to the ORDER_BY fields that could be contained in the key).
If the user specifies DISTINCT, a check is run in UNIQUE_ADD and,
if appropriate, the record is inserted.
If the second result record is being processed but a
SELECT .. INTO was requested, there is an error.
If only one result is expected, in many cases it does not need to
be buffered in the file (additional BD orders and I/O); there is space
in the count_buf, which is otherwise unused.
If keylen = 4, i.e. the result counter alone forms the key,
b02append_record can be used
(which is easier for BD than add_record)
since the insertion position 'all the way to the right' is already
established in the file by the counter notation
(highest-byte .. lowest-byte).
If the rowno_value (rowno < (=) value) is reached, the search is
terminated; however, this error is then destroyed in
K72_SINGLE_SELECT or VKB74 join_last_part because it is not an error
from the user's point of view but instead serves to end all loops.
 
UNIQUE_ADD
------------------------------------
 
The point is to recognize as quickly as possible whether a record
is 'distinct' from all the result records already present.  Therefore,
something is entered in the result key (after the ORDER-BY fields,
before the result counter) that serves as a type of hash value for
the entire record.  When DISTINCT is entered, the fields
specified in ORDER BY must also be output fields simultaneously,
i.e. they are also used to test distinctness.  For this reason, it
must be ensured that records with the same ORDER-BY values and
distinct 'hash' value immediately follow one another.  The record to
be examined has the highest result counter up to that point (end of
the key).  Therefore, starting from this key, a forward (previous)
search must be run in the result file until a record that appears
identical has been found or it has been determined that none can be
found because the beginning of the key (without result counter) looks
different from the record found for 'previous'.
The 'hash' value is formed by combining the hex values of up to
32 bytes that are evenly distributed throughout the record and packing
them into a 4-byte integer.
In the repeat loop, as many result records are retrieved as fit in
the buf_rec.buf at that particular time.  They are stored there as
follows:
 
 
      2    ||              ||
  ---------||--------------||
 | total   || result record||
 |  length ||              ||
  ---------||--------------||
           ||              ||
 
 
A result record has the following structure:
 
                |        keylen              |
    2      2        n       4         4       len-keylen-4
  --------------------------------------------------------
 | len | keylen | order  | hash  | result    | non-key    |
 |     |        | fields | value |  counter  |  fields    |
  --------------------------------------------------------
 
 
n stands for 0 - 248.
 
At the same time, B07CPREV_RECORD ensures that only those records
are transferred to the buffer that have the same key value (excl.
the result counter) as the current result record.  BD must carry out
this test if buf_rec.len > 0 (length to be compared).
If records have been supplied, they are examined until one
final statement on the distinctness of the new result record can be
established; not all records in the buffer necessarily have to be
examined.
The non-key fields of the records are compared.  If
they are equal (not_equal = false), the search is terminated.
The record must not be inserted.
The search is continued through several buffers, if appropriate,
until no other record is found in the result file with the same
key value (excl. the result counter).
If the record must be inserted, the result count is requested
as in K72_ADD_INTO_RESULT and, if appropriate, an error is sent.
Otherwise, the result count (already incremented in
K72_ADD_INTO_RESULT) must be lowered again.
 
FUNCTION_ADD
------------------------------------
 
This procedure is used to enter the MIN|MAX|SUM|COUNT values (AVG
is formed in DO_AVG) in result records, of which there can be more than
one due to GROUP BY.  (GROUP BY and ORDER BY requests entered
simultaneously by the user result in a series of K72_SINGLE_SELECT calls,
i.e. they do not have to be viewed simultaneously ]
The GROUP BY fields are located at the beginning of the
result-record key.  Manipulations in the key are always done with
h'00 00 00 01' as the result counter, since there is only one record
per group.
The current result record is located in 'result'.  The record
in which the function values are stored for one group, if it is already
present, is either located in count_buf (no GROUP BY specified) or is
transferred to this buffer.
If such a record does not yet exist for this group
(e_key_not_found), it is created new; for SELECT .. INTO, the number
of such buffers is again checked.
It is again assumed that the last qualification stack entry and
all function stack entries indicate how many positions there have been
since the previous function stack entry.
For DISTINCT AVG|SUM|COUNT, the existence of a particular combination
is registered in the help file specially created for this purpose by
inserting the group field values plus the current value as a key.
If there is an error (b_error <> e_ok), the entire KB processing must
be terminated; otherwise, there cannot be a harmless b_duplicate_key.
For all set functions except COUNT(*), an undef byte leads to
warning2.
For COUNT and AVG (11 bytes before the summation value already
contained in 'result'), the number of values found is entered (normally
a 1, in the case of NULL value, a 0).  The undef byte is explicitly
set to chr(0).
The summation buffer created is entered in the result file or,
if only one is expected, stored in count_buf.
If a summation buffer for this group is present, only those values
are important that are not NULL or that are required for COUNT(*)
(since NULL values are also included in the count).
'New' means that the value should be copied from the result
record to the summation record.   This is the case if, for MIN or
MAX, a value is lower or higher than the current value or that the
summation buffer contains NULL. The latter also applies for the
operators SUM and AVG.
For DISTINCT AVG|SUM|COUNT, the distinct test takes place in the
special files (group field values plus current value as a key).
If the value combination is already present,  the current value is
simply forgotten since the operators are never queried again.
Otherwise, the locally retained operator is transformed into
one without 'DISTINCT'.
Repl_needed signifies that at least one change has been carried
out in the summation buffer and, therefore, it must be replaced in
the file.
For COUNT and AVG, the counter in the summation buffer is
(additionally) incremented.
If necessary (new), the current value from 'result' is sent to
the summation buffer; for undef values, warning2 is set and, if
appropriate, the record in the file is replaced.
If a rowno condition was specified (maxresult < maxint4), only
the first maxresult results are used to form the function values;
when this limit is reached, the search is terminated.
 
PROCEDURE optimize_stack
 
This procedure is called for the strategies 'sequential', 'fieldin',
'between', 'intinv', and 'multindex' in the case where the result
table is being built immediately (and not at fetch time); the
procedure is called AFTER the startkeys and stopkeys for the
strategy have been built up via G04 calls; the
purpose of this optimization is to destroy all stack conditions that
are fully covered by the strategy itself, i.e stack conditions that
will evaluate to TRUE (VKB71) in any case because all the values
retrieved adhere to that condition due to the construction of
startkeys and stopkeys.
 
 
Note: not all conditions used for startkeys and stopkey can be
      automatically discarded :
 
      Example: multiple index (mi1, mi2, mi3)
               condition " mi1 >= 'x' AND mi2 >= 'y' "
 
               --> both conditions are used for building a startkey,
                   yet only the first condition may be discarded;
                   the second is needed to check all multiple keys
                   with mi1 > 'x'
 
Since the invalidation of stack entries is a fairly critical issue,
the software philosophy is defensive here; invalidation takes
place only at 'the last moment' before a BD call, and some
redundant checking is performed to make sure that the correct
sequence of stack entries is discarded.
 
Invalidation takes place by repeated calls to 'invalidate_stack'
 
For any of the above strategies, two phases of invalidation normally
take place: first for the secondary key(s) stack entries, then for
the primary key(s).
 
Note that a stack entry may represent a condition for both primary
and secondary keys (e.g. if the primary key is part of a multiple
index).  Hence, invalidation of conditions for primary keys
generally may not take place in the first phase.
 
After invalidation is completed, the stack is searched for
conditions remaining.  If none are left, then mqual_cnt and mqual_pos
are adjusted respectively.
 
PROCEDURE invalidate_stack
 
This procedure performs the actual invalidation of a condition
within the qualification stack.
 
 
        st_varcol,..               st_dummy
        st_value     ------>       st_dummy
         ...                         ....
        st_value + op_..           st_bool, epos=1 (TRUE)
 
 
Before a condition is invalidated, it is checked to see if it
has exactly the expected format.  If it differs in any point, then
invalidation is aborted; (an additional, not optimized condition
does no harm, the opposite is a catastrophy).
 
KB721ADD_INTO_OUTER_JOIN_RESULT
------------------------------------
 
The result -record will be added to the selr_id_outer_join -file. At
first call (selr_cnt_outer_join = 0) the selr_id_outer_join -file
will be created.
 
KB721ADD_OUTER_JOIN_RESULT
------------------------------------
 
The layout of the result -record is changed. The record is moved
back from position 3 (position of the keylength) to end of the record
of ckb7_oj_key_off1 -bytes. Into the free bytes the rec_id (counter of
current record of the keypart) and the outer_join -specification were
inserted.
It means, that one byte specificates if the record is put as a
left- or rightouterjoin record. In case of calling
kb721add_outer_join_result with oj_spec = ckb7_ojoin_full there will
be two records added one as left- and the other as rightouterjoin-record.
 
KB721BUILD_OUTER_RESULT
------------------------------------
 
This procedure searches through the stackentries and
replaces columns of the curr_tab by null_values in the result-record.
 
KB721MAKE_OUTER_JOIN_RESULT
------------------------------------
 
This Procedure reads all records of selr_id_outer_join. For each record
a search through oj_ok_keys_id -file take place. If no record with
the outerjoinkey is found in oj_ok_keys_id then the record must be
inserted as outerjoin-record. This happens by calling
kb721build_outer_result followed by k721add_into_result.
 
At last the auxiliaryfiles oj_ok_keys_id and selr_id_outer_join are
destroyed.
 
KB721STORE_OUTER_KEY
------------------------------------
 
At first call (selr_count_result = 1) the oj_ok_keys_id -file
will be created. The rec_id (countresult of buf_rec) is stored
as left- and as rightouterjoinkey -record in oj_ok_keys_id -file.
Duplictes will be ignored.
'
.CM *-END-* description ---------------------------------
***********************************************************
.CM -lll-
Code    :
 
 
CONST
      c_check_new_rec   = true (* k71sel_qualification_test *);
      c_aggr            = true (* k721function_add          *);
      c_single_index    = true (* kb721in_invlist  *);
      c_ignore_vwait    = true (* b02kb_select_rec *);
      c_return_next_key = true (* k74join_with_left_result *);
      c_direct_read     = true (* kb721seq_search, kb721eq_keyrecord *);
      c_usage_count     = true (* b03select_invrec *); (* h.b. PTS 1104210 *)
      c_use_shc_buf     = true (* PTS 1105795 M.Ki. *);
 
 
(*------------------------------*) 
 
PROCEDURE
      kb721add_into_outer_join_result (
            VAR t      : tgg00_TransContext;
            VAR selrec : tkb7_select_param);
 
BEGIN
WITH selrec, selr_selectbuffer, result DO
    BEGIN
    IF  (selr_cnt_outer_join = 0)
    THEN
        BEGIN
        selr_id_outer_join             := selr_resf_id;
        selr_id_outer_join.fileTfnTemp_gg00 := ttfnOuterJoin_egg00;
        b01tcreate_file (t, selr_id_outer_join);
        END;
    (*ENDIF*) 
    IF  t.trError_gg00 = e_ok
    THEN
        b07cadd_record (t, selr_id_outer_join, result.buf);
    (*ENDIF*) 
    IF  (t.trError_gg00 = e_duplicate_key)
    THEN
        t.trError_gg00 := e_ok
    ELSE
        selr_cnt_outer_join := succ (selr_cnt_outer_join);
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb721add_outer_result (
            VAR m       : tgg_mess_block;
            VAR selrec  : tkb7_select_param;
            oj_spec     : integer;
            VAR oj_info : tkb7_oj_info_type);
 
VAR
      ojtype       : integer;
      ojrec_id_pos : integer;
      rec_id       : tsp_int4;
 
BEGIN
WITH m, mb_qual^, selrec, selr_selectbuffer, oj_info DO
    BEGIN
&   ifdef trace
    t01buf (kb, result.buf, 1, result.len);
    t01buf (kb, buf_rec.buf, 1, buf_rec.len);
&   endif
    CASE oj_spec OF
        ckb7_ojoin_left,
        ckb7_ojoin_full :
            BEGIN
            ojtype       := ckb7_ojoin_left;
            ojrec_id_pos := cgg_rec_key_offset + mxgg_rescnt + 1;
            END;
        ckb7_ojoin_right :
            BEGIN
            ojtype       := ckb7_ojoin_right;
            ojrec_id_pos := cgg_rec_key_offset + 1;
            END;
        OTHERWISE
            BEGIN
            ojtype        := ckb7_ojoin_full;
            ojrec_id_pos  := 0;
            END;
        END;
    (*ENDCASE*) 
    mb_trns^.trError_gg00 := e_ok;
    g10mvb ('VKB721',   1,    
          sizeof(result.buf), sizeof(result.buf),
          result.buf, sizeof(result.len) + 1,
          result.buf, sizeof(result.len) + 1 + ckb7_oj_key_off1,
          result.len - sizeof(result.len), mb_trns^.trError_gg00);
    result.len    := result.len    + ckb7_oj_key_off1;
    result.keylen := result.keylen + ckb7_oj_key_off1;
    result.recVarcolOffset_gg00 := 0;
    result.recVarcolCnt_gg00    := 0;
    WHILE (ojtype < ckb7_ojoin_full) AND
          (mb_trns^.trError_gg00 = e_ok) DO
        BEGIN
        g10mv11 ('VKB721',   2,    
              sizeof(buf_rec.buf), sizeof(rec_id),
              buf_rec.buf, ojrec_id_pos,
              rec_id, 1, sizeof(rec_id), mb_trns^.trError_gg00);
        IF  rec_id > 0
        THEN
            BEGIN
            g10mv6 ('VKB721',   3,    
                  sizeof(buf_rec.buf), sizeof(result.buf),
                  buf_rec.buf, ojrec_id_pos,
                  result.buf, cgg_rec_key_offset, sizeof(rec_id),
                  mb_trns^.trError_gg00);
            result.keylen            := ckb7_oj_key_off1 -
                  sizeof(result.keylen);
            result.buf[ result.keylen + 4 ] := chr (ojtype);
            IF  mb_trns^.trError_gg00 = e_ok
            THEN
                kb721add_into_outer_join_result (mb_trns^, selrec);
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  (ojtype = ckb7_ojoin_left) AND (oj_spec = ckb7_ojoin_full)
        THEN
            BEGIN
            ojtype       := ckb7_ojoin_right;
            ojrec_id_pos := cgg_rec_key_offset + 1;
            END
        ELSE (* *** exit while *** *)
            ojtype      := ckb7_ojoin_full;
        (*ENDIF*) 
        END;
    (*ENDWHILE*) 
&   ifdef trace
    t01buf (kb, result.buf, 1, result.len);
    t01buf (kb, buf_rec.buf, 1, buf_rec.len);
&   endif
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb721build_outer_result (
            VAR m      : tgg_mess_block;
            VAR selrec : tkb7_select_param;
            curr_tab   : char);
 
VAR
      i    : integer;
      stop : integer;
 
BEGIN
WITH m, mb_qual^, selrec, selr_selectbuffer, result DO
    BEGIN
    i    := succ (mqual_pos);
    stop := mb_st^[ mqual_pos ].epos;
    WHILE (i < stop) DO
        BEGIN
        WHILE (i < stop)                                 AND
              (NOT (((mb_st^[ i ].etype = st_fixkey) OR
              (mb_st^[ i ].etype = st_varkey)        OR
              (mb_st^[ i ].etype = st_fixcol)        OR
              (mb_st^[ i ].etype = st_varkey)          ) AND
              (mb_st^[ i ].ecol_tab[ 2 ] = curr_tab))       )    DO
            i := succ (i);
        (*ENDWHILE*) 
        WHILE (i < stop) AND
              (mb_st^[ i ].etype <> st_output) DO
            i := succ (i);
        (*ENDWHILE*) 
        IF  (i < stop)                  AND
            (mb_st^[ i ].etype = st_output) AND
            (mb_st^[ i ].epos > keylen)
        THEN
            WITH mb_st^[ i ] DO
                BEGIN
                (* *** define-Byte *** *)
                buf[ epos ] := csp_undef_byte;
                (* *** NULL VALUE *** *)
                g10fil1 ('VKB721',   4,    
                      sizeof(buf), buf, epos + 1,
                      elen_var - 1, csp_defined_byte,
                      m.mb_trns^.trError_gg00);
                END;
            (*ENDWITH*) 
        (*ENDIF*) 
        i := succ (i);
        END;
    (*ENDWHILE*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb721count_one_invlist (
            VAR m      : tgg_mess_block;
            VAR getrec : tkb7_get_param;
            VAR selrec : tkb7_select_param;
            VAR selfields    : tgg_select_fields_param);
 
VAR
      _ftrees   : tgg_two_tree_ids;
      _stopkeys : tgg_two_keys;
      _startkeys  : tgg_two_keys;
      _start    : integer;
      _stop     : integer;
      _i        : integer;
      _istop    : tgg_bd_inv_set;
 
BEGIN
_istop := [ ];
_start := m.mb_qual^.mqual_pos + m.mb_st^[ m.mb_qual^.mqual_pos ].epos - 1;
_stop  := m.mb_qual^.mqual_pos + m.mb_qual^.mqual_cnt - 1;
selrec.selr_count_bd := true;
;
FOR _i := _start TO _stop DO
    IF  NOT (( m.mb_st^[ _i ].etype = st_dummy ) OR
        (( m.mb_st^[ _i ].etype = st_bool ) AND
        ( m.mb_st^[ _i ].epos = cgg_is_true )) OR
        ( m.mb_st^[ _i ].etype = st_jump_false ) OR
        (( m.mb_st^[ _i ].etype = st_op ) AND ( m.mb_st^[ _i ].eop = op_and )))
    THEN
        selrec.selr_count_bd := false;
    (*ENDIF*) 
(*ENDFOR*) 
IF  ( selrec.selr_count_bd )
THEN
    kb721search_through_one_invlist( m, getrec, selrec, selfields )
ELSE
    BEGIN
    _startkeys.listkey.len := selrec.selr_invkey.len;
    IF  ( _startkeys.listkey.len > 0 )
    THEN
        g10mv7 ('VKB721',   5,    
              sizeof( selrec.selr_invkey.k ), sizeof( _startkeys.listkey.k ),
              selrec.selr_invkey.k, 1,
              _startkeys.listkey.k, 1, _startkeys.listkey.len,
              m.mb_trns^.trError_gg00);
    (*ENDIF*) 
    _stopkeys.listkey.len := selrec.selr_invkey.len;
    IF  ( _stopkeys.listkey.len > 0 )
    THEN
        g10mv7 ('VKB721',   6,    
              sizeof( selrec.selr_invkey.k ), sizeof( _stopkeys.listkey.k ),
              selrec.selr_invkey.k, 1,
              _stopkeys.listkey.k, 1, _stopkeys.listkey.len,
              m.mb_trns^.trError_gg00);
    (*ENDIF*) 
    _istop := _istop + [ secondary_stop ];
    k73prim_key_build( selrec, _startkeys.reckey, _stopkeys.reckey,
          _istop, m.mb_trns^.trError_gg00 );
    _ftrees.inv_id  := selrec.selr_inv_id;
    _ftrees.file_id := m.mb_qual^.mtree;
    ;
    IF  ( m.mb_trns^.trError_gg00 = e_ok )
    THEN
        k73select_invrec( m, _ftrees, _startkeys, _stopkeys,
              selrec.selr_startkey, _istop, selrec.selr_selectbuffer.buf_rec,
              selfields, selrec.selr_selectbuffer.result.buf,
              e_no_next_record );
    (*ENDIF*) 
    IF  ( m.mb_trns^.trError_gg00 = e_no_next_record )
    THEN
        m.mb_trns^.trError_gg00 := e_ok
    (*ENDIF*) 
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb721eq_keyrecord (
            VAR m           : tgg_mess_block;
            VAR getrec      : tkb7_get_param;
            VAR selrec      : tkb7_select_param;
            VAR selfields   : tgg_select_fields_param;
            VAR gg_strategy : tgg07_StrategyInfo);
 
VAR
      _oj_info        : tkb7_oj_info_type;
 
BEGIN
IF  ( gg_strategy.str_strategy = strat_key_equal_sub )
THEN
    BEGIN
    selfields.sfp_bd_mess2_type := mm_direct;
    kb721subq_key_select( m, getrec, selrec, selfields, gg_strategy,
          c_direct_read );
    END
ELSE
    BEGIN
    _oj_info.is_outer_join := false;
    selfields.sfp_bd_mess2_type := mm_direct;
    kb721select_gets( m, selrec.selr_startkey, getrec,
          selrec, selfields, _oj_info );
    END;
(*ENDIF*) 
IF  ( a01diag_monitor_on )
THEN
    IF  ( m.mb_trns^.trBdTcachePtr_gg00 <> NIL )    AND
        ( m.mb_qual^.mtree.fileRoot_gg00 <> NIL_PAGE_NO_GG00 )
    THEN
        b21mp_root_put( m.mb_trns^.trBdTcachePtr_gg00,
              m.mb_qual^.mtree.fileRoot_gg00 );
    (*ENDIF*) 
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      k721function_add (
            VAR m      : tgg_mess_block;
            VAR selrec : tkb7_select_param;
            aggr       : boolean);
 
VAR
      new_rec      : boolean;
      null_found   : boolean;
      repl_needed  : boolean;
      act          : integer;
      count_outlen : integer;
      disnum       : integer;
      first        : integer;
      i            : integer;
      length       : integer;
      checknull_pos: integer;
      pos          : integer;
      stpos        : integer;
      cnt          : tsp_int4;
      agg_cnt      : tsp_int4;
      lres         : tsp_lcomp_result;
      hkey         : tgg_lkey;
      stddev_key   : tgg_lkey;
      ret          : tsp_num_error;
      operator     : tgg_stack_op_func;
      st_type      : tgg_stack_entry_type;
      htree_id     : tgg00_FileId;
 
BEGIN
WITH m, mb_qual^, selrec, selr_selectbuffer DO
    BEGIN
    agg_cnt       := 1;
    checknull_pos := 0;
    null_found    := false;
    selr_countresult := succ(selr_countresult);
    first       := mqual_pos;
    act         := first + mb_st^[ first ].epos - 2;
    disnum      := 0; (* look at distinct_files *)
    htree_id    := selr_distinct_id;
    FOR i := 1 TO mxgg_rescnt-1 DO
        result.info[ selr_keyl - mxgg_rescnt + i ] := chr(0);
    (*ENDFOR*) 
    result.info[ selr_keyl ] := chr(1);
    mb_trns^.trError_gg00 := e_ok;
    g10mv4 ('VKB721',   7,    
          sizeof(result.info), sizeof(hkey.k),
          result.info, 1, hkey.k, 1, selr_keyl,
          mb_trns^.trError_gg00);
    hkey.len := selr_keyl;
    IF  mb_trns^.trError_gg00  = e_ok
    THEN
        IF  selr_one_result
        THEN
            BEGIN
            IF  selr_countresult = 1
            THEN
                mb_trns^.trError_gg00 := e_key_not_found
            (*ENDIF*) 
            END
        ELSE
            b07cget_record (mb_trns^, selr_resf_id, hkey, lbuf);
        (*ENDIF*) 
    (*ENDIF*) 
    hkey.len := hkey.len-mxgg_rescnt;
    IF  mb_trns^.trError_gg00 = e_key_not_found
    THEN
        BEGIN
        selr_group_count := succ(selr_group_count);
        IF  ((selr_group_count = 2) AND (selr_maxresult = 0))
        THEN
            IF  (selr_oracle_selinto
                AND (selr_resf_id.fileTfnTemp_gg00 = ttfnInto_egg00)
                AND (selr_resf_id.fileTfn_gg00 = tfnTemp_egg00))
            THEN
                mb_trns^.trError_gg00 := e_ok
            ELSE
                mb_trns^.trError_gg00 := e_too_many_resultsets
            (*ENDIF*) 
        ELSE
            BEGIN
            mb_trns^.trError_gg00 := e_ok;
            WHILE ((act - mb_st^[ act ].epos > first) AND
                  (mb_trns^.trError_gg00 = e_ok)) DO
                BEGIN
                act   := act - mb_st^[ act ].epos;
                stpos := k721out_entry (mb_st, act);
                IF  ((mb_st^[ act ].eop_func = op_f_check_null) AND
                    ( mb_st^[ act ].etype    = st_func))
                THEN
                    checknull_pos := mb_st^[ stpos ].epos
                ELSE
                    IF  (mb_st^[ act ].eop_func in [ op_f_dis_avg, op_f_dis_sum,
                        op_f_dis_count,
                        op_f_stddev, op_f_dis_stddev,
                        op_f_variance, op_f_dis_variance ]) AND
                        (mb_st^[ act ].etype = st_func)
                    THEN
                        BEGIN
                        IF  disnum < ckb7_maxdistinctfiles
                        THEN
                            disnum := succ(disnum)
                        ELSE
                            mb_trns^.trError_gg00 := e_buffer_limit;
                        (*ENDIF*) 
                        IF  (result.buf[mb_st^[stpos].epos] <> csp_undef_byte)
                            AND
                            (result.buf[mb_st^[stpos].epos] <> csp_oflw_byte )
                        THEN
                            BEGIN
                            g10mv5 ('VKB721',   8,    
                                  sizeof(hkey.k), sizeof(buf_rec.info),
                                  hkey.k, 1, buf_rec.info, 1, hkey.len,
                                  mb_trns^.trError_gg00);
                            g10mv6 ('VKB721',   9,    
                                  sizeof(result.buf), sizeof(buf_rec.buf),
                                  result.buf, mb_st^[ stpos ].epos, buf_rec.buf,
                                  hkey.len+cgg_rec_key_offset+1,
                                  mb_st^[ stpos ].elen_var,
                                  mb_trns^.trError_gg00);
                            buf_rec.keylen := hkey.len+mb_st^[ stpos ].elen_var;
                            buf_rec.len := buf_rec.keylen+cgg_rec_key_offset;
                            buf_rec.recVarcolOffset_gg00 := 0;
                            buf_rec.recVarcolCnt_gg00    := 0;
                            IF  mb_st^[ act ].eop_func in
                                [ op_f_stddev, op_f_variance,
                                op_f_dis_stddev, op_f_dis_variance ]
                            THEN
                                BEGIN
                                s20ch4sw (1, g01code.kernel_swap,
                                      buf_rec.info, buf_rec.keylen+1,
                                      sw_normal);
                                buf_rec.len := buf_rec.len + 4
                                END;
                            (*ENDIF*) 
                            htree_id.fileTempCnt_gg00      := disnum;
                            htree_id.fileRoot_gg00       := selr_disrootarr[disnum].
                                  dfi_root;
                            htree_id.fileRootCheck_gg00 := selr_disrootarr[disnum].
                                  dfi_root_check;
                            IF  mb_trns^.trError_gg00 = e_ok
                            THEN
                                b07cadd_record (mb_trns^, htree_id, buf_rec.buf)
                            (*ENDIF*) 
                            END
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                (*ENDIF*) 
                IF  mb_st^[ act ].etype = st_func
                THEN
                    IF  (((result.buf[ mb_st^[ stpos ].epos ] = csp_undef_byte )
                        AND (mb_st^[ act ].eop_func <> op_f_all_count))
                        OR
                        ((result.buf[ mb_st^[ stpos ].epos ] = csp_oflw_byte )
                        AND NOT (mb_st^[ act ].eop_func in [ op_f_count,
                        op_f_dis_count, op_f_all_count ])))
                    THEN
                        BEGIN
                        null_found := true;
                        m.mb_trns^.trWarning_gg00 := m.mb_trns^.trWarning_gg00 +
                              [ warn0_exist, warn2_null_in_builtin_func ];
                        END;
                    (*ENDIF*) 
                (*ENDIF*) 
                IF  (NOT aggr) AND
                    (mb_st^[ act ].etype = st_func) AND
                    (mb_st^[ act ].eop_func in
                    [ op_f_avg   , op_f_dis_avg,
                    op_f_count   , op_f_dis_count, op_f_all_count,
                    op_f_stddev  , op_f_dis_stddev,
                    op_f_variance, op_f_dis_variance ])
                THEN
                    BEGIN
                    IF  mb_st^[ act ].eop_func in
                        [ op_f_avg   , op_f_dis_avg,
                        op_f_stddev  , op_f_dis_stddev,
                        op_f_variance, op_f_dis_variance ]
                    THEN
                        pos := mb_st^[ stpos ].epos + mxgg_number
                    ELSE
                        pos := mb_st^[ stpos ].epos;
                    (*ENDIF*) 
                    IF  mb_st^[ act ].eop_func in
                        [ op_f_count, op_f_dis_count ]
                    THEN
                        count_outlen := mb_st^[ stpos ].elen_var
                    ELSE
                        count_outlen := 0;
                    (*ENDIF*) 
                    IF  (((result.buf[mb_st^[stpos].epos] = csp_undef_byte)
                        AND
                        (mb_st^[act].eop_func <> op_f_all_count)) OR
                        ((result.buf[mb_st^[stpos].epos] = csp_oflw_byte)
                        AND
                        (NOT (mb_st^[act].eop_func in [op_f_count,
                        op_f_dis_count, op_f_all_count]))))
                    THEN
                        s41p4int (result.buf, pos+1, 0, ret)
                    ELSE
                        s41p4int (result.buf, pos+1, 1, ret);
                    (*ENDIF*) 
                    result.buf[ pos ] := csp_defined_byte;
                    IF  count_outlen > mxsp_resnum
                    THEN
                        g10fil1 ('VKB721',  10,    
                              sizeof(result.buf), result.buf, pos + mxsp_resnum,
                              count_outlen - mxsp_resnum, csp_defined_byte,
                              mb_trns^.trError_gg00);
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                END;
            (*ENDWHILE*) 
            IF  mb_trns^.trError_gg00 = e_ok
            THEN
                BEGIN
                IF  checknull_pos > 0
                THEN
                    IF  null_found
                    THEN
                        result.buf[ checknull_pos ] := csp_undef_byte
                    ELSE
                        result.buf[ checknull_pos ] := csp_defined_byte;
                    (*ENDIF*) 
                (*ENDIF*) 
                IF  selr_one_result
                THEN
                    g10mv6 ('VKB721',  11,    
                          sizeof(result.buf), sizeof(lbuf),
                          result.buf, 1, lbuf, 1, result.len,
                          mb_trns^.trError_gg00)
                ELSE
                    BEGIN
                    (* this add will in monitoring be counted by *)
                    (* b73cmds_count with selr_countresult       *)
                    b07cadd_record (mb_trns^, selr_resf_id, result.buf)
                    END
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END
    ELSE
        IF  mb_trns^.trError_gg00 = e_ok
        THEN
            BEGIN
            repl_needed := false;
            WHILE ((act - mb_st^[ act ].epos > first) AND
                  (mb_trns^.trError_gg00 = e_ok)) DO
                BEGIN
                act      := act - mb_st^[ act ].epos;
                operator := mb_st^[ act ].eop_func;
                st_type  := mb_st^[ act ].etype;
                stpos    := k721out_entry (mb_st, act);
                IF  ((operator = op_f_check_null) AND
                    ( st_type  = st_func))
                THEN
                    checknull_pos := mb_st^[ stpos ].epos
                ELSE
                    IF  (st_type = st_func) AND
                        (operator in [ op_f_dis_sum, op_f_dis_avg,
                        op_f_dis_count,
                        op_f_stddev  , op_f_dis_stddev,
                        op_f_variance, op_f_dis_variance ])
                    THEN
                        IF  disnum < ckb7_maxdistinctfiles
                        THEN
                            disnum := succ(disnum)
                        ELSE
                            mb_trns^.trError_gg00 := e_buffer_limit;
                        (*ENDIF*) 
                    (*ENDIF*) 
                (*ENDIF*) 
                IF  mb_trns^.trError_gg00 = e_ok
                THEN
                    WITH mb_st^[ stpos ] DO
                        BEGIN
                        IF  ((result.buf[ epos ] <> csp_undef_byte)
                            OR ((operator = op_f_all_count) AND
                            (st_type = st_func)))
                        THEN
                            BEGIN
                            new_rec := false;
                            IF  ( lbuf[ epos ] = csp_oflw_byte ) AND
                                (NOT (( operator = op_f_all_count ) AND
                                (st_type = st_func)))
                            THEN
                                repl_needed := false
                            ELSE
                                IF  (result.buf[ epos ] = csp_oflw_byte)
                                    AND
                                    ( NOT((operator in [ op_f_all_count,
                                    op_f_count, op_f_dis_count ])
                                    AND (st_type = st_func)))
                                THEN
                                    BEGIN
                                    repl_needed := true;
                                    lbuf[ epos ] := csp_oflw_byte
                                    END
                                ELSE
                                    BEGIN
                                    IF  (operator in [ op_f_min,
                                        op_f_max ]) AND
                                        (st_type = st_func)
                                    THEN
                                        BEGIN
                                        IF  lbuf[epos] = csp_undef_byte
                                        THEN
                                            new_rec := true
                                        ELSE
                                            BEGIN
                                            s30cmp (result.buf, epos+1,
                                                  elen_var-1, lbuf,
                                                  epos+1, elen_var-1,
                                                  lres);
&                                           ifdef TRACE
                                            t01buf (kb, result.buf, epos + 1, epos + elen_var -1);
                                            t01int4 (kb, 'lres        ', ord (lres));
                                            t01buf (kb, lbuf, epos + 1, epos + elen_var -1);
&                                           endif
                                            IF  ((((operator = op_f_min)
                                                AND
                                                (lres = l_less))
                                                OR
                                                ((operator = op_f_max)
                                                AND
                                                (lres = l_greater))))
                                                AND (st_type = st_func)
                                            THEN
                                                new_rec := true
                                            (*ENDIF*) 
                                            END
                                        (*ENDIF*) 
                                        END
                                    ELSE
                                        IF  (operator in
                                            [ op_f_dis_avg,
                                            op_f_dis_sum,
                                            op_f_dis_count,
                                            op_f_stddev,
                                            op_f_dis_stddev,
                                            op_f_variance,
                                            op_f_dis_variance ]) AND
                                            (st_type = st_func)
                                        THEN
                                            BEGIN
                                            g10mv5 ('VKB721',  12,    
                                                  sizeof(hkey.k),
                                                  sizeof(buf_rec.info),
                                                  hkey.k, 1,
                                                  buf_rec.info,
                                                  1, hkey.len,
                                                  mb_trns^.trError_gg00);
                                            g10mv6 ('VKB721',  13,    
                                                  sizeof(result.buf),
                                                  sizeof(buf_rec.buf),
                                                  result.buf, epos,
                                                  buf_rec.buf,
                                                  hkey.len+cgg_rec_key_offset+1,
                                                  elen_var,
                                                  mb_trns^.trError_gg00);
                                            buf_rec.keylen :=
                                                  hkey.len + elen_var;
                                            buf_rec.len    :=
                                                  buf_rec.keylen + cgg_rec_key_offset;
                                            buf_rec.recVarcolOffset_gg00 := 0;
                                            buf_rec.recVarcolCnt_gg00    := 0;
                                            IF  mb_st^[ act ].eop_func in
                                                [ op_f_stddev
                                                , op_f_variance
                                                , op_f_dis_stddev
                                                , op_f_dis_variance ]
                                            THEN
                                                BEGIN
                                                s20ch4sw (1, g01code.
                                                      kernel_swap,
                                                      buf_rec.info,
                                                      buf_rec.keylen+1,
                                                      sw_normal);
                                                buf_rec.len :=
                                                      buf_rec.len + 4
                                                END;
                                            (*ENDIF*) 
                                            htree_id.fileTempCnt_gg00   :=
                                                  disnum;
                                            htree_id.fileRoot_gg00      :=
                                                  selr_disrootarr[disnum
                                                  ].dfi_root;
                                            htree_id.fileRootCheck_gg00 :=
                                                  selr_disrootarr[disnum
                                                  ].dfi_root_check;
                                            IF  result.buf[ epos ] <>
                                                csp_oflw_byte
                                            THEN
                                                BEGIN
                                                IF  mb_trns^.trError_gg00 = e_ok
                                                THEN
                                                    b07cadd_record (mb_trns^,
                                                       htree_id, buf_rec.buf);
                                                (*ENDIF*) 
                                                IF  ((mb_trns^.trError_gg00 =
                                                    e_duplicate_key) AND
                                                    (operator in [ op_f_stddev,
                                                    op_f_variance ]))
                                                THEN
                                                    BEGIN
                                                    mb_trns^.trError_gg00 := e_ok;
                                                    stddev_key.len := buf_rec.keylen;
                                                    g10mv1 ('VKB721',  14,    
                                                       sizeof(buf_rec.buf),
                                                       sizeof(stddev_key.k),
                                                       buf_rec.buf, cgg_rec_key_offset+1,
                                                       stddev_key.k, 1, buf_rec.keylen,
                                                       mb_trns^.trError_gg00);
                                                    IF  mb_trns^.trError_gg00 = e_ok
                                                    THEN
                                                     b07cget_record (mb_trns^,
                                                        htree_id, stddev_key,
                                                        buf_rec.buf);
                                                    (*ENDIF*) 
                                                    s20ch4sw (1 +
                                                       s20or4sw (buf_rec.buf,
                                                       buf_rec.keylen+cgg_rec_key_offset+1,
                                                       sw_normal, g01code.kernel_swap),
                                                       g01code.kernel_swap, buf_rec.info,
                                                       buf_rec.keylen+1, sw_normal);
                                                    IF  mb_trns^.trError_gg00 = e_ok
                                                    THEN
                                                     b07crepl_record (mb_trns^, htree_id,
                                                        buf_rec.buf);
                                                    (*ENDIF*) 
                                                    END;
                                                (*ENDIF*) 
                                                END
                                            ELSE
                                                mb_trns^.trError_gg00 :=
                                                      e_duplicate_key;
                                            (*ENDIF*) 
                                            IF  mb_trns^.trError_gg00 =
                                                e_duplicate_key
                                            THEN
                                                mb_trns^.trError_gg00 :=
                                                      e_ok
                                            ELSE
                                                IF  (mb_trns^.trError_gg00 =
                                                    e_ok) AND
                                                    (st_type = st_func)
                                                THEN
                                                    CASE operator OF
                                                     op_f_dis_avg,
                                                     op_f_stddev,
                                                     op_f_dis_stddev,
                                                     op_f_variance,
                                                     op_f_dis_variance :
                                                      operator :=
                                                         op_f_avg;
                                                     op_f_dis_sum :
                                                      operator :=
                                                         op_f_sum;
                                                     op_f_dis_count :
                                                      operator :=
                                                         op_f_count
                                                     END
                                                    (*ENDCASE*) 
                                                (*ENDIF*) 
                                            (*ENDIF*) 
                                            END;
                                        (*ENDIF*) 
                                    (*ENDIF*) 
                                    IF  ((operator in [ op_f_avg,
                                        op_f_sum ]) AND
                                        (st_type = st_func) AND
                                        (mb_trns^.trError_gg00 = e_ok))
                                    THEN
                                        IF  lbuf[ epos ] = csp_undef_byte
                                        THEN
                                            new_rec := true
                                        ELSE
                                            BEGIN
                                            repl_needed := true;
                                            IF  k721out_entry (mb_st, stpos)
                                                <> succ (stpos)
                                            THEN
                                                s51add (result.buf,
                                                      epos+1, elen_var-1,
                                                      lbuf, epos+1,
                                                      elen_var,
                                                      lbuf, epos+1,
                                                      mb_st^[ stpos+1 ].epos,
                                                      mb_st^[ stpos+1 ].elen_var,
                                                      length, ret)
                                            ELSE
                                                s51add (result.buf,
                                                      epos+1, elen_var-1,
                                                      lbuf, epos+1,
                                                      elen_var-1,
                                                      lbuf, epos+1,
                                                      csp_fixed,
                                                      csp_float_frac,
                                                      length, ret);
                                            (*ENDIF*) 
                                            IF  ret <> num_ok
                                            THEN
                                                BEGIN
                                                lbuf[epos+1]:= chr(255);
                                                FOR i := 1 TO 9 DO
                                                    lbuf[ epos+1+i ] :=
                                                       chr(153)
                                                (*ENDFOR*) 
                                                END
                                            (*ENDIF*) 
                                            END;
                                        (*ENDIF*) 
                                    (*ENDIF*) 
                                    IF  (operator in   [
                                        op_f_avg,
                                        op_f_count,
                                        op_f_all_count ])
                                        AND
                                        (st_type = st_func)
                                        AND
                                        (mb_trns^.trError_gg00 = e_ok)
                                    THEN
                                        BEGIN
                                        repl_needed := true;
                                        IF  (operator = op_f_avg) AND
                                            (st_type = st_func)
                                        THEN
                                            pos := epos+mxgg_number+1
                                        ELSE
                                            pos := epos+1;
                                        (*ENDIF*) 
                                        s40g4int (lbuf, pos, cnt, ret);
&                                       ifdef TRACE
                                        t01int4 (kb, 'pos         ',
                                              pos);
                                        t01int4 (kb, 'ord(ret)    ',
                                              ord(ret));
&                                       endif
                                        IF  ret = num_ok
                                        THEN
                                            BEGIN
                                            IF  aggr
                                            THEN
                                                s40g4int (result.buf,
                                                      pos, agg_cnt, ret);
                                            (*ENDIF*) 
                                            IF  ret = num_ok
                                            THEN
                                                s41p4int (lbuf, pos,
                                                      cnt+agg_cnt, ret)
                                            (*ENDIF*) 
                                            END;
                                        (*ENDIF*) 
                                        END;
                                    (*ENDIF*) 
                                    IF  new_rec
                                    THEN
                                        BEGIN
                                        g10mv6 ('VKB721',  15,    
                                              sizeof(result.buf),
                                              sizeof(lbuf),
                                              result.buf, epos,
                                              lbuf, epos, elen_var,
                                              mb_trns^.trError_gg00);
                                        repl_needed := true
                                        END
                                    (*ENDIF*) 
                                    END
                                (*ENDIF*) 
                            (*ENDIF*) 
                            END
                        ELSE
                            IF  st_type = st_func
                            THEN
                                BEGIN
                                null_found := true;
                                m.mb_trns^.trWarning_gg00 :=
                                      m.mb_trns^.trWarning_gg00 +
                                      [ warn0_exist,
                                      warn2_null_in_builtin_func ];
                                END;
                            (*ENDIF*) 
                        (*ENDIF*) 
                        END
                    (*ENDWITH*) 
                (*ENDIF*) 
                END;
            (*ENDWHILE*) 
            IF  (null_found AND (checknull_pos > 0))
            THEN
                IF  lbuf[ checknull_pos ] = csp_defined_byte
                THEN
                    BEGIN
                    lbuf[ checknull_pos ] := csp_undef_byte;
                    repl_needed := true
                    END;
                (*ENDIF*) 
            (*ENDIF*) 
            IF  (repl_needed AND (mb_trns^.trError_gg00 = e_ok) AND
                NOT selr_one_result)
            THEN
                BEGIN
                b73cmd_count (iins_sorts_rows_ins);
                b07crepl_record (mb_trns^, selr_resf_id, lbuf)
                END
            (*ENDIF*) 
            END;
        (*ENDIF*) 
    (*ENDIF*) 
    IF  selr_countresult = selr_maxresult
    THEN
        mb_trns^.trError_gg00 := e_enough_resultsets
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb721in_keyrecord (
            VAR m           : tgg_mess_block;
            VAR getrec      : tkb7_get_param;
            VAR selrec      : tkb7_select_param;
            VAR selfields   : tgg_select_fields_param;
            VAR gg_strategy : tgg07_StrategyInfo);
 
VAR
      _dummy_cnt : tsp_int2;
      _i         : tsp_int2;
      _oj_info   : tkb7_oj_info_type;
 
BEGIN
&ifdef trace
t01int4 (kb, 'inelemcnt   ', gg_strategy.str_key_in_range.skir_inelemcnt );
&endif
_i         := 1;
_dummy_cnt := 0;
WHILE ( _i <= gg_strategy.str_key_in_range.skir_inelemcnt ) AND
      ( m.mb_trns^.trError_gg00 = e_ok ) DO
    BEGIN
    IF  ( m.mb_st^[ gg_strategy.str_key_in_range.skir_IN_SUBQ_stpos + _i + _dummy_cnt ].
        etype <> st_dummy )
    THEN
        BEGIN
        selfields.sfp_bd_use_stopkey := true;
        g04limitprimkeys( m, gg_strategy.str_key_in_range.skir_keystart,
              selrec.selr_startkey, gg_strategy.str_key_in_range.skir_keystop,
              selrec.selr_stopkey,
              selfields.sfp_bd_use_stopkey,
              gg_strategy.str_key_in_range.skir_IN_SUBQ_stpos, _i + _dummy_cnt );
        (* might return e_move_error *)
        _oj_info.is_outer_join := false;
        selfields.sfp_bd_mess2_type := mm_first;
        WHILE ( m.mb_trns^.trError_gg00 = e_ok ) DO
            BEGIN
            kb721select_gets( m, selrec.selr_startkey,
                  getrec, selrec, selfields, _oj_info );
            END;
        (*ENDWHILE*) 
        IF  ( m.mb_trns^.trError_gg00 = e_no_next_record )
        THEN
            m.mb_trns^.trError_gg00 := e_ok;
        (*ENDIF*) 
        _i := succ( _i );
        END
    ELSE
        _dummy_cnt := succ( _dummy_cnt );
    (*ENDIF*) 
    END;
(*ENDWHILE*) 
IF  ( a01diag_monitor_on )
THEN
    IF  ( m.mb_trns^.trBdTcachePtr_gg00 <> NIL )    AND
        ( m.mb_qual^.mtree.fileRoot_gg00 <> NIL_PAGE_NO_GG00 )
    THEN
        b21mp_root_put( m.mb_trns^.trBdTcachePtr_gg00,
              m.mb_qual^.mtree.fileRoot_gg00 );
    (*ENDIF*) 
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb721make_outer_join_result (
            VAR m             : tgg_mess_block;
            VAR selrec        : tkb7_select_param;
            VAR oj_ok_keys_id : tgg00_FileId);
 
VAR
      result_is_empty : boolean;
      result_empty    : boolean;
      is_buffer_limit : boolean;
      lc_result       : tsp_lcomp_result;
      aux_error       : tgg_basis_error;
      m_key           : tgg_lkey;
      set_result      : tgg_bd_set_result_record;
 
BEGIN
WITH m, selrec, selr_selectbuffer DO
    BEGIN
    result_is_empty := selr_countresult = 0;
    result_empty    := result_is_empty;
    WITH set_result DO
        BEGIN
        bd_key_check_len := 0;
        bd_max_rec_cnt   := csp_maxint2;
        bd_max_fill_len  := mxsp_buf;
        bd_next          := false;
        bd_drop_page     := false;
        END;
    (*ENDWITH*) 
    selr_oj_tree_pos.tpsPno_gg00 := NIL_PAGE_NO_GG00;
    m_key.len              := 0;
    aux_error              := e_buffer_limit;
    selr_tree_pos.tpsPno_gg00    := NIL_PAGE_NO_GG00;
    selr_r_currpos         := 1;
    selr_r_endpos          := 0;
    is_buffer_limit        := NOT result_is_empty;
    lc_result              := l_greater;
    WHILE ((aux_error = e_buffer_limit) OR
          is_buffer_limit) AND
          (mb_trns^.trError_gg00 = e_ok) DO
        BEGIN
        b07cnext_record (mb_trns^, selr_id_outer_join, m_key,
              set_result, selr_oj_tree_pos, lbuf);
        IF  mb_trns^.trError_gg00 = e_key_not_found
        THEN
            mb_trns^.trError_gg00 := e_ok;
        (*ENDIF*) 
        aux_error       := mb_trns^.trError_gg00;
        mb_trns^.trError_gg00 := e_ok;
        IF  ((aux_error = e_ok) OR (aux_error = e_buffer_limit))
        THEN
            BEGIN
            selr_l_currpos := 1;
            selr_l_endpos  := set_result.bd_fill_len;
            WHILE (selr_l_currpos < selr_l_endpos) DO
                BEGIN
                IF  (NOT result_is_empty) AND
                    (lc_result <> l_less)
                THEN
                    BEGIN
                    IF  (selr_r_currpos > selr_r_endpos)
                    THEN
                        BEGIN
                        IF  is_buffer_limit
                        THEN
                            BEGIN
                            b07cnext_record
                                  (mb_trns^, oj_ok_keys_id, m_key,
                                  set_result, selr_tree_pos, rbuf);
                            is_buffer_limit :=
                                  (mb_trns^.trError_gg00 = e_buffer_limit)
                                  AND (aux_error = e_buffer_limit);
                            IF  (mb_trns^.trError_gg00 = e_buffer_limit) OR
                                (mb_trns^.trError_gg00 = e_key_not_found)
                            THEN
                                mb_trns^.trError_gg00 := e_ok;
                            (*ENDIF*) 
                            selr_r_currpos := 1;
                            selr_r_endpos  := set_result.bd_fill_len;
                            END
                        ELSE
                            result_is_empty := true;
                        (*ENDIF*) 
                        END
                    ELSE
                        selr_r_currpos :=
                              selr_r_currpos + ckb7_oj_key_off1 + 2;
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                result_is_empty := selr_r_currpos > selr_r_endpos;
                IF  (NOT result_is_empty)
                THEN
                    s30cmp (
                          lbuf, selr_l_currpos + 4,
                          ckb7_oj_key_off1 - 2,
                          rbuf, selr_r_currpos + 4,
                          ckb7_oj_key_off1 - 2, lc_result)
                ELSE
                    lc_result := l_less;
                (*ENDIF*) 
                IF  (lc_result = l_less)
                THEN
                    BEGIN
                    result.len := selr_recl;
                    selr_l_currpos  :=
                          selr_l_currpos + ckb7_oj_key_off1;
                    g10mv6 ('VKB721',  16,    
                          sizeof(lbuf), sizeof(result.buf),
                          lbuf,       selr_l_currpos + 2,
                          result.buf, 3,
                          selr_recl - 2,
                          mb_trns^.trError_gg00);
                    IF  mb_trns^.trError_gg00 = e_ok
                    THEN
                        BEGIN
                        kb721build_outer_result (m, selrec,
                              lbuf[ selr_l_currpos + 1 ]);
                        k721add_into_result (mb_trns^, selrec, m.mb_next_mblock);
                        selr_l_currpos := selr_l_currpos + selr_recl;
                        END
                    (*ENDIF*) 
                    END
                ELSE
                    IF  (lc_result = l_equal)
                    THEN
                        selr_l_currpos := selr_l_currpos +
                              selr_recl + ckb7_oj_key_off1;
                    (*ENDIF*) 
                (*ENDIF*) 
                END;
            (*ENDWHILE*) 
            END;
        (*ENDIF*) 
        END;
    (*ENDWHILE*) 
    IF  (mb_trns^.trError_gg00 = e_ok)
    THEN
        mb_trns^.trError_gg00 := aux_error;
    (*ENDIF*) 
    aux_error := mb_trns^.trError_gg00;
    IF  NOT result_empty
    THEN
        b01destroy_file (mb_trns^, oj_ok_keys_id);
    (*ENDIF*) 
    IF  selr_cnt_outer_join > 0
    THEN
        b01destroy_file (mb_trns^, selr_id_outer_join);
    (*ENDIF*) 
    mb_trns^.trError_gg00 := aux_error
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb721select_gets (
            VAR m          : tgg_mess_block;
            VAR act_key    : tgg_lkey;
            VAR getrec     : tkb7_get_param;
            VAR selrec     : tkb7_select_param;
            VAR selfields  : tgg_select_fields_param;
            VAR oj_info    : tkb7_oj_info_type);
 
VAR
      _dummy_bool   : boolean;
      _sellength    : tsp_int4;
      _recbuf_size  : tsp_int4;
      _granted_lock : tgg00_LockReqMode;
      _htree_id     : tgg00_FileId;
      _recbuf_ptr   : tsp_moveobj_ptr;
      _dummy_lkey   : tgg_lkey;
 
BEGIN
_granted_lock := lckFree_egg00;
IF  ( m.mb_type = m_insert_select )
THEN
    BEGIN
    _htree_id := m.mb_qual^.mtree;
    selfields.sfp_result_length := cgg_rec_key_offset;
    ;
    IF  ( selrec.selr_is_nokey )
    THEN
        selfields.sfp_result_length :=
              selfields.sfp_result_length + 1 + mxgg_surrogate;
    (*ENDIF*) 
    END
ELSE
    selfields.sfp_result_length := 0;
(*ENDIF*) 
_sellength := selfields.sfp_result_length;
IF  ( selrec.selr_use_rowno AND ( selrec.selr_distinct <> no_distinct ))
THEN
    selfields.sfp_act_cntresult := 1
ELSE
    IF  ( NOT selrec.selr_count_all )
    THEN
        selfields.sfp_act_cntresult := selrec.selr_countresult + 1;
    (*ENDIF*) 
(*ENDIF*) 
IF  ( selfields.sfp_m_result_cnt > 1 )
THEN
    BEGIN
    selfields.sfp_resrec_maxlen :=
          selrec.selr_recl + selfields.sfp_result_length;
    selrec.selr_resrec_maxlen    := selfields.sfp_resrec_maxlen;
    END;
(*ENDIF*) 
m.mb_trns^.trError_gg00       := e_ok;
m.mb_qual^.mtree.fileBdUse_gg00 := [  ];
IF  ( m.mb_type = m_update )
THEN
    BEGIN
    selfields.sfp_m_result_addr := @selrec.selr_selectbuffer.longresult;
    selfields.sfp_m_result_size :=
          sizeof( selrec.selr_selectbuffer.longresult );
    END
ELSE
    BEGIN
    selfields.sfp_m_result_addr := @selrec.selr_selectbuffer.result;
    selfields.sfp_m_result_size :=
          sizeof( selrec.selr_selectbuffer.result );
    END;
(*ENDIF*) 
selfields.sfp_m_result_len  := 0;
IF  ( selrec.selr_intern_dist OR ( m.mb_type in [ m_update, m_delete ] ) )
THEN
    BEGIN
    _recbuf_size := sizeof( selrec.selr_selectbuffer.buf_rec );
    _recbuf_ptr  := @selrec.selr_selectbuffer.buf_rec;
    END
ELSE
    BEGIN
    _recbuf_size := 0;
    _recbuf_ptr  := NIL;
    END;
(*ENDIF*) 
b02kb_select_rec( m.mb_trns^, m.mb_qual^.mtree,
      act_key.keyVal_gg00, act_key.keyLen_gg00,
      selrec.selr_stopkey.keyVal_gg00, selrec.selr_stopkey.keyLen_gg00,
      _recbuf_size, _recbuf_ptr, NOT c_ignore_vwait,
      selfields, m.mb_qual^.mstack_desc, _dummy_bool, _granted_lock );
;
kb721result_handle( m, selrec, getrec, selfields, _dummy_lkey,
      act_key, _htree_id, oj_info, _granted_lock );
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb721seq_search (
            VAR m        : tgg_mess_block;
            VAR getrec   : tkb7_get_param;
            VAR selrec   : tkb7_select_param;
            VAR sel      : tgg_select_fields_param;
            VAR strat    : tgg07_StrategyInfo);
 
VAR
      _optim          : boolean;
      _read_first     : boolean;
      _read_last      : boolean;
      _qual_buf_len   : tsp_int2;
      _max_result_cnt : tsp_int2;
      _leaf_count     : tsp00_Int4;
      _record_count   : tsp00_Int4;
      _oj_info        : tkb7_oj_info_type;
      _startk         : tgg_lkey;
      _stopk          : tgg_lkey;
      _ic2            : tsp_int_map_c2;
 
BEGIN
IF  ( strat.str_strategy = strat_key_range_sub )
THEN
    kb721subq_key_select( m, getrec, selrec, sel, strat, NOT c_direct_read )
ELSE
    BEGIN
    IF  selrec.selr_count_bd
        AND
        ( selrec.selr_startkey.len = 0 )
        AND
        ( selrec.selr_stopkey.len = 0 )
    THEN
        BEGIN
        g10mv6 ('VKB721',  17,    
              m.mb_qual_size, sizeof( selrec.selr_selectbuffer.rbuf ),
              m.mb_qual^.buf, 1,
              selrec.selr_selectbuffer.rbuf, 1,
              m.mb_qual_len, m.mb_trns^.trError_gg00);
        ;
        IF  ( m.mb_trns^.trError_gg00 = e_ok )
        THEN
            BEGIN
            _qual_buf_len := m.mb_qual_len;
            m.mb_type      := m_column_statistic;
            m.mb_type2     := mm_key;
            bd01CalculateRecordsAndLeaves( m.mb_trns^, m.mb_qual^.mtree,
                  _leaf_count, _record_count );
            IF  ( m.mb_trns^.trError_gg00 = e_ok )
            THEN
                sel.sfp_act_cntresult := sel.sfp_act_cntresult + _record_count;
            (*ENDIF*) 
            m.mb_type      := m_select;
            m.mb_type2     := mm_with_functions;
            m.mb_qual_len  := _qual_buf_len;
            g10mv6 ('VKB721',  18,    
                  sizeof( selrec.selr_selectbuffer.rbuf ),
                  sizeof( m.mb_qual^.buf ),
                  selrec.selr_selectbuffer.rbuf, 1,
                  m.mb_qual^.buf, 1, m.mb_qual_len,
                  m.mb_trns^.trError_gg00);
            END
        (*ENDIF*) 
        END
    ELSE
        BEGIN
        _optim      := false;
        _read_first := false;
        _read_last  := false;
        IF  ( m.mb_qual^.mqual_pos > 0 )
        THEN
            _oj_info.is_outer_join := ( m.mb_type2 = mm_nil ) AND
                  ( m.mb_st^[ m.mb_qual^.mqual_pos ].eop = op_outer_join )
        ELSE
            _oj_info.is_outer_join := false;
        (*ENDIF*) 
        IF  ( m.mb_trns^.trError_gg00 = e_ok ) AND
            ( m.mb_type2 = mm_with_functions )
        THEN
            g04aggr_func( m, _read_first, _read_last, _optim );
        (*ENDIF*) 
        IF  ( _optim )
        THEN
            BEGIN
            _startk := selrec.selr_startkey;
            _stopk  := selrec.selr_stopkey;
            IF  ( _read_first )
            THEN
                IF  ( m.mb_trns^.trError_gg00 = e_ok )
                THEN
                    BEGIN
                    sel.sfp_bd_mess2_type := mm_first;
                    kb721select_gets( m, selrec.selr_startkey, getrec,
                          selrec, sel, _oj_info );
                    END;
                (*ENDIF*) 
            (*ENDIF*) 
            IF  ( _read_last )
            THEN
                IF  ( m.mb_trns^.trError_gg00 = e_ok )
                THEN
                    BEGIN
                    IF  ( _stopk.len = 0 )
                    THEN
                        BEGIN
                        selrec.selr_startkey.k   := b01fullkey;
                        selrec.selr_startkey.len := MAX_KEYLEN_GG00;
                        END
                    ELSE
                        selrec.selr_startkey := _stopk;
                    (*ENDIF*) 
                    selrec.selr_stopkey := _startk;
                    sel.sfp_bd_mess2_type := mm_last;
                    kb721select_gets( m, selrec.selr_startkey, getrec,
                          selrec, sel, _oj_info );
                    END;
                (*ENDIF*) 
            (*ENDIF*) 
            END
        ELSE
            BEGIN
            IF  ( m.mb_trns^.trError_gg00 = e_ok )
            THEN
                BEGIN
                IF  ( m.mb_type IN [ m_update, m_delete,
                    m_insert_select ] ) OR
                    ( m.mb_type2 IN [ mm_with_functions,
                    mm_with_join ] ) OR
                    ( sel.sfp_oj_spec <> ckb7_ojoin_none ) OR
                    ( selrec.selr_distinct <> no_distinct ) OR
                    selrec.selr_intern_dist OR _oj_info.is_outer_join OR
                    selrec.selr_union_select OR selrec.selr_one_result
                THEN
                    sel.sfp_m_result_cnt := 1
                ELSE
                    BEGIN
                    IF  (( selrec.selr_recl MOD 2 ) = 0)
                    THEN
                        sel.sfp_m_result_cnt :=
                              sizeof( selrec.selr_selectbuffer.result ) DIV
                              selrec.selr_recl
                    ELSE
                        sel.sfp_m_result_cnt :=
                              sizeof( selrec.selr_selectbuffer.result ) DIV
                              ( selrec.selr_recl + 1 );
                    (*ENDIF*) 
                    (* h.b. PTS 1001366 *)
                    IF  ( sel.sfp_m_result_cnt > selrec.selr_maxresult )
                    THEN
                        sel.sfp_m_result_cnt := selrec.selr_maxresult;
                    (*ENDIF*) 
                    IF  ( sel.sfp_m_result_cnt < 1 )
                    THEN
                        sel.sfp_m_result_cnt := 1;
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
&               ifdef TRACE
                t01int4 (kb_qual, 'res_in_cnt  ', sel.sfp_m_result_cnt);
&               endif
                _max_result_cnt := sel.sfp_m_result_cnt;
                sel.sfp_bd_mess2_type := mm_first;
                kb721select_gets( m, selrec.selr_startkey, getrec,
                      selrec, sel, _oj_info );
                END;
            (*ENDIF*) 
            IF  (( m.mb_qual^.mtree.fileTfnTemp_gg00 = ttfnRecursive_egg00 )
                AND
                selrec.selr_all_recursive )
            THEN
                IF  ( m.mb_trns^.trError_gg00 = e_no_next_record )
                THEN
                    BEGIN
                    _ic2.map_c2 := m.mb_qual^.mtree.fileLevel_gg00;
                    IF  ( _ic2.map_int > 1 )
                    THEN (* it was not first file *)
                        BEGIN
                        _ic2.map_int := pred(_ic2.map_int);
                        m.mb_qual^.mtree.fileLevel_gg00 := _ic2.map_c2;
                        m.mb_qual^.mtree.fileRoot_gg00  := NIL_PAGE_NO_GG00;
                        sel.sfp_bd_mess2_type := mm_first;
                        sel.sfp_m_result_cnt := _max_result_cnt;
                        selrec.selr_startkey.len := 0;
                        m.mb_trns^.trError_gg00 := e_ok
                        END
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
            (*ENDIF*) 
            WHILE ( m.mb_trns^.trError_gg00 = e_ok ) DO
                BEGIN
                WHILE m.mb_trns^.trError_gg00 = e_ok DO
                    kb721select_gets( m, selrec.selr_startkey, getrec,
                          selrec, sel, _oj_info );
                (*ENDWHILE*) 
                IF  (( m.mb_qual^.mtree.fileTfnTemp_gg00 = ttfnRecursive_egg00 ) AND
                    selrec.selr_all_recursive )
                THEN
                    IF  ( m.mb_trns^.trError_gg00 = e_no_next_record )
                    THEN
                        BEGIN
                        _ic2.map_c2 := m.mb_qual^.mtree.fileLevel_gg00;
                        IF  ( _ic2.map_int > 1 )
                        THEN (* it was not first file *)
                            BEGIN
                            _ic2.map_int := pred( _ic2.map_int );
                            m.mb_qual^.mtree.fileLevel_gg00 := _ic2.map_c2;
                            m.mb_qual^.mtree.fileRoot_gg00  := NIL_PAGE_NO_GG00;
                            sel.sfp_bd_mess2_type := mm_first;
                            sel.sfp_m_result_cnt := _max_result_cnt;
                            selrec.selr_startkey.len := 0;
                            m.mb_trns^.trError_gg00  := e_ok;
                            END
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                (*ENDIF*) 
                END;
            (*ENDWHILE*) 
            END;
        (*ENDIF*) 
        IF  _oj_info.is_outer_join      AND
            ( m.mb_type2 <> mm_with_join ) AND
            ( m.mb_trns^.trError_gg00 = e_no_next_record )
        THEN
            BEGIN
            m.mb_trns^.trError_gg00 := e_ok;
            IF   ( selrec.selr_cnt_outer_join > 0 )
            THEN
                kb721make_outer_join_result( m, selrec, _oj_info.oj_ok_keys_id )
            ELSE
                IF  ( selrec.selr_countresult > 0 )
                THEN (* *** oj_ok_keys_id - file exists *** *)
                    b01destroy_file( m.mb_trns^, _oj_info.oj_ok_keys_id );
                (*ENDIF*) 
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  ( m.mb_trns^.trError_gg00 = e_no_next_record ) OR
            ( m.mb_trns^.trError_gg00 = e_no_prev_record )
        THEN
            m.mb_trns^.trError_gg00 := e_ok;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    END;
(*ENDIF*) 
IF  ( a01diag_monitor_on )
THEN
    IF  ( m.mb_trns^.trBdTcachePtr_gg00 <> NIL )    AND
        ( m.mb_qual^.mtree.fileRoot_gg00 <> NIL_PAGE_NO_GG00 )
    THEN
        b21mp_root_put( m.mb_trns^.trBdTcachePtr_gg00,
              m.mb_qual^.mtree.fileRoot_gg00 );
    (*ENDIF*) 
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb721subq_key_select (
            VAR m           : tgg_mess_block;
            VAR getrec      : tkb7_get_param;
            VAR selrec      : tkb7_select_param;
            VAR selfields   : tgg_select_fields_param;
            VAR gg_strategy : tgg07_StrategyInfo;
            direct_read     : boolean);
 
VAR
      _ok             : boolean;
      _ix             : tsp_int2;
      _subq_pos       : tsp_int2;
      _oj_info        : tkb7_oj_info_type;
      _subqtree_id    : tgg00_FileId;
      _m_key          : tgg_lkey;
      _aux_error      : tgg_basis_error;
 
BEGIN
_aux_error := e_ok;
_ix        := 0;
_subq_pos  := 0;
WHILE ( _ix <= MAX_COLPOSARR_IDX_GG07 ) AND ( _aux_error = e_ok ) DO
    BEGIN
    IF  ( gg_strategy.str_key_in_range.skir_keystart[ _ix ] = 0 )
    THEN
        (* break through while loop *)
        _ix := MAX_COLPOSARR_IDX_GG07
    ELSE
        IF  ( m.mb_st^[ gg_strategy.str_key_in_range.skir_keystart[ _ix ] ].
            etype = st_dummy ) AND
            ( m.mb_st^[ gg_strategy.str_key_in_range.skir_keystart[ _ix ] + 1 ].
            etype = st_bool )
        THEN
            (* no records in subquery - file *)
            _aux_error := e_no_next_record
        ELSE
            IF  ( m.mb_st^
                [ gg_strategy.str_key_in_range.skir_keystart[ _ix ] + 1 ].
                etype = st_subquery )
            THEN
                BEGIN
                _subq_pos := gg_strategy.str_key_in_range.skir_keystart[ _ix ];
                _ix       := MAX_COLPOSARR_IDX_GG07;
                END;
            (*ENDIF*) 
        (*ENDIF*) 
    (*ENDIF*) 
    _ix := succ( _ix );
    END;
(*ENDWHILE*) 
IF  ( _aux_error = e_ok )
THEN
    BEGIN
    IF  ( _subq_pos <> 0 )
    THEN
        BEGIN
        _m_key.len := 0;
        g10mv9 ('VKB721',  19,    
              m.mb_data_size, sizeof( _subqtree_id ),
              m.mb_data^.mbp_buf, m.mb_st^[ _subq_pos + 1 ].epos,
              _subqtree_id, 1, mxgg_treeid,
              m.mb_trns^.trError_gg00);
        END;
    (*ENDIF*) 
    ;
    IF  ( m.mb_qual^.mqual_pos > 0 )
    THEN
        _oj_info.is_outer_join := ( m.mb_type2 = mm_nil ) AND
              ( m.mb_st^[ m.mb_qual^.mqual_pos ].eop = op_outer_join )
    ELSE
        _oj_info.is_outer_join := false;
    (*ENDIF*) 
    WHILE ( m.mb_trns^.trError_gg00 = e_ok ) AND ( _aux_error = e_ok ) DO
        BEGIN
        IF  ( _subq_pos <> 0 )
        THEN
            g04read_subquery( m, selrec.selr_selectbuffer.result, _subqtree_id, _m_key,
                  _aux_error, _ok )
        ELSE
            BEGIN
            _aux_error := e_no_next_record;
            _ok        := true;
            END;
        (*ENDIF*) 
        ;
        IF  ( _ok )
        THEN
            BEGIN
            selfields.sfp_bd_use_stopkey := false;
            gg04subq_limitkey( m, selrec.selr_selectbuffer.result,
                  gg_strategy.str_key_in_range.skir_keystart,
                  selrec.selr_startkey, selfields.sfp_bd_use_stopkey );
            (* might return e_move_error *)
            selfields.sfp_bd_use_stopkey := true;
            gg04subq_limitkey( m, selrec.selr_selectbuffer.result,
                  gg_strategy.str_key_in_range.skir_keystop,
                  selrec.selr_stopkey, selfields.sfp_bd_use_stopkey );
            (* might return e_move_error *)
            IF  ( NOT direct_read )
            THEN
                BEGIN
                selfields.sfp_bd_mess2_type := mm_first;
                WHILE ( m.mb_trns^.trError_gg00 = e_ok ) DO
                    kb721select_gets( m, selrec.selr_startkey, getrec,
                          selrec, selfields, _oj_info );
                (*ENDWHILE*) 
                IF  ( m.mb_trns^.trError_gg00 = e_no_next_record ) OR
                    ( m.mb_trns^.trError_gg00 = e_no_prev_record )
                THEN
                    m.mb_trns^.trError_gg00 := e_ok;
                (*ENDIF*) 
                END
            ELSE
                BEGIN
                selfields.sfp_bd_mess2_type := mm_direct;
                kb721select_gets( m, selrec.selr_startkey, getrec,
                      selrec, selfields, _oj_info );
                END;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        END;
    (*ENDWHILE*) 
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb721stddev (
            VAR m        : tgg_mess_block;
            VAR selrec   : tkb7_select_param;
            disnum       : integer;
            act          : integer;
            stpos        : integer);
 
VAR
      recpos       : integer;
      avgpos       : integer;
      avglen       : integer;
      i_cnt        : tsp_int4;
      cnt          : tsp_int4;
      set_result   : tgg_bd_set_result_record;
      htree_id     : tgg00_FileId;
      htree_pos    : tgg00_FilePos;
      hkey         : tgg_lkey;
      resbytelen   : integer;
      ret          : tsp_num_error;
 
BEGIN
WITH m, mb_qual^, selrec, selr_selectbuffer DO
    BEGIN
    WITH set_result DO
        BEGIN
        bd_key_check_len := selr_keyl - mxgg_rescnt;
        bd_max_rec_cnt   := csp_maxint2;
        bd_max_fill_len  := mxsp_buf;
        bd_next          := false;
        bd_drop_page     := false;
        END;
    (*ENDWITH*) 
&   ifdef TRACE
    t01int4 (kb_qual, 'disnum      ', disnum);
&   endif
    htree_id            := selr_distinct_id;
    htree_id.fileTempCnt_gg00   := disnum;
    htree_id.fileRoot_gg00      := selr_disrootarr[ disnum ].dfi_root;
    htree_id.fileRootCheck_gg00 := selr_disrootarr[ disnum ].dfi_root_check;
    htree_pos.tpsPno_gg00 := NIL_PAGE_NO_GG00;
    g10mv1 ('VKB721',  20,    
          sizeof(result.buf), sizeof(hkey.k),
          result.buf, cgg_rec_key_offset+1,
          hkey.k, 1, result.keylen-mxgg_rescnt,
          mb_trns^.trError_gg00);
    hkey.len := result.keylen - mxgg_rescnt;
    avgpos := mb_st^[ stpos ].epos+1;
    (*avglen := mb_st^[ stpos ].elen_var-1;*)
    (* mxgg_number, because in UNION there elen_var may be > mxgg_number *)
    avglen := mxgg_number - 1;
    ret := num_ok;
    s41plint (rbuf, 1, csp_fixed, csp_float_frac, 0, ret);
    IF  mb_trns^.trError_gg00 <> e_move_error
    THEN
        mb_trns^.trError_gg00 := e_buffer_limit;
    (*ENDIF*) 
    WHILE (mb_trns^.trError_gg00 = e_buffer_limit) AND (ret = num_ok) DO
        BEGIN
        b07cnext_record (mb_trns^, htree_id,
              hkey, set_result, htree_pos, buf_rec.buf);
        IF  mb_trns^.trRteCommPtr_gg00^.to_cancel
        THEN
            mb_trns^.trError_gg00 := e_cancelled;
        (*ENDIF*) 
        IF  mb_trns^.trError_gg00 = e_key_not_found
        THEN
            mb_trns^.trError_gg00 := e_ok;
        (*ENDIF*) 
        IF  ((mb_trns^.trError_gg00 = e_ok) OR
            (mb_trns^.trError_gg00 = e_buffer_limit))
        THEN
            BEGIN
            recpos := cgg_rec_key_offset + set_result.bd_key_check_len + 2;
            WHILE ((recpos < set_result.bd_fill_len) AND
                  (ret = num_ok)) DO
                BEGIN
&               ifdef TRACE
                t01name (kb_qual, 's51sub            ');
                t01buf (kb_qual, buf_rec.buf, recpos, recpos+avglen-1);
                t01buf (kb_qual, result.buf, avgpos, avgpos+avglen-1);
&               endif
                s51sub (buf_rec.buf, recpos, avglen,
                      result.buf, avgpos, avglen,
                      buf_rec.buf, recpos,
                      csp_fixed, csp_float_frac,
                      resbytelen, ret);
&               ifdef TRACE
                t01buf (kb_qual, buf_rec.buf,
                      recpos, recpos + resbytelen - 1);
                t01int4 (kb_qual, 'ret =       ', ord(ret));
&               endif
                IF  ret = num_ok
                THEN
                    BEGIN
&                   ifdef TRACE
                    t01name (kb_qual, 's51mul            ');
                    t01buf (kb_qual, buf_rec.buf,
                          recpos, recpos + avglen - 1);
&                   endif
                    s51mul (buf_rec.buf, recpos, avglen,
                          buf_rec.buf, recpos, avglen,
                          buf_rec.buf, recpos,
                          csp_fixed, csp_float_frac,
                          resbytelen, ret);
&                   ifdef TRACE
                    t01buf (kb_qual, buf_rec.buf,
                          recpos, recpos + resbytelen - 1);
                    t01int4 (kb_qual, 'ret =       ', ord(ret));
&                   endif
                    END;
                (*ENDIF*) 
                IF  ret = num_ok
                THEN
                    BEGIN
                    cnt := s20or4sw (buf_rec.buf, recpos + avglen,
                          sw_normal, g01code.kernel_swap);
&                   ifdef TRACE
                    t01name (kb_qual, 's51add            ');
                    t01int4 (kb_qual, 'cnt =       ', cnt);
                    t01buf (kb_qual, rbuf, 1, mxsp_number);
                    t01buf (kb_qual, buf_rec.buf,
                          recpos, recpos + avglen - 1);
&                   endif
                    i_cnt := 0;
                    REPEAT
                        i_cnt := succ(i_cnt);
                        s51add (rbuf, 1, mxsp_number,
                              buf_rec.buf, recpos, resbytelen,
                              rbuf, 1, csp_fixed, csp_float_frac,
                              resbytelen, ret);
                    UNTIL
                        (ret <> num_ok) OR
                        (i_cnt = cnt);
                    (*ENDREPEAT*) 
&                   ifdef TRACE
                    t01buf (kb_qual, rbuf, 1, resbytelen);
                    t01int4 (kb_qual, 'ret =       ', ord(ret));
&                   endif
                    END;
                (*ENDIF*) 
                recpos := recpos + buf_rec.len
                END
            (*ENDWHILE*) 
            END
        (*ENDIF*) 
        END;
    (*ENDWHILE*) 
    IF  ((mb_trns^.trError_gg00 = e_no_next_record) OR
        (mb_trns^.trError_gg00 = e_buffer_limit) OR
        (mb_trns^.trError_gg00 = e_ok))
    THEN
        BEGIN
        IF  ret = num_overflow
        THEN
            BEGIN
            ret := num_ok;
            result.buf[ avgpos-1 ] := csp_oflw_byte
            END
        ELSE
            IF  ret = num_ok
            THEN
                BEGIN
                s41p4int (rbuf, mxgg_number + 1, 1, ret);
                s51sub (result.buf, avgpos + mxgg_number, mxsp_resnum-1,
                      rbuf, mxgg_number+1, mxsp_resnum-1,
                      result.buf, avgpos + mxgg_number,
                      csp_resnum_deflen, csp_float_frac,
                      resbytelen, ret);
&               ifdef TRACE
                t01name (kb_qual, 's51div            ');
                t01buf (kb_qual, rbuf, 1, avglen);
                t01buf (kb_qual, result.buf, avgpos+mxgg_number,
                      avgpos+mxgg_number+mxsp_resnum-1);
&               endif
                IF  result.buf[ avgpos+mxgg_number ] = cgg_zero_exponent
                THEN
                    s41plint (result.buf, avgpos,
                          csp_fixed, csp_float_frac, 0, ret)
                ELSE
                    BEGIN
                    s51div (rbuf, 1, avglen,
                          result, avgpos + mxgg_number, mxsp_resnum-1,
                          result, avgpos,  csp_fixed, csp_float_frac,
                          resbytelen, ret);
&                   ifdef TRACE
                    t01buf (kb_qual, result.buf,
                          avgpos, avgpos + resbytelen - 1);
                    t01int4 (kb_qual, 'ret =       ', ord(ret));
&                   endif
                    IF  ((ret = num_ok) AND
                        (result.buf[ avgpos ] > cgg_zero_exponent) AND
                        ((mb_st^[ act ].eop_func = op_f_stddev) OR
                        ( mb_st^[ act ].eop_func = op_f_dis_stddev)))
                    THEN
                        s52sqrt (result.buf, avgpos, mxsp_number,
                              result.buf, avgpos, csp_fixed,
                              csp_float_frac, ret);
                    (*ENDIF*) 
                    IF  ret = num_trunc
                    THEN
                        ret := num_ok
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END;
            (*ENDIF*) 
        (*ENDIF*) 
        IF  ret <> num_ok
        THEN
            mb_trns^.trError_gg00 := e_num_invalid
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb721store_outer_key (
            VAR m       : tgg_mess_block;
            VAR selrec  : tkb7_select_param;
            VAR oj_info : tkb7_oj_info_type);
 
VAR
      i      : integer;
      j      : integer;
      rec_id : tsp_int4;
 
BEGIN
WITH m, mb_qual^, selrec, selr_selectbuffer, result, oj_info DO
    BEGIN
    mb_trns^.trError_gg00 := e_ok;
    IF  (selr_countresult = 1)
    THEN
        BEGIN
        oj_ok_keys_id             := selr_resf_id;
        oj_ok_keys_id.fileTfnTemp_gg00 := ttfnOuterJoinKeys_egg00;
        b01tcreate_file (mb_trns^, oj_ok_keys_id);
        END;
    (*ENDIF*) 
    i := 1;
    j := cgg_rec_key_offset+1;
    WHILE (i < 3) AND (mb_trns^.trError_gg00 = e_ok) DO
        BEGIN
        g10mv11 ('VKB721',  21,    
              sizeof(buf_rec.buf), sizeof(rec_id),
              buf_rec.buf, j, rec_id, 1, 4,
              mb_trns^.trError_gg00);
        IF  rec_id > 0
        THEN
            BEGIN
            g10mv6 ('VKB721',  22,    
                  sizeof(buf_rec.buf), sizeof(buf),
                  buf_rec.buf, j, buf, cgg_rec_key_offset+1, 4,
                  mb_trns^.trError_gg00);
            len    := cgg_rec_key_offset + sizeof(rec_id) + 1;
            keylen := len - cgg_rec_key_offset;
            recVarcolOffset_gg00 := 0;
            recVarcolCnt_gg00    := 0;
            IF  i = 2
            THEN
                buf[ len ] := chr (1)
            ELSE
                buf[ len ] := chr (2);
            (*ENDIF*) 
            IF  (mb_trns^.trError_gg00 = e_ok)
            THEN
                b07cadd_record (mb_trns^, oj_ok_keys_id, result.buf);
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  (mb_trns^.trError_gg00 = e_duplicate_key)
        THEN
            mb_trns^.trError_gg00 := e_ok;
        (*ENDIF*) 
        i := succ (i);
        j := j + 4;
        END;
    (*ENDWHILE*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb721unique_add (
            VAR t      : tgg00_TransContext;
            VAR selrec : tkb7_select_param);
 
VAR
      set_result : tgg_bd_set_result_record;
      is_equal   : boolean;
      i          : integer;
      comp_len   : integer;
      recpos     : integer;
      lc         : tsp_lcomp_result;
      new_key    : tgg_lkey;
 
BEGIN
WITH selrec, selr_selectbuffer, result DO
    BEGIN
    IF  selr_distinct_bytes
    THEN
        BEGIN
        recpos := keylen + cgg_rec_key_offset + 2;
        IF  selr_distinct = full_distinct
        THEN
            i := len - keylen - cgg_rec_key_offset - 1
        ELSE
            i := len - 1 - keylen - cgg_rec_key_offset - 1;
        (*ENDIF*) 
&       ifdef TRACE
        t01int4 (kb, 'i           ', i);
        t01buf (kb, buf, i + 1, len);
&       endif
        k50hash (buf, recpos, i, buf,
              cgg_rec_key_offset + keylen - mxgg_rescnt -
              cgg_cdistinct_bytes + 1);
        END;
&   ifdef TRACE
    (*ENDIF*) 
    i      := len - keylen - cgg_rec_key_offset - 1;
    t01int4 (kb, 'i           ', i);
    t01buf (kb, buf, i + 1, len);
&   endif
    new_key.len := keylen - mxgg_rescnt;
    g10mv1 ('VKB721',  23,    
          sizeof(buf), sizeof(new_key.k), buf, cgg_rec_key_offset + 1,
          new_key.k, 1, new_key.len, t.trError_gg00);
    is_equal := false;
    WITH set_result DO
        BEGIN
        bd_key_check_len := new_key.len;
        bd_max_rec_cnt   := csp_maxint2;
        bd_max_fill_len  := mxsp_buf;
        bd_next          := false;
        bd_drop_page     := false;
        END;
    (*ENDWITH*) 
    selrec.selr_tree_pos.tpsPno_gg00 := NIL_PAGE_NO_GG00;
    IF  t.trError_gg00 <> e_move_error
    THEN
        t.trError_gg00 := e_buffer_limit;
    (*ENDIF*) 
    WHILE (NOT is_equal) AND (t.trError_gg00 = e_buffer_limit) DO
        BEGIN
        b07cnext_record (t, selr_resf_id, new_key, set_result,
              selrec.selr_tree_pos, buf_rec.buf);
        IF  t.trRteCommPtr_gg00^.to_cancel
        THEN
            t.trError_gg00 := e_cancelled;
        (*ENDIF*) 
        IF  t.trError_gg00 = e_key_not_found
        THEN
            t.trError_gg00 := e_ok;
        (*ENDIF*) 
        IF  ((t.trError_gg00 = e_ok) OR (t.trError_gg00 = e_buffer_limit))
        THEN
            BEGIN
            recpos := 0;
            WHILE (NOT is_equal AND
                  (recpos < set_result.bd_fill_len)) DO
                BEGIN
                i := keylen + cgg_rec_key_offset + 1;
                IF  selr_distinct = full_distinct
                THEN
                    comp_len := len - i + 1
                ELSE
                    comp_len := len - i;
                (*ENDIF*) 
                s30cmp (buf, i, comp_len,
                      buf_rec.buf, recpos + i, comp_len, lc);
                is_equal := lc = l_equal;
&               ifdef TRACE
                t01int4 (kb, 'i           ', i);
                t01int4 (kb, 'comp_len    ', comp_len);
                t01buf (kb, buf, i, len);
                t01buf (kb, buf_rec.buf, recpos + i,
                      recpos+len);
                t01int4 (kb, 'lc          ', ord(lc));
                IF  is_equal
                THEN
                    t01int4 (kb,'is_equal    ', 1);
&               endif
                (*ENDIF*) 
                recpos := recpos + len
                END;
            (*ENDWHILE*) 
            IF  NOT is_equal
            THEN
                recpos := recpos - len;
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDWHILE*) 
    IF  ((t.trError_gg00 = e_no_next_record) OR (t.trError_gg00 = e_buffer_limit))
    THEN
        t.trError_gg00 := e_ok;
    (*ENDIF*) 
    IF  (t.trError_gg00 = e_ok)
    THEN
        IF  NOT is_equal
        THEN
            IF  ((selr_countresult = 2) AND (selr_maxresult = 0))
            THEN
                t.trError_gg00 := e_too_many_resultsets
            ELSE
                BEGIN
                b07cadd_record (t, selr_resf_id, result.buf);
                IF  selr_one_result (* corr_single *)
                THEN
                    g10mv6 ('VKB721',  24,    
                          sizeof(result.buf), sizeof(lbuf),
                          result.buf, 1, lbuf, 1, result.len,
                          t.trError_gg00);
                (*ENDIF*) 
                IF  t.trError_gg00 = e_ok
                THEN
                    IF  ((selr_countresult = selr_maxresult)
                        OR
                        (selr_oracle_selinto
                        AND (selr_resf_id.fileTfnTemp_gg00 = ttfnInto_egg00)
                        AND (selr_resf_id.fileTfn_gg00 = tfnTemp_egg00)))
                    THEN
                        t.trError_gg00 := e_enough_resultsets
                    (*ENDIF*) 
                (*ENDIF*) 
                END
            (*ENDIF*) 
        ELSE
            selr_countresult := pred(selr_countresult)
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb721viewkey_search (
            VAR m      : tgg_mess_block;
            VAR getrec : tkb7_get_param;
            VAR selrec : tkb7_select_param;
            VAR sel    : tgg_select_fields_param);
 
VAR
      curr_key       : tgg_lkey;
      oj_info        : tkb7_oj_info_type;
 
BEGIN
WITH m, mb_data^ DO
    BEGIN
    curr_key.len := mbp_keylen;
    g10mv13 ('VKB721',  25,    
          mb_data_size, sizeof(curr_key.k), mbp_buf, cgg_rec_key_offset + 1,
          curr_key.k, 1, curr_key.len,
          mb_trns^.trError_gg00)
    END;
(*ENDWITH*) 
oj_info.is_outer_join := false;
sel.sfp_bd_mess2_type := mm_direct;
IF  m.mb_trns^.trError_gg00 <> e_move_error
THEN
    kb721select_gets (m, curr_key, getrec, selrec, sel, oj_info);
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb721longcol_insert_select (
            VAR m              : tgg00_MessBlock;
            VAR selrec         : tkb7_select_param);
      (* PTS 1105795 M.Ki. *)
 
VAR
      has_shrt_col_file : boolean;
      i                 : tsp_int2;
      stack_pos         : tsp_int2;
      rec_pos           : tsp_int4;
      move_len          : tsp_int4;
      default_pos       : tsp00_IntMapC2;
      source_surr       : tgg_surrogate;
      source_tab_surr   : tgg_surrogate;
      dst_surr          : tgg_surrogate;
      default_rec_ptr   : tgg00_RecPtr;
      (* PTS 1120891 E.Z. *)
 
      ld_info_rec       : RECORD
            CASE boolean OF
                true :
                    (c1 : tsp00_C1);
                false :
                    (ld_info : tsp00_LdInfo);
                END;
            (*ENDCASE*) 
 
 
BEGIN
&ifdef TRACE
t01messblock ( kb, 'longcolins  ', m );
t01buf( kb, selrec.selr_selectbuffer.
      result.recBuf_gg00, 1, selrec.selr_selectbuffer.result.recLen_gg00 );
&ENDIF
IF  selrec.selr_selectbuffer.result.recLen_gg00 > MAX_RECLEN_GG00
THEN (* check if record would shrink enough to fit in page *)
    BEGIN
    i               := 1;
    move_len        := 0;
    stack_pos       := m.mb_qual^.mstring_pos;
    REPEAT
        IF  m.mb_st^[ stack_pos ].elen_var <> SURROGATE_MXGG00 + 1
        THEN
            (* PTS 1120891 E.Z. *)
            move_len := move_len +
                  m.mb_st^[ stack_pos ].elen_var - (SURROGATE_MXGG00 + 1);
        (*ENDIF*) 
        i := succ (i);
    UNTIL
        i > m.mb_qual^.mstring_cnt;
    (*ENDREPEAT*) 
    IF  (selrec.selr_selectbuffer.result.recLen_gg00 - move_len)
        > MAX_RECLEN_GG00
    THEN
        m.mb_trns^.trError_gg00 := e_too_long_record
    (*ENDIF*) 
    END;
(*ENDIF*) 
IF  m.mb_trns^.trError_gg00 = e_ok
THEN
    BEGIN
    i               := 1;
    move_len        := 0;
    stack_pos       := m.mb_qual^.mstring_pos;
    (* PTS 1120891 E.Z. *)
    rec_pos         := cgg_rec_key_offset + selrec.selr_selectbuffer.result.recKeyLen_gg00 + 1;
    source_surr     := cgg_zero_id;
    source_tab_surr := cgg_zero_id;
    default_rec_ptr := NIL;
&   ifdef TRACE
    t01buf( kb, selrec.selr_selectbuffer.
          result.recBuf_gg00, 1, selrec.selr_selectbuffer.result.recLen_gg00 );
&   ENDIF
    REPEAT
        (* PTS 1120891 E.Z. *)
        IF  m.mb_st^[stack_pos].elen_var = mxsp_long_desc + 1
        THEN
            BEGIN
            ld_info_rec.c1[1] := selrec.selr_selectbuffer.result.recBuf_gg00
                  [rec_pos + move_len + 1 + 8 + 8 + 2*4];
            IF  (ld_is_comment in ld_info_rec.ld_info) OR
                (ld_is_catalog in ld_info_rec.ld_info)
            THEN
                m.mb_trns^.trError_gg00 := e_not_implemented;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  m.mb_trns^.trError_gg00 = e_ok
        THEN
            BEGIN
&           ifdef TRACE
            t01stackentry (kb, m.mb_st^[stack_pos], stack_pos);
            t01int4 (kb_qual, 'i           ', i);
            t01int4 (kb_qual, 'move_len    ', move_len);
            t01int4 (kb_qual, 'rec_pos     ', rec_pos);
            t01int4 (kb_qual, 'rec_key_len ', selrec.selr_selectbuffer.result.recKeyLen_gg00);
&           ENDIF
            dst_surr := selrec.selr_resf_id.fileTabId_gg00; (* PTS 1116809 M.Ki. *)
            IF  m.mb_st^[stack_pos].ecol_tab[2] = chr(1)
            THEN
                has_shrt_col_file := true
            ELSE
                has_shrt_col_file := false;
            (*ENDIF*) 
            g10mv17 ('VKB721',  26,    
                  sizeof(selrec.selr_selectbuffer.result.recBuf_gg00),
                  sizeof(tgg_surrogate),
                  selrec.selr_selectbuffer.result.recBuf_gg00,
                  rec_pos + move_len + 1,
                  source_surr, 1,
                  SURROGATE_MXGG00,
                  m.mb_trns^.trError_gg00);
            IF  m.mb_st^[ stack_pos ].elen_var = SURROGATE_MXGG00 + 1
            THEN  (* null or default value *)
                BEGIN
                IF  (source_surr = cgg_zero_id)
                THEN
                    BEGIN
                    g10mv16 ('VKB721',  27,    
                          sizeof(selrec.selr_selectbuffer.result.recBuf_gg00),
                          sizeof(selrec.selr_selectbuffer.result.recBuf_gg00),
                          selrec.selr_selectbuffer.result.recBuf_gg00,
                          rec_pos + move_len,
                          selrec.selr_selectbuffer.result.recBuf_gg00, rec_pos,
                          SURROGATE_MXGG00 + 1,
                          m.mb_trns^.trError_gg00);
                    END
                ELSE (* default value; position of default record in data part *)
                    (*  is in surrogate                                        *)
                    BEGIN
                    default_pos.mapC2_sp00[ 1 ] := source_surr [mxgg_surrogate - 1];
                    default_pos.mapC2_sp00[ 2 ] := source_surr [mxgg_surrogate];
                    default_rec_ptr := @m.mb_data^.mbp_buf[ default_pos.mapInt_sp00 ];
&                   ifdef TRACE
                    t01int4 (kb_qual, 'default pos ', default_pos.mapInt_sp00);
                    t01buf  (kb_qual, default_rec_ptr^.recBuf_gg00, 1,
                          default_rec_ptr^.recLen_gg00 );
&                   ENDIF
                    k43_ins_copy_column (m.mb_trns, m.mb_header, m.mb_qual^.mtree,
                          selrec.selr_resf_id,
                          source_tab_surr, source_surr, dst_surr, has_shrt_col_file,
                          default_rec_ptr, c_use_shc_buf);
                    g10mv10 ('VKB721',  28,    
                          sizeof(tgg_surrogate),
                          sizeof(selrec.selr_selectbuffer.result.recBuf_gg00),
                          dst_surr, 1,
                          selrec.selr_selectbuffer.result.recBuf_gg00, rec_pos + 1,
                          SURROGATE_MXGG00,
                          m.mb_trns^.trError_gg00);
                    selrec.selr_selectbuffer.result.recBuf_gg00[ rec_pos ] := csp_defined_byte;
                    END;
                (*ENDIF*) 
                END
            ELSE
                BEGIN (* something was inserted into this column *)
                IF  source_surr <> cgg_zero_id
                THEN
                    BEGIN
                    g10mv17 ('VKB721',  29,    
                          sizeof(selrec.selr_selectbuffer.result.recBuf_gg00),
                          sizeof(tgg_surrogate),
                          selrec.selr_selectbuffer.result.recBuf_gg00,
                          rec_pos + move_len + SURROGATE_MXGG00 + 1,
                          source_tab_surr, 1,
                          SURROGATE_MXGG00,
                          m.mb_trns^.trError_gg00);
                    k43_ins_copy_column (m.mb_trns, m.mb_header, m.mb_qual^.mtree,
                          selrec.selr_resf_id,
                          source_tab_surr, source_surr, dst_surr, has_shrt_col_file,
                          default_rec_ptr, NOT c_use_shc_buf);
                    g10mv10 ('VKB721',  30,    
                          sizeof(tgg_surrogate),
                          sizeof(selrec.selr_selectbuffer.result.recBuf_gg00),
                          dst_surr, 1,
                          selrec.selr_selectbuffer.result.recBuf_gg00, rec_pos + 1,
                          SURROGATE_MXGG00,
                          m.mb_trns^.trError_gg00);
                    selrec.selr_selectbuffer.result.recBuf_gg00[ rec_pos ] := csp_defined_byte;
                    END
                ELSE (* move null value to correct position *)
                    BEGIN
                    g10mv10 ('VKB721',  31,    
                          sizeof(tgg_surrogate),
                          sizeof(selrec.selr_selectbuffer.result.recBuf_gg00),
                          source_surr, 1,
                          selrec.selr_selectbuffer.result.recBuf_gg00, rec_pos + 1,
                          SURROGATE_MXGG00,
                          m.mb_trns^.trError_gg00);
                    selrec.selr_selectbuffer.result.recBuf_gg00[ rec_pos ] := csp_undef_byte;
                    END;
                (*ENDIF*) 
                (* PTS 1120891 E.Z. *)
                move_len := move_len +
                      m.mb_st^[ stack_pos ].elen_var - (SURROGATE_MXGG00 + 1);
                END;
            (*ENDIF*) 
            rec_pos   := rec_pos + SURROGATE_MXGG00 + 1;
            stack_pos := succ(stack_pos);
            i         := succ(i);
&           ifdef TRACE
            t01buf( kb, selrec.selr_selectbuffer.
                  result.buf, 1, selrec.selr_selectbuffer.result.recLen_gg00 );
&           ENDIF
            END
        (*ENDIF*) 
    UNTIL
        (i > m.mb_qual^.mstring_cnt) OR (m.mb_trns^.trError_gg00 <> e_ok);
    (*ENDREPEAT*) 
    (* shrink record and correct record size and varcol offset *)
    g10mv16 ('VKB721',  32,    
          selrec.selr_selectbuffer.result.recLen_gg00,
          selrec.selr_selectbuffer.result.recLen_gg00,
          selrec.selr_selectbuffer.result.recBuf_gg00,
          rec_pos + move_len,
          selrec.selr_selectbuffer.result.recBuf_gg00, rec_pos,
          selrec.selr_selectbuffer.result.recLen_gg00 + 1 - rec_pos - move_len,
          m.mb_trns^.trError_gg00);
    selrec.selr_selectbuffer.result.recLen_gg00          :=
          selrec.selr_selectbuffer.result.recLen_gg00 - move_len;
    selrec.selr_selectbuffer.result.recVarcolOffset_gg00 :=
          selrec.selr_selectbuffer.result.recVarcolOffset_gg00 - move_len;
&   ifdef TRACE
    t01buf( kb, selrec.selr_selectbuffer.
          result.buf, 1, selrec.selr_selectbuffer.result.recLen_gg00 );
&   ENDIF
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb721result_handle (
            VAR m              : tgg_mess_block;
            VAR selrec         : tkb7_select_param;
            VAR getrec         : tkb7_get_param;
            VAR selfields      : tgg_select_fields_param;
            VAR inv_listkey    : tgg_lkey;
            VAR act_key        : tgg_lkey;
            VAR htree_id       : tgg00_FileId;
            VAR oj_info        : tkb7_oj_info_type;
            granted_lock       : tgg00_LockReqMode);
 
VAR
      _put_into      : boolean;
      _hlen          : tsp_int2;
      _hvarcoloffset : tsp_int2;
      _hvarcolcnt    : tsp_int2;
      _hreplicated   : tgg_replicated;
      _old_tr_err    : tgg_basis_error;
 
BEGIN
_old_tr_err         := e_ok;
selrec.selr_act_cntresult := selfields.sfp_m_result_cnt;
;
IF  ( selrec.selr_act_cntresult > 0 )
THEN
    IF  ( m.mb_trns^.trError_gg00 = e_no_next_record ) OR
        ( m.mb_trns^.trError_gg00 = e_no_prev_record )
    THEN
        BEGIN
        _old_tr_err      := m.mb_trns^.trError_gg00;
        m.mb_trns^.trError_gg00 := e_ok;
        END;
    (*ENDIF*) 
(*ENDIF*) 
IF  ( m.mb_trns^.trRteCommPtr_gg00^.to_cancel )
THEN
    m.mb_trns^.trError_gg00 := e_cancelled;
(*ENDIF*) 
IF  ( m.mb_trns^.trError_gg00 = e_key_not_found  ) OR
    ( m.mb_trns^.trError_gg00 = e_qual_violation ) OR
    ( m.mb_trns^.trError_gg00 = e_view_violation )
THEN
    m.mb_trns^.trError_gg00 := e_ok
ELSE
    IF  ( m.mb_trns^.trError_gg00 = e_buffer_limit ) AND
        ( m.mb_type = m_insert_select )
    THEN
        m.mb_trns^.trError_gg00 := e_too_long_record
    ELSE
        BEGIN
        IF  ( m.mb_trns^.trError_gg00 = e_ok )
        THEN
            BEGIN
            _put_into        := true;
            IF  ( selrec.selr_intern_dist )
            THEN
                BEGIN
                WITH selrec.selr_selectbuffer.buf_rec DO
                    BEGIN
                    _hlen                 := len;
                    len                  := keylen + cgg_rec_key_offset;
                    _hvarcoloffset        := recVarcolOffset_gg00;
                    recVarcolOffset_gg00 := 0;
                    _hvarcolcnt           := recVarcolCnt_gg00;
                    recVarcolCnt_gg00    := 0;
                    b07cadd_record( m.mb_trns^,
                          selrec.selr_distinct_id,
                          selrec.selr_selectbuffer.buf_rec.buf );
                    len                  := _hlen;
                    recVarcolOffset_gg00 := _hvarcoloffset;
                    recVarcolCnt_gg00    := _hvarcolcnt;
                    END;
                (*ENDWITH*) 
                IF  ( m.mb_trns^.trError_gg00 = e_duplicate_key )
                THEN
                    BEGIN
                    _put_into          := false;
                    selfields.sfp_rows_qual := selfields.sfp_rows_qual - 1;
                    m.mb_trns^.trError_gg00   := e_ok
                    END
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  _put_into AND ( m.mb_trns^.trError_gg00 = e_ok )
            THEN
                WITH selrec.selr_selectbuffer.result DO
                    IF  ( m.mb_type in [ m_update,m_delete,m_insert_select ] )
                    THEN
                        IF  ( m.mb_type in [ m_update, m_delete ] )
                        THEN
                            BEGIN
                            (* PTS 1120260 E.Z. *)
                            (*mess2_type = mm_qual*)
                            IF  ( m.mb_type = m_update )
                            THEN
                                BEGIN
                                k63upd_select( m, act_key,
                                      selrec.selr_selectbuffer.buf_rec,
                                      @selfields,
                                      @selrec.selr_selectbuffer.longresult,
                                      selfields.sfp_result_length,
                                      selrec.selr_selectbuffer.lbuf,
                                      selrec.selr_intersect_id,
                                      granted_lock );
                                WHILE ( m.mb_trns^.trError_gg00 =
                                      e_wait_for_lock_release ) DO
                                    BEGIN
                                    k53wait( m.mb_trns^, m.mb_type,
                                          m.mb_type2 );
                                    IF  ( m.mb_trns^.trError_gg00 = e_ok )
                                    THEN
                                        k63upd_select( m, act_key,
                                              selrec.selr_selectbuffer.
                                              buf_rec,
                                              @selfields,
                                              @selrec.selr_selectbuffer.longresult,
                                              selfields.sfp_result_length,
                                              selrec.selr_selectbuffer.lbuf,
                                              selrec.selr_intersect_id,
                                              granted_lock );
                                    (*ENDIF*) 
                                    END;
                                (*ENDWHILE*) 
                                END
                            ELSE
                                k61del_select( m, act_key,
                                      selrec.selr_selectbuffer.buf_rec,
                                      granted_lock );
                            (*ENDIF*) 
                            IF  ( m.mb_trns^.trError_gg00 = e_skip_key_upd )
                            THEN
                                m.mb_trns^.trError_gg00 := e_ok
                            ELSE
                                (* PTS 1120260 E.Z. *)
                                IF  (m.mb_type = m_update)   AND
                                    (selrec.selr_countresult = 1) AND
                                    (selrec.selr_maxresult = 0)
                                THEN
                                    m.mb_trns^.trError_gg00 := e_too_many_updatesets
                                ELSE
                                    selrec.selr_countresult :=
                                          succ( selrec.selr_countresult );
                                (*ENDIF*) 
                            (*ENDIF*) 
                            END
                        ELSE
                            BEGIN
                            (* m.mb_type = m_insert_select *)
                            IF  ( selrec.selr_is_nokey )
                            THEN
                                selrec.selr_selectbuffer.result.keylen :=
                                      1 + mxgg_surrogate;
                            (*ENDIF*) 
                            len := selfields.sfp_result_length;
                            ;
                            IF  m.mb_qual^.mstring_cnt > 0
                            THEN (* PTS 1105795 M.Ki. *)
                                kb721longcol_insert_select (
                                      m,
                                      selrec);
                            (*ENDIF*) 
                            IF  m.mb_trns^.trError_gg00 = e_ok
                            THEN
                                IF  ( len > mxgg_record )
                                THEN
                                    m.mb_trns^.trError_gg00 := e_too_long_record
                                ELSE
                                    BEGIN
&                                   ifdef TRACE
                                    t01buf( kb, selrec.selr_selectbuffer.
                                          result.buf, 1, len );
                                    IF  ( selrec.selr_is_nokey )
                                    THEN
                                        t01int4( kb, 'is_nokey    ', 1 );
&                                   endif
                                    (*ENDIF*) 
                                    m.mb_qual^.mtree := selrec.selr_resf_id;
                                    _hreplicated    := m.mb_replicated;
                                    IF  (( m.mb_qual^.mtree.fileTfnTemp_gg00 <>
                                        ttfnInternResult_egg00 ) OR
                                        ( m.mb_qual^.mtree.fileTfn_gg00 <> tfnTemp_egg00 )) AND
                                        ( _hreplicated = rpl_full )
                                    THEN
                                        (* insert select with one phase *)
                                        m.mb_replicated := rpl_none;
                                    (*ENDIF*) 
                                    k61ins_select( m,
                                          selrec.selr_selectbuffer.result,
                                          selrec.selr_is_nokey,
                                          selrec.selr_dupl[ 1 ] = cgg_update_dupl,
                                          selrec.selr_countresult + 1 );
                                    WHILE ( m.mb_trns^.trError_gg00 =
                                          e_wait_for_lock_release ) DO
                                        BEGIN
                                        k53wait( m.mb_trns^, m.mb_type,
                                              m.mb_type2 );
                                        IF  ( m.mb_trns^.trError_gg00 = e_ok )
                                        THEN
                                            k61ins_select( m,
                                                  selrec.selr_selectbuffer.result,
                                                  selrec.selr_is_nokey,
                                                  selrec.selr_dupl[ 1 ] =
                                                  cgg_update_dupl,
                                                  selrec.selr_countresult + 1 );
                                        (*ENDIF*) 
                                        END;
                                    (*ENDWHILE*) 
                                    m.mb_qual^.mtree := htree_id;
                                    m.mb_replicated  := _hreplicated;
                                    IF  (m.mb_trns^.trError_gg00 = e_ok)
                                    THEN
                                        BEGIN
                                        selrec.selr_countresult :=
                                              succ( selrec.selr_countresult );
                                        IF  ( selrec.selr_countresult =
                                            selrec.selr_maxresult )
                                        THEN
                                            m.mb_trns^.trError_gg00 :=
                                                  e_enough_resultsets;
                                        (*ENDIF*) 
                                        END
                                    ELSE
                                        IF  ( m.mb_trns^.trError_gg00 =
                                            e_duplicate_key )
                                        THEN
                                            IF  ( selrec.selr_dupl[ 1 ] = cgg_ignore_dupl )
                                            THEN
                                                m.mb_trns^.trError_gg00 := e_ok;
                                            (*ENDIF*) 
                                        (*ENDIF*) 
                                    (*ENDIF*) 
                                    END
                                (*ENDIF*) 
                            (*ENDIF*) 
                            END
                        (*ENDIF*) 
                    ELSE
                        BEGIN
                        len    := selrec.selr_recl;
                        keylen := selrec.selr_keyl;
                        IF  ( m.mb_type2 = mm_with_functions )
                        THEN
                            k721function_add( m, selrec, NOT c_aggr )
                        ELSE
                            IF  ( m.mb_type2 = mm_with_join )
                            THEN
                                k74join_with_left_result( m, getrec,
                                      selfields, selrec, inv_listkey,
                                      ( selfields.sfp_bd_inv_only = inv_only ) AND
                                      ( m.mb_st^[ m.mb_qual^.mstrat_pos + 1 ].
                                      ecol_tab[ 2 ] = chr ( 1 )))
                            ELSE
                                BEGIN
                                WITH oj_info DO
                                    IF  (selfields.sfp_oj_spec <>
                                        ckb7_ojoin_none)
                                    THEN
                                        BEGIN
                                        kb721add_outer_result( m,
                                              selrec, selfields.sfp_oj_spec,
                                              oj_info );
                                        selfields.sfp_oj_spec :=
                                              ckb7_ojoin_none;
                                        END
                                    ELSE
                                        BEGIN
                                        k721add_into_result( m.mb_trns^,
                                              selrec, m.mb_next_mblock );
                                        IF  is_outer_join AND
                                            ( m.mb_trns^.trError_gg00 = e_ok )
                                        THEN
                                            kb721store_outer_key( m,
                                                  selrec, oj_info );
                                        (*ENDIF*) 
                                        END;
                                    (*ENDIF*) 
                                (*ENDWITH*) 
                                END;
                            (*ENDIF*) 
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                (*ENDWITH*) 
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
(*ENDIF*) 
IF  ( m.mb_trns^.trError_gg00 = e_ok ) AND ( _old_tr_err <> e_ok )
THEN
    m.mb_trns^.trError_gg00 := _old_tr_err;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      k721add_into_result (
            VAR t                : tgg00_TransContext;
            VAR selrec           : tkb7_select_param;
            VAR next_mblock      : tgg_mess_block_ptr);
 
VAR
      ix          : tsp_int4;
      iy          : tsp_int4;
      recpos      : tsp_int4;
      aligned_len : tsp_int4;
      lkey        : tgg_lkey;
      result_ptr  : ^tkb7_rec_buf;
 
BEGIN
WITH selrec, selr_selectbuffer, result DO
    BEGIN
    ix          := 1;
    aligned_len := 0;
    IF  (selr_act_cntresult < 1)
    THEN
        selr_act_cntresult := 1
    ELSE
        IF  selr_one_result
        THEN
            selr_act_cntresult := 1
        ELSE
            IF  (selr_resrec_maxlen MOD 2 = 1)
            THEN
                aligned_len := selr_resrec_maxlen + 1
            ELSE
                aligned_len := selr_resrec_maxlen;
            (*ENDIF*) 
        (*ENDIF*) 
    (*ENDIF*) 
&   ifdef TRACE
    t01int4 (kb_qual, 'resrec_maxl ', selr_resrec_maxlen);
    t01int4 (kb_qual, 'aligned_len ', aligned_len);
    t01int4 (kb_qual, 'act_cntreslt', selr_act_cntresult);
    t01buf  (kb_qual, result.buf, 1, 500);
&   endif
    WHILE (ix <= selr_act_cntresult) AND
          (t.trError_gg00 = e_ok) DO
        BEGIN
        IF  (ix = 1)
        THEN
            result_ptr := @result
        ELSE
            BEGIN
            result_ptr := @result_ptr^.buf[ 1 + aligned_len ];
            result_ptr^.rec_head.hrecLen_gg00          := result.recLen_gg00;
            result_ptr^.rec_head.hrecKeyLen_gg00       := result.recKeyLen_gg00;
            result_ptr^.rec_head.hrecVarcolOffset_gg00 := 0;
            result_ptr^.rec_head.hrecVarcolCnt_gg00    := 0;
            END;
        (*ENDIF*) 
        IF  selr_union_select
        THEN
            k722_add_union_record (t, selrec)
        ELSE
            BEGIN
            IF  (next_mblock <> NIL) AND
                (keylen > mxgg_rescnt)
            THEN
                IF  (next_mblock^.mb_data <> NIL) AND
                    (next_mblock^.mb_qual <> NIL) AND
                    (next_mblock^.mb_st   <> NIL)
                THEN
                    BEGIN
                    (* **** In case of following joinsteps, the pages      *)
                    (*      will be read into datacache               **** *)
                    lkey.keyLen_gg00 := recKeyLen_gg00 - mxgg_rescnt;
                    g10mv14 ('VKB721',  33,    
                          sizeof (result_ptr^.buf), sizeof(lkey.keyVal_gg00),
                          result_ptr^.buf, cgg_rec_key_offset + 1,
                          lkey.keyVal_gg00, 1, lkey.keyLen_gg00, t.trError_gg00);
                    IF  t.trError_gg00 <> e_move_error
                    THEN
                        k75pre_fetch (t, next_mblock^.mb_qual^.mtree, lkey);
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
            (*ENDIF*) 
            selr_countresult := succ(selr_countresult);
            s20ch4sw (selr_countresult, g01code.kernel_swap,
                  result_ptr^.info, keylen - 3, sw_normal);
            IF  selr_distinct <> no_distinct
            THEN
                kb721unique_add (t, selrec)
            ELSE
                BEGIN
                IF  selr_union
                THEN
                    BEGIN
                    recpos := keylen + cgg_rec_key_offset + 2;
                    iy     := len - keylen - cgg_rec_key_offset - 1;
&                   ifdef TRACE
                    t01int4 (kb, 'iy          ', iy);
                    t01buf (kb, result_ptr^.buf, iy + 1, len);
&                   endif
                    k50hash (result_ptr^.buf, recpos, iy,
                          result_ptr^.buf,
                          cgg_rec_key_offset + keylen - mxgg_rescnt -
                          cgg_cdistinct_bytes + 1);
                    END;
                (*ENDIF*) 
                IF  ((selr_countresult = 2) AND (selr_maxresult = 0))
                THEN
                    t.trError_gg00 := e_too_many_resultsets
                ELSE
                    BEGIN
                    IF  selr_one_result
                    THEN
                        g10mv6 ('VKB721',  34,    
                              sizeof(result_ptr^.buf), sizeof(lbuf),
                              result_ptr^.buf, 1,
                              lbuf, 1, result_ptr^.rec_head.hrecLen_gg00, t.trError_gg00)
                    ELSE
                        IF  keylen > mxgg_rescnt
                        THEN
                            BEGIN
                            b07cadd_record (t, selr_resf_id, result_ptr^.buf);
                            IF  NOT selr_no_warn8_sort
                            THEN
                                BEGIN
&                               ifdef TRACE
                                t01int4 (kb_qual, 'WARN8 SORT  ', 0);
&                               endif
                                t.trWarning_gg00 := t.trWarning_gg00 +
                                      [ warn0_exist, warn8_scan_or_sort ];
                                selr_no_warn8_sort := true;
                                END;
                            (*ENDIF*) 
                            END
                        ELSE
                            BEGIN
&                           ifdef TRACE
                            t01int4 (bi, 'tree_page be',
                                  selrec.selr_tree_pos.tpsPno_gg00);
                            t01int4 (bi, 'tree_pos  be',
                                  selrec.selr_tree_pos.tpsIndex_gg00);
&                           endif
                            b07cappend_record (t, selr_resf_id,
                                  selrec.selr_tree_pos, result_ptr^.buf);
&                           ifdef TRACE
                            t01int4 (bi, 'tree_page af',
                                  selrec.selr_tree_pos.tpsPno_gg00);
                            t01int4 (bi, 'tree_pos  af',
                                  selrec.selr_tree_pos.tpsIndex_gg00);
&                           endif
                            (* PTS 1107952 E.Z. *)
                            END;
                        (*ENDIF*) 
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                IF  t.trError_gg00 = e_ok
                THEN
                    IF  ((selr_countresult = selr_maxresult)
                        OR
                        (selr_oracle_selinto
                        AND (selr_resf_id.fileTfnTemp_gg00 = ttfnInto_egg00)
                        AND (selr_resf_id.fileTfn_gg00 = tfnTemp_egg00)))
                    THEN
                        t.trError_gg00 := e_enough_resultsets
                    ELSE
                        IF  t.trRteCommPtr_gg00^.to_cancel
                        THEN
                            t.trError_gg00 := e_cancelled;
                        (*ENDIF*) 
                    (*ENDIF*) 
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        ix := succ(ix);
        END;
    (*ENDWHILE*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      k721call_later_output (
            VAR m       : tgg_mess_block;
            VAR res_buf : tsp_buf;
            h_keylen    : integer);
 
VAR
      stop  : integer;
      i     : integer;
      ic2   : tsp_int_map_c2;
 
BEGIN
WITH m, mb_qual^ DO
    BEGIN
    i := mqual_pos;
    IF  mb_st^[ mqual_pos ].etype = st_jump_output
    THEN
        stop := mqual_pos + mb_st^[ mqual_pos ].epos - 2
    ELSE
        stop := mqual_pos;
    (*ENDIF*) 
&   ifdef TRACE
    t01messblock (kb, 'later       ', m);
    t01int4 (kb, 'i           ', i);
    t01int4 (kb, 'stop        ', stop);
    t01int4 (kb, 'h_keylen    ', h_keylen);
&   endif
    WHILE i <= stop DO
        BEGIN
&       ifdef TRACE
        t01int4 (kb, 'i           ', i);
&       endif
        IF  mb_st^[ i ].etype = st_output
        THEN
            IF  mb_st^[ i ].eop_out = op_o_output_later
            THEN
                g10mv6 ('VKB721',  35,    
                      sizeof(res_buf), sizeof(res_buf),
                      res_buf, mb_st^[ i-1 ].epos,
                      res_buf, mb_st^[ i ].epos, mb_st^[ i ].elen_var,
                      mb_trns^.trError_gg00);
            (*ENDIF*) 
        (*ENDIF*) 
        i := succ(i)
        END;
    (*ENDWHILE*) 
    ic2.map_int := h_keylen;
    res_buf[ 3 ] := ic2.map_c2[ 1 ];
    res_buf[ 4 ] := ic2.map_c2[ 2 ];
    FOR i := 1 TO mxgg_rescnt-1 DO
        res_buf[ cgg_rec_key_offset + h_keylen - mxgg_rescnt + i ] := chr(0);
    (*ENDFOR*) 
    res_buf[ cgg_rec_key_offset + h_keylen ] := chr(1);
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      k721do_avg (
            VAR m        : tgg_mess_block;
            VAR selrec   : tkb7_select_param;
            later_output : boolean;
            h_keylen     : integer);
 
VAR
      set_result     : tgg_bd_set_result_record;
      no_repl_needed : boolean;
      overfl         : boolean;
      repl_needed    : boolean;
      act            : integer;
      disnum         : integer;
      first          : integer;
      i              : integer;
      length         : integer;
      pos            : integer;
      stpos          : integer;
      cnt_repl       : tsp_int4;
      hkey           : tgg_lkey;
      ret            : tsp_num_error;
 
BEGIN
WITH m, mb_qual^, selrec, selr_selectbuffer DO
    BEGIN
    first            := mqual_pos;
    hkey.keyLen_gg00 := 0;
    no_repl_needed   := true;
    cnt_repl := 0;
    WITH set_result DO
        BEGIN
        bd_key_check_len := 0;
        bd_max_rec_cnt   := 1;
        bd_max_fill_len  := mxsp_buf;
        bd_next          := true;
        bd_drop_page     := false;
        END;
    (*ENDWITH*) 
    selr_tree_pos.tpsPno_gg00 := NIL_PAGE_NO_GG00;
    REPEAT
        act := first - 2 + mb_st^[ first ].epos;
        disnum := 0;
        IF  selr_one_result
        THEN
            BEGIN
            mb_trns^.trError_gg00 := e_ok;
            g10mv6 ('VKB721',  36,    
                  sizeof(lbuf), sizeof(result.buf), lbuf, 1,
                  result.buf, 1, selr_recl, mb_trns^.trError_gg00)
            END
        ELSE
            b07cnext_record (mb_trns^, selr_resf_id,
                  hkey, set_result, selr_tree_pos, result.buf);
        (*ENDIF*) 
        IF  mb_trns^.trRteCommPtr_gg00^.to_cancel
        THEN
            mb_trns^.trError_gg00 := e_cancelled;
        (*ENDIF*) 
        IF  mb_trns^.trError_gg00 = e_key_not_found
        THEN
            mb_trns^.trError_gg00 := e_ok;
        (*ENDIF*) 
        IF  mb_trns^.trError_gg00 = e_ok
        THEN
            BEGIN
            repl_needed := false;
            WHILE ((act - mb_st^[ act ].epos > first) AND
                  (mb_trns^.trError_gg00 = e_ok)) DO
                BEGIN
                act   := act - mb_st^[ act ].epos;
                stpos := k721out_entry (mb_st, act);
                IF  ((mb_st^[ act ].eop_func = op_f_dis_avg)      OR
                    ( mb_st^[ act ].eop_func = op_f_dis_sum)      OR
                    ( mb_st^[ act ].eop_func = op_f_dis_count)    OR
                    ( mb_st^[ act ].eop_func = op_f_dis_stddev)   OR
                    ( mb_st^[ act ].eop_func = op_f_dis_variance) OR
                    ( mb_st^[ act ].eop_func = op_f_stddev)       OR
                    ( mb_st^[ act ].eop_func = op_f_variance)) AND
                    (mb_st^[ act ].etype = st_func)
                THEN
                    IF  disnum < ckb7_maxdistinctfiles
                    THEN
                        disnum := succ(disnum)
                    ELSE
                        mb_trns^.trError_gg00 := e_buffer_limit;
                    (*ENDIF*) 
                (*ENDIF*) 
                IF  (mb_st^[ act ].eop_func in
                    [ op_f_avg   , op_f_dis_avg,
                    op_f_sum     , op_f_dis_sum,
                    op_f_stddev  , op_f_dis_stddev,
                    op_f_variance, op_f_dis_variance ]) AND
                    (mb_st^[ act ].etype = st_func)
                THEN
                    BEGIN
                    no_repl_needed := false;
                    pos := mb_st^[ stpos ].epos;
                    IF  ((result.buf[ pos ] <> csp_undef_byte) AND
                        (result.buf[ pos+1 ] = chr(255)))
                    THEN
                        BEGIN
                        i := pos+2;
                        overfl := true;
                        REPEAT
                            IF  result.buf[ i ] <> chr(153)
                            THEN
                                overfl := false;
                            (*ENDIF*) 
                            i := succ(i)
                        UNTIL
                            ((i = pos+10) OR NOT overfl);
                        (*ENDREPEAT*) 
                        IF  overfl
                        THEN
                            BEGIN
                            result.buf[ pos ] := csp_oflw_byte;
                            repl_needed := true
                            END
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                IF  (mb_st^[ act ].eop_func in
                    [ op_f_avg   , op_f_dis_avg,
                    op_f_stddev  , op_f_dis_stddev,
                    op_f_variance, op_f_dis_variance ]) AND
                    (mb_st^[ act ].etype = st_func)
                THEN
                    WITH mb_st^[ stpos ] DO
                        BEGIN
                        IF  (result.buf[ epos ] <> csp_undef_byte) AND
                            (result.buf[ epos ] <> csp_oflw_byte)
                        THEN
                            BEGIN
                            s51div (result.buf, epos+1, mxgg_number-1,
                                  result, epos+mxgg_number+1, mxsp_resnum-1,
                                  result, epos+1, csp_fixed,
                                  csp_float_frac, length, ret);
                            repl_needed := true;
                            IF  mb_st^[ act ].eop_func in
                                [ op_f_stddev  , op_f_dis_stddev,
                                op_f_variance, op_f_dis_variance ]
                            THEN
                                kb721stddev
                                      (m, selrec, disnum, act, stpos)
                            (*ENDIF*) 
                            END
                        (*ENDIF*) 
                        END
                    (*ENDWITH*) 
                (*ENDIF*) 
                END;
            (*ENDWHILE*) 
            IF  later_output
            THEN
                k721call_later_output (m, result.buf, h_keylen);
            (*ENDIF*) 
            IF  selr_one_result
            THEN
                BEGIN
                no_repl_needed := true;
                g10mv6 ('VKB721',  37,    
                      sizeof(result.buf), sizeof(lbuf), result.buf, 1,
                      lbuf, 1, selr_recl, mb_trns^.trError_gg00);
                END
            ELSE
                BEGIN
                IF  repl_needed AND (mb_trns^.trError_gg00 = e_ok)
                THEN
                    BEGIN
                    cnt_repl := succ(cnt_repl);
                    b07crepl_record (mb_trns^, selr_resf_id, result.buf)
                    END
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            END
        (*ENDIF*) 
    UNTIL
        ((mb_trns^.trError_gg00 <> e_ok) OR no_repl_needed);
    (*ENDREPEAT*) 
    IF  mb_trns^.trError_gg00 = e_no_next_record
    THEN
        mb_trns^.trError_gg00 := e_ok;
    (*ENDIF*) 
    b73cmds_count (iins_sorts_rows_ins, cnt_repl);
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      k721do_rowno (
            VAR m      : tgg_mess_block;
            VAR selrec : tkb7_select_param);
 
VAR
      set_result : tgg_bd_set_result_record;
      last       : integer;
      i          : integer;
      j          : integer;
      pos        : integer;
      hkey       : tgg_lkey;
      ret        : tsp_num_error;
      rowno_pos  : PACKED ARRAY [ 1..MAX_COL_PER_TAB_GG00 ] OF tsp_int2;
 
BEGIN
WITH m, mb_qual^, selrec, selr_selectbuffer DO
    BEGIN
    last := mb_st^[ mqual_pos ].epos + mqual_pos - 1;
    i    := 1;
    j    := 0;
    WHILE (i < last) DO
        BEGIN
        WHILE ((i < last) AND (mb_st^[ i ].etype <> st_rowno)) DO
            i := succ (i);
        (*ENDWHILE*) 
        IF  (i < last)
        THEN
            IF  (mb_st^[ i ].etype = st_rowno)
            THEN
                BEGIN
                i := k721out_entry (mb_st, i);
                IF  (mb_st^[ i ].etype = st_output)
                THEN
                    BEGIN
                    j              := succ (j);
                    rowno_pos[ j ] := mb_st^[ i ].epos;
                    END;
                (*ENDIF*) 
                END;
            (*ENDIF*) 
        (*ENDIF*) 
        END;
    (*ENDWHILE*) 
    WITH set_result DO
        BEGIN
        bd_key_check_len := 0;
        bd_max_rec_cnt   := 1;
        bd_max_fill_len  := mxsp_buf;
        bd_next          := true;
        bd_drop_page     := false;
        END;
    (*ENDWITH*) 
    selr_countresult    := 0;
    hkey.len            := 0;
    selr_tree_pos.tpsPno_gg00 := NIL_PAGE_NO_GG00;
    REPEAT
        b07cnext_record (mb_trns^, selr_resf_id, hkey,
              set_result, selr_tree_pos, result.buf);
        IF  mb_trns^.trRteCommPtr_gg00^.to_cancel
        THEN
            mb_trns^.trError_gg00 := e_cancelled;
        (*ENDIF*) 
        IF  mb_trns^.trError_gg00 = e_key_not_found
        THEN
            mb_trns^.trError_gg00 := e_ok;
        (*ENDIF*) 
        IF  (mb_trns^.trError_gg00 = e_ok)
        THEN
            BEGIN
            selr_countresult := succ (selr_countresult);
            FOR i := 1 TO j DO
                BEGIN
                pos               := rowno_pos[ i ];
                result.buf[ pos ] := csp_defined_byte;
                s41plint (result.buf, pos + 1, csp_resnum_deflen, 0,
                      selr_countresult, ret);
                END;
            (*ENDFOR*) 
            b07crepl_record (mb_trns^, selr_resf_id, result.buf);
            END;
        (*ENDIF*) 
    UNTIL
        (mb_trns^.trError_gg00 <> e_ok);
    (*ENDREPEAT*) 
    IF  (mb_trns^.trError_gg00 = e_no_next_record)
    THEN
        mb_trns^.trError_gg00 := e_ok;
    (*ENDIF*) 
    b73cmds_count (iins_sorts_rows_ins, selr_countresult);
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      k721eval_pagecount (VAR m : tgg_mess_block);
 
VAR
      ret          : tsp_num_error;
      pos          : integer;
      pagecount    : tsp_int4;
      record_cnt   : tsp_int4;
      min_page_cnt : tsp_int4;
      startkey     : tgg_lkey;
      stopkey      : tgg_lkey;
      CountRecords : boolean;
 
BEGIN
WITH m, mb_qual^ DO
    BEGIN
    pos     := 1;
    ret     := num_ok;
    mb_trns^.trError_gg00 := e_ok;
    s40g4int (mb_data^.mbp_4kbuf, pos, pagecount, ret);
    IF  ret = num_overflow
    THEN
        mb_trns^.trError_gg00 := e_num_overflow
    ELSE
        IF  ret = num_invalid
        THEN
            mb_trns^.trError_gg00 := e_num_invalid;
        (*ENDIF*) 
    (*ENDIF*) 
    IF  mb_trns^.trError_gg00 = e_ok
    THEN
        BEGIN
        pos          := pos + mxsp_resnum - 1;
        startkey.len := ord (mb_data^.mbp_buf [ pos ]);
        g10mv13 ('VKB721',  38,    
              mb_data_size, sizeof(startkey.k),
              mb_data^.mbp_buf, pos + 1, startkey.k, 1, startkey.len,
              mb_trns^.trError_gg00);
        pos         := pos + 1 + startkey.len;
        stopkey.len := ord (mb_data^.mbp_buf [ pos ]);
        g10mv13 ('VKB721',  39,    
              mb_data_size, sizeof(stopkey.k),
              mb_data^.mbp_buf, pos + 1, stopkey.k, 1, stopkey.len,
              mb_trns^.trError_gg00);
        IF  mb_trns^.trError_gg00 = e_ok
        THEN
            IF  g04inv_tfn (mtree.fileTfn_gg00)
            THEN
                BEGIN
                CountRecords := (mb_type2 <> mm_table) AND (mb_type2 = mm_key);
                b03calculate_page_count (mb_trns^, mtree, startkey, stopkey,
                      CountRecords, pagecount, min_page_cnt,
                      record_cnt)
                END
            ELSE
                IF  mb_type2 <> mm_table
                THEN
                    b02eval_page_count (mb_trns^, mtree, startkey, stopkey,
                          mb_type2 = mm_key, pagecount, min_page_cnt,
                          record_cnt)
                ELSE
                    b02calculate_page_count (mb_trns^, mtree, startkey,
                          stopkey, pagecount)
                (*ENDIF*) 
            (*ENDIF*) 
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  mb_trns^.trError_gg00 = e_ok
    THEN
        BEGIN
        s41p4int (mb_data^.mbp_4kbuf, 1, pagecount, ret);
        s41p4int (mb_data^.mbp_4kbuf, mxsp_resnum, record_cnt, ret);
        s41p4int (mb_data^.mbp_4kbuf, 2 * mxsp_resnum - 1,
              min_page_cnt, ret);
        mb_qual_len  := mxgg_mb_part1head;
        mb_data_len  := 3 * (mxsp_resnum - 1);
        mb_type := m_return_result;
        END
    ELSE
        BEGIN
        mb_qual_len  := 0;
        mb_data_len  := 0;
        mb_type := m_return_error
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      k721inv_gets (
            VAR m            : tgg_mess_block;
            VAR ftrees       : tgg_two_tree_ids;
            VAR startkeys    : tgg_two_keys;
            VAR stopkeys     : tgg_two_keys;
            VAR act_key      : tgg_lkey;
            istop            : tgg_bd_inv_set;
            mtype            : tgg_message2_type;
            VAR getrec       : tkb7_get_param;
            VAR selrec       : tkb7_select_param;
            VAR selfields    : tgg_select_fields_param;
            VAR oj_info      : tkb7_oj_info_type);
 
VAR
      _sellength    : tsp_int4;
      _htree_id     : tgg00_FileId;
      _granted_lock : tgg00_LockReqMode;
 
BEGIN
_granted_lock := lckFree_egg00;
IF  ( m.mb_type = m_insert_select )
THEN
    BEGIN
    _htree_id := m.mb_qual^.mtree;
    selfields.sfp_result_length := cgg_rec_key_offset;
    IF  ( selrec.selr_is_nokey )
    THEN
        selfields.sfp_result_length :=
              selfields.sfp_result_length + 1 + mxgg_surrogate
    (*ENDIF*) 
    END
ELSE
    selfields.sfp_result_length := 0;
(*ENDIF*) 
_sellength := selfields.sfp_result_length;
IF  ( selrec.selr_use_rowno AND ( selrec.selr_distinct <> no_distinct ))
THEN
    selfields.sfp_act_cntresult := 1
ELSE
    IF  ( NOT selrec.selr_count_all )
    THEN
        selfields.sfp_act_cntresult := selrec.selr_countresult + 1;
    (*ENDIF*) 
(*ENDIF*) 
m.mb_trns^.trError_gg00       := e_ok;
m.mb_qual^.mtree.fileBdUse_gg00 := [  ];
selfields.sfp_bd_mess2_type := mtype;
IF  ( m.mb_type = m_update )
THEN
    BEGIN
    selfields.sfp_m_result_addr := @selrec.selr_selectbuffer.longresult;
    selfields.sfp_m_result_size := sizeof( selrec.selr_selectbuffer.longresult );
    END
ELSE
    BEGIN
    selfields.sfp_m_result_addr := @selrec.selr_selectbuffer.result;
    selfields.sfp_m_result_size := sizeof( selrec.selr_selectbuffer.result );
    END;
(*ENDIF*) 
selfields.sfp_m_result_len  := 0;
(* h.b. PTS 1104210 *)
b03select_invrec( m.mb_trns^, ftrees, startkeys, stopkeys, act_key,
      istop, sizeof( selrec.selr_selectbuffer.buf_rec ),
      @selrec.selr_selectbuffer.buf_rec, selfields,
      m.mb_qual^.mstack_desc, _granted_lock, c_usage_count );
kb721result_handle( m, selrec, getrec, selfields, startkeys.listkey,
      startkeys.reckey, _htree_id, oj_info, _granted_lock );
END;
 
(*------------------------------*) 
 
PROCEDURE
      k721null_result (
            VAR m         : tgg_mess_block;
            VAR selrec    : tkb7_select_param;
            VAR sel       : tgg_select_fields_param;
            act_cntresult : tsp_int4;
            later_output  : boolean;
            h_keylen      : integer);
 
VAR
      act      : integer;
      first    : integer;
      pos      : integer;
      stpos    : integer;
      st_begin : integer;
      m_pos    : integer;
      m_cnt    : integer;
      res      : tsp_num_error;
 
BEGIN
WITH m, mb_qual^, selrec, selr_selectbuffer DO
    BEGIN
    result.len                  := selr_recl;
    result.keylen               := selr_keyl;
    result.recVarcolOffset_gg00 := 0;
    result.recVarcolCnt_gg00    := 0;
    first := mqual_pos;
    act := first - 2 + mb_st^[ first ].epos;
    pos := first + 1;
    WHILE pos < act DO
        BEGIN
        st_begin := pos;
        WHILE (pos < act) AND (mb_st^[ pos ].etype <> st_output) DO
            BEGIN
            IF  mb_st^[ pos ].etype = st_func
            THEN
                st_begin := 0;
            (*ENDIF*) 
            pos := succ(pos)
            END;
        (*ENDWHILE*) 
        IF  pos < act
        THEN
            IF  mb_st^[ pos + 1 ].etype = st_output
            THEN
                pos := succ(pos);
            (*ENDIF*) 
        (*ENDIF*) 
        IF  st_begin > 0
        THEN
            BEGIN
            m_pos  := mqual_pos;
            m_cnt  := mqual_cnt;
            mqual_pos := st_begin;
            mqual_cnt := pos - st_begin + 1;
            sel.sfp_m_result_addr := @result;
            sel.sfp_m_result_size := sizeof (result);
            sel.sfp_m_result_len  := 0;
            k71sel_qualification_test (m, sel, c_check_new_rec,
                  mb_data^.mbp_rec);
            mqual_pos := m_pos;
            mqual_cnt := m_cnt;
            END;
        (*ENDIF*) 
        pos := succ(pos)
        END;
    (*ENDWHILE*) 
    WHILE ((act - mb_st^[ act ].epos > first) AND
          (mb_trns^.trError_gg00 = e_ok)) DO
        BEGIN
&       ifdef TRACE
        t01int4 (kb_qual, 'act         ', act);
&       endif
        act   := act - mb_st^[ act ].epos;
        stpos := k721out_entry (mb_st, act);
        IF  ((mb_st^[ act ].eop_func = op_f_count) OR
            (mb_st^[ act ].eop_func = op_f_dis_count) OR
            (mb_st^[ act ].eop_func = op_f_all_count)) AND
            (mb_st^[ act ].etype = st_func)
        THEN
            BEGIN
            pos := mb_st^[ stpos ].epos;
            result.buf[ pos ] := csp_defined_byte;
            g10mv2 ('VKB721',  40,    
                  sizeof(g01glob.rescnt_0), sizeof(result.buf),
                  g01glob.rescnt_0, 2,
                  result.buf, pos+1, sizeof(tsp_resnum)-1,
                  mb_trns^.trError_gg00);
            END
        ELSE
            IF  (mb_st^[ act ].eop_func = op_f_count_kb) AND
                (mb_st^[ act ].etype = st_func)
            THEN
                BEGIN
                result.buf[ mb_st^[ stpos ].epos ] := csp_defined_byte;
                s41p4int (result.buf, mb_st^[ stpos ].epos+1,
                      act_cntresult, res)
                END
            ELSE
                IF  (mb_st^[ act ].eop_func = op_f_check_null) AND
                    (mb_st^[ act ].etype = st_func)
                THEN
                    result.buf[ mb_st^[ stpos ].epos ] := csp_defined_byte
                ELSE
                    IF  mb_st^[ act ].etype = st_func
                    THEN
                        BEGIN
                        result.buf[ mb_st^[ stpos ].epos ] := csp_undef_byte;
                        g10fil1 ('VKB721',  41,    
                              sizeof(result.buf), result.buf,
                              mb_st^[ stpos ].epos+1,
                              mb_st^[ stpos ].elen_var - 1, csp_defined_byte,
                              mb_trns^.trError_gg00);
                        END
                    (*ENDIF*) 
                (*ENDIF*) 
            (*ENDIF*) 
        (*ENDIF*) 
        END;
    (*ENDWHILE*) 
    IF  mb_trns^.trError_gg00 = e_ok
    THEN
        BEGIN
        IF  later_output
        THEN
            k721call_later_output (m, result.buf, h_keylen);
        (*ENDIF*) 
        k721add_into_result (mb_trns^, selrec, m.mb_next_mblock)
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb721search_through_one_invlist (
            VAR m         : tgg_mess_block;
            VAR getrec    : tkb7_get_param;
            VAR selrec    : tkb7_select_param;
            VAR selfields : tgg_select_fields_param);
 
VAR
      _unqualified     : boolean;
      _aux_error       : tgg_basis_error;
      _binvset         : tgg_bd_inv_set;
      _keyLen          : tsp00_IntMapC2;
      _keypos          : integer;
      _primkeycnt      : tsp_int4;
      _listlen         : tsp_int4;
      _inv_tree_pos    : tgg00_FilePos;
      _set_result      : tgg_bd_set_result_record;
      _act_key         : tgg_lkey;
      _inv_primkey     : tgg_lkey;
      _oj_info         : tkb7_oj_info_type;
      _qual_buf        : tsp_buf;
      _aux_qual_kind   : tgg_qual_kind;
 
BEGIN
WITH m, selrec DO
    BEGIN
    IF  (selr_startkey.len > 0)
    THEN
        BEGIN
        g10mv7 ('VKB721',  42,    
              sizeof(selr_startkey.k), sizeof(_act_key.k),
              selr_startkey.k, 1, _act_key.k, 1, selr_startkey.len,
              mb_trns^.trError_gg00);
        _act_key.len := selr_startkey.len;
        END
    ELSE
        _act_key.len := 0;
    (*ENDIF*) 
    _oj_info.is_outer_join := false;
    _aux_error             := e_buffer_limit;
    IF  ftsTemp_egg00 in selr_inv_id.fileType_gg00
    THEN
        BEGIN
        WITH _set_result DO
            BEGIN
            bd_key_check_len := 0;
            bd_max_rec_cnt   := csp_maxint2;
            bd_max_fill_len  := mxsp_buf;
            bd_next          := false;
            bd_drop_page     := true;
            END;
        (*ENDWITH*) 
        WITH _inv_tree_pos DO
            BEGIN
            tpsPno_gg00   := NIL_PAGE_NO_GG00;
            tpsIndex_gg00 := csp_maxint2
            END;
        (*ENDWITH*) 
        _aux_qual_kind         := selfields.sfp_bd_inv_only;
        selfields.sfp_bd_inv_only   := primary_only;
        WHILE (_aux_error = e_buffer_limit) AND
              (mb_trns^.trError_gg00 = e_ok) DO
            BEGIN
            b07cnext_record (mb_trns^, selr_inv_id, _act_key,
                  _set_result, _inv_tree_pos, _qual_buf);
            IF  mb_trns^.trError_gg00 = e_key_not_found
            THEN
                mb_trns^.trError_gg00 := e_ok;
            (*ENDIF*) 
            IF  (mb_trns^.trError_gg00 = e_ok) OR
                (mb_trns^.trError_gg00 = e_buffer_limit)
            THEN
                _listlen := _set_result.bd_fill_len;
            (*ENDIF*) 
            _aux_error       := mb_trns^.trError_gg00;
            mb_trns^.trError_gg00 := e_ok;
            IF  (_aux_error = e_ok) OR (_aux_error = e_buffer_limit)
            THEN
                BEGIN
                _keypos := 1;
&               ifdef TRACE
                t01buf (ak_strat, _qual_buf, 1, _listlen);
&               endif
                WHILE (_keypos <= _listlen) AND
                      (mb_trns^.trError_gg00 = e_ok) DO
                    BEGIN
                    _keyLen.mapC2_sp00 [1] := _qual_buf[ _keypos + 2 ];
                    _keyLen.mapC2_sp00 [2] := _qual_buf[ _keypos + 3 ];
                    _act_key.keyLen_gg00   := _keyLen.mapInt_sp00;
                    g10mv1 ('VKB721',  43,    
                          sizeof(_qual_buf), sizeof(_act_key.k),
                          _qual_buf, _keypos + cgg_rec_key_offset,
                          _act_key.k, 1,_act_key.len,
                          mb_trns^.trError_gg00);
                    selfields.sfp_bd_mess2_type := mm_direct;
                    IF  ( mb_trns^.trError_gg00 = e_ok )
                    THEN
                        kb721select_gets( m, _act_key, getrec,
                              selrec, selfields, _oj_info );
                    (*ENDIF*) 
                    _keypos := _keypos + _act_key.len + cgg_rec_key_offset;
                    END
                (*ENDWHILE*) 
                END
            ELSE
                IF  ( _aux_error <> e_inv_list_not_found )
                THEN
                    mb_trns^.trError_gg00 := _aux_error;
                (*ENDIF*) 
            (*ENDIF*) 
            END;
        (*ENDWHILE*) 
        selfields.sfp_bd_inv_only := _aux_qual_kind;
        END
    ELSE
        BEGIN
        IF  ( selfields.sfp_bd_use_stopkey )
        THEN
            _binvset := [ incl_first, primary_stop ]
        ELSE
            _binvset := [ incl_first ];
        (*ENDIF*) 
        IF  ( _act_key.len > 0 )
        THEN
            BEGIN
            g10mv7 ('VKB721',  44,    
                  sizeof(_act_key.k), sizeof(_inv_primkey.k),
                  _act_key.k, 1, _inv_primkey.k, 1, _act_key.len,
                  mb_trns^.trError_gg00);
            _inv_primkey.len := _act_key.len;
            END
        ELSE
            _inv_primkey.len := 0;
        (*ENDIF*) 
        WHILE (_aux_error = e_buffer_limit) AND
              (mb_trns^.trError_gg00 = e_ok) DO
            BEGIN
            b03get_inv (mb_trns^, selr_inv_id, selr_invkey,
                  _inv_primkey, selr_stopkey, _inv_primkey, _binvset, selr_count_bd,
                  lckFree_egg00, _qual_buf, _primkeycnt, _listlen);
            _aux_error       := mb_trns^.trError_gg00;
            mb_trns^.trError_gg00 := e_ok;
            (*  _binvset         := _binvset - [ incl_first ]; *)
            IF  (_aux_error = e_ok) OR (_aux_error = e_buffer_limit)
            THEN
                IF  selr_count_bd
                THEN
                    selfields.sfp_act_cntresult := selfields.sfp_act_cntresult +
                          _primkeycnt
                ELSE
                    BEGIN
                    _keypos := 1;
&                   ifdef TRACE
                    t01buf (ak_strat, _qual_buf, 1, _listlen);
&                   endif
                    WHILE (_keypos <= _listlen) AND
                          (mb_trns^.trError_gg00 = e_ok) DO
                        BEGIN
                        _unqualified := false;
                        _keyLen.mapC2_sp00 [1] :=  _qual_buf[ _keypos     ];
                        _keyLen.mapC2_sp00 [2] :=  _qual_buf[ _keypos + 1 ];
                        _act_key.keyLen_gg00   := _keyLen.mapInt_sp00;
                        IF  (selfields.sfp_bd_inv_only = inv_and_primary)
                        THEN
                            BEGIN
                            IF  mb_type = m_update
                            THEN
                                BEGIN
                                selfields.sfp_m_result_addr := @selrec.selr_selectbuffer.longresult;
                                selfields.sfp_m_result_size := sizeof (selrec.selr_selectbuffer.longresult);
                                END
                            ELSE
                                BEGIN
                                selfields.sfp_m_result_addr :=
                                      @selrec.selr_selectbuffer.result;
                                selfields.sfp_m_result_size :=
                                      sizeof (selrec.selr_selectbuffer.result);
                                END;
                            (*ENDIF*) 
                            selfields.sfp_m_result_len  := 0;
                            k71inv_col_select (mb_trns^, selfields,
                                  mb_qual^.mstack_desc, @selr_invkey.k,
                                  selr_invkey.len, @_qual_buf[ _keypos+2 ],
                                  _act_key.keyLen_gg00, _unqualified);
                            IF  (mb_trns^.trError_gg00 = e_qual_violation)
                            THEN
                                mb_trns^.trError_gg00 := e_ok;
                            (*ENDIF*) 
                            END;
                        (*ENDIF*) 
                        IF  (mb_trns^.trError_gg00 = e_ok) AND
                            (NOT _unqualified)        AND
                            ((selfields.sfp_bd_inv_only = primary_only) OR
                            (selfields.sfp_bd_inv_only = inv_and_primary))
                        THEN
                            BEGIN
                            g10mv1 ('VKB721',  45,    
                                  sizeof(_qual_buf), sizeof(_act_key.k),
                                  _qual_buf, _keypos+2, _act_key.k, 1,
                                  _act_key.len, mb_trns^.trError_gg00);
                            _aux_qual_kind        := selfields.sfp_bd_inv_only;
                            selfields.sfp_bd_inv_only  := primary_only;
                            selfields.sfp_bd_mess2_type := mm_direct;
                            IF  ( mb_trns^.trError_gg00 = e_ok )
                            THEN
                                kb721select_gets (m, _act_key, getrec,
                                      selrec, selfields, _oj_info);
                            (*ENDIF*) 
                            selfields.sfp_bd_inv_only := _aux_qual_kind;
                            END;
                        (*ENDIF*) 
                        _keypos := _keypos + _act_key.len + 2;
                        END
                    (*ENDWHILE*) 
                    END
                (*ENDIF*) 
            ELSE
                IF  (_aux_error <> e_inv_list_not_found)
                THEN
                    mb_trns^.trError_gg00 := _aux_error;
                (*ENDIF*) 
            (*ENDIF*) 
            END;
        (*ENDWHILE*) 
        END;
    (*ENDIF*) 
    IF  (mb_trns^.trError_gg00 = e_no_next_invkey) OR
        (mb_trns^.trError_gg00 = e_no_next_record)
    THEN
        mb_trns^.trError_gg00 := e_ok;
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      k721catalog_add_into_result (
            VAR m           : tgg_mess_block;
            VAR sel         : tgg_select_fields_param;
            VAR selrec_ctxt : tsp_buf;
            VAR getrec      : tkb7_get_param;
            VAR result_rec  : tgg_rec_buf;
            VAR one_res_rec : tgg_rec_buf;
            VAR res_cnt     : tsp_int4);
 
VAR
      _selrec      : tkb7_select_param;
      _dummy_lkey  : tgg_lkey;
      _recptr      : tgg00_RecPtr;
 
BEGIN
m.mb_trns^.trError_gg00 := e_ok;
WITH _selrec DO
    BEGIN
    g10mv3 ('VKB721',  46,    
          sizeof (selrec_ctxt), sizeof (_selrec),
          selrec_ctxt, 1, _selrec, sizeof (selr_selectbuffer) + 1,
          sizeof (_selrec) - sizeof (selr_selectbuffer),
          m.mb_trns^.trError_gg00);
    IF  (selr_use_rowno AND (selr_distinct <> no_distinct))
    THEN
        sel.sfp_act_cntresult := 1
    ELSE
        IF  NOT selr_count_all
        THEN
            sel.sfp_act_cntresult := selr_countresult+1;
        (*ENDIF*) 
    (*ENDIF*) 
    sel.sfp_m_result_addr := @_selrec.selr_selectbuffer.result;
    sel.sfp_m_result_size := sizeof (_selrec.selr_selectbuffer.result);
    sel.sfp_m_result_len  := 0;
    END;
(*ENDWITH*) 
g10fil1 ('VKB721',  47,    
      sizeof(_selrec.selr_selectbuffer.result.buf),
      _selrec.selr_selectbuffer.result.buf,
      1, _selrec.selr_recl, csp_defined_byte,
      m.mb_trns^.trError_gg00);
IF  m.mb_trns^.trError_gg00 = e_ok
THEN
    k71sel_qualification_test (m, sel, NOT c_check_new_rec, result_rec);
(*ENDIF*) 
IF  m.mb_trns^.trError_gg00 = e_ok
THEN
    BEGIN
    WITH _selrec DO
        BEGIN
        selr_selectbuffer.result.len    := selr_recl;
        selr_selectbuffer.result.keylen := selr_keyl;
        IF  one_res_rec.len > 0
        THEN
            g10mv6 ('VKB721',  48,    
                  sizeof(one_res_rec.buf),
                  sizeof(selr_selectbuffer.lbuf),
                  one_res_rec.buf, 1,
                  selr_selectbuffer.lbuf, 1, one_res_rec.len,
                  m.mb_trns^.trError_gg00);
        (*ENDIF*) 
        IF  m.mb_trns^.trError_gg00 = e_ok
        THEN
            IF  m.mb_type2 = mm_with_functions
            THEN
                k721function_add (m, _selrec, NOT c_aggr)
            ELSE
                IF  m.mb_type2 = mm_with_join
                THEN
                    k74join_with_left_result (m, getrec, sel,
                          _selrec, _dummy_lkey, NOT c_return_next_key)
                ELSE
                    k721add_into_result (m.mb_trns^, _selrec, m.mb_next_mblock);
                (*ENDIF*) 
            (*ENDIF*) 
        (*ENDIF*) 
        g10mv8 ('VKB721',  49,    
              sizeof (_selrec), sizeof (selrec_ctxt),
              _selrec, sizeof (selr_selectbuffer) + 1, selrec_ctxt, 1,
              sizeof (_selrec) - sizeof (selr_selectbuffer),
              m.mb_trns^.trError_gg00);
        res_cnt := selr_countresult;
        IF  selr_one_result
        THEN
            BEGIN
            _recptr := @selr_selectbuffer.lbuf;
            g10mv6 ('VKB721',  50,    
                  sizeof(selr_selectbuffer.lbuf),
                  sizeof(one_res_rec.buf), selr_selectbuffer.lbuf, 1,
                  one_res_rec.buf, 1, _recptr^.len,
                  m.mb_trns^.trError_gg00);
            END;
        (*ENDIF*) 
        END;
    (*ENDWITH*) 
    END
ELSE
    IF  (m.mb_trns^.trError_gg00 = e_qual_violation) OR
        (m.mb_trns^.trError_gg00 = e_view_violation)
    THEN
        m.mb_trns^.trError_gg00 := e_ok
    (*ENDIF*) 
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      k721read_subquery (VAR m : tgg_mess_block);
 
CONST
      c_inclusive = true;
 
VAR
      max_keys : integer;
      ok_e     : tgg_basis_error;
      key      : tgg_lkey;
      rec      : tgg_rec_buf;
 
BEGIN
max_keys := m.mb_data^.mbp_rec.len;
key.len  := m.mb_data^.mbp_rec.keylen;
m.mb_trns^.trError_gg00 := e_ok;
g10mv1 ('VKB721',  51,    
      m.mb_data_size, sizeof (key.k),
      m.mb_data^.mbp_4kbuf, cgg_rec_key_offset + 1, key.k, 1, key.len,
      m.mb_trns^.trError_gg00);
m.mb_data_len     := 0;
s10fil2 (m.mb_data_size,
      m.mb_data^.mbp_buf, 1, m.mb_data_size, chr(255));
ok_e := e_key_not_found;
IF  m.mb_trns^.trError_gg00 = e_ok
THEN
    REPEAT
        b02next_record (m.mb_trns^,
              m.mb_qual^.mtree, key, NOT c_inclusive, rec);
        IF  m.mb_trns^.trError_gg00 = ok_e
        THEN
            BEGIN
            max_keys := max_keys - 1;
            ok_e     := e_ok;
            IF  m.mb_data_len + cgg_rec_key_offset + rec.keylen <=
                sizeof (tsp_buf)
            THEN
                BEGIN
                m.mb_trns^.trError_gg00 := e_ok;
                key.len           := rec.keylen;
                g10mv1 ('VKB721',  52,    
                      sizeof (rec.buf), sizeof (key.k),
                      rec.buf, cgg_rec_key_offset + 1, key.k, 1, key.len,
                      m.mb_trns^.trError_gg00);
                g10mv15 ('VKB721',  53,    
                      sizeof (rec.buf), m.mb_data_size,
                      rec.buf, 1, m.mb_data^.mbp_buf, m.mb_data_len + 1,
                      cgg_rec_key_offset + key.len - 8,
                      m.mb_trns^.trError_gg00);
                m.mb_data_len :=
                      m.mb_data_len + cgg_rec_key_offset + key.len
                END
            ELSE
                m.mb_trns^.trError_gg00 := e_buffer_limit;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
    UNTIL
        (m.mb_trns^.trError_gg00 <> e_ok) OR (max_keys = 0);
    (*ENDREPEAT*) 
(*ENDIF*) 
m.mb_qual_len  := 0;
IF  (m.mb_trns^.trError_gg00 = e_ok            ) OR
    (m.mb_trns^.trError_gg00 = e_no_next_record) OR
    (m.mb_trns^.trError_gg00 = e_buffer_limit  )
THEN
    BEGIN
    m.mb_type := m_return_result;
    IF  m.mb_trns^.trError_gg00 = e_no_next_record
    THEN
        m.mb_type2 := mm_last
    ELSE
        m.mb_type2 := mm_nil;
    (*ENDIF*) 
    m.mb_trns^.trError_gg00 := e_ok;
    END
ELSE
    BEGIN
    m.mb_data_len  := 0;
    m.mb_type      := m_return_error
    END
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      k721strat_distribution (
            VAR m                : tgg_mess_block;
            VAR getrec           : tkb7_get_param;
            VAR selrec           : tkb7_select_param;
            VAR selfields        : tgg_select_fields_param;
            VAR gg_strategy      : tgg07_StrategyInfo;
            VAR finding_possible : boolean);
 
BEGIN
CASE gg_strategy.str_strategy OF
    strat_key_equal,
    strat_key_equal_sub :
        kb721eq_keyrecord( m, getrec, selrec, selfields, gg_strategy );
    strat_key_in :
        kb721in_keyrecord( m, getrec, selrec, selfields, gg_strategy );
    strat_key_range,
    strat_key_range_sub :
        kb721seq_search( m, getrec, selrec, selfields, gg_strategy );
    (*strat_inv_ordered,*)
    strat_inv_range :
        k73_index_range( m, getrec, selrec, selfields, gg_strategy,
              finding_possible );
    strat_inv_in :
        k73in_multindex( m, getrec, selrec, selfields, gg_strategy );
    strat_inv_range_sub :
        k73sub_multindex( m, getrec, selrec, selfields, gg_strategy );
    strat_join_viewkey :
        kb721viewkey_search( m, getrec, selrec, selfields );
    OTHERWISE
        m.mb_trns^.trError_gg00 := e_unknown_strategy
    END;
(*ENDCASE*) 
IF  ( m.mb_trns^.trError_gg00 = e_ok ) AND ( m.mb_type = m_update )
THEN
    k62late_unique_check( m );
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      k721out_entry (
            st_addr     : tgg_stack_list_ptr;
            start_entry : integer) : integer;
 
VAR
      curr : integer;
 
BEGIN
curr := succ (start_entry);
WHILE (st_addr^[ curr ].etype = st_result)
      OR
      (
      (st_addr^[ curr ].etype = st_op)         AND
      ((st_addr^[ curr ].eop  = op_fixed)  OR
      ( st_addr^[ curr ].eop  = op_ebcdic) OR
      ( st_addr^[ curr ].eop  = op_ascii))
      )
      OR
      (
      (st_addr^[ curr ].etype = st_build_in_func)              AND
      ((st_addr^[ curr ].eop_build_in = op_b_format_change) OR
      ( st_addr^[ curr ].eop_build_in = op_b_expand)        OR
      ( st_addr^[ curr ].eop_build_in = op_b_uni_trans))
      )
      DO
    curr := succ (curr);
(*ENDWHILE*) 
k721out_entry := curr
END;
 
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
.PA 
