.ad 8
.bm 8
.fm 4
.bt $Copyright (c) 2000-2005 SAP AG$$Page %$
.tm 12
.hm 6
.hs 3
.TT 1 $SQL$Project Distributed Database System$VKB722$
.tt 2 $$$
.TT 3 $$Unionhandling$1999-08-13$
***********************************************************
.nf
 
 .nf

    ========== licence begin  GPL
    Copyright (c) 2000-2005 SAP AG

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end
.fo

 
.fo
.nf
.sp
MODULE  : Unionhandling
=========
.sp
Purpose : Two temporary resulttables are unioned
.CM *-END-* purpose -------------------------------------
.sp
.cp 3
Define  :
 
        PROCEDURE
              k722_union_select (VAR m : tgg00_MessBlock);
 
        PROCEDURE
              k722_add_union_record (
                    VAR t        : tgg00_TransContext;
                    VAR selrec   : tgg07_select_param);
 
.CM *-END-* define --------------------------------------
.sp;.cp 3
Use     :
 
        FROM
              filesysteminterface_1 : VBD01;
 
        PROCEDURE
              b01move_filecontent (
                    VAR t         : tgg00_TransContext;
                    VAR source_id : tgg00_FileId;
                    VAR target_id : tgg00_FileId);
 
        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);
 
      ------------------------------ 
 
        FROM
              filesysteminterface_7 : VBD07;
 
        PROCEDURE
              b07cadd_record (
                    VAR t           : tgg00_TransContext;
                    VAR act_tree_id : tgg00_FileId;
                    VAR b           : tgg00_Rec);
 
        PROCEDURE
              b07cappend_record (
                    VAR t        : tgg00_TransContext;
                    VAR file_id  : tgg00_FileId;
                    VAR tree_pos : tgg00_FilePos;
                    VAR b        : tgg00_Rec);
 
        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           : tsp00_Buf);
 
        PROCEDURE
              b07cdel_record (
                    VAR t           : tgg00_TransContext;
                    VAR act_tree_id : tgg00_FileId;
                    VAR rk          : tgg00_Lkey);
 
      ------------------------------ 
 
        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      : tgg04_CodeGlobals;
 
      ------------------------------ 
 
        FROM
              Kernel_move_and_fill : VGG101;
 
        PROCEDURE
              SAPDB_PascalFill (
                    mod_id   : tsp00_C6;
                    mod_num  : tsp00_Int4;
                    obj_upb  : tsp00_Int4;
                    obj      : tsp00_MoveObjPtr;
                    obj_pos  : tsp00_Int4;
                    length   : tsp00_Int4;
                    fillchar : char;
                    VAR e    : tgg00_BasisError);
 
        PROCEDURE
              SAPDB_PascalMove (
                    mod_id      : tsp00_C6;
                    mod_num     : tsp00_Int4;
                    source_upb  : tsp00_Int4;
                    dest_upb    : tsp00_Int4;
                    source      : tsp00_MoveObjPtr;
                    src_pos     : tsp00_Int4;
                    destin      : tsp00_MoveObjPtr;
                    dest_pos    : tsp00_Int4;
                    length      : tsp00_Int4;
                    VAR e       : tgg00_BasisError);
 
        PROCEDURE
              g10mv (
                    mod_id      : tsp00_C6;            
                    mod_num     : tsp00_Int4;
                    source_upb  : tsp00_Int4;          
                    dest_upb    : tsp00_Int4;
                    source      : tsp00_MoveObjPtr;       
                    src_pos     : tsp00_Int4;
                    destin      : tsp00_MoveObjPtr;       
                    dest_pos    : tsp00_Int4;
                    length      : tsp00_Int4;
                    VAR e       : tgg00_BasisError);
 
      ------------------------------ 
 
        FROM
              RTE-Extension-20 : VSP20;
 
        PROCEDURE
              s20ch4sw (
                    val        : tsp00_Int4;
                    sourceswap : tsp00_SwapKind;
                    VAR dest   : tgg00_RecBody;
                    di         : tsp00_Int4;
                    destswap   : tsp00_SwapKind);
 
        FUNCTION
              s20or4a (
                    VAR str : tsp00_Buf;
                    si : tsp00_Int4) : tsp00_Int4;
 
      ------------------------------ 
 
        FROM
              RTE-Extension-30 : VSP30;
 
        PROCEDURE
              s30lcm (
                    VAR buf1     : tsp00_Buf;
                    fieldpos1    : tsp00_Int4;
                    fieldlength1 : tsp00_Int4;
                    VAR buf2     : tsp00_Buf;
                    fieldpos2    : tsp00_Int4;
                    fieldlength2 : tsp00_Int4;
                    VAR l_result : tsp00_LcompResult);
 
      ------------------------------ 
 
        FROM
              KB_trans_state: VKB50;
 
        PROCEDURE
              k50hash (
                    VAR buf    : tsp00_Buf;
                    pos        : tsp00_Int4;
                    len        : tsp00_Int4;
                    VAR resbuf : tsp00_Buf;
                    respos     : integer);
 
      ------------------------------ 
 
        FROM
              PUT-Conversions : VSP41;
 
        PROCEDURE
              s41p4int (
                    VAR buf : tsp00_ResNum;
                    pos     : tsp00_Int4;
                    source  : tsp00_Int4;
                    VAR res : tsp00_NumError);
&       ifdef TRACE
 
      ------------------------------ 
 
        FROM
              Test_Procedures : VTA01;
 
        PROCEDURE
              t01sname (
                    debug : tgg00_Debug;
                    nam   : tsp00_Sname);
 
        PROCEDURE
              t01lkey (
                    level : tgg00_Debug;
                    VAR k : tgg00_Lkey);
 
        PROCEDURE
              t01int4 (
                    debug    : tgg00_Debug;
                    nam      : tsp00_Sname;
                    int      : tsp00_Int4);
 
        PROCEDURE
              t01site (
                    debug    : tgg00_Debug;
                    nam      : tsp00_Sname;
                    site     : tgg00_ServerdbNo);
 
        PROCEDURE
              t01treeid  (
                    level    : tgg00_Debug;
                    nam      : tsp00_Sname;
                    VAR tree : tgg00_FileId);
&       endif
 
.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :
 
        PROCEDURE
              b07cnext_record;
 
              tsp00_MoveObj tsp00_Buf
 
        PROCEDURE
              s20ch4sw;
 
              tsp00_MoveObj tgg00_RecBody
 
        FUNCTION
              s20or4a;
 
              tsp00_MoveObj tsp00_Buf
 
        PROCEDURE
              s30lcm;
 
              tsp00_MoveObj tsp00_Buf
 
        PROCEDURE
              s41p4int;
 
              tsp00_MoveObj tsp00_ResNum
 
.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  :
.sp
.cp 3
Created : 1991-04-26
.sp
.cp 3
.sp
.cp 3
Release :      Date : 1999-08-13
.sp
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Specification:
.sp 2
This module puts the results of two selects together. The results of
the first select are stored in the file with treeid resf_id and of
the second select in the file with treeid source_id. The unionresult
is put into resf_id-file.
.CM *-END-* specification -------------------------------
.sp 2
***********************************************************
.sp
.cp 102
.fo
.oc _/1
Description:
.sp 2
PROCEDURE K722_UNION_SELECT
.sp 2
This is the kb-mainprocedure to put two select results together.
First the parameters given in messagebuffer part1 are used to
initialize the variables. In case of the union_kind some special
initializations are made. To process the union the procedure
kb722_process_union is called.
.br;In case of intersection all results, which are in both select
results were put into an auxiliaryfile. At last the auxiliaryfile
is moved to the resultfile.
.br;In case of union the results, of 2.nd select
results were added into the resultfile.
.br;In case of except the results, of 2.nd select
results were deleted from the resultfile.
.br;The resultfile of the 2.nd select is destroyed and if
no error is detected then the countresult, selr_key_cnt_offs and the
resulttreeid are moved into part1 of the returning messagebuffer.
.sp
PROCEDURE KB722_PROCESS_UNION
.sp 2
In a loop all resultrecords of the second select are read. For each
record k722_add_union_record is called.
.sp 2
PROCEDURE k722_add_union_record
.sp 2
First the unionkey is build by calling kb722_build_union_invkey.
Then a search for the unionkey in the resultfile is made. In case
of the union_kind union the record will be inserted into the resultfile
if no same record was found or if unionall is specified.
.br;In case of union_kind except and record was found into resultfile
it will be deleted there.
.br;If intersect is specified and the record was found into resultfile
then the record is inserted into an auxiliaryfile.
.sp 2
PROCEDURE KB722_BUILD_UNION_INVKEY
.sp 2
This procedure valuate a hash-value in case of the resultrecord and
puts it into the inv_key for returning.
.sp
.CM *-END-* description ---------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.nf
.oc _/1
Structure:
 
.CM *-END-* structure -----------------------------------
.sp 2
**********************************************************
.sp
.cp 10
.nf
.oc _/1
.CM -lll-
Code    :
 
 
(*------------------------------*) 
 
PROCEDURE
      kb722_build_union_invkey (
            VAR result  : tgg00_Rec;
            VAR inv_key : tgg00_Lkey;
            VAR b_err   : tgg00_BasisError);
 
VAR
      i      : integer;
      recpos : integer;
 
BEGIN
WITH result DO
    BEGIN
    recpos      := cgg_rec_key_offset + keylen + 2;
    inv_key.len := keylen;
    i           := len - keylen - cgg_rec_key_offset - 1;
    k50hash (buf, recpos, i, buf,
          cgg_rec_key_offset + keylen - RESCNT_MXGG04 -
          cgg04_cdistinct_bytes + 1);
    g10mv ('VKB722',   1,
          sizeof(buf), sizeof(inv_key.k), @buf, cgg_rec_key_offset+1,
          @inv_key.k, 1, inv_key.len, b_err);
    SAPDB_PascalFill ('VKB722',   2,
          sizeof(inv_key.k), @inv_key.k,
          inv_key.len - RESCNT_MXGG04 + 1, RESCNT_MXGG04,
          chr (0), b_err);
&   ifdef trace
    t01int4  (kb, 'inv_key.len ', inv_key.len);
    t01lkey (kb, inv_key);
&   endif
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb722_process_union  (
            VAR m         : tgg00_MessBlock;
            VAR selrec    : tgg07_select_param;
            VAR infile_id : tgg00_FileId);
 
VAR
      _set_result : tgg00_BdSetResultRecord;
      _next_error : tgg00_BasisError;
      _search_key : tgg00_Lkey;
      _recpos     : integer;
      _buflen     : integer;
      _tree1_pos  : tgg00_FilePos;
 
BEGIN
_set_result.bd_key_check_len := 0;
_set_result.bd_max_rec_cnt   := csp_maxint2;
_set_result.bd_max_fill_len  := mxsp_buf;
_set_result.bd_next          := false;
_set_result.bd_drop_page     := false;
_search_key.len  := 0;
_tree1_pos.tpsPno_gg00 := NIL_PAGE_NO_GG00;
m.mb_trns^.trError_gg00 := e_buffer_limit;
WHILE m.mb_trns^.trError_gg00 = e_buffer_limit DO
    BEGIN
    b07cnext_record (m.mb_trns^, infile_id, _search_key,
          _set_result, _tree1_pos, m.mb_data^.mbp_4kbuf);
    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
    THEN
        BEGIN
        _next_error      := e_ok;
        m.mb_trns^.trError_gg00 := e_ok
        END
    ELSE
        IF  m.mb_trns^.trError_gg00 = e_buffer_limit
        THEN
            BEGIN
            _next_error        := e_buffer_limit;
            m.mb_trns^.trError_gg00 := e_ok
            END
        ELSE
            _next_error := m.mb_trns^.trError_gg00;
        (*ENDIF*) 
    (*ENDIF*) 
    IF  m.mb_trns^.trError_gg00 = e_ok
    THEN
        BEGIN
        _recpos            := 0;
        _buflen            := _set_result.bd_fill_len;
&       ifdef trace
        t01int4 (kb, 'keylen      ', m.mb_data^.mbp_keylen);
        t01int4 (kb, 'reclen      ', m.mb_data^.mbp_reclen);
        t01int4 (kb, 'buflen      ', _buflen);
&       endif
        WHILE (_recpos          < _buflen) AND
              (m.mb_trns^.trError_gg00 = e_ok)       DO
            BEGIN
&           ifdef trace
            t01int4 (kb, 'recpos      ', _recpos);
&           endif
            g10mv ('VKB722',   3,
                  m.mb_data_size, sizeof(selrec.selr_selectbuffer.result.buf),
                  @m.mb_data^.mbp_4kbuf, _recpos + 1,
                  @selrec.selr_selectbuffer.result.buf, 1, m.mb_data^.mbp_reclen,
                  m.mb_trns^.trError_gg00);
            IF  m.mb_trns^.trError_gg00 = e_ok
            THEN
                BEGIN
                k722_add_union_record (m.mb_trns^, selrec);
                _recpos := _recpos + m.mb_data^.mbp_reclen;
                END
            (*ENDIF*) 
            END;
        (*ENDWHILE*) 
        IF  m.mb_trns^.trError_gg00 = e_ok
        THEN
            m.mb_trns^.trError_gg00 := _next_error
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    END;
(*ENDWHILE*) 
IF  m.mb_trns^.trError_gg00 = e_no_next_record
THEN
    m.mb_trns^.trError_gg00 := e_ok;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      k722_add_union_record (
            VAR t        : tgg00_TransContext;
            VAR selrec   : tgg07_select_param);
 
VAR
      _set_result : tgg00_BdSetResultRecord;
      _is_equal   : boolean;
      _lc         : tsp00_LcompResult;
      _next_error : tgg00_BasisError;
      _recpos     : integer;
      _buflen     : integer;
      _tree1_pos  : tgg00_FilePos;
      _inv_key    : tgg00_Lkey;
      _res_key    : tgg00_Lkey;
 
BEGIN
WITH selrec.selr_selectbuffer.result DO
    BEGIN
    _is_equal := false;
    IF  selrec.selr.selr_append_all
    THEN
        BEGIN
        SAPDB_PascalFill ('VKB722',   4,
              sizeof(selrec.selr_selectbuffer.result.info),
              @selrec.selr_selectbuffer.result.info,
              1, selrec.selr_selectbuffer.result.keylen - RESCNT_MXGG04,
              chr (0), t.trError_gg00);
        selrec.selr.selr_countresult := succ (selrec.selr.selr_countresult);
        s20ch4sw (selrec.selr.selr_countresult + selrec.selr.selr_key_cnt_offs,
              g01code.kernel_swap, selrec.selr_selectbuffer.result.info,
              selrec.selr_selectbuffer.result.keylen - 3, sw_normal);
        IF  t.trError_gg00 = e_ok
        THEN
            BEGIN
            b07cappend_record (t, selrec.selr.selr_resf_id, selrec.selr.selr_tree_pos,
                  selrec.selr_selectbuffer.result);
            IF  t.trRteCommPtr_gg00^.to_cancel
            THEN
                t.trError_gg00 := e_cancelled;
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END
    ELSE
        BEGIN
        kb722_build_union_invkey (selrec.selr_selectbuffer.result,
              _inv_key, t.trError_gg00);
        WITH _set_result DO
            BEGIN
            bd_key_check_len := _inv_key.len - RESCNT_MXGG04;
            bd_max_rec_cnt   := csp_maxint2;
            bd_max_fill_len  := mxsp_buf;
            bd_next          := false;
            bd_drop_page     := false;
            END;
        (*ENDWITH*) 
        _tree1_pos.tpsPno_gg00 := NIL_PAGE_NO_GG00;
        IF  (t.trError_gg00 = e_ok) AND
            NOT (selrec.selr.selr_isunion AND selrec.selr.selr_isall)
        THEN
            REPEAT
                b07cnext_record (t, selrec.selr.selr_resf_id, _inv_key,
                      _set_result, _tree1_pos,
                      selrec.selr_selectbuffer.buf_rec.buf);
                _is_equal := false;
                _recpos   := 0;
                IF  t.trRteCommPtr_gg00^.to_cancel
                THEN
                    t.trError_gg00 := e_cancelled;
                (*ENDIF*) 
                IF  t.trError_gg00 = e_key_not_found
                THEN
                    BEGIN
                    _next_error := e_ok;
                    t.trError_gg00   := e_ok
                    END
                ELSE
                    IF  t.trError_gg00 = e_buffer_limit
                    THEN
                        BEGIN
                        _next_error := e_buffer_limit;
                        t.trError_gg00   := e_ok
                        END
                    ELSE
                        _next_error := t.trError_gg00;
                    (*ENDIF*) 
                (*ENDIF*) 
                IF  t.trError_gg00 = e_ok
                THEN
                    BEGIN
                    _buflen   := _set_result.bd_fill_len;
                    _is_equal := false;
                    WHILE (NOT _is_equal) AND (_recpos < _buflen) DO
                        BEGIN
                        s30lcm (selrec.selr_selectbuffer.buf_rec.buf,
                              _recpos + keylen + cgg_rec_key_offset + 1,
                              len - keylen - cgg_rec_key_offset - 1,
                              selrec.selr_selectbuffer.result.buf,
                              keylen + cgg_rec_key_offset + 1,
                              len - keylen - cgg_rec_key_offset - 1, _lc);
                        _is_equal := _lc = l_equal;
                        _recpos   := _recpos + len
                        END;
                    (*ENDWHILE*) 
                    g10mv ('VKB722',   5,
                          sizeof(selrec.selr_selectbuffer.buf_rec.buf),
                          sizeof(_res_key.k),
                          @selrec.selr_selectbuffer.buf_rec.buf,
                          _recpos + cgg_rec_key_offset + 1 - len,
                          @_res_key.k, 1, keylen, t.trError_gg00);
                    _res_key.len := keylen;
&                   ifdef TRACE
                    t01lkey (kb, _res_key);
                    t01lkey (kb, _inv_key);
&                   endif
                    END;
                (*ENDIF*) 
                IF  t.trError_gg00 = e_ok
                THEN
                    t.trError_gg00 := _next_error;
                (*ENDIF*) 
            UNTIL
                _is_equal OR (t.trError_gg00 <> e_buffer_limit);
            (*ENDREPEAT*) 
        (*ENDIF*) 
        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
            BEGIN
            IF  selrec.selr.selr_isexcept
            THEN
                IF  _is_equal
                THEN
                    BEGIN
&                   ifdef TRACE
                    t01lkey (kb, _res_key);
&                   endif
                    b07cdel_record (t, selrec.selr.selr_resf_id, _res_key);
                    selrec.selr.selr_countresult := pred (selrec.selr.selr_countresult);
                    IF  t.trError_gg00 = e_key_not_found
                    THEN
                        t.trError_gg00    := e_ok
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
            (*ENDIF*) 
            IF  selrec.selr.selr_isintersect  AND
                _is_equal
            THEN
                (* PTS 1122903 E.Z. *)
                BEGIN
                (* *** intersected record is inserted into      *)
                (*     selrec.selr.selr_intersect_id auxfile     *** *)
                selrec.selr.selr_countresult := succ (selrec.selr.selr_countresult);
                s20ch4sw (selrec.selr.selr_countresult +
                      selrec.selr.selr_key_cnt_offs,
                      g01code.kernel_swap,
                      selrec.selr_selectbuffer.result.info,
                      selrec.selr_selectbuffer.result.keylen - 3, sw_normal);
                b07cadd_record (t, selrec.selr.selr_intersect_id,
                      selrec.selr_selectbuffer.result);
                (* *** delete union_id record. This makes        *)
                (*     an one to one relation between the two    *)
                (*     selects (intersect all)               *** *)
                IF  t.trError_gg00 = e_ok
                THEN
                    b07cdel_record (t, selrec.selr.selr_resf_id, _res_key);
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  selrec.selr.selr_isunion          AND
                (selrec.selr.selr_isall        OR
                (NOT _is_equal)  )
            THEN
                BEGIN
                selrec.selr.selr_countresult := succ (selrec.selr.selr_countresult);
                s20ch4sw (selrec.selr.selr_countresult + selrec.selr.selr_key_cnt_offs,
                      g01code.kernel_swap,
                      selrec.selr_selectbuffer.result.info,
                      selrec.selr_selectbuffer.result.keylen - 3, sw_normal);
                b07cadd_record (t, selrec.selr.selr_resf_id,
                      selrec.selr_selectbuffer.result);
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    (* PTS 1122903 E.Z. *)
    IF  (t.trError_gg00 = e_ok) AND NOT selrec.selr.selr_isexcept
    THEN
        IF  (selrec.selr.selr_countresult > 0) AND
            (selrec.selr.selr_countresult = selrec.selr.selr_rowno)
        THEN
            t.trError_gg00 := e_enough_resultsets
        ELSE
            IF  ((selrec.selr.selr_countresult = 2) AND (selrec.selr.selr_maxresult = 0))
            THEN
                t.trError_gg00 := e_too_many_resultsets
            (*ENDIF*) 
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      k722_union_select (VAR m : tgg00_MessBlock);
 
VAR
      _union_kind : tsp00_Uint1;
      _res        : tsp00_NumError;
      _ic2        : tsp_int_map_c2;
      _old_cntres : tsp00_Int4;
      _aux_error  : tgg00_BasisError;
      _source_id  : tgg00_FileId;
      _selrec     : tgg07_select_param;
 
BEGIN
b73cmd_count (iins_sorts);
_selrec.selr.selr_resf_id := m.mb_qual^.mtree;
g10mv ('VKB722',   6,
      m.mb_qual_size, sizeof(_source_id),
      @m.mb_qual^.buf, MB_PART1_HEAD_MXGG00 + 1,
      @_source_id, 1, sizeof(_source_id), m.mb_trns^.trError_gg00);
_union_kind := ord (m.mb_qual^.buf[ MB_PART1_HEAD_MXGG00 +
      FILE_ID_MXGG00 + 1 ]);
_selrec.selr.selr_append_all := _union_kind > cgg04_union_append;
IF  _selrec.selr.selr_append_all
THEN
    BEGIN
    _union_kind          := _union_kind - cgg04_union_append;
    _selrec.selr.selr_tree_pos.tpsPno_gg00 := NIL_PAGE_NO_GG00;
    END;
(*ENDIF*) 
_selrec.selr.selr_isall := _union_kind > 3;
IF  _selrec.selr.selr_isall
THEN
    _union_kind := _union_kind - 3;
(*ENDIF*) 
_selrec.selr.selr_isunion     := _union_kind = cgg04_union_byte;
_selrec.selr.selr_isexcept    := _union_kind = cgg04_except_byte;
_selrec.selr.selr_isintersect := _union_kind = cgg04_intersect_byte;
IF  _selrec.selr.selr_isintersect
THEN
    BEGIN
    _selrec.selr.selr_countresult              := 0;
    _selrec.selr.selr_intersect_id             := m.mb_qual^.mtree;
    _selrec.selr.selr_intersect_id.fileTfnTemp_gg00 := ttfnUnionIntersect_egg00;
    _selrec.selr.selr_intersect_id.fileRoot_gg00    := NIL_PAGE_NO_GG00;
    b01tcreate_file (m.mb_trns^, _selrec.selr.selr_intersect_id);
    END
ELSE
    _selrec.selr.selr_countresult := s20or4a (m.mb_qual^.buf,
          MB_PART1_HEAD_MXGG00 + FILE_ID_MXGG00 + 2);
(*ENDIF*) 
_old_cntres := _selrec.selr.selr_countresult;
_selrec.selr.selr_key_cnt_offs := s20or4a (m.mb_qual^.buf,
      MB_PART1_HEAD_MXGG00 + FILE_ID_MXGG00 + 6);
(* *** determine the number of records wanted *** *)
_ic2.map_c2 [ 1 ] := m.mb_qual^.buf[ m.mb_qual_len  - 1 ];
_ic2.map_c2 [ 2 ] := m.mb_qual^.buf[ m.mb_qual_len  ];
IF  _ic2.map_int = cgg04_subquery_one_record
THEN
    BEGIN
    _selrec.selr.selr_maxresult := 0;
    _selrec.selr.selr_rowno     := 0;
    END
ELSE
    IF  _ic2.map_int = cgg04_at_least_one_record
    THEN
        BEGIN
        _selrec.selr.selr_maxresult := 1;
        _selrec.selr.selr_rowno     := 1;
        END
    ELSE
        BEGIN
        _selrec.selr.selr_maxresult := csp_maxint4;
        _selrec.selr.selr_rowno     := csp_maxint4;
        END;
    (*ENDIF*) 
(*ENDIF*) 
&ifdef trace
IF  ( _union_kind = cgg04_union_byte )
THEN
    BEGIN
    IF  ( _selrec.selr.selr_isall )
    THEN
        t01sname( kb, 'UNION ALL   ' )
    ELSE
        t01sname( kb, 'UNION       ' )
    (*ENDIF*) 
    END
ELSE
    IF  ( _union_kind = cgg04_except_byte )
    THEN
        BEGIN
        IF  ( _selrec.selr.selr_isall )
        THEN
            t01sname( kb, 'EXEPT ALL   ' )
        ELSE
            t01sname( kb, 'EXEPT       ' )
        (*ENDIF*) 
        END
    ELSE
        BEGIN
        IF  ( _selrec.selr.selr_isall )
        THEN
            t01sname( kb, 'INTERSCT ALL' )
        ELSE
            t01sname( kb, 'INTERSECT   ' );
        (*ENDIF*) 
        END;
    (*ENDIF*) 
(*ENDIF*) 
t01int4    (kb, 'key_cnt_offs', _selrec.selr.selr_key_cnt_offs);
t01treeid (kb, 'source_id   ', _source_id);
t01int4    (kb, 'countresult ', _selrec.selr.selr_countresult);
t01site   (kb, 'src_id.rsite', _source_id.fileResultSite_gg00);
t01treeid (kb, 'result_id   ', _selrec.selr.selr_resf_id);
&endif
(* *** begin source_id file (2. select) handling *** *)
IF  (m.mb_trns^.trError_gg00 =  e_ok)
THEN
    kb722_process_union  (m, _selrec, _source_id);
(* *** end   source_id file (2. select) handling *** *)
(*ENDIF*) 
IF  (m.mb_trns^.trError_gg00 = e_no_next_record)   OR
    (m.mb_trns^.trError_gg00 = e_enough_resultsets)
THEN
    m.mb_trns^.trError_gg00 := e_ok;
(*ENDIF*) 
IF  _selrec.selr.selr_isexcept
THEN
    IF  ((_selrec.selr.selr_countresult >= 2) AND (_selrec.selr.selr_maxresult = 0))
    THEN
        m.mb_trns^.trError_gg00 := e_too_many_resultsets;
    (*ENDIF*) 
(*ENDIF*) 
IF  _selrec.selr.selr_isintersect
THEN
    BEGIN
    IF  (m.mb_trns^.trError_gg00 = e_ok)
    THEN
        b01move_filecontent (m.mb_trns^,
              _selrec.selr.selr_intersect_id, _selrec.selr.selr_resf_id);
    (*ENDIF*) 
    _aux_error := m.mb_trns^.trError_gg00;
    b01destroy_file (m.mb_trns^, _selrec.selr.selr_intersect_id);
    IF  _aux_error <> e_ok
    THEN
        m.mb_trns^.trError_gg00 := _aux_error;
    (*ENDIF*) 
    END;
(*ENDIF*) 
_aux_error := m.mb_trns^.trError_gg00;
b01destroy_file (m.mb_trns^, _source_id);
IF  _aux_error <> e_ok
THEN
    m.mb_trns^.trError_gg00 := _aux_error;
(*ENDIF*) 
IF  m.mb_trns^.trError_gg00 = e_ok
THEN
    (* *** put return parameters 'countresult',                        *)
    (*     'selr.selr_key_cnt_offs', and 'resf_id' into message_buffer. *** *)
    BEGIN
    IF  (_selrec.selr.selr_countresult - _old_cntres > 0)
    THEN
        b73cmds_count (iins_sorts_rows_ins,
              (_selrec.selr.selr_countresult - _old_cntres));
&   ifdef trace
    (*ENDIF*) 
    t01int4 (kb, 'countresult ', _selrec.selr.selr_countresult);
    t01int4 (kb, 'key_cnt_offs', _selrec.selr.selr_key_cnt_offs);
&   endif
    s41p4int (m.mb_qual^.mr_resnum, 2, _selrec.selr.selr_countresult, _res);
    m.mb_qual^.mr_res_build   := true;
    m.mb_qual^.mr_resnum[ 1 ] := csp_defined_byte;
    m.mb_qual^.mr_restree     := _selrec.selr.selr_resf_id;
    s41p4int (m.mb_qual^.mr_keycnt, 2, _selrec.selr.selr_key_cnt_offs, _res);
    m.mb_qual^.mr_keycnt[ 1 ] := csp_defined_byte;
    m.mb_qual_len  := MB_PART1_HEAD_MXGG00 +
          2 * (sizeof(tsp00_ResNum) + 1) + FILE_ID_MXGG00;
    m.mb_data_len   := 0;
    m.mb_type       := m_return_result;
    m.mb_type2      := mm_file
    END
(*ENDIF*) 
END;
 
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
.PA 
